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 "includes.h" 24 : #include "librpc/gen_ndr/ndr_security.h" 25 : #include "libcli/security/security.h" 26 : #include "lib/util/tsort.h" 27 : 28 : #define SEC_ACE_HEADER_SIZE (2 * sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t)) 29 : 30 : /** 31 : * Check if ACE has OBJECT type. 32 : */ 33 4 : bool sec_ace_object(uint8_t type) 34 : { 35 4 : if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || 36 4 : type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || 37 4 : type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || 38 : type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { 39 0 : return true; 40 : } 41 4 : return false; 42 : } 43 : 44 : /** 45 : * copy a struct security_ace structure. 46 : */ 47 0 : void sec_ace_copy(struct security_ace *ace_dest, const struct security_ace *ace_src) 48 : { 49 0 : ace_dest->type = ace_src->type; 50 0 : ace_dest->flags = ace_src->flags; 51 0 : ace_dest->size = ace_src->size; 52 0 : ace_dest->access_mask = ace_src->access_mask; 53 0 : ace_dest->object = ace_src->object; 54 0 : ace_dest->trustee = ace_src->trustee; 55 0 : } 56 : 57 : /******************************************************************* 58 : Sets up a struct security_ace structure. 59 : ********************************************************************/ 60 : 61 70870 : void init_sec_ace(struct security_ace *t, const struct dom_sid *sid, enum security_ace_type type, 62 : uint32_t mask, uint8_t flag) 63 : { 64 70870 : t->type = type; 65 70870 : t->flags = flag; 66 70870 : t->size = ndr_size_dom_sid(sid, 0) + 8; 67 70870 : t->access_mask = mask; 68 : 69 70870 : t->trustee = *sid; 70 70870 : } 71 : 72 41948 : int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2) 73 : { 74 41948 : int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE; 75 41948 : int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE; 76 : 77 41948 : if (a1_inh == a2_inh) 78 41948 : return 0; 79 : 80 0 : if (!a1_inh && a2_inh) 81 0 : return -1; 82 0 : return 1; 83 : } 84 : 85 : /******************************************************************* 86 : Comparison function to apply the order explained below in a group. 87 : *******************************************************************/ 88 : 89 46892 : int nt_ace_canon_comp( const struct security_ace *a1, const struct security_ace *a2) 90 : { 91 46892 : if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) && 92 0 : (a2->type != SEC_ACE_TYPE_ACCESS_DENIED)) 93 0 : return -1; 94 : 95 46892 : if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) && 96 0 : (a1->type != SEC_ACE_TYPE_ACCESS_DENIED)) 97 0 : return 1; 98 : 99 : /* Both access denied or access allowed. */ 100 : 101 : /* 1. ACEs that apply to the object itself */ 102 : 103 46892 : if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) && 104 44449 : (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY)) 105 2065 : return -1; 106 44827 : else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) && 107 43783 : (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY)) 108 1399 : return 1; 109 : 110 : /* 2. ACEs that apply to a subobject of the object, such as 111 : * a property set or property. */ 112 : 113 43428 : if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && 114 17489 : !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) 115 578 : return -1; 116 42850 : else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) && 117 22559 : !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT))) 118 5648 : return 1; 119 : 120 37202 : return 0; 121 : } 122 : 123 : /******************************************************************* 124 : Functions to convert a SEC_DESC ACE DACL list into canonical order. 125 : JRA. 126 : 127 : --- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp 128 : 129 : The following describes the preferred order: 130 : 131 : To ensure that noninherited ACEs have precedence over inherited ACEs, 132 : place all noninherited ACEs in a group before any inherited ACEs. 133 : This ordering ensures, for example, that a noninherited access-denied ACE 134 : is enforced regardless of any inherited ACE that allows access. 135 : 136 : Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows: 137 : 1. Access-denied ACEs that apply to the object itself 138 : 2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property 139 : 3. Access-allowed ACEs that apply to the object itself 140 : 4. Access-allowed ACEs that apply to a subobject of the object" 141 : 142 : ********************************************************************/ 143 : 144 6212 : void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces) 145 : { 146 : unsigned int i; 147 : 148 6212 : if (!srclist || num_aces == 0) 149 0 : return; 150 : 151 : /* Sort so that non-inherited ACE's come first. */ 152 6212 : TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp); 153 : 154 : /* Find the boundary between non-inherited ACEs. */ 155 36192 : for (i = 0; i < num_aces; i++ ) { 156 29980 : struct security_ace *curr_ace = &srclist[i]; 157 : 158 29980 : if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE) 159 0 : break; 160 : } 161 : 162 : /* i now points at entry number of the first inherited ACE. */ 163 : 164 : /* Sort the non-inherited ACEs. */ 165 6212 : TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp); 166 : 167 : /* Now sort the inherited ACEs. */ 168 6212 : TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp); 169 : } 170 : 171 :