1 /* $NetBSD: fsaccess.c,v 1.1 2024/02/18 20:57:49 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 /*! \file
17 * \brief
18 * This file contains the OS-independent functionality of the API.
19 */
20 #include <stdbool.h>
21
22 #include <isc/fsaccess.h>
23 #include <isc/print.h>
24 #include <isc/result.h>
25 #include <isc/util.h>
26
27 /*!
28 * Shorthand. Maybe ISC__FSACCESS_PERMISSIONBITS should not even be in
29 * <isc/fsaccess.h>. Could check consistency with sizeof(isc_fsaccess_t)
30 * and the number of bits in each function.
31 */
32 #define STEP (ISC__FSACCESS_PERMISSIONBITS)
33 #define GROUP (STEP)
34 #define OTHER (STEP * 2)
35
36 void
isc_fsaccess_add(int trustee,int permission,isc_fsaccess_t * access)37 isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access) {
38 REQUIRE(trustee <= 0x7);
39 REQUIRE(permission <= 0xFF);
40
41 if ((trustee & ISC_FSACCESS_OWNER) != 0) {
42 *access |= permission;
43 }
44
45 if ((trustee & ISC_FSACCESS_GROUP) != 0) {
46 *access |= (permission << GROUP);
47 }
48
49 if ((trustee & ISC_FSACCESS_OTHER) != 0) {
50 *access |= (permission << OTHER);
51 }
52 }
53
54 void
isc_fsaccess_remove(int trustee,int permission,isc_fsaccess_t * access)55 isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access) {
56 REQUIRE(trustee <= 0x7);
57 REQUIRE(permission <= 0xFF);
58
59 if ((trustee & ISC_FSACCESS_OWNER) != 0) {
60 *access &= ~permission;
61 }
62
63 if ((trustee & ISC_FSACCESS_GROUP) != 0) {
64 *access &= ~(permission << GROUP);
65 }
66
67 if ((trustee & ISC_FSACCESS_OTHER) != 0) {
68 *access &= ~(permission << OTHER);
69 }
70 }
71
72 static isc_result_t
check_bad_bits(isc_fsaccess_t access,bool is_dir)73 check_bad_bits(isc_fsaccess_t access, bool is_dir) {
74 isc_fsaccess_t bits;
75
76 /*
77 * Check for disallowed user bits.
78 */
79 if (is_dir) {
80 bits = ISC_FSACCESS_READ | ISC_FSACCESS_WRITE |
81 ISC_FSACCESS_EXECUTE;
82 } else {
83 bits = ISC_FSACCESS_CREATECHILD | ISC_FSACCESS_ACCESSCHILD |
84 ISC_FSACCESS_DELETECHILD | ISC_FSACCESS_LISTDIRECTORY;
85 }
86
87 /*
88 * Set group bad bits.
89 */
90 bits |= bits << STEP;
91 /*
92 * Set other bad bits.
93 */
94 bits |= bits << STEP;
95
96 if ((access & bits) != 0) {
97 if (is_dir) {
98 return (ISC_R_NOTFILE);
99 } else {
100 return (ISC_R_NOTDIRECTORY);
101 }
102 }
103
104 return (ISC_R_SUCCESS);
105 }
106