00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 BOOL lookup_name(TALLOC_CTX *mem_ctx,
00034 const char *full_name, int flags,
00035 const char **ret_domain, const char **ret_name,
00036 DOM_SID *ret_sid, enum lsa_SidType *ret_type)
00037 {
00038 char *p;
00039 const char *tmp;
00040 const char *domain = NULL;
00041 const char *name = NULL;
00042 uint32 rid;
00043 DOM_SID sid;
00044 enum lsa_SidType type;
00045 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
00046
00047 if (tmp_ctx == NULL) {
00048 DEBUG(0, ("talloc_new failed\n"));
00049 return False;
00050 }
00051
00052 p = strchr_m(full_name, '\\');
00053
00054 if (p != NULL) {
00055 domain = talloc_strndup(tmp_ctx, full_name,
00056 PTR_DIFF(p, full_name));
00057 name = talloc_strdup(tmp_ctx, p+1);
00058 } else {
00059 domain = talloc_strdup(tmp_ctx, "");
00060 name = talloc_strdup(tmp_ctx, full_name);
00061 }
00062
00063 if ((domain == NULL) || (name == NULL)) {
00064 DEBUG(0, ("talloc failed\n"));
00065 TALLOC_FREE(tmp_ctx);
00066 return False;
00067 }
00068
00069 DEBUG(10,("lookup_name: %s => %s (domain), %s (name)\n",
00070 full_name, domain, name));
00071 DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
00072
00073 if ((flags & LOOKUP_NAME_DOMAIN) &&
00074 strequal(domain, get_global_sam_name()))
00075 {
00076
00077
00078 if (lookup_global_sam_name(name, flags, &rid, &type)) {
00079 sid_copy(&sid, get_global_sam_sid());
00080 sid_append_rid(&sid, rid);
00081 goto ok;
00082 }
00083 TALLOC_FREE(tmp_ctx);
00084 return False;
00085 }
00086
00087 if ((flags & LOOKUP_NAME_BUILTIN) &&
00088 strequal(domain, builtin_domain_name()))
00089 {
00090
00091 if (lookup_builtin_name(name, &rid)) {
00092 sid_copy(&sid, &global_sid_Builtin);
00093 sid_append_rid(&sid, rid);
00094 type = SID_NAME_ALIAS;
00095 goto ok;
00096 }
00097 TALLOC_FREE(tmp_ctx);
00098 return False;
00099 }
00100
00101
00102
00103
00104 if ((domain[0] != '\0') &&
00105 (flags & ~(LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED)) &&
00106 (winbind_lookup_name(domain, name, &sid, &type))) {
00107 goto ok;
00108 }
00109
00110 if (strequal(domain, unix_users_domain_name())) {
00111 if (lookup_unix_user_name(name, &sid)) {
00112 type = SID_NAME_USER;
00113 goto ok;
00114 }
00115 TALLOC_FREE(tmp_ctx);
00116 return False;
00117 }
00118
00119 if (strequal(domain, unix_groups_domain_name())) {
00120 if (lookup_unix_group_name(name, &sid)) {
00121 type = SID_NAME_DOM_GRP;
00122 goto ok;
00123 }
00124 TALLOC_FREE(tmp_ctx);
00125 return False;
00126 }
00127
00128 if ((domain[0] == '\0') && (!(flags & LOOKUP_NAME_ISOLATED))) {
00129 TALLOC_FREE(tmp_ctx);
00130 return False;
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 if ((flags & LOOKUP_NAME_WKN) &&
00141 lookup_wellknown_name(tmp_ctx, name, &sid, &domain))
00142 {
00143 type = SID_NAME_WKN_GRP;
00144 goto ok;
00145 }
00146
00147
00148
00149 if ((flags & (LOOKUP_NAME_BUILTIN|LOOKUP_NAME_REMOTE)) &&
00150 strequal(name, builtin_domain_name()))
00151 {
00152
00153 tmp = name; name = domain; domain = tmp;
00154 sid_copy(&sid, &global_sid_Builtin);
00155 type = SID_NAME_DOMAIN;
00156 goto ok;
00157 }
00158
00159
00160
00161 if ((flags & LOOKUP_NAME_DOMAIN) &&
00162 strequal(name, get_global_sam_name()))
00163 {
00164 if (!secrets_fetch_domain_sid(name, &sid)) {
00165 DEBUG(3, ("Could not fetch my SID\n"));
00166 TALLOC_FREE(tmp_ctx);
00167 return False;
00168 }
00169
00170 tmp = name; name = domain; domain = tmp;
00171 type = SID_NAME_DOMAIN;
00172 goto ok;
00173 }
00174
00175
00176
00177 if ((flags & LOOKUP_NAME_DOMAIN) && !IS_DC &&
00178 strequal(name, lp_workgroup()))
00179 {
00180 if (!secrets_fetch_domain_sid(name, &sid)) {
00181 DEBUG(3, ("Could not fetch the domain SID\n"));
00182 TALLOC_FREE(tmp_ctx);
00183 return False;
00184 }
00185
00186 tmp = name; name = domain; domain = tmp;
00187 type = SID_NAME_DOMAIN;
00188 goto ok;
00189 }
00190
00191
00192
00193
00194 if ((flags & LOOKUP_NAME_REMOTE) && IS_DC &&
00195 (secrets_fetch_trusted_domain_password(name, NULL, &sid, NULL)))
00196 {
00197
00198 tmp = name; name = domain; domain = tmp;
00199 type = SID_NAME_DOMAIN;
00200 goto ok;
00201 }
00202
00203
00204
00205 if ((flags & LOOKUP_NAME_BUILTIN) &&
00206 lookup_builtin_name(name, &rid))
00207 {
00208 domain = talloc_strdup(tmp_ctx, builtin_domain_name());
00209 sid_copy(&sid, &global_sid_Builtin);
00210 sid_append_rid(&sid, rid);
00211 type = SID_NAME_ALIAS;
00212 goto ok;
00213 }
00214
00215
00216
00217
00218
00219
00220 if ((flags & LOOKUP_NAME_DOMAIN) &&
00221 lookup_global_sam_name(name, flags, &rid, &type))
00222 {
00223 domain = talloc_strdup(tmp_ctx, get_global_sam_name());
00224 sid_copy(&sid, get_global_sam_sid());
00225 sid_append_rid(&sid, rid);
00226 goto ok;
00227 }
00228
00229
00230
00231 if (!(flags & LOOKUP_NAME_REMOTE)) {
00232 TALLOC_FREE(tmp_ctx);
00233 return False;
00234 }
00235
00236
00237
00238
00239 if (!IS_DC &&
00240 (winbind_lookup_name(lp_workgroup(), name, &sid, &type))) {
00241 domain = talloc_strdup(tmp_ctx, lp_workgroup());
00242 goto ok;
00243 }
00244
00245
00246
00247
00248
00249
00250 if (IS_DC && winbind_lookup_name("", name, &sid, &type)) {
00251 DOM_SID dom_sid;
00252 uint32 tmp_rid;
00253 enum lsa_SidType domain_type;
00254
00255 if (type == SID_NAME_DOMAIN) {
00256
00257 tmp = name; name = domain; domain = tmp;
00258 goto ok;
00259 }
00260
00261
00262
00263
00264
00265 sid_copy(&dom_sid, &sid);
00266 sid_split_rid(&dom_sid, &tmp_rid);
00267
00268 if (!winbind_lookup_sid(tmp_ctx, &dom_sid, &domain, NULL,
00269 &domain_type) ||
00270 (domain_type != SID_NAME_DOMAIN)) {
00271 DEBUG(2, ("winbind could not find the domain's name "
00272 "it just looked up for us\n"));
00273 TALLOC_FREE(tmp_ctx);
00274 return False;
00275 }
00276 goto ok;
00277 }
00278
00279
00280
00281
00282
00283
00284 if (lookup_unix_user_name(name, &sid)) {
00285 domain = talloc_strdup(tmp_ctx, unix_users_domain_name());
00286 type = SID_NAME_USER;
00287 goto ok;
00288 }
00289
00290 if (lookup_unix_group_name(name, &sid)) {
00291 domain = talloc_strdup(tmp_ctx, unix_groups_domain_name());
00292 type = SID_NAME_DOM_GRP;
00293 goto ok;
00294 }
00295
00296
00297
00298
00299
00300 TALLOC_FREE(tmp_ctx);
00301 return False;
00302
00303 ok:
00304 if ((domain == NULL) || (name == NULL)) {
00305 DEBUG(0, ("talloc failed\n"));
00306 TALLOC_FREE(tmp_ctx);
00307 return False;
00308 }
00309
00310
00311
00312
00313
00314 if ((ret_name != NULL) &&
00315 !(*ret_name = talloc_strdup(mem_ctx, name))) {
00316 DEBUG(0, ("talloc failed\n"));
00317 TALLOC_FREE(tmp_ctx);
00318 return False;
00319 }
00320
00321 if (ret_domain != NULL) {
00322 char *tmp_dom;
00323 if (!(tmp_dom = talloc_strdup(mem_ctx, domain))) {
00324 DEBUG(0, ("talloc failed\n"));
00325 TALLOC_FREE(tmp_ctx);
00326 return False;
00327 }
00328 strupper_m(tmp_dom);
00329 *ret_domain = tmp_dom;
00330 }
00331
00332 if (ret_sid != NULL) {
00333 sid_copy(ret_sid, &sid);
00334 }
00335
00336 if (ret_type != NULL) {
00337 *ret_type = type;
00338 }
00339
00340 TALLOC_FREE(tmp_ctx);
00341 return True;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 BOOL lookup_name_smbconf(TALLOC_CTX *mem_ctx,
00351 const char *full_name, int flags,
00352 const char **ret_domain, const char **ret_name,
00353 DOM_SID *ret_sid, enum lsa_SidType *ret_type)
00354 {
00355 char *qualified_name;
00356 const char *p;
00357
00358
00359 if ((p = strchr_m(full_name, *lp_winbind_separator())) != NULL) {
00360
00361
00362
00363 if (*lp_winbind_separator() != '\\') {
00364 char *tmp;
00365
00366
00367
00368 tmp = talloc_strdup(mem_ctx, full_name);
00369 if (!tmp) {
00370 return False;
00371 }
00372 tmp[p - full_name] = '\\';
00373 full_name = tmp;
00374 }
00375
00376 return lookup_name(mem_ctx, full_name, flags,
00377 ret_domain, ret_name,
00378 ret_sid, ret_type);
00379 }
00380
00381
00382 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
00383 get_global_sam_name(),
00384 full_name );
00385 if (!qualified_name) {
00386 return False;
00387 }
00388
00389 if (lookup_name(mem_ctx, qualified_name, flags,
00390 ret_domain, ret_name,
00391 ret_sid, ret_type)) {
00392 return True;
00393 }
00394
00395
00396 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
00397 flags & LOOKUP_NAME_GROUP ?
00398 unix_groups_domain_name() :
00399 unix_users_domain_name(),
00400 full_name );
00401 if (!qualified_name) {
00402 return False;
00403 }
00404
00405 return lookup_name(mem_ctx, qualified_name, flags,
00406 ret_domain, ret_name,
00407 ret_sid, ret_type);
00408 }
00409
00410 static BOOL wb_lookup_rids(TALLOC_CTX *mem_ctx,
00411 const DOM_SID *domain_sid,
00412 int num_rids, uint32 *rids,
00413 const char **domain_name,
00414 const char **names, enum lsa_SidType *types)
00415 {
00416 int i;
00417 const char **my_names;
00418 enum lsa_SidType *my_types;
00419 TALLOC_CTX *tmp_ctx;
00420
00421 if (!(tmp_ctx = talloc_init("wb_lookup_rids"))) {
00422 return False;
00423 }
00424
00425 if (!winbind_lookup_rids(tmp_ctx, domain_sid, num_rids, rids,
00426 domain_name, &my_names, &my_types)) {
00427 *domain_name = "";
00428 for (i=0; i<num_rids; i++) {
00429 names[i] = "";
00430 types[i] = SID_NAME_UNKNOWN;
00431 }
00432 TALLOC_FREE(tmp_ctx);
00433 return True;
00434 }
00435
00436 if (!(*domain_name = talloc_strdup(mem_ctx, *domain_name))) {
00437 TALLOC_FREE(tmp_ctx);
00438 return False;
00439 }
00440
00441
00442
00443
00444
00445
00446 for (i=0; i<num_rids; i++) {
00447 if (my_names[i] == NULL) {
00448 TALLOC_FREE(tmp_ctx);
00449 return False;
00450 }
00451 if (!(names[i] = talloc_strdup(names, my_names[i]))) {
00452 TALLOC_FREE(tmp_ctx);
00453 return False;
00454 }
00455 types[i] = my_types[i];
00456 }
00457 TALLOC_FREE(tmp_ctx);
00458 return True;
00459 }
00460
00461 static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
00462 int num_rids, uint32_t *rids,
00463 const char **domain_name,
00464 const char ***names, enum lsa_SidType **types)
00465 {
00466 int i;
00467
00468 if (num_rids) {
00469 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
00470 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
00471
00472 if ((*names == NULL) || (*types == NULL)) {
00473 return False;
00474 }
00475 } else {
00476 *names = NULL;
00477 *types = NULL;
00478 }
00479
00480 if (sid_check_is_domain(domain_sid)) {
00481 NTSTATUS result;
00482
00483 if (*domain_name == NULL) {
00484 *domain_name = talloc_strdup(
00485 mem_ctx, get_global_sam_name());
00486 }
00487
00488 if (*domain_name == NULL) {
00489 return False;
00490 }
00491
00492 become_root();
00493 result = pdb_lookup_rids(domain_sid, num_rids, rids,
00494 *names, *types);
00495 unbecome_root();
00496
00497 return (NT_STATUS_IS_OK(result) ||
00498 NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
00499 NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED));
00500 }
00501
00502 if (sid_check_is_builtin(domain_sid)) {
00503
00504 if (*domain_name == NULL) {
00505 *domain_name = talloc_strdup(
00506 mem_ctx, builtin_domain_name());
00507 }
00508
00509 if (*domain_name == NULL) {
00510 return False;
00511 }
00512
00513 for (i=0; i<num_rids; i++) {
00514 if (lookup_builtin_rid(*names, rids[i],
00515 &(*names)[i])) {
00516 if ((*names)[i] == NULL) {
00517 return False;
00518 }
00519 (*types)[i] = SID_NAME_ALIAS;
00520 } else {
00521 (*types)[i] = SID_NAME_UNKNOWN;
00522 }
00523 }
00524 return True;
00525 }
00526
00527 if (sid_check_is_wellknown_domain(domain_sid, NULL)) {
00528 for (i=0; i<num_rids; i++) {
00529 DOM_SID sid;
00530 sid_copy(&sid, domain_sid);
00531 sid_append_rid(&sid, rids[i]);
00532 if (lookup_wellknown_sid(mem_ctx, &sid,
00533 domain_name, &(*names)[i])) {
00534 if ((*names)[i] == NULL) {
00535 return False;
00536 }
00537 (*types)[i] = SID_NAME_WKN_GRP;
00538 } else {
00539 (*types)[i] = SID_NAME_UNKNOWN;
00540 }
00541 }
00542 return True;
00543 }
00544
00545 if (sid_check_is_unix_users(domain_sid)) {
00546 if (*domain_name == NULL) {
00547 *domain_name = talloc_strdup(
00548 mem_ctx, unix_users_domain_name());
00549 }
00550 for (i=0; i<num_rids; i++) {
00551 (*names)[i] = talloc_strdup(
00552 (*names), uidtoname(rids[i]));
00553 (*types)[i] = SID_NAME_USER;
00554 }
00555 return True;
00556 }
00557
00558 if (sid_check_is_unix_groups(domain_sid)) {
00559 if (*domain_name == NULL) {
00560 *domain_name = talloc_strdup(
00561 mem_ctx, unix_groups_domain_name());
00562 }
00563 for (i=0; i<num_rids; i++) {
00564 (*names)[i] = talloc_strdup(
00565 (*names), gidtoname(rids[i]));
00566 (*types)[i] = SID_NAME_DOM_GRP;
00567 }
00568 return True;
00569 }
00570
00571 return wb_lookup_rids(mem_ctx, domain_sid, num_rids, rids,
00572 domain_name, *names, *types);
00573 }
00574
00575
00576
00577
00578
00579 static BOOL lookup_as_domain(const DOM_SID *sid, TALLOC_CTX *mem_ctx,
00580 const char **name)
00581 {
00582 const char *tmp;
00583 enum lsa_SidType type;
00584
00585 if (sid_check_is_domain(sid)) {
00586 *name = talloc_strdup(mem_ctx, get_global_sam_name());
00587 return True;
00588 }
00589
00590 if (sid_check_is_builtin(sid)) {
00591 *name = talloc_strdup(mem_ctx, builtin_domain_name());
00592 return True;
00593 }
00594
00595 if (sid_check_is_wellknown_domain(sid, &tmp)) {
00596 *name = talloc_strdup(mem_ctx, tmp);
00597 return True;
00598 }
00599
00600 if (sid->num_auths != 4) {
00601
00602 return False;
00603 }
00604
00605 if (IS_DC) {
00606 uint32 i, num_domains;
00607 struct trustdom_info **domains;
00608
00609
00610
00611
00612
00613 if (!NT_STATUS_IS_OK(secrets_trusted_domains(mem_ctx,
00614 &num_domains,
00615 &domains))) {
00616 return False;
00617 }
00618
00619 for (i=0; i<num_domains; i++) {
00620 if (sid_equal(sid, &domains[i]->sid)) {
00621 *name = talloc_strdup(mem_ctx,
00622 domains[i]->name);
00623 return True;
00624 }
00625 }
00626 return False;
00627 }
00628
00629 if (winbind_lookup_sid(mem_ctx, sid, &tmp, NULL, &type) &&
00630 (type == SID_NAME_DOMAIN)) {
00631 *name = tmp;
00632 return True;
00633 }
00634
00635 return False;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 static BOOL check_dom_sid_to_level(const DOM_SID *sid, int level)
00658 {
00659 int ret = False;
00660
00661 switch(level) {
00662 case 1:
00663 ret = True;
00664 break;
00665 case 2:
00666 ret = (!sid_check_is_builtin(sid) &&
00667 !sid_check_is_wellknown_domain(sid, NULL));
00668 break;
00669 case 3:
00670 case 4:
00671 case 6:
00672 ret = sid_check_is_domain(sid);
00673 break;
00674 case 5:
00675 ret = False;
00676 break;
00677 }
00678
00679 DEBUG(10, ("%s SID %s in level %d\n",
00680 ret ? "Accepting" : "Rejecting",
00681 sid_string_static(sid), level));
00682 return ret;
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697 NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids,
00698 const DOM_SID **sids, int level,
00699 struct lsa_dom_info **ret_domains,
00700 struct lsa_name_info **ret_names)
00701 {
00702 TALLOC_CTX *tmp_ctx;
00703 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00704 struct lsa_name_info *name_infos;
00705 struct lsa_dom_info *dom_infos = NULL;
00706
00707 int i, j;
00708
00709 if (!(tmp_ctx = talloc_new(mem_ctx))) {
00710 DEBUG(0, ("talloc_new failed\n"));
00711 return NT_STATUS_NO_MEMORY;
00712 }
00713
00714 if (num_sids) {
00715 name_infos = TALLOC_ARRAY(mem_ctx, struct lsa_name_info, num_sids);
00716 if (name_infos == NULL) {
00717 result = NT_STATUS_NO_MEMORY;
00718 goto fail;
00719 }
00720 } else {
00721 name_infos = NULL;
00722 }
00723
00724 dom_infos = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_dom_info,
00725 MAX_REF_DOMAINS);
00726 if (dom_infos == NULL) {
00727 result = NT_STATUS_NO_MEMORY;
00728 goto fail;
00729 }
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 for (i=0; i<num_sids; i++) {
00746 DOM_SID sid;
00747 uint32 rid;
00748 const char *domain_name = NULL;
00749
00750 sid_copy(&sid, sids[i]);
00751 name_infos[i].type = SID_NAME_USE_NONE;
00752
00753 if (lookup_as_domain(&sid, name_infos, &domain_name)) {
00754
00755
00756
00757
00758
00759
00760
00761 if (domain_name == NULL) {
00762 result = NT_STATUS_NO_MEMORY;
00763 goto fail;
00764 }
00765
00766 name_infos[i].rid = 0;
00767 name_infos[i].type = SID_NAME_DOMAIN;
00768 name_infos[i].name = NULL;
00769
00770 if (sid_check_is_builtin(&sid)) {
00771
00772
00773 name_infos[i].name = talloc_strdup(
00774 name_infos, builtin_domain_name());
00775 if (name_infos[i].name == NULL) {
00776 result = NT_STATUS_NO_MEMORY;
00777 goto fail;
00778 }
00779 }
00780 } else {
00781
00782 if (!sid_split_rid(&sid, &rid)) {
00783 result = NT_STATUS_INVALID_PARAMETER;
00784 goto fail;
00785 }
00786 }
00787
00788 if (!check_dom_sid_to_level(&sid, level)) {
00789 name_infos[i].rid = 0;
00790 name_infos[i].type = SID_NAME_UNKNOWN;
00791 name_infos[i].name = NULL;
00792 continue;
00793 }
00794
00795 for (j=0; j<MAX_REF_DOMAINS; j++) {
00796 if (!dom_infos[j].valid) {
00797 break;
00798 }
00799 if (sid_equal(&sid, &dom_infos[j].sid)) {
00800 break;
00801 }
00802 }
00803
00804 if (j == MAX_REF_DOMAINS) {
00805
00806 result = NT_STATUS_NONE_MAPPED;
00807 goto fail;
00808 }
00809
00810 if (!dom_infos[j].valid) {
00811
00812
00813 dom_infos[j].valid = True;
00814 sid_copy(&dom_infos[j].sid, &sid);
00815
00816 if (domain_name != NULL) {
00817
00818
00819 dom_infos[j].name =
00820 talloc_strdup(dom_infos, domain_name);
00821 if (dom_infos[j].name == NULL) {
00822 result = NT_STATUS_NO_MEMORY;
00823 goto fail;
00824 }
00825 } else {
00826
00827 dom_infos[j].name = NULL;
00828 }
00829 }
00830
00831 name_infos[i].dom_idx = j;
00832
00833 if (name_infos[i].type == SID_NAME_USE_NONE) {
00834 name_infos[i].rid = rid;
00835
00836 ADD_TO_ARRAY(dom_infos, int, i, &dom_infos[j].idxs,
00837 &dom_infos[j].num_idxs);
00838
00839 if (dom_infos[j].idxs == NULL) {
00840 result = NT_STATUS_NO_MEMORY;
00841 goto fail;
00842 }
00843 }
00844 }
00845
00846
00847
00848 for (i=0; i<MAX_REF_DOMAINS; i++) {
00849 uint32_t *rids;
00850 const char *domain_name = NULL;
00851 const char **names;
00852 enum lsa_SidType *types;
00853 struct lsa_dom_info *dom = &dom_infos[i];
00854
00855 if (!dom->valid) {
00856
00857 break;
00858 }
00859
00860 if (dom->num_idxs) {
00861 if (!(rids = TALLOC_ARRAY(tmp_ctx, uint32, dom->num_idxs))) {
00862 result = NT_STATUS_NO_MEMORY;
00863 goto fail;
00864 }
00865 } else {
00866 rids = NULL;
00867 }
00868
00869 for (j=0; j<dom->num_idxs; j++) {
00870 rids[j] = name_infos[dom->idxs[j]].rid;
00871 }
00872
00873 if (!lookup_rids(tmp_ctx, &dom->sid,
00874 dom->num_idxs, rids, &domain_name,
00875 &names, &types)) {
00876 result = NT_STATUS_NO_MEMORY;
00877 goto fail;
00878 }
00879
00880 if (!(dom->name = talloc_strdup(dom_infos, domain_name))) {
00881 result = NT_STATUS_NO_MEMORY;
00882 goto fail;
00883 }
00884
00885 for (j=0; j<dom->num_idxs; j++) {
00886 int idx = dom->idxs[j];
00887 name_infos[idx].type = types[j];
00888 if (types[j] != SID_NAME_UNKNOWN) {
00889 name_infos[idx].name =
00890 talloc_strdup(name_infos, names[j]);
00891 if (name_infos[idx].name == NULL) {
00892 result = NT_STATUS_NO_MEMORY;
00893 goto fail;
00894 }
00895 } else {
00896 name_infos[idx].name = NULL;
00897 }
00898 }
00899 }
00900
00901 *ret_domains = dom_infos;
00902 *ret_names = name_infos;
00903 return NT_STATUS_OK;
00904
00905 fail:
00906 TALLOC_FREE(dom_infos);
00907 TALLOC_FREE(name_infos);
00908 TALLOC_FREE(tmp_ctx);
00909 return result;
00910 }
00911
00912
00913
00914
00915
00916 BOOL lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
00917 const char **ret_domain, const char **ret_name,
00918 enum lsa_SidType *ret_type)
00919 {
00920 struct lsa_dom_info *domain;
00921 struct lsa_name_info *name;
00922 TALLOC_CTX *tmp_ctx;
00923 BOOL ret = False;
00924
00925 if (!(tmp_ctx = talloc_new(mem_ctx))) {
00926 DEBUG(0, ("talloc_new failed\n"));
00927 return False;
00928 }
00929
00930 if (!NT_STATUS_IS_OK(lookup_sids(tmp_ctx, 1, &sid, 1,
00931 &domain, &name))) {
00932 goto done;
00933 }
00934
00935 if (name->type == SID_NAME_UNKNOWN) {
00936 goto done;
00937 }
00938
00939 if ((ret_domain != NULL) &&
00940 !(*ret_domain = talloc_strdup(mem_ctx, domain->name))) {
00941 goto done;
00942 }
00943
00944 if ((ret_name != NULL) &&
00945 !(*ret_name = talloc_strdup(mem_ctx, name->name))) {
00946 goto done;
00947 }
00948
00949 if (ret_type != NULL) {
00950 *ret_type = name->type;
00951 }
00952
00953 ret = True;
00954
00955 done:
00956 if (ret) {
00957 DEBUG(10, ("Sid %s -> %s\\%s(%d)\n",
00958 sid_string_static(sid), domain->name,
00959 name->name, name->type));
00960 } else {
00961 DEBUG(10, ("failed to lookup sid %s\n",
00962 sid_string_static(sid)));
00963 }
00964 TALLOC_FREE(tmp_ctx);
00965 return ret;
00966 }
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 #define MAX_UID_SID_CACHE_SIZE 100
00977 #define TURNOVER_UID_SID_CACHE_SIZE 10
00978 #define MAX_GID_SID_CACHE_SIZE 100
00979 #define TURNOVER_GID_SID_CACHE_SIZE 10
00980
00981 static size_t n_uid_sid_cache = 0;
00982 static size_t n_gid_sid_cache = 0;
00983
00984 static struct uid_sid_cache {
00985 struct uid_sid_cache *next, *prev;
00986 uid_t uid;
00987 DOM_SID sid;
00988 enum lsa_SidType sidtype;
00989 } *uid_sid_cache_head;
00990
00991 static struct gid_sid_cache {
00992 struct gid_sid_cache *next, *prev;
00993 gid_t gid;
00994 DOM_SID sid;
00995 enum lsa_SidType sidtype;
00996 } *gid_sid_cache_head;
00997
00998
00999
01000
01001
01002 static BOOL fetch_sid_from_uid_cache(DOM_SID *psid, uid_t uid)
01003 {
01004 struct uid_sid_cache *pc;
01005
01006 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
01007 if (pc->uid == uid) {
01008 *psid = pc->sid;
01009 DEBUG(3,("fetch sid from uid cache %u -> %s\n",
01010 (unsigned int)uid, sid_string_static(psid)));
01011 DLIST_PROMOTE(uid_sid_cache_head, pc);
01012 return True;
01013 }
01014 }
01015 return False;
01016 }
01017
01018
01019
01020
01021
01022 static BOOL fetch_uid_from_cache( uid_t *puid, const DOM_SID *psid )
01023 {
01024 struct uid_sid_cache *pc;
01025
01026 for (pc = uid_sid_cache_head; pc; pc = pc->next) {
01027 if (sid_compare(&pc->sid, psid) == 0) {
01028 *puid = pc->uid;
01029 DEBUG(3,("fetch uid from cache %u -> %s\n",
01030 (unsigned int)*puid, sid_string_static(psid)));
01031 DLIST_PROMOTE(uid_sid_cache_head, pc);
01032 return True;
01033 }
01034 }
01035 return False;
01036 }
01037
01038
01039
01040
01041
01042 void store_uid_sid_cache(const DOM_SID *psid, uid_t uid)
01043 {
01044 struct uid_sid_cache *pc;
01045
01046
01047
01048 if ( sid_check_is_in_unix_users( psid ) )
01049 return;
01050
01051 if (n_uid_sid_cache >= MAX_UID_SID_CACHE_SIZE && n_uid_sid_cache > TURNOVER_UID_SID_CACHE_SIZE) {
01052
01053 struct uid_sid_cache *pc_next;
01054 size_t i;
01055
01056 for (i = 0, pc = uid_sid_cache_head; i < (n_uid_sid_cache - TURNOVER_UID_SID_CACHE_SIZE); i++, pc = pc->next)
01057 ;
01058 for(; pc; pc = pc_next) {
01059 pc_next = pc->next;
01060 DLIST_REMOVE(uid_sid_cache_head,pc);
01061 SAFE_FREE(pc);
01062 n_uid_sid_cache--;
01063 }
01064 }
01065
01066 pc = SMB_MALLOC_P(struct uid_sid_cache);
01067 if (!pc)
01068 return;
01069 pc->uid = uid;
01070 sid_copy(&pc->sid, psid);
01071 DLIST_ADD(uid_sid_cache_head, pc);
01072 n_uid_sid_cache++;
01073 }
01074
01075
01076
01077
01078
01079 static BOOL fetch_sid_from_gid_cache(DOM_SID *psid, gid_t gid)
01080 {
01081 struct gid_sid_cache *pc;
01082
01083 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
01084 if (pc->gid == gid) {
01085 *psid = pc->sid;
01086 DEBUG(3,("fetch sid from gid cache %u -> %s\n",
01087 (unsigned int)gid, sid_string_static(psid)));
01088 DLIST_PROMOTE(gid_sid_cache_head, pc);
01089 return True;
01090 }
01091 }
01092 return False;
01093 }
01094
01095
01096
01097
01098
01099 static BOOL fetch_gid_from_cache(gid_t *pgid, const DOM_SID *psid)
01100 {
01101 struct gid_sid_cache *pc;
01102
01103 for (pc = gid_sid_cache_head; pc; pc = pc->next) {
01104 if (sid_compare(&pc->sid, psid) == 0) {
01105 *pgid = pc->gid;
01106 DEBUG(3,("fetch gid from cache %u -> %s\n",
01107 (unsigned int)*pgid, sid_string_static(psid)));
01108 DLIST_PROMOTE(gid_sid_cache_head, pc);
01109 return True;
01110 }
01111 }
01112 return False;
01113 }
01114
01115
01116
01117
01118
01119 void store_gid_sid_cache(const DOM_SID *psid, gid_t gid)
01120 {
01121 struct gid_sid_cache *pc;
01122
01123
01124
01125 if ( sid_check_is_in_unix_groups( psid ) )
01126 return;
01127
01128 if (n_gid_sid_cache >= MAX_GID_SID_CACHE_SIZE && n_gid_sid_cache > TURNOVER_GID_SID_CACHE_SIZE) {
01129
01130 struct gid_sid_cache *pc_next;
01131 size_t i;
01132
01133 for (i = 0, pc = gid_sid_cache_head; i < (n_gid_sid_cache - TURNOVER_GID_SID_CACHE_SIZE); i++, pc = pc->next)
01134 ;
01135 for(; pc; pc = pc_next) {
01136 pc_next = pc->next;
01137 DLIST_REMOVE(gid_sid_cache_head,pc);
01138 SAFE_FREE(pc);
01139 n_gid_sid_cache--;
01140 }
01141 }
01142
01143 pc = SMB_MALLOC_P(struct gid_sid_cache);
01144 if (!pc)
01145 return;
01146 pc->gid = gid;
01147 sid_copy(&pc->sid, psid);
01148 DLIST_ADD(gid_sid_cache_head, pc);
01149
01150 DEBUG(3,("store_gid_sid_cache: gid %u in cache -> %s\n", (unsigned int)gid,
01151 sid_string_static(psid)));
01152
01153 n_gid_sid_cache++;
01154 }
01155
01156
01157
01158
01159
01160 static void legacy_uid_to_sid(DOM_SID *psid, uid_t uid)
01161 {
01162 uint32 rid;
01163 BOOL ret;
01164
01165 ZERO_STRUCTP(psid);
01166
01167 become_root();
01168 ret = pdb_uid_to_rid(uid, &rid);
01169 unbecome_root();
01170
01171 if (ret) {
01172
01173 sid_copy(psid, get_global_sam_sid());
01174 sid_append_rid(psid, rid);
01175 goto done;
01176 }
01177
01178
01179
01180 uid_to_unix_users_sid(uid, psid);
01181
01182 done:
01183 DEBUG(10,("LEGACY: uid %u -> sid %s\n", (unsigned int)uid,
01184 sid_string_static(psid)));
01185
01186 store_uid_sid_cache(psid, uid);
01187 return;
01188 }
01189
01190
01191
01192
01193
01194 static void legacy_gid_to_sid(DOM_SID *psid, gid_t gid)
01195 {
01196 BOOL ret;
01197
01198 ZERO_STRUCTP(psid);
01199
01200 become_root();
01201 ret = pdb_gid_to_sid(gid, psid);
01202 unbecome_root();
01203
01204 if (ret) {
01205
01206 goto done;
01207 }
01208
01209
01210
01211 gid_to_unix_groups_sid(gid, psid);
01212
01213 done:
01214 DEBUG(10,("LEGACY: gid %u -> sid %s\n", (unsigned int)gid,
01215 sid_string_static(psid)));
01216
01217 store_gid_sid_cache(psid, gid);
01218 return;
01219 }
01220
01221
01222
01223
01224
01225 static BOOL legacy_sid_to_uid(const DOM_SID *psid, uid_t *puid)
01226 {
01227 enum lsa_SidType type;
01228 uint32 rid;
01229
01230 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
01231 union unid_t id;
01232 BOOL ret;
01233
01234 become_root();
01235 ret = pdb_sid_to_id(psid, &id, &type);
01236 unbecome_root();
01237
01238 if (ret) {
01239 if (type != SID_NAME_USER) {
01240 DEBUG(5, ("sid %s is a %s, expected a user\n",
01241 sid_string_static(psid),
01242 sid_type_lookup(type)));
01243 return False;
01244 }
01245 *puid = id.uid;
01246 goto done;
01247 }
01248
01249
01250 }
01251
01252 DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_static(psid)));
01253 return False;
01254
01255 done:
01256 DEBUG(10,("LEGACY: sid %s -> uid %u\n", sid_string_static(psid),
01257 (unsigned int)*puid ));
01258
01259 store_uid_sid_cache(psid, *puid);
01260 return True;
01261 }
01262
01263
01264
01265
01266
01267
01268 static BOOL legacy_sid_to_gid(const DOM_SID *psid, gid_t *pgid)
01269 {
01270 uint32 rid;
01271 GROUP_MAP map;
01272 union unid_t id;
01273 enum lsa_SidType type;
01274
01275 if ((sid_check_is_in_builtin(psid) ||
01276 sid_check_is_in_wellknown_domain(psid))) {
01277 BOOL ret;
01278
01279 become_root();
01280 ret = pdb_getgrsid(&map, *psid);
01281 unbecome_root();
01282
01283 if (ret) {
01284 *pgid = map.gid;
01285 goto done;
01286 }
01287 DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_static(psid)));
01288 return False;
01289 }
01290
01291 if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
01292 BOOL ret;
01293
01294 become_root();
01295 ret = pdb_sid_to_id(psid, &id, &type);
01296 unbecome_root();
01297
01298 if (ret) {
01299 if ((type != SID_NAME_DOM_GRP) &&
01300 (type != SID_NAME_ALIAS)) {
01301 DEBUG(5, ("LEGACY: sid %s is a %s, expected a group\n",
01302 sid_string_static(psid),
01303 sid_type_lookup(type)));
01304 return False;
01305 }
01306 *pgid = id.gid;
01307 goto done;
01308 }
01309
01310
01311 }
01312
01313 DEBUG(10,("LEGACY: mapping failed for sid %s\n", sid_string_static(psid)));
01314 return False;
01315
01316 done:
01317 DEBUG(10,("LEGACY: sid %s -> gid %u\n", sid_string_static(psid),
01318 (unsigned int)*pgid ));
01319
01320 store_gid_sid_cache(psid, *pgid);
01321
01322 return True;
01323 }
01324
01325
01326
01327
01328
01329 void uid_to_sid(DOM_SID *psid, uid_t uid)
01330 {
01331 ZERO_STRUCTP(psid);
01332
01333 if (fetch_sid_from_uid_cache(psid, uid))
01334 return;
01335
01336 if (!winbind_uid_to_sid(psid, uid)) {
01337 if (!winbind_ping()) {
01338 legacy_uid_to_sid(psid, uid);
01339 return;
01340 }
01341
01342 DEBUG(5, ("uid_to_sid: winbind failed to find a sid for uid %u\n",
01343 uid));
01344 return;
01345 }
01346
01347 DEBUG(10,("uid %u -> sid %s\n",
01348 (unsigned int)uid, sid_string_static(psid)));
01349
01350 store_uid_sid_cache(psid, uid);
01351 return;
01352 }
01353
01354
01355
01356
01357
01358 void gid_to_sid(DOM_SID *psid, gid_t gid)
01359 {
01360 ZERO_STRUCTP(psid);
01361
01362 if (fetch_sid_from_gid_cache(psid, gid))
01363 return;
01364
01365 if (!winbind_gid_to_sid(psid, gid)) {
01366 if (!winbind_ping()) {
01367 legacy_gid_to_sid(psid, gid);
01368 return;
01369 }
01370
01371 DEBUG(5, ("gid_to_sid: winbind failed to find a sid for gid %u\n",
01372 gid));
01373 return;
01374 }
01375
01376 DEBUG(10,("gid %u -> sid %s\n",
01377 (unsigned int)gid, sid_string_static(psid)));
01378
01379 store_gid_sid_cache(psid, gid);
01380 return;
01381 }
01382
01383
01384
01385
01386
01387 BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
01388 {
01389 uint32 rid;
01390 gid_t gid;
01391
01392 if (fetch_uid_from_cache(puid, psid))
01393 return True;
01394
01395 if (fetch_gid_from_cache(&gid, psid)) {
01396 return False;
01397 }
01398
01399
01400
01401 if (sid_peek_check_rid(&global_sid_Unix_Users, psid, &rid)) {
01402 uid_t uid = rid;
01403 *puid = uid;
01404
01405
01406 DEBUG(10,("sid %s -> uid %u\n", sid_string_static(psid),
01407 (unsigned int)*puid ));
01408 return True;
01409 }
01410
01411 if (!winbind_sid_to_uid(puid, psid)) {
01412 if (!winbind_ping()) {
01413 return legacy_sid_to_uid(psid, puid);
01414 }
01415
01416 DEBUG(5, ("winbind failed to find a uid for sid %s\n",
01417 sid_string_static(psid)));
01418 return False;
01419 }
01420
01421
01422
01423
01424 DEBUG(10,("sid %s -> uid %u\n", sid_string_static(psid),
01425 (unsigned int)*puid ));
01426
01427 store_uid_sid_cache(psid, *puid);
01428 return True;
01429 }
01430
01431
01432
01433
01434
01435
01436 BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
01437 {
01438 uint32 rid;
01439 uid_t uid;
01440
01441 if (fetch_gid_from_cache(pgid, psid))
01442 return True;
01443
01444 if (fetch_uid_from_cache(&uid, psid))
01445 return False;
01446
01447
01448
01449 if (sid_peek_check_rid(&global_sid_Unix_Groups, psid, &rid)) {
01450 gid_t gid = rid;
01451 *pgid = gid;
01452
01453
01454 DEBUG(10,("sid %s -> gid %u\n", sid_string_static(psid),
01455 (unsigned int)*pgid ));
01456 return True;
01457 }
01458
01459
01460
01461
01462 if ( !winbind_sid_to_gid(pgid, psid) ) {
01463 if (!winbind_ping()) {
01464 return legacy_sid_to_gid(psid, pgid);
01465 }
01466
01467 DEBUG(10,("winbind failed to find a gid for sid %s\n",
01468 sid_string_static(psid)));
01469 return False;
01470 }
01471
01472 DEBUG(10,("sid %s -> gid %u\n", sid_string_static(psid),
01473 (unsigned int)*pgid ));
01474
01475 store_gid_sid_cache(psid, *pgid);
01476
01477 return True;
01478 }
01479