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 #include "includes.h"
00026 #include "winbindd.h"
00027
00028 #undef DBGC_CLASS
00029 #define DBGC_CLASS DBGC_WINBIND
00030
00031
00032
00033
00034
00035 static NTSTATUS query_user_list(struct winbindd_domain *domain,
00036 TALLOC_CTX *mem_ctx,
00037 uint32 *num_entries,
00038 WINBIND_USERINFO **info)
00039 {
00040 NTSTATUS result;
00041 POLICY_HND dom_pol;
00042 unsigned int i, start_idx;
00043 uint32 loop_count;
00044 struct rpc_pipe_client *cli;
00045
00046 DEBUG(3,("rpc: query_user_list\n"));
00047
00048 *num_entries = 0;
00049 *info = NULL;
00050
00051 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00052 if (!NT_STATUS_IS_OK(result))
00053 return result;
00054
00055 i = start_idx = 0;
00056 loop_count = 0;
00057
00058 do {
00059 TALLOC_CTX *ctx2;
00060 uint32 num_dom_users, j;
00061 uint32 max_entries, max_size;
00062 SAM_DISPINFO_CTR ctr;
00063 SAM_DISPINFO_1 info1;
00064
00065 ZERO_STRUCT( ctr );
00066 ZERO_STRUCT( info1 );
00067 ctr.sam.info1 = &info1;
00068
00069 if (!(ctx2 = talloc_init("winbindd enum_users")))
00070 return NT_STATUS_NO_MEMORY;
00071
00072
00073
00074 get_query_dispinfo_params(loop_count, &max_entries,
00075 &max_size);
00076
00077 result = rpccli_samr_query_dispinfo(cli, mem_ctx, &dom_pol,
00078 &start_idx, 1,
00079 &num_dom_users,
00080 max_entries, max_size,
00081 &ctr);
00082
00083 loop_count++;
00084
00085 *num_entries += num_dom_users;
00086
00087 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, WINBIND_USERINFO,
00088 *num_entries);
00089
00090 if (!(*info)) {
00091 talloc_destroy(ctx2);
00092 return NT_STATUS_NO_MEMORY;
00093 }
00094
00095 for (j = 0; j < num_dom_users; i++, j++) {
00096 fstring username, fullname;
00097 uint32 rid = ctr.sam.info1->sam[j].rid_user;
00098
00099 unistr2_to_ascii( username, &(&ctr.sam.info1->str[j])->uni_acct_name, sizeof(username)-1);
00100 unistr2_to_ascii( fullname, &(&ctr.sam.info1->str[j])->uni_full_name, sizeof(fullname)-1);
00101
00102 (*info)[i].acct_name = talloc_strdup(mem_ctx, username );
00103 (*info)[i].full_name = talloc_strdup(mem_ctx, fullname );
00104 (*info)[i].homedir = NULL;
00105 (*info)[i].shell = NULL;
00106 sid_compose(&(*info)[i].user_sid, &domain->sid, rid);
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 sid_compose(&(*info)[i].group_sid, &domain->sid,
00117 DOMAIN_GROUP_RID_USERS);
00118 }
00119
00120 talloc_destroy(ctx2);
00121
00122 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
00123
00124 return result;
00125 }
00126
00127
00128 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
00129 TALLOC_CTX *mem_ctx,
00130 uint32 *num_entries,
00131 struct acct_info **info)
00132 {
00133 POLICY_HND dom_pol;
00134 NTSTATUS status;
00135 uint32 start = 0;
00136 struct rpc_pipe_client *cli;
00137
00138 *num_entries = 0;
00139 *info = NULL;
00140
00141 DEBUG(3,("rpc: enum_dom_groups\n"));
00142
00143 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00144 if (!NT_STATUS_IS_OK(status))
00145 return status;
00146
00147 do {
00148 struct acct_info *info2 = NULL;
00149 uint32 count = 0;
00150 TALLOC_CTX *mem_ctx2;
00151
00152 mem_ctx2 = talloc_init("enum_dom_groups[rpc]");
00153
00154
00155 status = rpccli_samr_enum_dom_groups(cli, mem_ctx2, &dom_pol,
00156 &start,
00157 0xFFFF,
00158 &info2, &count);
00159
00160 if (!NT_STATUS_IS_OK(status) &&
00161 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
00162 talloc_destroy(mem_ctx2);
00163 break;
00164 }
00165
00166 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
00167 struct acct_info,
00168 (*num_entries) + count);
00169 if (! *info) {
00170 talloc_destroy(mem_ctx2);
00171 return NT_STATUS_NO_MEMORY;
00172 }
00173
00174 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
00175 (*num_entries) += count;
00176 talloc_destroy(mem_ctx2);
00177 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
00178
00179 return NT_STATUS_OK;
00180 }
00181
00182
00183
00184 static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
00185 TALLOC_CTX *mem_ctx,
00186 uint32 *num_entries,
00187 struct acct_info **info)
00188 {
00189 POLICY_HND dom_pol;
00190 NTSTATUS result;
00191 struct rpc_pipe_client *cli;
00192
00193 *num_entries = 0;
00194 *info = NULL;
00195
00196 DEBUG(3,("rpc: enum_local_groups\n"));
00197
00198 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00199 if (!NT_STATUS_IS_OK(result))
00200 return result;
00201
00202 do {
00203 struct acct_info *info2 = NULL;
00204 uint32 count = 0, start = *num_entries;
00205 TALLOC_CTX *mem_ctx2;
00206
00207 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]");
00208
00209 result = rpccli_samr_enum_als_groups( cli, mem_ctx2, &dom_pol,
00210 &start, 0xFFFF, &info2,
00211 &count);
00212
00213 if (!NT_STATUS_IS_OK(result) &&
00214 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) )
00215 {
00216 talloc_destroy(mem_ctx2);
00217 return result;
00218 }
00219
00220 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info,
00221 struct acct_info,
00222 (*num_entries) + count);
00223 if (! *info) {
00224 talloc_destroy(mem_ctx2);
00225 return NT_STATUS_NO_MEMORY;
00226 }
00227
00228 memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2));
00229 (*num_entries) += count;
00230 talloc_destroy(mem_ctx2);
00231
00232 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
00233
00234 return NT_STATUS_OK;
00235 }
00236
00237
00238 NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain,
00239 TALLOC_CTX *mem_ctx,
00240 const char *domain_name,
00241 const char *name,
00242 DOM_SID *sid,
00243 enum lsa_SidType *type)
00244 {
00245 NTSTATUS result;
00246 DOM_SID *sids = NULL;
00247 enum lsa_SidType *types = NULL;
00248 char *full_name = NULL;
00249 struct rpc_pipe_client *cli;
00250 POLICY_HND lsa_policy;
00251
00252 if(name == NULL || *name=='\0') {
00253 DEBUG(3,("rpc: name_to_sid name=%s\n", domain_name));
00254 full_name = talloc_asprintf(mem_ctx, "%s", domain_name);
00255 } else {
00256 DEBUG(3,("rpc: name_to_sid name=%s\\%s\n", domain_name, name));
00257 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name);
00258 }
00259 if (!full_name) {
00260 DEBUG(0, ("talloc_asprintf failed!\n"));
00261 return NT_STATUS_NO_MEMORY;
00262 }
00263
00264 ws_name_return( full_name, WB_REPLACE_CHAR );
00265
00266 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", full_name?full_name:"", domain_name ));
00267
00268 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
00269 if (!NT_STATUS_IS_OK(result))
00270 return result;
00271
00272 result = rpccli_lsa_lookup_names(cli, mem_ctx, &lsa_policy, 1,
00273 (const char**) &full_name, NULL, &sids, &types);
00274
00275 if (!NT_STATUS_IS_OK(result))
00276 return result;
00277
00278
00279
00280 sid_copy(sid, &sids[0]);
00281 *type = types[0];
00282
00283 return NT_STATUS_OK;
00284 }
00285
00286
00287
00288
00289 NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain,
00290 TALLOC_CTX *mem_ctx,
00291 const DOM_SID *sid,
00292 char **domain_name,
00293 char **name,
00294 enum lsa_SidType *type)
00295 {
00296 char **domains;
00297 char **names;
00298 enum lsa_SidType *types;
00299 NTSTATUS result;
00300 struct rpc_pipe_client *cli;
00301 POLICY_HND lsa_policy;
00302
00303 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_static(sid),
00304 domain->name ));
00305
00306 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
00307 if (!NT_STATUS_IS_OK(result))
00308 return result;
00309
00310 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
00311 1, sid, &domains, &names, &types);
00312 if (!NT_STATUS_IS_OK(result))
00313 return result;
00314
00315 *type = (enum lsa_SidType)types[0];
00316 *domain_name = domains[0];
00317 *name = names[0];
00318
00319 ws_name_replace( *name, WB_REPLACE_CHAR );
00320
00321 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name));
00322 return NT_STATUS_OK;
00323 }
00324
00325 NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain,
00326 TALLOC_CTX *mem_ctx,
00327 const DOM_SID *sid,
00328 uint32 *rids,
00329 size_t num_rids,
00330 char **domain_name,
00331 char ***names,
00332 enum lsa_SidType **types)
00333 {
00334 char **domains;
00335 NTSTATUS result;
00336 struct rpc_pipe_client *cli;
00337 POLICY_HND lsa_policy;
00338 DOM_SID *sids;
00339 size_t i;
00340 char **ret_names;
00341
00342 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name ));
00343
00344 if (num_rids) {
00345 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids);
00346 if (sids == NULL) {
00347 return NT_STATUS_NO_MEMORY;
00348 }
00349 } else {
00350 sids = NULL;
00351 }
00352
00353 for (i=0; i<num_rids; i++) {
00354 if (!sid_compose(&sids[i], sid, rids[i])) {
00355 return NT_STATUS_INTERNAL_ERROR;
00356 }
00357 }
00358
00359 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
00360 if (!NT_STATUS_IS_OK(result)) {
00361 return result;
00362 }
00363
00364 result = rpccli_lsa_lookup_sids(cli, mem_ctx, &lsa_policy,
00365 num_rids, sids, &domains,
00366 names, types);
00367 if (!NT_STATUS_IS_OK(result) &&
00368 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
00369 return result;
00370 }
00371
00372 ret_names = *names;
00373 for (i=0; i<num_rids; i++) {
00374 if ((*types)[i] != SID_NAME_UNKNOWN) {
00375 ws_name_replace( ret_names[i], WB_REPLACE_CHAR );
00376 *domain_name = domains[i];
00377 }
00378 }
00379
00380 return result;
00381 }
00382
00383
00384 static NTSTATUS query_user(struct winbindd_domain *domain,
00385 TALLOC_CTX *mem_ctx,
00386 const DOM_SID *user_sid,
00387 WINBIND_USERINFO *user_info)
00388 {
00389 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00390 POLICY_HND dom_pol, user_pol;
00391 SAM_USERINFO_CTR *ctr;
00392 fstring sid_string;
00393 uint32 user_rid;
00394 NET_USER_INFO_3 *user;
00395 struct rpc_pipe_client *cli;
00396
00397 DEBUG(3,("rpc: query_user sid=%s\n",
00398 sid_to_string(sid_string, user_sid)));
00399
00400 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
00401 return NT_STATUS_UNSUCCESSFUL;
00402
00403
00404
00405 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
00406 {
00407
00408 DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
00409 sid_string_static(user_sid)));
00410
00411 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
00412 sid_compose(&user_info->group_sid, &domain->sid,
00413 user->group_rid);
00414
00415 user_info->acct_name = unistr2_tdup(mem_ctx,
00416 &user->uni_user_name);
00417 user_info->full_name = unistr2_tdup(mem_ctx,
00418 &user->uni_full_name);
00419
00420 user_info->homedir = NULL;
00421 user_info->shell = NULL;
00422 user_info->primary_gid = (gid_t)-1;
00423
00424 TALLOC_FREE(user);
00425
00426 return NT_STATUS_OK;
00427 }
00428
00429
00430
00431 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00432 if (!NT_STATUS_IS_OK(result))
00433 return result;
00434
00435
00436 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
00437 SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid,
00438 &user_pol);
00439
00440 if (!NT_STATUS_IS_OK(result))
00441 return result;
00442
00443
00444 result = rpccli_samr_query_userinfo(cli, mem_ctx, &user_pol,
00445 0x15, &ctr);
00446
00447 rpccli_samr_close(cli, mem_ctx, &user_pol);
00448
00449 if (!NT_STATUS_IS_OK(result))
00450 return result;
00451
00452 sid_compose(&user_info->user_sid, &domain->sid, user_rid);
00453 sid_compose(&user_info->group_sid, &domain->sid,
00454 ctr->info.id21->group_rid);
00455 user_info->acct_name = unistr2_tdup(mem_ctx,
00456 &ctr->info.id21->uni_user_name);
00457 user_info->full_name = unistr2_tdup(mem_ctx,
00458 &ctr->info.id21->uni_full_name);
00459 user_info->homedir = NULL;
00460 user_info->shell = NULL;
00461 user_info->primary_gid = (gid_t)-1;
00462
00463 return NT_STATUS_OK;
00464 }
00465
00466
00467 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
00468 TALLOC_CTX *mem_ctx,
00469 const DOM_SID *user_sid,
00470 uint32 *num_groups, DOM_SID **user_grpsids)
00471 {
00472 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00473 POLICY_HND dom_pol, user_pol;
00474 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
00475 DOM_GID *user_groups;
00476 unsigned int i;
00477 fstring sid_string;
00478 uint32 user_rid;
00479 struct rpc_pipe_client *cli;
00480
00481 DEBUG(3,("rpc: lookup_usergroups sid=%s\n",
00482 sid_to_string(sid_string, user_sid)));
00483
00484 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid))
00485 return NT_STATUS_UNSUCCESSFUL;
00486
00487 *num_groups = 0;
00488 *user_grpsids = NULL;
00489
00490
00491 result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
00492 num_groups, user_grpsids);
00493
00494 if (NT_STATUS_IS_OK(result)) {
00495 return NT_STATUS_OK;
00496 }
00497
00498
00499
00500 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00501 if (!NT_STATUS_IS_OK(result))
00502 return result;
00503
00504
00505 result = rpccli_samr_open_user(cli, mem_ctx, &dom_pol,
00506 des_access, user_rid, &user_pol);
00507
00508 if (!NT_STATUS_IS_OK(result))
00509 return result;
00510
00511
00512 result = rpccli_samr_query_usergroups(cli, mem_ctx, &user_pol,
00513 num_groups, &user_groups);
00514
00515 rpccli_samr_close(cli, mem_ctx, &user_pol);
00516
00517 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0)
00518 return result;
00519
00520 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
00521 if (!(*user_grpsids))
00522 return NT_STATUS_NO_MEMORY;
00523
00524 for (i=0;i<(*num_groups);i++) {
00525 sid_copy(&((*user_grpsids)[i]), &domain->sid);
00526 sid_append_rid(&((*user_grpsids)[i]),
00527 user_groups[i].g_rid);
00528 }
00529
00530 return NT_STATUS_OK;
00531 }
00532
00533 NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain,
00534 TALLOC_CTX *mem_ctx,
00535 uint32 num_sids, const DOM_SID *sids,
00536 uint32 *num_aliases, uint32 **alias_rids)
00537 {
00538 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00539 POLICY_HND dom_pol;
00540 DOM_SID2 *query_sids;
00541 uint32 num_query_sids = 0;
00542 int i;
00543 struct rpc_pipe_client *cli;
00544 uint32 *alias_rids_query, num_aliases_query;
00545 int rangesize = MAX_SAM_ENTRIES_W2K;
00546 uint32 total_sids = 0;
00547 int num_queries = 1;
00548
00549 *num_aliases = 0;
00550 *alias_rids = NULL;
00551
00552 DEBUG(3,("rpc: lookup_useraliases\n"));
00553
00554 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00555 if (!NT_STATUS_IS_OK(result))
00556 return result;
00557
00558 do {
00559
00560
00561 num_query_sids = MIN(num_sids - total_sids, rangesize);
00562
00563 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
00564 num_queries, num_query_sids));
00565
00566 if (num_query_sids) {
00567 query_sids = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_query_sids);
00568 if (query_sids == NULL) {
00569 return NT_STATUS_NO_MEMORY;
00570 }
00571 } else {
00572 query_sids = NULL;
00573 }
00574
00575 for (i=0; i<num_query_sids; i++) {
00576 sid_copy(&query_sids[i].sid, &sids[total_sids++]);
00577 query_sids[i].num_auths = query_sids[i].sid.num_auths;
00578 }
00579
00580
00581
00582 result = rpccli_samr_query_useraliases(cli, mem_ctx, &dom_pol,
00583 num_query_sids, query_sids,
00584 &num_aliases_query,
00585 &alias_rids_query);
00586
00587 if (!NT_STATUS_IS_OK(result)) {
00588 *num_aliases = 0;
00589 *alias_rids = NULL;
00590 TALLOC_FREE(query_sids);
00591 goto done;
00592 }
00593
00594
00595
00596 for (i=0; i<num_aliases_query; i++) {
00597 size_t na = *num_aliases;
00598 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i],
00599 alias_rids, &na)) {
00600 return NT_STATUS_NO_MEMORY;
00601 }
00602 *num_aliases = na;
00603 }
00604
00605 TALLOC_FREE(query_sids);
00606
00607 num_queries++;
00608
00609 } while (total_sids < num_sids);
00610
00611 done:
00612 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries "
00613 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize));
00614
00615 return result;
00616 }
00617
00618
00619
00620 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
00621 TALLOC_CTX *mem_ctx,
00622 const DOM_SID *group_sid, uint32 *num_names,
00623 DOM_SID **sid_mem, char ***names,
00624 uint32 **name_types)
00625 {
00626 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00627 uint32 i, total_names = 0;
00628 POLICY_HND dom_pol, group_pol;
00629 uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
00630 uint32 *rid_mem = NULL;
00631 uint32 group_rid;
00632 unsigned int j;
00633 fstring sid_string;
00634 struct rpc_pipe_client *cli;
00635 unsigned int orig_timeout;
00636
00637 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
00638 sid_to_string(sid_string, group_sid)));
00639
00640 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid))
00641 return NT_STATUS_UNSUCCESSFUL;
00642
00643 *num_names = 0;
00644
00645 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00646 if (!NT_STATUS_IS_OK(result))
00647 return result;
00648
00649 result = rpccli_samr_open_group(cli, mem_ctx, &dom_pol,
00650 des_access, group_rid, &group_pol);
00651
00652 if (!NT_STATUS_IS_OK(result))
00653 return result;
00654
00655
00656
00657
00658
00659
00660
00661 orig_timeout = cli_set_timeout(cli->cli, 35000);
00662
00663 result = rpccli_samr_query_groupmem(cli, mem_ctx,
00664 &group_pol, num_names, &rid_mem,
00665 name_types);
00666
00667
00668 cli_set_timeout(cli->cli, orig_timeout);
00669
00670 rpccli_samr_close(cli, mem_ctx, &group_pol);
00671
00672 if (!NT_STATUS_IS_OK(result))
00673 return result;
00674
00675 if (!*num_names) {
00676 names = NULL;
00677 name_types = NULL;
00678 sid_mem = NULL;
00679 return NT_STATUS_OK;
00680 }
00681
00682
00683
00684
00685
00686
00687 #define MAX_LOOKUP_RIDS 900
00688
00689 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);
00690 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);
00691 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names);
00692
00693 for (j=0;j<(*num_names);j++)
00694 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]);
00695
00696 if (*num_names>0 && (!*names || !*name_types))
00697 return NT_STATUS_NO_MEMORY;
00698
00699 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
00700 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
00701 uint32 tmp_num_names = 0;
00702 char **tmp_names = NULL;
00703 uint32 *tmp_types = NULL;
00704
00705
00706
00707 result = rpccli_samr_lookup_rids(cli, mem_ctx,
00708 &dom_pol,
00709 num_lookup_rids,
00710 &rid_mem[i],
00711 &tmp_num_names,
00712 &tmp_names, &tmp_types);
00713
00714
00715
00716
00717 if (!NT_STATUS_IS_OK(result) &&
00718 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
00719 return result;
00720
00721
00722
00723
00724 memcpy(&(*names)[i], tmp_names, sizeof(char *) *
00725 tmp_num_names);
00726
00727 memcpy(&(*name_types)[i], tmp_types, sizeof(uint32) *
00728 tmp_num_names);
00729
00730 total_names += tmp_num_names;
00731 }
00732
00733 *num_names = total_names;
00734
00735 return NT_STATUS_OK;
00736 }
00737
00738 #ifdef HAVE_LDAP
00739
00740 #include <ldap.h>
00741
00742 static int get_ldap_seq(const char *server, int port, uint32 *seq)
00743 {
00744 int ret = -1;
00745 struct timeval to;
00746 const char *attrs[] = {"highestCommittedUSN", NULL};
00747 LDAPMessage *res = NULL;
00748 char **values = NULL;
00749 LDAP *ldp = NULL;
00750
00751 *seq = DOM_SEQUENCE_NONE;
00752
00753
00754
00755
00756
00757
00758 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());
00759 if (ldp == NULL)
00760 return -1;
00761
00762
00763 to.tv_sec = 10;
00764 to.tv_usec = 0;
00765
00766 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)",
00767 CONST_DISCARD(char **, attrs), 0, &to, &res))
00768 goto done;
00769
00770 if (ldap_count_entries(ldp, res) != 1)
00771 goto done;
00772
00773 values = ldap_get_values(ldp, res, "highestCommittedUSN");
00774 if (!values || !values[0])
00775 goto done;
00776
00777 *seq = atoi(values[0]);
00778 ret = 0;
00779
00780 done:
00781
00782 if (values)
00783 ldap_value_free(values);
00784 if (res)
00785 ldap_msgfree(res);
00786 if (ldp)
00787 ldap_unbind(ldp);
00788 return ret;
00789 }
00790
00791
00792
00793
00794
00795
00796 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)
00797 {
00798 int ret = -1;
00799 fstring ipstr;
00800
00801 fstrcpy( ipstr, inet_ntoa(domain->dcaddr.sin_addr));
00802 if ((ret = get_ldap_seq( ipstr, LDAP_PORT, seq)) == 0) {
00803 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence "
00804 "number for Domain (%s) from DC (%s)\n",
00805 domain->name, ipstr));
00806 }
00807 return ret;
00808 }
00809
00810 #endif
00811
00812
00813 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
00814 {
00815 TALLOC_CTX *mem_ctx;
00816 SAM_UNK_CTR ctr;
00817 NTSTATUS result;
00818 POLICY_HND dom_pol;
00819 BOOL got_seq_num = False;
00820 struct rpc_pipe_client *cli;
00821
00822 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name));
00823
00824 *seq = DOM_SEQUENCE_NONE;
00825
00826 if (!(mem_ctx = talloc_init("sequence_number[rpc]")))
00827 return NT_STATUS_NO_MEMORY;
00828
00829 #ifdef HAVE_LDAP
00830 if ( domain->native_mode )
00831 {
00832 int res;
00833
00834 DEBUG(8,("using get_ldap_seq() to retrieve the "
00835 "sequence number\n"));
00836
00837 res = get_ldap_sequence_number( domain, seq );
00838 if (res == 0)
00839 {
00840 result = NT_STATUS_OK;
00841 DEBUG(10,("domain_sequence_number: LDAP for "
00842 "domain %s is %u\n",
00843 domain->name, *seq));
00844 goto done;
00845 }
00846
00847 DEBUG(10,("domain_sequence_number: failed to get LDAP "
00848 "sequence number for domain %s\n",
00849 domain->name ));
00850 }
00851 #endif
00852
00853 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00854 if (!NT_STATUS_IS_OK(result)) {
00855 goto done;
00856 }
00857
00858
00859
00860 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 8, &ctr);
00861
00862 if (NT_STATUS_IS_OK(result)) {
00863 *seq = ctr.info.inf8.seq_num;
00864 got_seq_num = True;
00865 goto seq_num;
00866 }
00867
00868
00869
00870
00871 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 2, &ctr);
00872
00873 if (NT_STATUS_IS_OK(result)) {
00874 *seq = ctr.info.inf2.seq_num;
00875 got_seq_num = True;
00876 }
00877
00878 seq_num:
00879 if (got_seq_num) {
00880 DEBUG(10,("domain_sequence_number: for domain %s is %u\n",
00881 domain->name, (unsigned)*seq));
00882 } else {
00883 DEBUG(10,("domain_sequence_number: failed to get sequence "
00884 "number (%u) for domain %s\n",
00885 (unsigned)*seq, domain->name ));
00886 }
00887
00888 done:
00889
00890 talloc_destroy(mem_ctx);
00891
00892 return result;
00893 }
00894
00895
00896 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
00897 TALLOC_CTX *mem_ctx,
00898 uint32 *num_domains,
00899 char ***names,
00900 char ***alt_names,
00901 DOM_SID **dom_sids)
00902 {
00903 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00904 uint32 enum_ctx = 0;
00905 struct rpc_pipe_client *cli;
00906 POLICY_HND lsa_policy;
00907
00908 DEBUG(3,("rpc: trusted_domains\n"));
00909
00910 *num_domains = 0;
00911 *names = NULL;
00912 *alt_names = NULL;
00913 *dom_sids = NULL;
00914
00915 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy);
00916 if (!NT_STATUS_IS_OK(result))
00917 return result;
00918
00919 result = STATUS_MORE_ENTRIES;
00920
00921 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
00922 uint32 start_idx, num;
00923 char **tmp_names;
00924 DOM_SID *tmp_sids;
00925 int i;
00926
00927 result = rpccli_lsa_enum_trust_dom(cli, mem_ctx,
00928 &lsa_policy, &enum_ctx,
00929 &num, &tmp_names,
00930 &tmp_sids);
00931
00932 if (!NT_STATUS_IS_OK(result) &&
00933 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES))
00934 break;
00935
00936 start_idx = *num_domains;
00937 *num_domains += num;
00938 *names = TALLOC_REALLOC_ARRAY(mem_ctx, *names,
00939 char *, *num_domains);
00940 *dom_sids = TALLOC_REALLOC_ARRAY(mem_ctx, *dom_sids,
00941 DOM_SID, *num_domains);
00942 *alt_names = TALLOC_REALLOC_ARRAY(mem_ctx, *alt_names,
00943 char *, *num_domains);
00944 if ((*names == NULL) || (*dom_sids == NULL) ||
00945 (*alt_names == NULL))
00946 return NT_STATUS_NO_MEMORY;
00947
00948 for (i=0; i<num; i++) {
00949 (*names)[start_idx+i] = tmp_names[i];
00950 (*dom_sids)[start_idx+i] = tmp_sids[i];
00951 (*alt_names)[start_idx+i] = talloc_strdup(mem_ctx, "");
00952 }
00953 }
00954 return result;
00955 }
00956
00957
00958 NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain,
00959 TALLOC_CTX *mem_ctx,
00960 SAM_UNK_INFO_12 *lockout_policy)
00961 {
00962 NTSTATUS result;
00963 struct rpc_pipe_client *cli;
00964 POLICY_HND dom_pol;
00965 SAM_UNK_CTR ctr;
00966
00967 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name));
00968
00969 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
00970 if (!NT_STATUS_IS_OK(result)) {
00971 goto done;
00972 }
00973
00974 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 12, &ctr);
00975 if (!NT_STATUS_IS_OK(result)) {
00976 goto done;
00977 }
00978
00979 *lockout_policy = ctr.info.inf12;
00980
00981 DEBUG(10,("msrpc_lockout_policy: bad_attempt_lockout %d\n",
00982 ctr.info.inf12.bad_attempt_lockout));
00983
00984 done:
00985
00986 return result;
00987 }
00988
00989
00990 NTSTATUS msrpc_password_policy(struct winbindd_domain *domain,
00991 TALLOC_CTX *mem_ctx,
00992 SAM_UNK_INFO_1 *password_policy)
00993 {
00994 NTSTATUS result;
00995 struct rpc_pipe_client *cli;
00996 POLICY_HND dom_pol;
00997 SAM_UNK_CTR ctr;
00998
00999 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name));
01000
01001 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);
01002 if (!NT_STATUS_IS_OK(result)) {
01003 goto done;
01004 }
01005
01006 result = rpccli_samr_query_dom_info(cli, mem_ctx, &dom_pol, 1, &ctr);
01007 if (!NT_STATUS_IS_OK(result)) {
01008 goto done;
01009 }
01010
01011 *password_policy = ctr.info.inf1;
01012
01013 DEBUG(10,("msrpc_password_policy: min_length_password %d\n",
01014 ctr.info.inf1.min_length_password));
01015
01016 done:
01017
01018 return result;
01019 }
01020
01021
01022
01023 struct winbindd_methods msrpc_methods = {
01024 False,
01025 query_user_list,
01026 enum_dom_groups,
01027 enum_local_groups,
01028 msrpc_name_to_sid,
01029 msrpc_sid_to_name,
01030 msrpc_rids_to_names,
01031 query_user,
01032 lookup_usergroups,
01033 msrpc_lookup_useraliases,
01034 lookup_groupmem,
01035 sequence_number,
01036 msrpc_lockout_policy,
01037 msrpc_password_policy,
01038 trusted_domains,
01039 };