2 Unix SMB/CIFS implementation.
4 routines for marshalling/unmarshalling security descriptors
7 Copyright (C) Andrew Tridgell 2003
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 2 of the License, or
12 (at your option) any later version.
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.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 NTSTATUS ndr_pull_security_ace(struct ndr_pull *ndr, struct security_ace *ace)
33 struct ndr_pull_save save;
35 ndr_pull_save(ndr, &save);
37 NDR_CHECK(ndr_pull_uint8(ndr, &ace->type));
38 NDR_CHECK(ndr_pull_uint8(ndr, &ace->flags));
39 NDR_CHECK(ndr_pull_uint16(ndr, &size));
40 NDR_CHECK(ndr_pull_limit_size(ndr, size, 4));
42 NDR_CHECK(ndr_pull_uint32(ndr, &ace->access_mask));
44 if (sec_ace_object(ace->type)) {
45 NDR_ALLOC(ndr, ace->obj);
46 NDR_CHECK(ndr_pull_uint32(ndr, &ace->obj->flags));
47 if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) {
48 NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &ace->obj->object_guid));
50 if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
51 NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &ace->obj->inherit_guid));
58 NDR_CHECK(ndr_pull_dom_sid(ndr, &ace->trustee));
60 ndr_pull_restore(ndr, &save);
61 NDR_CHECK(ndr_pull_advance(ndr, size));
69 NTSTATUS ndr_pull_security_acl(struct ndr_pull *ndr, struct security_acl *acl)
73 struct ndr_pull_save save;
75 ndr_pull_save(ndr, &save);
77 NDR_CHECK(ndr_pull_uint16(ndr, &acl->revision));
78 NDR_CHECK(ndr_pull_uint16(ndr, &size));
79 NDR_CHECK(ndr_pull_limit_size(ndr, size, 4));
80 NDR_CHECK(ndr_pull_uint32(ndr, &acl->num_aces));
82 NDR_ALLOC_N(ndr, acl->aces, acl->num_aces);
84 for (i=0;i<acl->num_aces;i++) {
85 NDR_CHECK(ndr_pull_security_ace(ndr, &acl->aces[i]));
88 ndr_pull_restore(ndr, &save);
89 NDR_CHECK(ndr_pull_advance(ndr, size));
95 parse a security_acl offset and structure
97 NTSTATUS ndr_pull_security_acl_ofs(struct ndr_pull *ndr, struct security_acl **acl)
100 struct ndr_pull_save save;
102 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
104 /* it is valid for an acl ptr to be NULL */
109 ndr_pull_save(ndr, &save);
110 NDR_CHECK(ndr_pull_set_offset(ndr, ofs));
111 NDR_ALLOC(ndr, *acl);
112 NDR_CHECK(ndr_pull_security_acl(ndr, *acl));
113 ndr_pull_restore(ndr, &save);
122 NTSTATUS ndr_pull_dom_sid(struct ndr_pull *ndr, struct dom_sid *sid)
126 NDR_CHECK(ndr_pull_uint8(ndr, &sid->sid_rev_num));
127 NDR_CHECK(ndr_pull_uint8(ndr, &sid->num_auths));
129 NDR_CHECK(ndr_pull_uint8(ndr, &sid->id_auth[i]));
132 NDR_ALLOC_N(ndr, sid->sub_auths, sid->num_auths);
134 for (i=0;i<sid->num_auths;i++) {
135 NDR_CHECK(ndr_pull_uint32(ndr, &sid->sub_auths[i]));
142 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
144 NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, struct dom_sid *sid)
147 NDR_CHECK(ndr_pull_uint32(ndr, &num_auths));
148 return ndr_pull_dom_sid(ndr, sid);
152 parse a dom_sid offset and structure
154 NTSTATUS ndr_pull_dom_sid_ofs(struct ndr_pull *ndr, struct dom_sid **sid)
157 struct ndr_pull_save save;
159 NDR_CHECK(ndr_pull_uint32(ndr, &ofs));
161 /* it is valid for a dom_sid ptr to be NULL */
166 ndr_pull_save(ndr, &save);
167 NDR_CHECK(ndr_pull_set_offset(ndr, ofs));
168 NDR_ALLOC(ndr, *sid);
169 NDR_CHECK(ndr_pull_dom_sid(ndr, *sid));
170 ndr_pull_restore(ndr, &save);
176 parse a security descriptor
178 NTSTATUS ndr_pull_security_descriptor(struct ndr_pull *ndr,
179 struct security_descriptor *sd)
181 NDR_CHECK(ndr_pull_uint8(ndr, &sd->revision));
182 NDR_CHECK(ndr_pull_uint16(ndr, &sd->type));
183 NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &sd->owner_sid));
184 NDR_CHECK(ndr_pull_dom_sid_ofs(ndr, &sd->group_sid));
185 NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &sd->sacl));
186 NDR_CHECK(ndr_pull_security_acl_ofs(ndr, &sd->dacl));
195 NTSTATUS ndr_push_security_ace(struct ndr_push *ndr, struct security_ace *ace)
197 struct ndr_push_save save1, save2;
199 NDR_CHECK(ndr_push_uint8(ndr, ace->type));
200 NDR_CHECK(ndr_push_uint8(ndr, ace->flags));
201 ndr_push_save(ndr, &save1);
202 NDR_CHECK(ndr_push_uint16(ndr, 0));
203 NDR_CHECK(ndr_push_uint32(ndr, ace->access_mask));
205 if (sec_ace_object(ace->type)) {
206 NDR_CHECK(ndr_push_uint32(ndr, ace->obj->flags));
207 if (ace->obj->flags & SEC_ACE_OBJECT_PRESENT) {
208 NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &ace->obj->object_guid));
210 if (ace->obj->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
211 NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &ace->obj->inherit_guid));
215 NDR_CHECK(ndr_push_dom_sid(ndr, &ace->trustee));
217 ndr_push_save(ndr, &save2);
218 ndr_push_restore(ndr, &save1);
219 NDR_CHECK(ndr_push_uint16(ndr, 2 + save2.offset - save1.offset));
220 ndr_push_restore(ndr, &save2);
229 NTSTATUS ndr_push_security_acl(struct ndr_push *ndr, struct security_acl *acl)
232 struct ndr_push_save save1, save2;
234 NDR_CHECK(ndr_push_uint16(ndr, acl->revision));
235 ndr_push_save(ndr, &save1);
236 NDR_CHECK(ndr_push_uint16(ndr, 0));
237 NDR_CHECK(ndr_push_uint32(ndr, acl->num_aces));
238 for (i=0;i<acl->num_aces;i++) {
239 NDR_CHECK(ndr_push_security_ace(ndr, &acl->aces[i]));
241 ndr_push_save(ndr, &save2);
242 ndr_push_restore(ndr, &save1);
243 NDR_CHECK(ndr_push_uint16(ndr, 2 + save2.offset - save1.offset));
244 ndr_push_restore(ndr, &save2);
252 NTSTATUS ndr_push_dom_sid(struct ndr_push *ndr, struct dom_sid *sid)
256 NDR_CHECK(ndr_push_uint8(ndr, sid->sid_rev_num));
257 NDR_CHECK(ndr_push_uint8(ndr, sid->num_auths));
259 NDR_CHECK(ndr_push_uint8(ndr, sid->id_auth[i]));
261 for (i=0;i<sid->num_auths;i++) {
262 NDR_CHECK(ndr_push_uint32(ndr, sid->sub_auths[i]));
269 parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
271 NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, struct dom_sid *sid)
273 NDR_CHECK(ndr_push_uint32(ndr, sid->num_auths));
274 return ndr_push_dom_sid(ndr, sid);
279 generate a ndr security descriptor
281 NTSTATUS ndr_push_security_descriptor(struct ndr_push *ndr,
282 struct security_descriptor *sd)
284 struct ndr_push_save save;
285 struct ndr_push_save ofs1, ofs2, ofs3, ofs4;
287 ndr_push_save(ndr, &save);
289 NDR_CHECK(ndr_push_uint8(ndr, sd->revision));
290 NDR_CHECK(ndr_push_uint16(ndr, sd->type));
292 NDR_CHECK(ndr_push_offset(ndr, &ofs1));
293 NDR_CHECK(ndr_push_offset(ndr, &ofs2));
294 NDR_CHECK(ndr_push_offset(ndr, &ofs3));
295 NDR_CHECK(ndr_push_offset(ndr, &ofs4));
298 NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs1, &save));
299 NDR_CHECK(ndr_push_dom_sid(ndr, sd->owner_sid));
303 NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs2, &save));
304 NDR_CHECK(ndr_push_dom_sid(ndr, sd->group_sid));
308 NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs3, &save));
309 NDR_CHECK(ndr_push_security_acl(ndr, sd->sacl));
313 NDR_CHECK(ndr_push_offset_ptr(ndr, &ofs4, &save));
314 NDR_CHECK(ndr_push_security_acl(ndr, sd->dacl));
324 void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, struct dom_sid *sid)
331 ndr->print(ndr, "%-25s: (NULL SID)", name);
335 maxlen = sid->num_auths * 11 + 25;
336 ret = talloc(ndr->mem_ctx, maxlen);
339 ia = (sid->id_auth[5]) +
340 (sid->id_auth[4] << 8 ) +
341 (sid->id_auth[3] << 16) +
342 (sid->id_auth[2] << 24);
344 ofs = snprintf(ret, maxlen, "S-%u-%lu",
345 (unsigned int)sid->sid_rev_num, (unsigned long)ia);
347 for (i = 0; i < sid->num_auths; i++) {
348 ofs += snprintf(ret + ofs, maxlen - ofs, "-%lu", (unsigned long)sid->sub_auths[i]);
351 ndr->print(ndr, "%-25s: %s", name, ret);
354 void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, struct dom_sid2 *sid)
356 ndr_print_dom_sid(ndr, name, sid);
363 void ndr_print_security_ace(struct ndr_print *ndr, const char *name, struct security_ace *ace)
365 ndr_print_struct(ndr, name, "security_ace");
367 ndr_print_uint8(ndr, "type", ace->type);
368 ndr_print_uint8(ndr, "flags", ace->flags);
369 ndr_print_uint32(ndr, "access_mask", ace->access_mask);
371 ndr_print_struct(ndr, name, "security_ace_obj");
373 ndr_print_uint32(ndr, "flags", ace->obj->flags);
374 ndr_print_GUID(ndr, "object_guid", &ace->obj->object_guid);
375 ndr_print_GUID(ndr, "inherit_guid", &ace->obj->inherit_guid);
378 ndr_print_dom_sid(ndr, "trustee", &ace->trustee);
385 void ndr_print_security_acl(struct ndr_print *ndr, const char *name, struct security_acl *acl)
387 ndr_print_struct(ndr, name, "security_acl");
389 ndr_print_uint16(ndr, "revision", acl->revision);
390 ndr_print_uint32(ndr, "num_aces", acl->num_aces);
391 ndr_print_array(ndr, "aces", acl->aces,
392 sizeof(acl->aces[0]), acl->num_aces,
393 (ndr_print_fn_t) ndr_print_security_ace);
398 print a security descriptor
400 void ndr_print_security_descriptor(struct ndr_print *ndr,
402 struct security_descriptor *sd)
404 ndr_print_struct(ndr, name, "security_descriptor");
406 ndr_print_uint8(ndr, "revision", sd->revision);
407 ndr_print_uint16(ndr, "type", sd->type);
408 ndr_print_ptr(ndr, "owner_sid", sd->owner_sid);
410 ndr_print_dom_sid(ndr, "owner_sid", sd->owner_sid);
412 ndr_print_ptr(ndr, "group_sid", sd->group_sid);
414 ndr_print_dom_sid(ndr, "group_sid", sd->group_sid);
416 ndr_print_ptr(ndr, "sacl", sd->sacl);
418 ndr_print_security_acl(ndr, "sacl", sd->sacl);
420 ndr_print_ptr(ndr, "dacl", sd->dacl);
422 ndr_print_security_acl(ndr, "dacl", sd->dacl);
430 implementation of sec_desc_buf - an encapsulated security descriptor
432 NTSTATUS ndr_pull_sec_desc_buf(struct ndr_pull *ndr, int ndr_flags,
433 struct sec_desc_buf *sdbuf)
435 if (ndr_flags & NDR_SCALARS) {
437 NDR_CHECK(ndr_pull_uint32(ndr, &sdbuf->size));
438 NDR_CHECK(ndr_pull_uint32(ndr, &_ptr));
440 NDR_ALLOC(ndr, sdbuf->sd);
445 if (ndr_flags & NDR_BUFFERS) {
447 struct ndr_pull ndr2;
449 NDR_CHECK(ndr_pull_uint32(ndr, &size));
450 if (size != sdbuf->size) {
451 return NT_STATUS_INFO_LENGTH_MISMATCH;
453 NDR_CHECK(ndr_pull_subcontext(ndr, &ndr2, sdbuf->size));
454 NDR_CHECK(ndr_pull_security_descriptor(&ndr2, sdbuf->sd));
455 NDR_CHECK(ndr_pull_advance(ndr, sdbuf->size));
465 void ndr_print_sec_desc_buf(struct ndr_print *ndr, const char *name,
466 struct sec_desc_buf *sdbuf)
468 ndr_print_struct(ndr, name, "sec_desc_buf");
470 ndr_print_uint32(ndr, "size", sdbuf->size);
471 ndr_print_ptr(ndr, "sd", sdbuf->sd);
473 ndr_print_security_descriptor(ndr, "sd", sdbuf->sd);