00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "includes.h"
00027
00028
00029
00030
00031
00032
00033 const DOM_SID global_sid_World_Domain =
00034 { 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00035 const DOM_SID global_sid_World =
00036 { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00037 const DOM_SID global_sid_Creator_Owner_Domain =
00038 { 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00039 const DOM_SID global_sid_NT_Authority =
00040 { 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00041 const DOM_SID global_sid_System =
00042 { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00043 const DOM_SID global_sid_NULL =
00044 { 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00045 const DOM_SID global_sid_Authenticated_Users =
00046 { 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00047 const DOM_SID global_sid_Network =
00048 { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00049
00050 const DOM_SID global_sid_Creator_Owner =
00051 { 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00052 const DOM_SID global_sid_Creator_Group =
00053 { 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00054 const DOM_SID global_sid_Anonymous =
00055 { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00056
00057 const DOM_SID global_sid_Builtin =
00058 { 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00059 const DOM_SID global_sid_Builtin_Administrators =
00060 { 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00061 const DOM_SID global_sid_Builtin_Users =
00062 { 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00063 const DOM_SID global_sid_Builtin_Guests =
00064 { 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00065 const DOM_SID global_sid_Builtin_Power_Users =
00066 { 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00067 const DOM_SID global_sid_Builtin_Account_Operators =
00068 { 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00069 const DOM_SID global_sid_Builtin_Server_Operators =
00070 { 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00071 const DOM_SID global_sid_Builtin_Print_Operators =
00072 { 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00073 const DOM_SID global_sid_Builtin_Backup_Operators =
00074 { 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00075 const DOM_SID global_sid_Builtin_Replicator =
00076 { 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00077 const DOM_SID global_sid_Builtin_PreWin2kAccess =
00078 { 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00079
00080 const DOM_SID global_sid_Unix_Users =
00081 { 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00082 const DOM_SID global_sid_Unix_Groups =
00083 { 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
00084
00085
00086 #if 0
00087 #define SECURITY_NULL_SID_AUTHORITY 0
00088 #define SECURITY_WORLD_SID_AUTHORITY 1
00089 #define SECURITY_LOCAL_SID_AUTHORITY 2
00090 #define SECURITY_CREATOR_SID_AUTHORITY 3
00091 #define SECURITY_NT_AUTHORITY 5
00092 #endif
00093
00094
00095
00096
00097
00098 static DOM_SID anon_sid_array[3] =
00099 { { 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
00100 { 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}},
00101 { 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
00102 NT_USER_TOKEN anonymous_token = { 3, anon_sid_array, SE_NONE };
00103
00104 static DOM_SID system_sid_array[1] =
00105 { { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} };
00106 NT_USER_TOKEN system_token = { 1, system_sid_array, SE_ALL_PRIVS };
00107
00108
00109
00110
00111
00112 static const struct {
00113 enum lsa_SidType sid_type;
00114 const char *string;
00115 } sid_name_type[] = {
00116 {SID_NAME_USER, "User"},
00117 {SID_NAME_DOM_GRP, "Domain Group"},
00118 {SID_NAME_DOMAIN, "Domain"},
00119 {SID_NAME_ALIAS, "Local Group"},
00120 {SID_NAME_WKN_GRP, "Well-known Group"},
00121 {SID_NAME_DELETED, "Deleted Account"},
00122 {SID_NAME_INVALID, "Invalid Account"},
00123 {SID_NAME_UNKNOWN, "UNKNOWN"},
00124 {SID_NAME_COMPUTER, "Computer"},
00125
00126 {(enum lsa_SidType)0, NULL}
00127 };
00128
00129 const char *sid_type_lookup(uint32 sid_type)
00130 {
00131 int i = 0;
00132
00133
00134 while(sid_name_type[i].sid_type != 0) {
00135 if (sid_name_type[i].sid_type == sid_type)
00136 return sid_name_type[i].string;
00137 i++;
00138 }
00139
00140
00141 return "SID *TYPE* is INVALID";
00142 }
00143
00144
00145
00146
00147
00148 NT_USER_TOKEN *get_system_token(void)
00149 {
00150 return &system_token;
00151 }
00152
00153
00154
00155
00156
00157
00158 const char *get_global_sam_name(void)
00159 {
00160 if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) {
00161 return lp_workgroup();
00162 }
00163 return global_myname();
00164 }
00165
00166
00167
00168
00169
00170 char *sid_to_string(fstring sidstr_out, const DOM_SID *sid)
00171 {
00172 char subauth[16];
00173 int i;
00174 uint32 ia;
00175
00176 if (!sid) {
00177 fstrcpy(sidstr_out, "(NULL SID)");
00178 return sidstr_out;
00179 }
00180
00181
00182
00183
00184
00185 ia = (sid->id_auth[5]) +
00186 (sid->id_auth[4] << 8 ) +
00187 (sid->id_auth[3] << 16) +
00188 (sid->id_auth[2] << 24);
00189
00190 slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
00191
00192 for (i = 0; i < sid->num_auths; i++) {
00193 slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
00194 fstrcat(sidstr_out, subauth);
00195 }
00196
00197 return sidstr_out;
00198 }
00199
00200
00201
00202
00203
00204 const char *sid_string_static(const DOM_SID *sid)
00205 {
00206 static fstring sid_str;
00207 sid_to_string(sid_str, sid);
00208 return sid_str;
00209 }
00210
00211
00212
00213
00214
00215 BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
00216 {
00217 const char *p;
00218 char *q;
00219
00220 uint32 conv;
00221
00222 if ((sidstr[0] != 'S' && sidstr[0] != 's') || sidstr[1] != '-') {
00223 DEBUG(3,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
00224 return False;
00225 }
00226
00227 ZERO_STRUCTP(sidout);
00228
00229
00230 p = sidstr + 2;
00231 conv = (uint32) strtoul(p, &q, 10);
00232 if (!q || (*q != '-')) {
00233 DEBUG(3,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
00234 return False;
00235 }
00236 sidout->sid_rev_num = (uint8) conv;
00237 q++;
00238
00239
00240 conv = (uint32) strtoul(q, &q, 10);
00241 if (!q || (*q != '-')) {
00242 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
00243 return False;
00244 }
00245
00246
00247 sidout->id_auth[0] = 0;
00248 sidout->id_auth[1] = 0;
00249 sidout->id_auth[2] = (conv & 0xff000000) >> 24;
00250 sidout->id_auth[3] = (conv & 0x00ff0000) >> 16;
00251 sidout->id_auth[4] = (conv & 0x0000ff00) >> 8;
00252 sidout->id_auth[5] = (conv & 0x000000ff);
00253
00254 q++;
00255 sidout->num_auths = 0;
00256
00257 for(conv = (uint32) strtoul(q, &q, 10);
00258 q && (*q =='-' || *q =='\0') && (sidout->num_auths < MAXSUBAUTHS);
00259 conv = (uint32) strtoul(q, &q, 10)) {
00260 sid_append_rid(sidout, conv);
00261 if (*q == '\0')
00262 break;
00263 q++;
00264 }
00265
00266 return True;
00267 }
00268
00269 DOM_SID *string_sid_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
00270 {
00271 DOM_SID *result = TALLOC_P(mem_ctx, DOM_SID);
00272
00273 if (result == NULL)
00274 return NULL;
00275
00276 if (!string_to_sid(result, sidstr))
00277 return NULL;
00278
00279 return result;
00280 }
00281
00282
00283
00284
00285
00286 BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
00287 {
00288 if (sid->num_auths < MAXSUBAUTHS) {
00289 sid->sub_auths[sid->num_auths++] = rid;
00290 return True;
00291 }
00292 return False;
00293 }
00294
00295 BOOL sid_compose(DOM_SID *dst, const DOM_SID *domain_sid, uint32 rid)
00296 {
00297 sid_copy(dst, domain_sid);
00298 return sid_append_rid(dst, rid);
00299 }
00300
00301
00302
00303
00304
00305 BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
00306 {
00307 if (sid->num_auths > 0) {
00308 sid->num_auths--;
00309 *rid = sid->sub_auths[sid->num_auths];
00310 return True;
00311 }
00312 return False;
00313 }
00314
00315
00316
00317
00318
00319 BOOL sid_peek_rid(const DOM_SID *sid, uint32 *rid)
00320 {
00321 if (!sid || !rid)
00322 return False;
00323
00324 if (sid->num_auths > 0) {
00325 *rid = sid->sub_auths[sid->num_auths - 1];
00326 return True;
00327 }
00328 return False;
00329 }
00330
00331
00332
00333
00334
00335
00336 BOOL sid_peek_check_rid(const DOM_SID *exp_dom_sid, const DOM_SID *sid, uint32 *rid)
00337 {
00338 if (!exp_dom_sid || !sid || !rid)
00339 return False;
00340
00341 if (sid->num_auths != (exp_dom_sid->num_auths+1)) {
00342 return False;
00343 }
00344
00345 if (sid_compare_domain(exp_dom_sid, sid)!=0){
00346 *rid=(-1);
00347 return False;
00348 }
00349
00350 return sid_peek_rid(sid, rid);
00351 }
00352
00353
00354
00355
00356
00357 void sid_copy(DOM_SID *dst, const DOM_SID *src)
00358 {
00359 int i;
00360
00361 ZERO_STRUCTP(dst);
00362
00363 dst->sid_rev_num = src->sid_rev_num;
00364 dst->num_auths = src->num_auths;
00365
00366 memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
00367
00368 for (i = 0; i < src->num_auths; i++)
00369 dst->sub_auths[i] = src->sub_auths[i];
00370 }
00371
00372
00373
00374
00375
00376 BOOL sid_linearize(char *outbuf, size_t len, const DOM_SID *sid)
00377 {
00378 size_t i;
00379
00380 if (len < sid_size(sid))
00381 return False;
00382
00383 SCVAL(outbuf,0,sid->sid_rev_num);
00384 SCVAL(outbuf,1,sid->num_auths);
00385 memcpy(&outbuf[2], sid->id_auth, 6);
00386 for(i = 0; i < sid->num_auths; i++)
00387 SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]);
00388
00389 return True;
00390 }
00391
00392
00393
00394
00395
00396 BOOL sid_parse(const char *inbuf, size_t len, DOM_SID *sid)
00397 {
00398 int i;
00399 if (len < 8)
00400 return False;
00401
00402 ZERO_STRUCTP(sid);
00403
00404 sid->sid_rev_num = CVAL(inbuf, 0);
00405 sid->num_auths = CVAL(inbuf, 1);
00406 memcpy(sid->id_auth, inbuf+2, 6);
00407 if (len < 8 + sid->num_auths*4)
00408 return False;
00409 for (i=0;i<sid->num_auths;i++)
00410 sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
00411 return True;
00412 }
00413
00414
00415
00416
00417
00418 static int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
00419 {
00420 int i;
00421
00422 if (sid1 == sid2)
00423 return 0;
00424 if (!sid1)
00425 return -1;
00426 if (!sid2)
00427 return 1;
00428
00429 if (sid1->sid_rev_num != sid2->sid_rev_num)
00430 return sid1->sid_rev_num - sid2->sid_rev_num;
00431
00432 for (i = 0; i < 6; i++)
00433 if (sid1->id_auth[i] != sid2->id_auth[i])
00434 return sid1->id_auth[i] - sid2->id_auth[i];
00435
00436 return 0;
00437 }
00438
00439
00440
00441
00442
00443 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
00444 {
00445 int i;
00446
00447 if (sid1 == sid2)
00448 return 0;
00449 if (!sid1)
00450 return -1;
00451 if (!sid2)
00452 return 1;
00453
00454
00455 if (sid1->num_auths != sid2->num_auths)
00456 return sid1->num_auths - sid2->num_auths;
00457
00458 for (i = sid1->num_auths-1; i >= 0; --i)
00459 if (sid1->sub_auths[i] != sid2->sub_auths[i])
00460 return sid1->sub_auths[i] - sid2->sub_auths[i];
00461
00462 return sid_compare_auth(sid1, sid2);
00463 }
00464
00465
00466
00467
00468
00469
00470 int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
00471 {
00472 int n, i;
00473
00474 n = MIN(sid1->num_auths, sid2->num_auths);
00475
00476 for (i = n-1; i >= 0; --i)
00477 if (sid1->sub_auths[i] != sid2->sub_auths[i])
00478 return sid1->sub_auths[i] - sid2->sub_auths[i];
00479
00480 return sid_compare_auth(sid1, sid2);
00481 }
00482
00483
00484
00485
00486
00487 BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
00488 {
00489 return sid_compare(sid1, sid2) == 0;
00490 }
00491
00492
00493
00494
00495
00496 size_t sid_size(const DOM_SID *sid)
00497 {
00498 if (sid == NULL)
00499 return 0;
00500
00501 return sid->num_auths * sizeof(uint32) + 8;
00502 }
00503
00504
00505
00506
00507
00508 BOOL non_mappable_sid(DOM_SID *sid)
00509 {
00510 DOM_SID dom;
00511 uint32 rid;
00512
00513 sid_copy(&dom, sid);
00514 sid_split_rid(&dom, &rid);
00515
00516 if (sid_equal(&dom, &global_sid_Builtin))
00517 return True;
00518
00519 if (sid_equal(&dom, &global_sid_NT_Authority))
00520 return True;
00521
00522 return False;
00523 }
00524
00525
00526
00527
00528
00529
00530 char *sid_binstring(const DOM_SID *sid)
00531 {
00532 char *buf, *s;
00533 int len = sid_size(sid);
00534 buf = (char *)SMB_MALLOC(len);
00535 if (!buf)
00536 return NULL;
00537 sid_linearize(buf, len, sid);
00538 s = binary_string_rfc2254(buf, len);
00539 free(buf);
00540 return s;
00541 }
00542
00543
00544
00545
00546
00547
00548 char *sid_binstring_hex(const DOM_SID *sid)
00549 {
00550 char *buf, *s;
00551 int len = sid_size(sid);
00552 buf = (char *)SMB_MALLOC(len);
00553 if (!buf)
00554 return NULL;
00555 sid_linearize(buf, len, sid);
00556 s = binary_string(buf, len);
00557 free(buf);
00558 return s;
00559 }
00560
00561
00562
00563
00564
00565 DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src)
00566 {
00567 DOM_SID *dst;
00568
00569 if(!src)
00570 return NULL;
00571
00572 if((dst = TALLOC_ZERO_P(ctx, DOM_SID)) != NULL) {
00573 sid_copy( dst, src);
00574 }
00575
00576 return dst;
00577 }
00578
00579
00580
00581
00582
00583 BOOL add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00584 DOM_SID **sids, size_t *num)
00585 {
00586 *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID,
00587 (*num)+1);
00588 if (*sids == NULL) {
00589 *num = 0;
00590 return False;
00591 }
00592
00593 sid_copy(&((*sids)[*num]), sid);
00594 *num += 1;
00595
00596 return True;
00597 }
00598
00599
00600
00601
00602
00603
00604 BOOL add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00605 DOM_SID **sids, size_t *num_sids)
00606 {
00607 size_t i;
00608
00609 for (i=0; i<(*num_sids); i++) {
00610 if (sid_compare(sid, &(*sids)[i]) == 0)
00611 return True;
00612 }
00613
00614 return add_sid_to_array(mem_ctx, sid, sids, num_sids);
00615 }
00616
00617
00618
00619
00620
00621 void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num)
00622 {
00623 DOM_SID *sid_list = *sids;
00624 size_t i;
00625
00626 for ( i=0; i<*num; i++ ) {
00627
00628
00629
00630
00631 if ( sid_equal(sid, &sid_list[i]) ) {
00632 *num -= 1;
00633 break;
00634 }
00635 }
00636
00637
00638
00639
00640 for ( ; i<*num; i++ )
00641 sid_copy( &sid_list[i], &sid_list[i+1] );
00642
00643 return;
00644 }
00645
00646 BOOL add_rid_to_array_unique(TALLOC_CTX *mem_ctx,
00647 uint32 rid, uint32 **pp_rids, size_t *p_num)
00648 {
00649 size_t i;
00650
00651 for (i=0; i<*p_num; i++) {
00652 if ((*pp_rids)[i] == rid)
00653 return True;
00654 }
00655
00656 *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1);
00657
00658 if (*pp_rids == NULL) {
00659 *p_num = 0;
00660 return False;
00661 }
00662
00663 (*pp_rids)[*p_num] = rid;
00664 *p_num += 1;
00665 return True;
00666 }
00667
00668 BOOL is_null_sid(const DOM_SID *sid)
00669 {
00670 static const DOM_SID null_sid = {0};
00671 return sid_equal(sid, &null_sid);
00672 }