1 /* $NetBSD: fsaccess.h,v 1.1 2024/02/18 20:57:52 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 #ifndef ISC_FSACCESS_H 17 #define ISC_FSACCESS_H 1 18 19 /*! \file isc/fsaccess.h 20 * \brief The ISC filesystem access module encapsulates the setting of file 21 * and directory access permissions into one API that is meant to be 22 * portable to multiple operating systems. 23 * 24 * The two primary operating system flavors that are initially accommodated 25 * are POSIX and Windows NT 4.0 and later. The Windows NT access model is 26 * considerable more flexible than POSIX's model (as much as I am loathe to 27 * admit it), and so the ISC API has a higher degree of complexity than would 28 * be needed to simply address POSIX's needs. 29 * 30 * The full breadth of NT's flexibility is not available either, for the 31 * present time. Much of it is to provide compatibility with what Unix 32 * programmers are expecting. This is also due to not yet really needing all 33 * of the functionality of an NT system (or, for that matter, a POSIX system) 34 * in BIND9, and so resolving how to handle the various incompatibilities has 35 * been a purely theoretical exercise with no operational experience to 36 * indicate how flawed the thinking may be. 37 * 38 * Some of the more notable dumbing down of NT for this API includes: 39 * 40 *\li Each of FILE_READ_DATA and FILE_READ_EA are set with #ISC_FSACCESS_READ. 41 * 42 * \li All of FILE_WRITE_DATA, FILE_WRITE_EA and FILE_APPEND_DATA are 43 * set with #ISC_FSACCESS_WRITE. FILE_WRITE_ATTRIBUTES is not set 44 * so as to be consistent with Unix, where only the owner of the file 45 * or the superuser can change the attributes/mode of a file. 46 * 47 * \li Both of FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY are set with 48 * #ISC_FSACCESS_CREATECHILD. This is similar to setting the WRITE 49 * permission on a Unix directory. 50 * 51 * \li SYNCHRONIZE is always set for files and directories, unless someone 52 * can give me a reason why this is a bad idea. 53 * 54 * \li READ_CONTROL and FILE_READ_ATTRIBUTES are always set; this is 55 * consistent with Unix, where any file or directory can be stat()'d 56 * unless the directory path disallows complete access somewhere along 57 * the way. 58 * 59 * \li WRITE_DAC is only set for the owner. This too is consistent with 60 * Unix, and is tighter security than allowing anyone else to be 61 * able to set permissions. 62 * 63 * \li DELETE is only set for the owner. On Unix the ability to delete 64 * a file is controlled by the directory permissions, but it isn't 65 * currently clear to me what happens on NT if the directory has 66 * FILE_DELETE_CHILD set but a file within it does not have DELETE 67 * set. Always setting DELETE on the file/directory for the owner 68 * gives maximum flexibility to the owner without exposing the 69 * file to deletion by others. 70 * 71 * \li WRITE_OWNER is never set. This too is consistent with Unix, 72 * and is also tighter security than allowing anyone to change the 73 * ownership of the file apart from the superu..ahem, Administrator. 74 * 75 * \li Inheritance is set to NO_INHERITANCE. 76 * 77 * Unix's dumbing down includes: 78 * 79 * \li The sticky bit cannot be set. 80 * 81 * \li setuid and setgid cannot be set. 82 * 83 * \li Only regular files and directories can be set. 84 * 85 * The rest of this comment discusses a few of the incompatibilities 86 * between the two systems that need more thought if this API is to 87 * be extended to accommodate them. 88 * 89 * The Windows standard access right "DELETE" doesn't have a direct 90 * equivalent in the Unix world, so it isn't clear what should be done 91 * with it. 92 * 93 * The Unix sticky bit is not supported. While NT does have a concept 94 * of allowing users to create files in a directory but not delete or 95 * rename them, it does not have a concept of allowing them to be deleted 96 * if they are owned by the user trying to delete/rename. While it is 97 * probable that something could be cobbled together in NT 5 with inheritance, 98 * it can't really be done in NT 4 as a single property that you could 99 * set on a directory. You'd need to coordinate something with file creation 100 * so that every file created had DELETE set for the owner but no one else. 101 * 102 * On Unix systems, setting #ISC_FSACCESS_LISTDIRECTORY sets READ. 103 * ... setting either #ISC_FSACCESS_CREATECHILD or #ISC_FSACCESS_DELETECHILD 104 * sets WRITE. 105 * ... setting #ISC_FSACCESS_ACCESSCHILD sets EXECUTE. 106 * 107 * On NT systems, setting #ISC_FSACCESS_LISTDIRECTORY sets FILE_LIST_DIRECTORY. 108 * ... setting #ISC_FSACCESS_CREATECHILD sets FILE_CREATE_CHILD independently. 109 * ... setting #ISC_FSACCESS_DELETECHILD sets FILE_DELETE_CHILD independently. 110 * ... setting #ISC_FSACCESS_ACCESSCHILD sets FILE_TRAVERSE. 111 * 112 * Unresolved: XXXDCL 113 * \li What NT access right controls the ability to rename a file? 114 * \li How does DELETE work? If a directory has FILE_DELETE_CHILD but a 115 * file or directory within it does not have DELETE, is that file 116 * or directory deletable? 117 * \li To implement isc_fsaccess_get(), mapping an existing Unix permission 118 * mode_t back to an isc_fsaccess_t is pretty trivial; however, mapping 119 * an NT DACL could be impossible to do in a responsible way. 120 * \li Similarly, trying to implement the functionality of being able to 121 * say "add group writability to whatever permissions already exist" 122 * could be tricky on NT because of the order-of-entry issue combined 123 * with possibly having one or more matching ACEs already explicitly 124 * granting or denying access. Because this functionality is 125 * not yet needed by the ISC, no code has been written to try to 126 * solve this problem. 127 */ 128 129 #include <inttypes.h> 130 131 #include <isc/lang.h> 132 #include <isc/types.h> 133 134 /* 135 * Trustees. 136 */ 137 #define ISC_FSACCESS_OWNER 0x1 /*%< User account. */ 138 #define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */ 139 #define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */ 140 #define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */ 141 142 /* 143 * Types of permission. 144 */ 145 #define ISC_FSACCESS_READ 0x00000001 /*%< File only. */ 146 #define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */ 147 #define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */ 148 #define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */ 149 #define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */ 150 #define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */ 151 #define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */ 152 153 /*% 154 * Adding any permission bits beyond 0x200 would mean typedef'ing 155 * isc_fsaccess_t as uint64_t, and redefining this value to 156 * reflect the new range of permission types, Probably to 21 for 157 * maximum flexibility. The number of bits has to accommodate all of 158 * the permission types, and three full sets of them have to fit 159 * within an isc_fsaccess_t. 160 */ 161 #define ISC__FSACCESS_PERMISSIONBITS 10 162 163 ISC_LANG_BEGINDECLS 164 165 void 166 isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access); 167 168 void 169 isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access); 170 171 isc_result_t 172 isc_fsaccess_set(const char *path, isc_fsaccess_t access); 173 174 ISC_LANG_ENDDECLS 175 176 #endif /* ISC_FSACCESS_H */ 177