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