Line data Source code
1 : /* 2 : * Unix SMB/Netbios implementation. 3 : * struct security_ace handling functions 4 : * Copyright (C) Andrew Tridgell 1992-1998, 5 : * Copyright (C) Jeremy R. Allison 1995-2003. 6 : * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, 7 : * Copyright (C) Paul Ashton 1997-1998. 8 : * 9 : * This program is free software; you can redistribute it and/or modify 10 : * it under the terms of the GNU General Public License as published by 11 : * the Free Software Foundation; either version 3 of the License, or 12 : * (at your option) any later version. 13 : * 14 : * This program is distributed in the hope that it will be useful, 15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : * GNU General Public License for more details. 18 : * 19 : * You should have received a copy of the GNU General Public License 20 : * along with this program; if not, see <http://www.gnu.org/licenses/>. 21 : */ 22 : 23 : #include "replace.h" 24 : #include "librpc/gen_ndr/ndr_security.h" 25 : #include "libcli/security/security.h" 26 : #include "lib/util/tsort.h" 27 : 28 : /** 29 : * Check if ACE has OBJECT type. 30 : */ 31 523306795 : bool sec_ace_object(uint8_t type) 32 : { 33 523306795 : if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || 34 204080076 : type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || 35 198942044 : type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || 36 198942044 : type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT || 37 198942044 : type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT || 38 179491882 : type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT || 39 : type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT) { 40 : /* 41 : * MS-DTYP has a reserved value for 42 : * SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT, but we 43 : * don't assume that it will be an object ACE just 44 : * because it sounds like one. 45 : */ 46 333466488 : return true; 47 : } 48 179491882 : return false; 49 : } 50 : 51 : /** 52 : * Check if ACE is a CALLBACK type, which means it will have a blob of data at 53 : * the end. 54 : */ 55 314611141 : bool sec_ace_callback(uint8_t type) 56 : { 57 314611141 : if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK || 58 302328437 : type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK || 59 302328437 : type == SEC_ACE_TYPE_ACCESS_ALLOWED_CALLBACK_OBJECT || 60 314605609 : type == SEC_ACE_TYPE_ACCESS_DENIED_CALLBACK_OBJECT || 61 314605609 : type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK || 62 12277172 : type == SEC_ACE_TYPE_SYSTEM_AUDIT_CALLBACK_OBJECT) { 63 : /* 64 : * While SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK and 65 : * SEC_ACE_TYPE_SYSTEM_ALARM_CALLBACK_OBJECT sound like 66 : * callback types, they are reserved values in MS-DTYP, 67 : * and their eventual use is not defined. 68 : */ 69 9118 : return true; 70 : } 71 302328437 : return false; 72 : } 73 : 74 : /** 75 : * Check if an ACE type is resource attribute, which means it will 76 : * have a blob of data at the end defining an attribute on the object. 77 : * Resource attribute ACEs should only occur in SACLs. 78 : */ 79 232208910 : bool sec_ace_resource(uint8_t type) 80 : { 81 232208910 : return type == SEC_ACE_TYPE_SYSTEM_RESOURCE_ATTRIBUTE; 82 : } 83 : 84 219120487 : bool sec_ace_has_extra_blob(uint8_t type) 85 : { 86 219120487 : return sec_ace_callback(type) || sec_ace_resource(type); 87 : } 88 : 89 : 90 : /******************************************************************* 91 : Sets up a struct security_ace structure. 92 : ********************************************************************/ 93 : 94 2535331 : void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum security_ace_type type, 95 : uint32_t mask, uint8_t flag) 96 : { 97 2535331 : t->type = type; 98 2535331 : t->flags = flag; 99 2535331 : t->size = ndr_size_dom_sid(sid, 0) + 8; 100 2535331 : t->access_mask = mask; 101 : 102 2535331 : t->trustee = *sid; 103 2535331 : t->coda.ignored.data = NULL; 104 2535331 : t->coda.ignored.length = 0; 105 2535331 : } 106 : 107 1821715 : int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2) 108 : { 109 1821715 : int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE; 110 1821715 : int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE; 111 : 112 1821715 : if (a1_inh == a2_inh) 113 1813601 : return 0; 114 : 115 0 : if (!a1_inh && a2_inh) 116 0 : return -1; 117 0 : return 1; 118 : } 119 : 120 : /******************************************************************* 121 : Comparison function to apply the order explained below in a group. 122 : *******************************************************************/ 123 : 124 1842612 : int nt_ace_canon_comp( const struct security_ace *a1, const struct security_ace *a2) 125 : { 126 1842612 : if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) && 127 0 : (a2->type != SEC_ACE_TYPE_ACCESS_DENIED)) 128 0 : return -1; 129 : 130 1842612 : if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) && 131 0 : (a1->type != SEC_ACE_TYPE_ACCESS_DENIED)) 132 0 : return 1; 133 : 134 : /* Both access denied or access allowed. */ 135 : 136 : /* 1. ACEs that apply to the object itself */ 137 : 138 1842612 : if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) && 139 1826214 : (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY)) 140 24757 : return -1; 141 1817583 : else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) && 142 1796112 : (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY)) 143 2981 : return 1; 144 : 145 : /* 2. ACEs that apply to a subobject of the object, such as 146 : * a property set or property. */ 147 : 148 1814506 : if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && 149 96723 : !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) 150 11993 : return -1; 151 1802401 : else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && 152 116380 : !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) 153 32206 : return 1; 154 : 155 1762673 : return 0; 156 : } 157 : 158 : /******************************************************************* 159 : Functions to convert a SEC_DESC ACE DACL list into canonical order. 160 : JRA. 161 : 162 : --- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp 163 : 164 : The following describes the preferred order: 165 : 166 : To ensure that noninherited ACEs have precedence over inherited ACEs, 167 : place all noninherited ACEs in a group before any inherited ACEs. 168 : This ordering ensures, for example, that a noninherited access-denied ACE 169 : is enforced regardless of any inherited ACE that allows access. 170 : 171 : Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows: 172 : 1. Access-denied ACEs that apply to the object itself 173 : 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property 174 : 3. Access-allowed ACEs that apply to the object itself 175 : 4. Access-allowed ACEs that apply to a subobject of the object" 176 : 177 : ********************************************************************/ 178 : 179 420648 : void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces) 180 : { 181 1655 : unsigned int i; 182 : 183 420648 : if (!srclist || num_aces == 0) 184 0 : return; 185 : 186 : /* Sort so that non-inherited ACE's come first. */ 187 420648 : TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp); 188 : 189 : /* Find the boundary between non-inherited ACEs. */ 190 2038638 : for (i = 0; i < num_aces; i++ ) { 191 1617990 : struct security_ace *curr_ace = &srclist[i]; 192 : 193 1617990 : if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE) 194 0 : break; 195 : } 196 : 197 : /* i now points at entry number of the first inherited ACE. */ 198 : 199 : /* Sort the non-inherited ACEs. */ 200 420648 : TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp); 201 : 202 : /* Now sort the inherited ACEs. */ 203 420648 : TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp); 204 : }