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 70818 : 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 70818 : t->type = type;
65 70818 : t->flags = flag;
66 70818 : t->size = ndr_size_dom_sid(sid, 0) + 8;
67 70818 : t->access_mask = mask;
68 :
69 70818 : t->trustee = *sid;
70 70818 : }
71 :
72 41836 : int nt_ace_inherit_comp(const struct security_ace *a1, const struct security_ace *a2)
73 : {
74 41836 : int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
75 41836 : int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
76 :
77 41836 : if (a1_inh == a2_inh)
78 41836 : 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 46760 : int nt_ace_canon_comp( const struct security_ace *a1, const struct security_ace *a2)
90 : {
91 46760 : if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
92 0 : (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
93 0 : return -1;
94 :
95 46760 : 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 81407 : if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
104 44325 : (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
105 2063 : return -1;
106 78868 : else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
107 43655 : (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
108 1393 : return 1;
109 :
110 : /* 2. ACEs that apply to a subobject of the object, such as
111 : * a property set or property. */
112 :
113 57273 : if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
114 17441 : !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
115 578 : return -1;
116 60846 : else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
117 22489 : !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
118 5626 : return 1;
119 :
120 37100 : 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 6192 : void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces)
145 : {
146 : unsigned int i;
147 :
148 6192 : if (!srclist || num_aces == 0)
149 0 : return;
150 :
151 : /* Sort so that non-inherited ACE's come first. */
152 6192 : TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp);
153 :
154 : /* Find the boundary between non-inherited ACEs. */
155 36088 : for (i = 0; i < num_aces; i++ ) {
156 29896 : struct security_ace *curr_ace = &srclist[i];
157 :
158 29896 : 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 6192 : TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp);
166 :
167 : /* Now sort the inherited ACEs. */
168 6192 : TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp);
169 : }
170 :
171 :
|