source: branches/samba-3.5.x/source3/lib/util_sid.c

Last change on this file was 738, checked in by Silvan Scherrer, 13 years ago

Samba Server 3.5: update branche to 3.5.18

File size: 22.1 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
6 Copyright (C) Jeremy Allison 1999
7 Copyright (C) Stefan (metze) Metzmacher 2002
8 Copyright (C) Simo Sorce 2002
9 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "includes.h"
26
27/*
28 * Some useful sids, more well known sids can be found at
29 * http://support.microsoft.com/kb/243330/EN-US/
30 */
31
32
33const DOM_SID global_sid_World_Domain = /* Everyone domain */
34{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
35const DOM_SID global_sid_World = /* Everyone */
36{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
37const DOM_SID global_sid_Creator_Owner_Domain = /* Creator Owner domain */
38{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
39const DOM_SID global_sid_NT_Authority = /* NT Authority */
40{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
41const DOM_SID global_sid_System = /* System */
42{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
43const DOM_SID global_sid_NULL = /* NULL sid */
44{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
45const DOM_SID global_sid_Authenticated_Users = /* All authenticated rids */
46{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
47#if 0
48/* for documentation */
49const DOM_SID global_sid_Restriced = /* Restriced Code */
50{ 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
51#endif
52const DOM_SID global_sid_Network = /* Network rids */
53{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
54
55const DOM_SID global_sid_Creator_Owner = /* Creator Owner */
56{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
57const DOM_SID global_sid_Creator_Group = /* Creator Group */
58{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
59const DOM_SID global_sid_Anonymous = /* Anonymous login */
60{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
61
62const DOM_SID global_sid_Builtin = /* Local well-known domain */
63{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
64const DOM_SID global_sid_Builtin_Administrators = /* Builtin administrators */
65{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
66const DOM_SID global_sid_Builtin_Users = /* Builtin users */
67{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
68const DOM_SID global_sid_Builtin_Guests = /* Builtin guest users */
69{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
70const DOM_SID global_sid_Builtin_Power_Users = /* Builtin power users */
71{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
72const DOM_SID global_sid_Builtin_Account_Operators = /* Builtin account operators */
73{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
74const DOM_SID global_sid_Builtin_Server_Operators = /* Builtin server operators */
75{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
76const DOM_SID global_sid_Builtin_Print_Operators = /* Builtin print operators */
77{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
78const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators */
79{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
80const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
81{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
82const DOM_SID global_sid_Builtin_PreWin2kAccess = /* Builtin pre win2k access */
83{ 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
84
85const DOM_SID global_sid_Unix_Users = /* Unmapped Unix users */
86{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
87const DOM_SID global_sid_Unix_Groups = /* Unmapped Unix groups */
88{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
89
90/* Unused, left here for documentary purposes */
91#if 0
92#define SECURITY_NULL_SID_AUTHORITY 0
93#define SECURITY_WORLD_SID_AUTHORITY 1
94#define SECURITY_LOCAL_SID_AUTHORITY 2
95#define SECURITY_CREATOR_SID_AUTHORITY 3
96#define SECURITY_NT_AUTHORITY 5
97#endif
98
99/*
100 * An NT compatible anonymous token.
101 */
102
103static DOM_SID anon_sid_array[3] =
104{ { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
105 { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
106 { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
107NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
108
109static DOM_SID system_sid_array[1] =
110{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
111NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
112
113/****************************************************************************
114 Lookup string names for SID types.
115****************************************************************************/
116
117static const struct {
118 enum lsa_SidType sid_type;
119 const char *string;
120} sid_name_type[] = {
121 {SID_NAME_USER, "User"},
122 {SID_NAME_DOM_GRP, "Domain Group"},
123 {SID_NAME_DOMAIN, "Domain"},
124 {SID_NAME_ALIAS, "Local Group"},
125 {SID_NAME_WKN_GRP, "Well-known Group"},
126 {SID_NAME_DELETED, "Deleted Account"},
127 {SID_NAME_INVALID, "Invalid Account"},
128 {SID_NAME_UNKNOWN, "UNKNOWN"},
129 {SID_NAME_COMPUTER, "Computer"},
130
131 {(enum lsa_SidType)0, NULL}
132};
133
134const char *sid_type_lookup(uint32 sid_type)
135{
136 int i = 0;
137
138 /* Look through list */
139 while(sid_name_type[i].sid_type != 0) {
140 if (sid_name_type[i].sid_type == sid_type)
141 return sid_name_type[i].string;
142 i++;
143 }
144
145 /* Default return */
146 return "SID *TYPE* is INVALID";
147}
148
149/**************************************************************************
150 Create the SYSTEM token.
151***************************************************************************/
152
153NT_USER_TOKEN *get_system_token(void)
154{
155 return &system_token;
156}
157
158/******************************************************************
159 get the default domain/netbios name to be used when dealing
160 with our passdb list of accounts
161******************************************************************/
162
163const char *get_global_sam_name(void)
164{
165 if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
166 return lp_workgroup();
167 }
168 return global_myname();
169}
170
171/*****************************************************************
172 Convert a SID to an ascii string.
173*****************************************************************/
174
175char *sid_to_fstring(fstring sidstr_out, const DOM_SID *sid)
176{
177 char *str = sid_string_talloc(talloc_tos(), sid);
178 fstrcpy(sidstr_out, str);
179 TALLOC_FREE(str);
180 return sidstr_out;
181}
182
183/*****************************************************************
184 Essentially a renamed dom_sid_string from librpc/ndr with a
185 panic if it didn't work
186
187 This introduces a dependency on librpc/ndr/sid.o which can easily
188 be turned around if necessary
189*****************************************************************/
190
191char *sid_string_talloc(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
192{
193 char *result = dom_sid_string(mem_ctx, sid);
194 SMB_ASSERT(result != NULL);
195 return result;
196}
197
198/*****************************************************************
199 Useful function for debug lines.
200*****************************************************************/
201
202char *sid_string_dbg(const DOM_SID *sid)
203{
204 return sid_string_talloc(talloc_tos(), sid);
205}
206
207/*****************************************************************
208 Use with care!
209*****************************************************************/
210
211char *sid_string_tos(const DOM_SID *sid)
212{
213 return sid_string_talloc(talloc_tos(), sid);
214}
215
216/*****************************************************************
217 Convert a string to a SID. Returns True on success, False on fail.
218*****************************************************************/
219
220bool string_to_sid(DOM_SID *sidout, const char *sidstr)
221{
222 const char *p;
223 char *q;
224 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
225 uint32 conv;
226
227 if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
228 DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
229 return False;
230 }
231
232 ZERO_STRUCTP(sidout);
233
234 /* Get the revision number. */
235 p = sidstr + 2;
236 conv = (uint32) strtoul(p, &q, 10);
237 if (!q || (*q != '-')) {
238 DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
239 return False;
240 }
241 sidout->sid_rev_num = (uint8) conv;
242 q++;
243
244 /* get identauth */
245 conv = (uint32) strtoul(q, &q, 10);
246 if (!q || (*q != '-')) {
247 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
248 return False;
249 }
250 /* identauth in decimal should be < 2^32 */
251 /* NOTE - the conv value is in big-endian format. */
252 sidout->id_auth[0] = 0;
253 sidout->id_auth[1] = 0;
254 sidout->id_auth[2] = (conv & 0xff000000) >> 24;
255 sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
256 sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
257 sidout->id_auth[5] = (conv & 0x000000ff);
258
259 q++;
260 sidout->num_auths = 0;
261
262 for(conv = (uint32) strtoul(q, &q, 10);
263 q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
264 conv = (uint32) strtoul(q, &q, 10)) {
265 sid_append_rid(sidout, conv);
266 if (*q == '\0')
267 break;
268 q++;
269 }
270
271 return True;
272}
273
274DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
275{
276 DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
277
278 if (result == NULL)
279 return NULL;
280
281 if (!string_to_sid(result, sidstr))
282 return NULL;
283
284 return result;
285}
286
287/*****************************************************************
288 Add a rid to the end of a sid
289*****************************************************************/
290
291bool sid_append_rid(DOM_SID *sid, uint32 rid)
292{
293 if (sid->num_auths < MAXSUBAUTHS) {
294 sid->sub_auths[sid->num_auths++] = rid;
295 return True;
296 }
297 return False;
298}
299
300bool sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
301{
302 sid_copy(dst, domain_sid);
303 return sid_append_rid(dst, rid);
304}
305
306/*****************************************************************
307 Removes the last rid from the end of a sid
308*****************************************************************/
309
310bool sid_split_rid(DOM_SID *sid, uint32 *rid)
311{
312 if (sid->num_auths > 0) {
313 sid->num_auths--;
314 *rid = sid->sub_auths[sid->num_auths];
315 return True;
316 }
317 return False;
318}
319
320/*****************************************************************
321 Return the last rid from the end of a sid
322*****************************************************************/
323
324bool sid_peek_rid(const DOM_SID *sid, uint32 *rid)
325{
326 if (!sid || !rid)
327 return False;
328
329 if (sid->num_auths > 0) {
330 *rid = sid->sub_auths[sid->num_auths - 1];
331 return True;
332 }
333 return False;
334}
335
336/*****************************************************************
337 Return the last rid from the end of a sid
338 and check the sid against the exp_dom_sid
339*****************************************************************/
340
341bool sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
342{
343 if (!exp_dom_sid || !sid || !rid)
344 return False;
345
346 if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
347 return False;
348 }
349
350 if (sid_compare_domain(exp_dom_sid, sid)!=0){
351 *rid=(-1);
352 return False;
353 }
354
355 return sid_peek_rid(sid, rid);
356}
357
358/*****************************************************************
359 Copies a sid
360*****************************************************************/
361
362void sid_copy(DOM_SID *dst, const DOM_SID *src)
363{
364 int i;
365
366 ZERO_STRUCTP(dst);
367
368 dst->sid_rev_num = src->sid_rev_num;
369 dst->num_auths = src->num_auths;
370
371 memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
372
373 for (i = 0; i < src->num_auths; i++)
374 dst->sub_auths[i] = src->sub_auths[i];
375}
376
377/*****************************************************************
378 Write a sid out into on-the-wire format.
379*****************************************************************/
380
381bool sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
382{
383 size_t i;
384
385 if (len < ndr_size_dom_sid(sid, NULL, 0))
386 return False;
387
388 SCVAL(outbuf,0,sid->sid_rev_num);
389 SCVAL(outbuf,1,sid->num_auths);
390 memcpy(&outbuf[2], sid->id_auth, 6);
391 for(i = 0; i < sid->num_auths; i++)
392 SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]);
393
394 return True;
395}
396
397/*****************************************************************
398 Parse a on-the-wire SID to a DOM_SID.
399*****************************************************************/
400
401bool sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
402{
403 int i;
404 if (len < 8)
405 return False;
406
407 ZERO_STRUCTP(sid);
408
409 sid->sid_rev_num = CVAL(inbuf, 0);
410 sid->num_auths = CVAL(inbuf, 1);
411 if (sid->num_auths > MAXSUBAUTHS) {
412 return false;
413 }
414 memcpy(sid->id_auth, inbuf+2, 6);
415 if (len < 8 + sid->num_auths*4)
416 return False;
417 for (i=0;i<sid->num_auths;i++)
418 sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
419 return True;
420}
421
422/*****************************************************************
423 Compare the auth portion of two sids.
424*****************************************************************/
425
426static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
427{
428 int i;
429
430 if (sid1 == sid2)
431 return 0;
432 if (!sid1)
433 return -1;
434 if (!sid2)
435 return 1;
436
437 if (sid1->sid_rev_num != sid2->sid_rev_num)
438 return sid1->sid_rev_num - sid2->sid_rev_num;
439
440 for (i = 0; i < 6; i++)
441 if (sid1->id_auth[i] != sid2->id_auth[i])
442 return sid1->id_auth[i] - sid2->id_auth[i];
443
444 return 0;
445}
446
447/*****************************************************************
448 Compare two sids.
449*****************************************************************/
450
451int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
452{
453 int i;
454
455 if (sid1 == sid2)
456 return 0;
457 if (!sid1)
458 return -1;
459 if (!sid2)
460 return 1;
461
462 /* Compare most likely different rids, first: i.e start at end */
463 if (sid1->num_auths != sid2->num_auths)
464 return sid1->num_auths - sid2->num_auths;
465
466 for (i = sid1->num_auths-1; i >= 0; --i)
467 if (sid1->sub_auths[i] != sid2->sub_auths[i])
468 return sid1->sub_auths[i] - sid2->sub_auths[i];
469
470 return sid_compare_auth(sid1, sid2);
471}
472
473/*****************************************************************
474 See if 2 SIDs are in the same domain
475 this just compares the leading sub-auths
476*****************************************************************/
477
478int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
479{
480 int n, i;
481
482 n = MIN(sid1->num_auths, sid2->num_auths);
483
484 for (i = n-1; i >= 0; --i)
485 if (sid1->sub_auths[i] != sid2->sub_auths[i])
486 return sid1->sub_auths[i] - sid2->sub_auths[i];
487
488 return sid_compare_auth(sid1, sid2);
489}
490
491/*****************************************************************
492 Compare two sids.
493*****************************************************************/
494
495bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
496{
497 return sid_compare(sid1, sid2) == 0;
498}
499
500/*****************************************************************
501 Returns true if SID is internal (and non-mappable).
502*****************************************************************/
503
504bool non_mappable_sid(DOM_SID *sid)
505{
506 DOM_SID dom;
507 uint32 rid;
508
509 sid_copy(&dom, sid);
510 sid_split_rid(&dom, &rid);
511
512 if (sid_equal(&dom, &global_sid_Builtin))
513 return True;
514
515 if (sid_equal(&dom, &global_sid_NT_Authority))
516 return True;
517
518 return False;
519}
520
521/*****************************************************************
522 Return the binary string representation of a DOM_SID.
523 Caller must free.
524*****************************************************************/
525
526char *sid_binstring(TALLOC_CTX *mem_ctx, const DOM_SID *sid)
527{
528 uint8_t *buf;
529 char *s;
530 int len = ndr_size_dom_sid(sid, NULL, 0);
531 buf = talloc_array(mem_ctx, uint8_t, len);
532 if (!buf) {
533 return NULL;
534 }
535 sid_linearize((char *)buf, len, sid);
536 s = binary_string_rfc2254(mem_ctx, buf, len);
537 TALLOC_FREE(buf);
538 return s;
539}
540
541/*****************************************************************
542 Return the binary string representation of a DOM_SID.
543 Caller must free.
544*****************************************************************/
545
546char *sid_binstring_hex(const DOM_SID *sid)
547{
548 char *buf, *s;
549 int len = ndr_size_dom_sid(sid, NULL, 0);
550 buf = (char *)SMB_MALLOC(len);
551 if (!buf)
552 return NULL;
553 sid_linearize(buf, len, sid);
554 s = binary_string(buf, len);
555 free(buf);
556 return s;
557}
558
559/*******************************************************************
560 Tallocs a duplicate SID.
561********************************************************************/
562
563DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
564{
565 DOM_SID *dst;
566
567 if(!src)
568 return NULL;
569
570 if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) {
571 sid_copy( dst, src);
572 }
573
574 return dst;
575}
576
577/********************************************************************
578 Add SID to an array SIDs
579********************************************************************/
580
581NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
582 DOM_SID **sids, size_t *num)
583{
584 *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
585 (*num)+1);
586 if (*sids == NULL) {
587 *num = 0;
588 return NT_STATUS_NO_MEMORY;
589 }
590
591 sid_copy(&((*sids)[*num]), sid);
592 *num += 1;
593
594 return NT_STATUS_OK;
595}
596
597
598/********************************************************************
599 Add SID to an array SIDs ensuring that it is not already there
600********************************************************************/
601
602NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
603 DOM_SID **sids, size_t *num_sids)
604{
605 size_t i;
606
607 for (i=0; i<(*num_sids); i++) {
608 if (sid_compare(sid, &(*sids)[i]) == 0)
609 return NT_STATUS_OK;
610 }
611
612 return add_sid_to_array(mem_ctx, sid, sids, num_sids);
613}
614
615/********************************************************************
616 Remove SID from an array
617********************************************************************/
618
619void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
620{
621 DOM_SID *sid_list = *sids;
622 size_t i;
623
624 for ( i=0; i<*num; i++ ) {
625
626 /* if we find the SID, then decrement the count
627 and break out of the loop */
628
629 if ( sid_equal(sid, &sid_list[i]) ) {
630 *num -= 1;
631 break;
632 }
633 }
634
635 /* This loop will copy the remainder of the array
636 if i < num of sids ni the array */
637
638 for ( ; i<*num; i++ )
639 sid_copy( &sid_list[i], &sid_list[i+1] );
640
641 return;
642}
643
644bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
645 uint32 rid, uint32 **pp_rids, size_t *p_num)
646{
647 size_t i;
648
649 for (i=0; i<*p_num; i++) {
650 if ((*pp_rids)[i] == rid)
651 return True;
652 }
653
654 *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
655
656 if (*pp_rids == NULL) {
657 *p_num = 0;
658 return False;
659 }
660
661 (*pp_rids)[*p_num] = rid;
662 *p_num += 1;
663 return True;
664}
665
666bool is_null_sid(const DOM_SID *sid)
667{
668 static const DOM_SID null_sid = {0};
669 return sid_equal(sid, &null_sid);
670}
671
672bool is_sid_in_token(const NT_USER_TOKEN *token, const DOM_SID *sid)
673{
674 int i;
675
676 for (i=0; i<token->num_sids; i++) {
677 if (sid_compare(sid, &token->user_sids[i]) == 0)
678 return true;
679 }
680 return false;
681}
682
683NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx,
684 const struct netr_SamInfo3 *info3,
685 DOM_SID **user_sids,
686 size_t *num_user_sids,
687 bool include_user_group_rid)
688{
689 NTSTATUS status;
690 DOM_SID sid;
691 DOM_SID *sid_array = NULL;
692 size_t num_sids = 0;
693 int i;
694
695 if (include_user_group_rid) {
696 if (!sid_compose(&sid, info3->base.domain_sid, info3->base.rid)) {
697 DEBUG(3, ("could not compose user SID from rid 0x%x\n",
698 info3->base.rid));
699 return NT_STATUS_INVALID_PARAMETER;
700 }
701 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
702 if (!NT_STATUS_IS_OK(status)) {
703 DEBUG(3, ("could not append user SID from rid 0x%x\n",
704 info3->base.rid));
705 return status;
706 }
707 }
708
709 if (!sid_compose(&sid, info3->base.domain_sid, info3->base.primary_gid)) {
710 DEBUG(3, ("could not compose group SID from rid 0x%x\n",
711 info3->base.primary_gid));
712 return NT_STATUS_INVALID_PARAMETER;
713 }
714 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
715 if (!NT_STATUS_IS_OK(status)) {
716 DEBUG(3, ("could not append group SID from rid 0x%x\n",
717 info3->base.rid));
718 return status;
719 }
720
721 for (i = 0; i < info3->base.groups.count; i++) {
722 /* Don't add the primary group sid twice. */
723 if (info3->base.primary_gid == info3->base.groups.rids[i].rid) {
724 continue;
725 }
726 if (!sid_compose(&sid, info3->base.domain_sid,
727 info3->base.groups.rids[i].rid)) {
728 DEBUG(3, ("could not compose SID from additional group "
729 "rid 0x%x\n", info3->base.groups.rids[i].rid));
730 return NT_STATUS_INVALID_PARAMETER;
731 }
732 status = add_sid_to_array(mem_ctx, &sid, &sid_array, &num_sids);
733 if (!NT_STATUS_IS_OK(status)) {
734 DEBUG(3, ("could not append SID from additional group "
735 "rid 0x%x\n", info3->base.groups.rids[i].rid));
736 return status;
737 }
738 }
739
740 /* SID filtering should only be handled by the domain controller on a
741 trust by trust basis, and is counter-indicated for forests. Since
742 native AD return all Domain Local groups as other SIDs, then this
743 must not filter them when parsing INFO3 responses such that the
744 list is identical to the tokenGroups LDAP query.
745 */
746
747 for (i = 0; i < info3->sidcount; i++) {
748 status = add_sid_to_array(mem_ctx, info3->sids[i].sid,
749 &sid_array, &num_sids);
750 if (!NT_STATUS_IS_OK(status)) {
751 DEBUG(3, ("could not add SID to array: %s\n",
752 sid_string_dbg(info3->sids[i].sid)));
753 return status;
754 }
755 }
756
757 *user_sids = sid_array;
758 *num_user_sids = num_sids;
759
760 return NT_STATUS_OK;
761}
Note: See TracBrowser for help on using the repository browser.