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