xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/fsaccess.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
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