Changeset 745 for trunk/server/source3/winbindd/winbindd_ads.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/winbindd/winbindd_ads.c
r414 r745 24 24 #include "includes.h" 25 25 #include "winbindd.h" 26 #include "../librpc/gen_ndr/cli_netlogon.h" 26 #include "rpc_client/rpc_client.h" 27 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 28 #include "../libds/common/flags.h" 29 #include "ads.h" 30 #include "secrets.h" 31 #include "../libcli/ldap/ldap_ndr.h" 32 #include "../libcli/security/security.h" 33 #include "../libds/common/flag_mapping.h" 34 #include "passdb.h" 27 35 28 36 #ifdef HAVE_ADS … … 153 161 TALLOC_CTX *mem_ctx, 154 162 uint32 *num_entries, 155 struct wbint_userinfo ** info)163 struct wbint_userinfo **pinfo) 156 164 { 157 165 ADS_STRUCT *ads = NULL; … … 192 200 } 193 201 194 (* info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);195 if (!* info) {202 (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count); 203 if (!*pinfo) { 196 204 status = NT_STATUS_NO_MEMORY; 197 205 goto done; 198 206 } 199 207 200 i= 0;208 count = 0; 201 209 202 210 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 203 const char *name; 204 const char *gecos = NULL; 205 const char *homedir = NULL; 206 const char *shell = NULL; 211 struct wbint_userinfo *info = &((*pinfo)[count]); 207 212 uint32 group; 208 213 uint32 atype; 209 DOM_SID user_sid;210 gid_t primary_gid = (gid_t)-1;211 214 212 215 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || … … 216 219 } 217 220 218 name = ads_pull_username(ads, mem_ctx, msg); 219 220 if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) { 221 status = nss_get_info_cached( domain, &user_sid, mem_ctx, 222 ads, msg, &homedir, &shell, &gecos, 223 &primary_gid ); 224 } 225 226 if (gecos == NULL) { 227 gecos = ads_pull_string(ads, mem_ctx, msg, "name"); 228 } 221 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 222 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 223 info->homedir = NULL; 224 info->shell = NULL; 225 info->primary_gid = (gid_t)-1; 229 226 230 227 if (!ads_pull_sid(ads, msg, "objectSid", 231 & (*info)[i].user_sid)) {232 DEBUG(1, ("No sid for %s !?\n",name));228 &info->user_sid)) { 229 DEBUG(1, ("No sid for %s !?\n", info->acct_name)); 233 230 continue; 234 231 } 232 235 233 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) { 236 DEBUG(1,("No primary group for %s !?\n", name)); 234 DEBUG(1, ("No primary group for %s !?\n", 235 info->acct_name)); 237 236 continue; 238 237 } 239 240 (*info)[i].acct_name = name; 241 (*info)[i].full_name = gecos; 242 (*info)[i].homedir = homedir; 243 (*info)[i].shell = shell; 244 (*info)[i].primary_gid = primary_gid; 245 sid_compose(&(*info)[i].group_sid, &domain->sid, group); 246 i++; 247 } 248 249 (*num_entries) = i; 238 sid_compose(&info->group_sid, &domain->sid, group); 239 240 count += 1; 241 } 242 243 (*num_entries) = count; 244 ads_msgfree(ads, res); 245 246 for (i=0; i<count; i++) { 247 struct wbint_userinfo *info = &((*pinfo)[i]); 248 const char *gecos = NULL; 249 gid_t primary_gid = (gid_t)-1; 250 251 status = nss_get_info_cached(domain, &info->user_sid, mem_ctx, 252 &info->homedir, &info->shell, 253 &gecos, &primary_gid); 254 if (!NT_STATUS_IS_OK(status)) { 255 /* 256 * Deliberately ignore this error, there might be more 257 * users to fill 258 */ 259 continue; 260 } 261 262 if (gecos != NULL) { 263 info->full_name = gecos; 264 } 265 info->primary_gid = primary_gid; 266 } 267 250 268 status = NT_STATUS_OK; 251 269 … … 253 271 254 272 done: 255 if (res)256 ads_msgfree(ads, res);257 258 273 return status; 259 274 } … … 263 278 TALLOC_CTX *mem_ctx, 264 279 uint32 *num_entries, 265 struct acct_info **info)280 struct wb_acct_info **info) 266 281 { 267 282 ADS_STRUCT *ads = NULL; … … 337 352 } 338 353 339 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct acct_info, count);354 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wb_acct_info, count); 340 355 if (!*info) { 341 356 status = NT_STATUS_NO_MEMORY; … … 347 362 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 348 363 char *name, *gecos; 349 DOM_SIDsid;364 struct dom_sid sid; 350 365 uint32 rid; 351 366 … … 385 400 TALLOC_CTX *mem_ctx, 386 401 uint32 *num_entries, 387 struct acct_info **info)402 struct wb_acct_info **info) 388 403 { 389 404 /* … … 408 423 const char *name, 409 424 uint32_t flags, 410 DOM_SID*sid,425 struct dom_sid *sid, 411 426 enum lsa_SidType *type) 412 427 { … … 419 434 static NTSTATUS sid_to_name(struct winbindd_domain *domain, 420 435 TALLOC_CTX *mem_ctx, 421 const DOM_SID*sid,436 const struct dom_sid *sid, 422 437 char **domain_name, 423 438 char **name, … … 431 446 static NTSTATUS rids_to_names(struct winbindd_domain *domain, 432 447 TALLOC_CTX *mem_ctx, 433 const DOM_SID*sid,448 const struct dom_sid *sid, 434 449 uint32 *rids, 435 450 size_t num_rids, … … 451 466 static NTSTATUS query_user(struct winbindd_domain *domain, 452 467 TALLOC_CTX *mem_ctx, 453 const DOM_SID *sid,468 const struct dom_sid *sid, 454 469 struct wbint_userinfo *info) 455 470 { … … 464 479 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 465 480 struct netr_SamInfo3 *user = NULL; 466 gid_t gid; 481 gid_t gid = -1; 482 int ret; 483 char *ads_name; 467 484 468 485 DEBUG(3,("ads: query_user\n")); … … 470 487 info->homedir = NULL; 471 488 info->shell = NULL; 472 info->primary_gid = (gid_t)-1;473 489 474 490 /* try netsamlogon cache first */ … … 485 501 info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string); 486 502 487 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,503 nss_get_info_cached( domain, sid, mem_ctx, 488 504 &info->homedir, &info->shell, &info->full_name, 489 505 &gid ); … … 507 523 /* Assume "Domain Users" for the primary group */ 508 524 509 sid_compose(&info->group_sid, &domain->sid, DOMAIN_ GROUP_RID_USERS );525 sid_compose(&info->group_sid, &domain->sid, DOMAIN_RID_USERS ); 510 526 511 527 /* Try to fill in what the nss_info backend can do */ 512 528 513 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,529 nss_get_info_cached( domain, sid, mem_ctx, 514 530 &info->homedir, &info->shell, &info->full_name, 515 531 &gid); 516 532 info->primary_gid = gid; 517 533 518 status = NT_STATUS_OK; 519 goto done; 534 return NT_STATUS_OK; 520 535 } 521 536 … … 524 539 if ( (ads = ads_cached_connection(domain)) == NULL ) { 525 540 domain->last_status = NT_STATUS_SERVER_DISABLED; 526 goto done; 527 } 528 529 sidstr = sid_binstring(talloc_tos(), sid); 530 if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { 531 status = NT_STATUS_NO_MEMORY; 532 goto done; 541 return NT_STATUS_SERVER_DISABLED; 542 } 543 544 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid); 545 546 ret = asprintf(&ldap_exp, "(objectSid=%s)", sidstr); 547 TALLOC_FREE(sidstr); 548 if (ret == -1) { 549 return NT_STATUS_NO_MEMORY; 533 550 } 534 551 rc = ads_search_retry(ads, &msg, ldap_exp, attrs); 535 free(ldap_exp); 536 TALLOC_FREE(sidstr); 552 SAFE_FREE(ldap_exp); 537 553 if (!ADS_ERR_OK(rc) || !msg) { 538 554 DEBUG(1,("query_user(sid=%s) ads_search: %s\n", 539 555 sid_string_dbg(sid), ads_errstr(rc))); 540 goto done;556 return ads_ntstatus(rc); 541 557 } 542 558 … … 545 561 DEBUG(1,("query_user(sid=%s): Not found\n", 546 562 sid_string_dbg(sid))); 547 goto done; 563 ads_msgfree(ads, msg); 564 return NT_STATUS_NO_SUCH_USER; 548 565 } 549 566 550 567 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 551 568 552 nss_get_info_cached( domain, sid, mem_ctx, ads, msg, 569 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { 570 DEBUG(1,("No primary group for %s !?\n", 571 sid_string_dbg(sid))); 572 ads_msgfree(ads, msg); 573 return NT_STATUS_NO_SUCH_USER; 574 } 575 sid_copy(&info->user_sid, sid); 576 sid_compose(&info->group_sid, &domain->sid, group_rid); 577 578 /* 579 * We have to fetch the "name" attribute before doing the 580 * nss_get_info_cached call. nss_get_info_cached might destroy 581 * the ads struct, potentially invalidating the ldap message. 582 */ 583 ads_name = ads_pull_string(ads, mem_ctx, msg, "name"); 584 585 ads_msgfree(ads, msg); 586 msg = NULL; 587 588 status = nss_get_info_cached( domain, sid, mem_ctx, 553 589 &info->homedir, &info->shell, &info->full_name, 554 590 &gid); 555 591 info->primary_gid = gid; 592 if (!NT_STATUS_IS_OK(status)) { 593 DEBUG(1, ("nss_get_info_cached failed: %s\n", 594 nt_errstr(status))); 595 return status; 596 } 556 597 557 598 if (info->full_name == NULL) { 558 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 559 } 560 561 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { 562 DEBUG(1,("No primary group for %s !?\n", 563 sid_string_dbg(sid))); 564 goto done; 565 } 566 567 sid_copy(&info->user_sid, sid); 568 sid_compose(&info->group_sid, &domain->sid, group_rid); 599 info->full_name = ads_name; 600 } else { 601 TALLOC_FREE(ads_name); 602 } 569 603 570 604 status = NT_STATUS_OK; 571 605 572 606 DEBUG(3,("ads query_user gave %s\n", info->acct_name)); 573 done: 574 if (msg) 575 ads_msgfree(ads, msg); 576 577 return status; 607 return NT_STATUS_OK; 578 608 } 579 609 … … 583 613 TALLOC_CTX *mem_ctx, 584 614 const char *user_dn, 585 DOM_SID*primary_group,586 size_t *p_num_groups, DOM_SID**user_sids)615 struct dom_sid *primary_group, 616 uint32_t *p_num_groups, struct dom_sid **user_sids) 587 617 { 588 618 ADS_STATUS rc; … … 595 625 const char *group_attrs[] = {"objectSid", NULL}; 596 626 char *escaped_dn; 597 size_t num_groups = 0;627 uint32_t num_groups = 0; 598 628 599 629 DEBUG(3,("ads: lookup_usergroups_member\n")); … … 653 683 for (msg = ads_first_entry(ads, res); msg; 654 684 msg = ads_next_entry(ads, msg)) { 655 DOM_SIDgroup_sid;685 struct dom_sid group_sid; 656 686 657 687 if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { … … 690 720 TALLOC_CTX *mem_ctx, 691 721 const char *user_dn, 692 DOM_SID*primary_group,693 size_t *p_num_groups,694 DOM_SID**user_sids)722 struct dom_sid *primary_group, 723 uint32_t *p_num_groups, 724 struct dom_sid **user_sids) 695 725 { 696 726 ADS_STATUS rc; … … 698 728 ADS_STRUCT *ads; 699 729 const char *attrs[] = {"memberOf", NULL}; 700 size_t num_groups = 0;701 DOM_SID*group_sids = NULL;730 uint32_t num_groups = 0; 731 struct dom_sid *group_sids = NULL; 702 732 int i; 703 733 char **strings = NULL; … … 740 770 } 741 771 742 group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);772 group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1); 743 773 if (!group_sids) { 744 774 status = NT_STATUS_NO_MEMORY; … … 802 832 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 803 833 TALLOC_CTX *mem_ctx, 804 const DOM_SID *sid,805 uint32 *p_num_groups, DOM_SID**user_sids)834 const struct dom_sid *sid, 835 uint32 *p_num_groups, struct dom_sid **user_sids) 806 836 { 807 837 ADS_STRUCT *ads = NULL; … … 811 841 LDAPMessage *msg = NULL; 812 842 char *user_dn = NULL; 813 DOM_SID*sids;843 struct dom_sid *sids; 814 844 int i; 815 DOM_SIDprimary_group;845 struct dom_sid primary_group; 816 846 uint32 primary_group_rid; 817 847 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 818 size_t num_groups = 0;848 uint32_t num_groups = 0; 819 849 820 850 DEBUG(3,("ads: lookup_usergroups\n")); … … 881 911 } 882 912 883 sid_copy(&primary_group, &domain->sid); 884 sid_append_rid(&primary_group, primary_group_rid); 913 sid_compose(&primary_group, &domain->sid, primary_group_rid); 885 914 886 915 count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids); … … 902 931 &primary_group, 903 932 &num_groups, user_sids); 904 *p_num_groups = (uint32)num_groups;933 *p_num_groups = num_groups; 905 934 if (NT_STATUS_IS_OK(status)) { 906 935 goto done; … … 913 942 &primary_group, 914 943 &num_groups, user_sids); 915 *p_num_groups = (uint32)num_groups;944 *p_num_groups = num_groups; 916 945 goto done; 917 946 } … … 954 983 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 955 984 TALLOC_CTX *mem_ctx, 956 uint32 num_sids, const DOM_SID*sids,985 uint32 num_sids, const struct dom_sid *sids, 957 986 uint32 *num_aliases, uint32 **alias_rids) 958 987 { … … 968 997 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 969 998 TALLOC_CTX *mem_ctx, 970 const DOM_SID*group_sid,999 const struct dom_sid *group_sid, 971 1000 enum lsa_SidType type, 972 1001 uint32 *num_names, 973 DOM_SID**sid_mem, char ***names,1002 struct dom_sid **sid_mem, char ***names, 974 1003 uint32 **name_types) 975 1004 { … … 983 1012 size_t num_members = 0; 984 1013 ads_control args; 985 DOM_SID*sid_mem_nocache = NULL;1014 struct dom_sid *sid_mem_nocache = NULL; 986 1015 char **names_nocache = NULL; 987 1016 enum lsa_SidType *name_types_nocache = NULL; … … 1015 1044 } 1016 1045 1017 if ((sidbinstr = sid_binstring(talloc_tos(), group_sid)) == NULL) {1046 if ((sidbinstr = ldap_encode_ndr_dom_sid(talloc_tos(), group_sid)) == NULL) { 1018 1047 status = NT_STATUS_NO_MEMORY; 1019 1048 goto done; … … 1057 1086 1058 1087 if (num_members) { 1059 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);1088 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members); 1060 1089 (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members); 1061 1090 (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members); 1062 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, DOM_SID, num_members);1091 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members); 1063 1092 1064 1093 if ((members == NULL) || (*sid_mem == NULL) || … … 1080 1109 enum lsa_SidType name_type; 1081 1110 char *name, *domain_name; 1082 DOM_SIDsid;1111 struct dom_sid sid; 1083 1112 1084 1113 rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, … … 1261 1290 { 1262 1291 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1292 WERROR werr; 1263 1293 int i; 1264 1294 uint32 flags; 1265 1295 struct rpc_pipe_client *cli; 1266 uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT);1267 1296 int ret_count; 1297 struct dcerpc_binding_handle *b; 1268 1298 1269 1299 DEBUG(3,("ads: trusted_domains\n")); … … 1275 1305 trusts in the target forest */ 1276 1306 1277 if ( domain->primary || 1278 ((domain->domain_flags&fr_flags) == fr_flags) ) 1279 { 1307 if (domain->primary || domain_is_forest_root(domain)) { 1280 1308 flags = NETR_TRUST_FLAG_OUTBOUND | 1281 1309 NETR_TRUST_FLAG_INBOUND | … … 1294 1322 } 1295 1323 1296 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx, 1324 b = cli->binding_handle; 1325 1326 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx, 1297 1327 cli->desthost, 1298 1328 flags, 1299 1329 trusts, 1300 NULL);1330 &werr); 1301 1331 if (!NT_STATUS_IS_OK(result)) { 1302 1332 return result; 1333 } 1334 1335 if (!W_ERROR_IS_OK(werr)) { 1336 return werror_to_ntstatus(werr); 1303 1337 } 1304 1338 if (trusts->count == 0) { … … 1355 1389 wcache_tdc_add_domain( &d ); 1356 1390 ret_count++; 1357 } else if ( (domain->domain_flags&fr_flags) == fr_flags) {1391 } else if (domain_is_forest_root(domain)) { 1358 1392 /* Check if we already have this record. If 1359 1393 * we are following our forest root that is not
Note:
See TracChangeset
for help on using the changeset viewer.