r12312: Reformatting and a trivial change: is_share_read_only_for_user only uses
[Samba/nascimento.git] / source3 / lib / util_sid.c
blobb94be474a9ee9902dcc25d6440c39c3046b316af
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
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 2 of the License, or
14 (at your option) any later version.
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.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include "includes.h"
29 * Some useful sids
33 const 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}};
35 const 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}};
37 const 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}};
39 const 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}};
41 const 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}};
43 const 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}};
45 const 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 const DOM_SID global_sid_Network = /* Network rids */
48 { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
50 const DOM_SID global_sid_Creator_Owner = /* Creator Owner */
51 { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
52 const DOM_SID global_sid_Creator_Group = /* Creator Group */
53 { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
54 const DOM_SID global_sid_Anonymous = /* Anonymous login */
55 { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
57 const DOM_SID global_sid_Builtin = /* Local well-known domain */
58 { 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
59 const DOM_SID global_sid_Builtin_Administrators = /* Builtin administrators */
60 { 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
61 const DOM_SID global_sid_Builtin_Users = /* Builtin users */
62 { 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
63 const DOM_SID global_sid_Builtin_Guests = /* Builtin guest users */
64 { 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
65 const DOM_SID global_sid_Builtin_Power_Users = /* Builtin power users */
66 { 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
67 const DOM_SID global_sid_Builtin_Account_Operators = /* Builtin account operators */
68 { 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
69 const DOM_SID global_sid_Builtin_Server_Operators = /* Builtin server operators */
70 { 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
71 const DOM_SID global_sid_Builtin_Print_Operators = /* Builtin print operators */
72 { 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
73 const DOM_SID global_sid_Builtin_Backup_Operators = /* Builtin backup operators */
74 { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
75 const DOM_SID global_sid_Builtin_Replicator = /* Builtin replicator */
76 { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
78 /* Unused, left here for documentary purposes */
79 #if 0
80 #define SECURITY_NULL_SID_AUTHORITY 0
81 #define SECURITY_WORLD_SID_AUTHORITY 1
82 #define SECURITY_LOCAL_SID_AUTHORITY 2
83 #define SECURITY_CREATOR_SID_AUTHORITY 3
84 #define SECURITY_NT_AUTHORITY 5
85 #endif
88 * An NT compatible anonymous token.
91 static DOM_SID anon_sid_array[3] =
92 { { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
93 { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
94 { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
95 NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
97 static DOM_SID system_sid_array[1] =
98 { { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
99 NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
101 /****************************************************************************
102 Lookup string names for SID types.
103 ****************************************************************************/
105 static const struct {
106 enum SID_NAME_USE sid_type;
107 const char *string;
108 } sid_name_type[] = {
109 {SID_NAME_USER, "User"},
110 {SID_NAME_DOM_GRP, "Domain Group"},
111 {SID_NAME_DOMAIN, "Domain"},
112 {SID_NAME_ALIAS, "Local Group"},
113 {SID_NAME_WKN_GRP, "Well-known Group"},
114 {SID_NAME_DELETED, "Deleted Account"},
115 {SID_NAME_INVALID, "Invalid Account"},
116 {SID_NAME_UNKNOWN, "UNKNOWN"},
117 {SID_NAME_COMPUTER, "Computer"},
119 {(enum SID_NAME_USE)0, NULL}
122 const char *sid_type_lookup(uint32 sid_type)
124 int i = 0;
126 /* Look through list */
127 while(sid_name_type[i].sid_type != 0) {
128 if (sid_name_type[i].sid_type == sid_type)
129 return sid_name_type[i].string;
130 i++;
133 /* Default return */
134 return "SID *TYPE* is INVALID";
137 /**************************************************************************
138 Create the SYSTEM token.
139 ***************************************************************************/
141 NT_USER_TOKEN *get_system_token(void)
143 return &system_token;
146 /******************************************************************
147 get the default domain/netbios name to be used when dealing
148 with our passdb list of accounts
149 ******************************************************************/
151 const char *get_global_sam_name(void)
153 if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
154 return lp_workgroup();
156 return global_myname();
159 /*****************************************************************
160 Convert a SID to an ascii string.
161 *****************************************************************/
163 char *sid_to_string(fstring sidstr_out, const DOM_SID *sid)
165 char subauth[16];
166 int i;
167 uint32 ia;
169 if (!sid) {
170 fstrcpy(sidstr_out, "(NULL SID)");
171 return sidstr_out;
175 * BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
176 * in a range of 2^48.
178 ia = (sid->id_auth[5]) +
179 (sid->id_auth[4] << 8 ) +
180 (sid->id_auth[3] << 16) +
181 (sid->id_auth[2] << 24);
183 slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
185 for (i = 0; i < sid->num_auths; i++) {
186 slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
187 fstrcat(sidstr_out, subauth);
190 return sidstr_out;
193 /*****************************************************************
194 Useful function for debug lines.
195 *****************************************************************/
197 const char *sid_string_static(const DOM_SID *sid)
199 static fstring sid_str;
200 sid_to_string(sid_str, sid);
201 return sid_str;
204 /*****************************************************************
205 Convert a string to a SID. Returns True on success, False on fail.
206 *****************************************************************/
208 BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
210 const char *p;
211 char *q;
212 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
213 uint32 conv;
215 if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
216 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
217 return False;
220 ZERO_STRUCTP(sidout);
222 /* Get the revision number. */
223 p = sidstr + 2;
224 conv = (uint32) strtoul(p, &q, 10);
225 if (!q || (*q != '-')) {
226 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
227 return False;
229 sidout->sid_rev_num = (uint8) conv;
230 q++;
232 /* get identauth */
233 conv = (uint32) strtoul(q, &q, 10);
234 if (!q || (*q != '-')) {
235 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
236 return False;
238 /* identauth in decimal should be < 2^32 */
239 /* NOTE - the conv value is in big-endian format. */
240 sidout->id_auth[0] = 0;
241 sidout->id_auth[1] = 0;
242 sidout->id_auth[2] = (conv & 0xff000000) >> 24;
243 sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
244 sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
245 sidout->id_auth[5] = (conv & 0x000000ff);
247 q++;
248 sidout->num_auths = 0;
250 for(conv = (uint32) strtoul(q, &q, 10);
251 q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
252 conv = (uint32) strtoul(q, &q, 10)) {
253 sid_append_rid(sidout, conv);
254 if (*q == '\0')
255 break;
256 q++;
259 return True;
262 DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
264 DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
266 if (result == NULL)
267 return NULL;
269 if (!string_to_sid(result, sidstr))
270 return NULL;
272 return result;
275 /*****************************************************************
276 Add a rid to the end of a sid
277 *****************************************************************/
279 BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
281 if (sid->num_auths < MAXSUBAUTHS) {
282 sid->sub_auths[sid->num_auths++] = rid;
283 return True;
285 return False;
288 BOOL sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
290 sid_copy(dst, domain_sid);
291 return sid_append_rid(dst, rid);
294 /*****************************************************************
295 Removes the last rid from the end of a sid
296 *****************************************************************/
298 BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
300 if (sid->num_auths > 0) {
301 sid->num_auths--;
302 *rid = sid->sub_auths[sid->num_auths];
303 return True;
305 return False;
308 /*****************************************************************
309 Return the last rid from the end of a sid
310 *****************************************************************/
312 BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid)
314 if (!sid || !rid)
315 return False;
317 if (sid->num_auths > 0) {
318 *rid = sid->sub_auths[sid->num_auths - 1];
319 return True;
321 return False;
324 /*****************************************************************
325 Return the last rid from the end of a sid
326 and check the sid against the exp_dom_sid
327 *****************************************************************/
329 BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
331 if (!exp_dom_sid || !sid || !rid)
332 return False;
334 if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
335 return False;
338 if (sid_compare_domain(exp_dom_sid, sid)!=0){
339 *rid=(-1);
340 return False;
343 return sid_peek_rid(sid, rid);
346 /*****************************************************************
347 Copies a sid
348 *****************************************************************/
350 void sid_copy(DOM_SID *dst, const DOM_SID *src)
352 int i;
354 ZERO_STRUCTP(dst);
356 dst->sid_rev_num = src->sid_rev_num;
357 dst->num_auths = src->num_auths;
359 memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
361 for (i = 0; i < src->num_auths; i++)
362 dst->sub_auths[i] = src->sub_auths[i];
365 /*****************************************************************
366 Write a sid out into on-the-wire format.
367 *****************************************************************/
369 BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
371 size_t i;
373 if (len < sid_size(sid))
374 return False;
376 SCVAL(outbuf,0,sid->sid_rev_num);
377 SCVAL(outbuf,1,sid->num_auths);
378 memcpy(&outbuf[2], sid->id_auth, 6);
379 for(i = 0; i < sid->num_auths; i++)
380 SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]);
382 return True;
385 /*****************************************************************
386 Parse a on-the-wire SID to a DOM_SID.
387 *****************************************************************/
389 BOOL sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
391 int i;
392 if (len < 8)
393 return False;
395 ZERO_STRUCTP(sid);
397 sid->sid_rev_num = CVAL(inbuf, 0);
398 sid->num_auths = CVAL(inbuf, 1);
399 memcpy(sid->id_auth, inbuf+2, 6);
400 if (len < 8 + sid->num_auths*4)
401 return False;
402 for (i=0;i<sid->num_auths;i++)
403 sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
404 return True;
407 /*****************************************************************
408 Compare the auth portion of two sids.
409 *****************************************************************/
411 static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
413 int i;
415 if (sid1 == sid2)
416 return 0;
417 if (!sid1)
418 return -1;
419 if (!sid2)
420 return 1;
422 if (sid1->sid_rev_num != sid2->sid_rev_num)
423 return sid1->sid_rev_num - sid2->sid_rev_num;
425 for (i = 0; i < 6; i++)
426 if (sid1->id_auth[i] != sid2->id_auth[i])
427 return sid1->id_auth[i] - sid2->id_auth[i];
429 return 0;
432 /*****************************************************************
433 Compare two sids.
434 *****************************************************************/
436 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
438 int i;
440 if (sid1 == sid2)
441 return 0;
442 if (!sid1)
443 return -1;
444 if (!sid2)
445 return 1;
447 /* Compare most likely different rids, first: i.e start at end */
448 if (sid1->num_auths != sid2->num_auths)
449 return sid1->num_auths - sid2->num_auths;
451 for (i = sid1->num_auths-1; i >= 0; --i)
452 if (sid1->sub_auths[i] != sid2->sub_auths[i])
453 return sid1->sub_auths[i] - sid2->sub_auths[i];
455 return sid_compare_auth(sid1, sid2);
458 /*****************************************************************
459 See if 2 SIDs are in the same domain
460 this just compares the leading sub-auths
461 *****************************************************************/
463 int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
465 int n, i;
467 n = MIN(sid1->num_auths, sid2->num_auths);
469 for (i = n-1; i >= 0; --i)
470 if (sid1->sub_auths[i] != sid2->sub_auths[i])
471 return sid1->sub_auths[i] - sid2->sub_auths[i];
473 return sid_compare_auth(sid1, sid2);
476 /*****************************************************************
477 Compare two sids.
478 *****************************************************************/
480 BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
482 return sid_compare(sid1, sid2) == 0;
485 /*****************************************************************
486 Calculates size of a sid.
487 *****************************************************************/
489 size_t sid_size(const DOM_SID *sid)
491 if (sid == NULL)
492 return 0;
494 return sid->num_auths * sizeof(uint32) + 8;
497 /*****************************************************************
498 Returns true if SID is internal (and non-mappable).
499 *****************************************************************/
501 BOOL non_mappable_sid(DOM_SID *sid)
503 DOM_SID dom;
504 uint32 rid;
506 sid_copy(&dom, sid);
507 sid_split_rid(&dom, &rid);
509 if (sid_equal(&dom, &global_sid_Builtin))
510 return True;
512 if (sid_equal(&dom, &global_sid_NT_Authority))
513 return True;
515 return False;
518 /*****************************************************************
519 Return the binary string representation of a DOM_SID.
520 Caller must free.
521 *****************************************************************/
523 char *sid_binstring(const DOM_SID *sid)
525 char *buf, *s;
526 int len = sid_size(sid);
527 buf = SMB_MALLOC(len);
528 if (!buf)
529 return NULL;
530 sid_linearize(buf, len, sid);
531 s = binary_string(buf, len);
532 free(buf);
533 return s;
536 /*******************************************************************
537 Tallocs a duplicate SID.
538 ********************************************************************/
540 DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
542 DOM_SID *dst;
544 if(!src)
545 return NULL;
547 if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) {
548 sid_copy( dst, src);
551 return dst;
554 /********************************************************************
555 Add SID to an array SIDs
556 ********************************************************************/
558 void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
559 DOM_SID **sids, size_t *num)
561 if (mem_ctx != NULL)
562 *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
563 (*num)+1);
564 else
565 *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1);
567 if (*sids == NULL)
568 return;
570 sid_copy(&((*sids)[*num]), sid);
571 *num += 1;
573 return;
577 /********************************************************************
578 Add SID to an array SIDs ensuring that it is not already there
579 ********************************************************************/
581 void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
582 DOM_SID **sids, size_t *num_sids)
584 size_t i;
586 for (i=0; i<(*num_sids); i++) {
587 if (sid_compare(sid, &(*sids)[i]) == 0)
588 return;
591 add_sid_to_array(mem_ctx, sid, sids, num_sids);
594 /********************************************************************
595 Remove SID from an array
596 ********************************************************************/
598 void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
600 DOM_SID *sid_list = *sids;
601 size_t i;
603 for ( i=0; i<*num; i++ ) {
605 /* if we find the SID, then decrement the count
606 and break out of the loop */
608 if ( sid_equal(sid, &sid_list[i]) ) {
609 *num -= 1;
610 break;
614 /* This loop will copy the remainder of the array
615 if i < num of sids ni the array */
617 for ( ; i<*num; i++ )
618 sid_copy( &sid_list[i], &sid_list[i+1] );
620 return;