00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025 #include "winbindd.h"
00026
00027 #undef DBGC_CLASS
00028 #define DBGC_CLASS DBGC_WINBIND
00029
00030 extern struct winbindd_methods cache_methods;
00031 extern struct winbindd_methods builtin_passdb_methods;
00032 extern struct winbindd_methods sam_passdb_methods;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 static struct winbindd_domain *_domain_list;
00047
00048
00049
00050
00051
00052
00053
00054 static time_t last_trustdom_scan;
00055
00056 struct winbindd_domain *domain_list(void)
00057 {
00058
00059
00060 if ((!_domain_list) && (!init_domain_list())) {
00061 smb_panic("Init_domain_list failed\n");
00062 }
00063
00064 return _domain_list;
00065 }
00066
00067
00068
00069 void free_domain_list(void)
00070 {
00071 struct winbindd_domain *domain = _domain_list;
00072
00073 while(domain) {
00074 struct winbindd_domain *next = domain->next;
00075
00076 DLIST_REMOVE(_domain_list, domain);
00077 SAFE_FREE(domain);
00078 domain = next;
00079 }
00080 }
00081
00082 static BOOL is_internal_domain(const DOM_SID *sid)
00083 {
00084 if (sid == NULL)
00085 return False;
00086
00087 if ( IS_DC )
00088 return sid_check_is_builtin(sid);
00089
00090 return (sid_check_is_domain(sid) || sid_check_is_builtin(sid));
00091 }
00092
00093 static BOOL is_in_internal_domain(const DOM_SID *sid)
00094 {
00095 if (sid == NULL)
00096 return False;
00097
00098 if ( IS_DC )
00099 return sid_check_is_in_builtin(sid);
00100
00101 return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid));
00102 }
00103
00104
00105
00106 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
00107 struct winbindd_methods *methods,
00108 const DOM_SID *sid)
00109 {
00110 struct winbindd_domain *domain;
00111 const char *alternative_name = NULL;
00112
00113
00114
00115 if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
00116 alternative_name = alt_name;
00117 }
00118
00119
00120
00121 for (domain = _domain_list; domain; domain = domain->next) {
00122 if (strequal(domain_name, domain->name) ||
00123 strequal(domain_name, domain->alt_name)) {
00124 return domain;
00125 }
00126 if (alternative_name && *alternative_name) {
00127 if (strequal(alternative_name, domain->name) ||
00128 strequal(alternative_name, domain->alt_name)) {
00129 return domain;
00130 }
00131 }
00132 if (sid) {
00133 if (is_null_sid(sid)) {
00134
00135 } else if (sid_equal(sid, &domain->sid)) {
00136 return domain;
00137 }
00138 }
00139 }
00140
00141
00142
00143 if ((domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL)
00144 return NULL;
00145
00146
00147
00148 ZERO_STRUCTP(domain);
00149
00150 fstrcpy(domain->name, domain_name);
00151 if (alternative_name) {
00152 fstrcpy(domain->alt_name, alternative_name);
00153 }
00154
00155 domain->methods = methods;
00156 domain->backend = NULL;
00157 domain->internal = is_internal_domain(sid);
00158 domain->sequence_number = DOM_SEQUENCE_NONE;
00159 domain->last_seq_check = 0;
00160 domain->initialized = False;
00161 domain->online = is_internal_domain(sid);
00162 domain->check_online_timeout = 0;
00163 if (sid) {
00164 sid_copy(&domain->sid, sid);
00165 }
00166
00167
00168 DLIST_ADD(_domain_list, domain);
00169
00170 DEBUG(2,("Added domain %s %s %s\n",
00171 domain->name, domain->alt_name,
00172 &domain->sid?sid_string_static(&domain->sid):""));
00173
00174 return domain;
00175 }
00176
00177
00178
00179
00180
00181 struct trustdom_state {
00182 TALLOC_CTX *mem_ctx;
00183 struct winbindd_response *response;
00184 };
00185
00186 static void trustdom_recv(void *private_data, BOOL success);
00187
00188 static void add_trusted_domains( struct winbindd_domain *domain )
00189 {
00190 TALLOC_CTX *mem_ctx;
00191 struct winbindd_request *request;
00192 struct winbindd_response *response;
00193
00194 struct trustdom_state *state;
00195
00196 mem_ctx = talloc_init("add_trusted_domains");
00197 if (mem_ctx == NULL) {
00198 DEBUG(0, ("talloc_init failed\n"));
00199 return;
00200 }
00201
00202 request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request);
00203 response = TALLOC_P(mem_ctx, struct winbindd_response);
00204 state = TALLOC_P(mem_ctx, struct trustdom_state);
00205
00206 if ((request == NULL) || (response == NULL) || (state == NULL)) {
00207 DEBUG(0, ("talloc failed\n"));
00208 talloc_destroy(mem_ctx);
00209 return;
00210 }
00211
00212 state->mem_ctx = mem_ctx;
00213 state->response = response;
00214
00215 request->length = sizeof(*request);
00216 request->cmd = WINBINDD_LIST_TRUSTDOM;
00217
00218 async_domain_request(mem_ctx, domain, request, response,
00219 trustdom_recv, state);
00220 }
00221
00222 static void trustdom_recv(void *private_data, BOOL success)
00223 {
00224 struct trustdom_state *state =
00225 talloc_get_type_abort(private_data, struct trustdom_state);
00226 struct winbindd_response *response = state->response;
00227 char *p;
00228
00229 if ((!success) || (response->result != WINBINDD_OK)) {
00230 DEBUG(1, ("Could not receive trustdoms\n"));
00231 talloc_destroy(state->mem_ctx);
00232 return;
00233 }
00234
00235 p = (char *)response->extra_data.data;
00236
00237 while ((p != NULL) && (*p != '\0')) {
00238 char *q, *sidstr, *alt_name;
00239 DOM_SID sid;
00240
00241 alt_name = strchr(p, '\\');
00242 if (alt_name == NULL) {
00243 DEBUG(0, ("Got invalid trustdom response\n"));
00244 break;
00245 }
00246
00247 *alt_name = '\0';
00248 alt_name += 1;
00249
00250 sidstr = strchr(alt_name, '\\');
00251 if (sidstr == NULL) {
00252 DEBUG(0, ("Got invalid trustdom response\n"));
00253 break;
00254 }
00255
00256 *sidstr = '\0';
00257 sidstr += 1;
00258
00259 q = strchr(sidstr, '\n');
00260 if (q != NULL)
00261 *q = '\0';
00262
00263 if (!string_to_sid(&sid, sidstr)) {
00264
00265 if ( strcmp(sidstr,"S-0-0") == 0) {
00266 sid_copy( &sid, &global_sid_NULL);
00267 } else {
00268 DEBUG(0, ("Got invalid trustdom response\n"));
00269 break;
00270 }
00271 }
00272
00273 if (find_domain_from_name_noinit(p) == NULL) {
00274 struct winbindd_domain *domain;
00275 char *alternate_name = NULL;
00276
00277
00278
00279 if ( !strequal( alt_name, "(null)" ) )
00280 alternate_name = alt_name;
00281
00282 domain = add_trusted_domain(p, alternate_name,
00283 &cache_methods,
00284 &sid);
00285 setup_domain_child(domain, &domain->child, NULL);
00286 }
00287 p=q;
00288 if (p != NULL)
00289 p += 1;
00290 }
00291
00292 SAFE_FREE(response->extra_data.data);
00293 talloc_destroy(state->mem_ctx);
00294 }
00295
00296
00297
00298
00299
00300 void rescan_trusted_domains( void )
00301 {
00302 time_t now = time(NULL);
00303
00304
00305
00306 if ((now >= last_trustdom_scan) &&
00307 ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) )
00308 return;
00309
00310
00311
00312 add_trusted_domains( find_our_domain() );
00313
00314 last_trustdom_scan = now;
00315
00316 return;
00317 }
00318
00319 struct init_child_state {
00320 TALLOC_CTX *mem_ctx;
00321 struct winbindd_domain *domain;
00322 struct winbindd_request *request;
00323 struct winbindd_response *response;
00324 void (*continuation)(void *private_data, BOOL success);
00325 void *private_data;
00326 };
00327
00328 static void init_child_recv(void *private_data, BOOL success);
00329 static void init_child_getdc_recv(void *private_data, BOOL success);
00330
00331 enum winbindd_result init_child_connection(struct winbindd_domain *domain,
00332 void (*continuation)(void *private_data,
00333 BOOL success),
00334 void *private_data)
00335 {
00336 TALLOC_CTX *mem_ctx;
00337 struct winbindd_request *request;
00338 struct winbindd_response *response;
00339 struct init_child_state *state;
00340 struct winbindd_domain *request_domain;
00341
00342 mem_ctx = talloc_init("init_child_connection");
00343 if (mem_ctx == NULL) {
00344 DEBUG(0, ("talloc_init failed\n"));
00345 return WINBINDD_ERROR;
00346 }
00347
00348 request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request);
00349 response = TALLOC_P(mem_ctx, struct winbindd_response);
00350 state = TALLOC_P(mem_ctx, struct init_child_state);
00351
00352 if ((request == NULL) || (response == NULL) || (state == NULL)) {
00353 DEBUG(0, ("talloc failed\n"));
00354 TALLOC_FREE(mem_ctx);
00355 continuation(private_data, False);
00356 return WINBINDD_ERROR;
00357 }
00358
00359 request->length = sizeof(*request);
00360
00361 state->mem_ctx = mem_ctx;
00362 state->domain = domain;
00363 state->request = request;
00364 state->response = response;
00365 state->continuation = continuation;
00366 state->private_data = private_data;
00367
00368 if (IS_DC || domain->primary) {
00369
00370 request->cmd = WINBINDD_INIT_CONNECTION;
00371 fstrcpy(request->domain_name, domain->name);
00372 request->data.init_conn.is_primary = True;
00373 fstrcpy(request->data.init_conn.dcname, "");
00374 async_request(mem_ctx, &domain->child, request, response,
00375 init_child_recv, state);
00376 return WINBINDD_PENDING;
00377 }
00378
00379
00380
00381
00382 request->cmd = WINBINDD_GETDCNAME;
00383 fstrcpy(request->domain_name, domain->name);
00384
00385 request_domain = find_our_domain();
00386
00387 async_domain_request(mem_ctx, request_domain, request, response,
00388 init_child_getdc_recv, state);
00389 return WINBINDD_PENDING;
00390 }
00391
00392 static void init_child_getdc_recv(void *private_data, BOOL success)
00393 {
00394 struct init_child_state *state =
00395 talloc_get_type_abort(private_data, struct init_child_state);
00396 const char *dcname = "";
00397
00398 DEBUG(10, ("Received getdcname response\n"));
00399
00400 if (success && (state->response->result == WINBINDD_OK)) {
00401 dcname = state->response->data.dc_name;
00402 }
00403
00404 state->request->cmd = WINBINDD_INIT_CONNECTION;
00405 fstrcpy(state->request->domain_name, state->domain->name);
00406 state->request->data.init_conn.is_primary = False;
00407 fstrcpy(state->request->data.init_conn.dcname, dcname);
00408
00409 async_request(state->mem_ctx, &state->domain->child,
00410 state->request, state->response,
00411 init_child_recv, state);
00412 }
00413
00414 static void init_child_recv(void *private_data, BOOL success)
00415 {
00416 struct init_child_state *state =
00417 talloc_get_type_abort(private_data, struct init_child_state);
00418
00419 DEBUG(5, ("Received child initialization response for domain %s\n",
00420 state->domain->name));
00421
00422 if ((!success) || (state->response->result != WINBINDD_OK)) {
00423 DEBUG(3, ("Could not init child\n"));
00424 state->continuation(state->private_data, False);
00425 talloc_destroy(state->mem_ctx);
00426 return;
00427 }
00428
00429 fstrcpy(state->domain->name,
00430 state->response->data.domain_info.name);
00431 fstrcpy(state->domain->alt_name,
00432 state->response->data.domain_info.alt_name);
00433 string_to_sid(&state->domain->sid,
00434 state->response->data.domain_info.sid);
00435 state->domain->native_mode =
00436 state->response->data.domain_info.native_mode;
00437 state->domain->active_directory =
00438 state->response->data.domain_info.active_directory;
00439 state->domain->sequence_number =
00440 state->response->data.domain_info.sequence_number;
00441
00442 init_dc_connection(state->domain);
00443
00444 if (state->continuation != NULL)
00445 state->continuation(state->private_data, True);
00446 talloc_destroy(state->mem_ctx);
00447 }
00448
00449 enum winbindd_result winbindd_dual_init_connection(struct winbindd_domain *domain,
00450 struct winbindd_cli_state *state)
00451 {
00452
00453 state->request.domain_name
00454 [sizeof(state->request.domain_name)-1]='\0';
00455 state->request.data.init_conn.dcname
00456 [sizeof(state->request.data.init_conn.dcname)-1]='\0';
00457
00458 if (strlen(state->request.data.init_conn.dcname) > 0) {
00459 fstrcpy(domain->dcname, state->request.data.init_conn.dcname);
00460 }
00461
00462 init_dc_connection(domain);
00463
00464 if (!domain->initialized) {
00465
00466
00467
00468
00469
00470 DEBUG(5, ("winbindd_dual_init_connection: %s returning without initialization "
00471 "online = %d\n", domain->name, (int)domain->online ));
00472 }
00473
00474 fstrcpy(state->response.data.domain_info.name, domain->name);
00475 fstrcpy(state->response.data.domain_info.alt_name, domain->alt_name);
00476 fstrcpy(state->response.data.domain_info.sid,
00477 sid_string_static(&domain->sid));
00478
00479 state->response.data.domain_info.native_mode
00480 = domain->native_mode;
00481 state->response.data.domain_info.active_directory
00482 = domain->active_directory;
00483 state->response.data.domain_info.primary
00484 = domain->primary;
00485 state->response.data.domain_info.sequence_number =
00486 domain->sequence_number;
00487
00488 return WINBINDD_OK;
00489 }
00490
00491
00492 BOOL init_domain_list(void)
00493 {
00494 struct winbindd_domain *domain;
00495 int role = lp_server_role();
00496
00497
00498 free_domain_list();
00499
00500
00501
00502 if ( role == ROLE_DOMAIN_MEMBER ) {
00503 DOM_SID our_sid;
00504
00505 if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) {
00506 DEBUG(0, ("Could not fetch our SID - did we join?\n"));
00507 return False;
00508 }
00509
00510 domain = add_trusted_domain( lp_workgroup(), lp_realm(),
00511 &cache_methods, &our_sid);
00512 domain->primary = True;
00513 setup_domain_child(domain, &domain->child, NULL);
00514
00515
00516
00517
00518
00519
00520
00521 set_domain_online_request(domain);
00522 }
00523
00524
00525
00526 domain = add_trusted_domain(get_global_sam_name(), NULL,
00527 &sam_passdb_methods, get_global_sam_sid());
00528 if ( role != ROLE_DOMAIN_MEMBER ) {
00529 domain->primary = True;
00530 }
00531 setup_domain_child(domain, &domain->child, NULL);
00532
00533
00534
00535 domain = add_trusted_domain("BUILTIN", NULL, &builtin_passdb_methods,
00536 &global_sid_Builtin);
00537 setup_domain_child(domain, &domain->child, NULL);
00538
00539 return True;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name)
00555 {
00556 struct winbindd_domain *domain;
00557
00558
00559
00560 for (domain = domain_list(); domain != NULL; domain = domain->next) {
00561 if (strequal(domain_name, domain->name) ||
00562 (domain->alt_name[0] &&
00563 strequal(domain_name, domain->alt_name))) {
00564 return domain;
00565 }
00566 }
00567
00568
00569
00570 return NULL;
00571 }
00572
00573 struct winbindd_domain *find_domain_from_name(const char *domain_name)
00574 {
00575 struct winbindd_domain *domain;
00576
00577 domain = find_domain_from_name_noinit(domain_name);
00578
00579 if (domain == NULL)
00580 return NULL;
00581
00582 if (!domain->initialized)
00583 init_dc_connection(domain);
00584
00585 return domain;
00586 }
00587
00588
00589
00590 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID *sid)
00591 {
00592 struct winbindd_domain *domain;
00593
00594
00595
00596 for (domain = domain_list(); domain != NULL; domain = domain->next) {
00597 if (sid_compare_domain(sid, &domain->sid) == 0)
00598 return domain;
00599 }
00600
00601
00602
00603 return NULL;
00604 }
00605
00606
00607
00608 struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid)
00609 {
00610 struct winbindd_domain *domain;
00611
00612 domain = find_domain_from_sid_noinit(sid);
00613
00614 if (domain == NULL)
00615 return NULL;
00616
00617 if (!domain->initialized)
00618 init_dc_connection(domain);
00619
00620 return domain;
00621 }
00622
00623 struct winbindd_domain *find_our_domain(void)
00624 {
00625 struct winbindd_domain *domain;
00626
00627
00628
00629 for (domain = domain_list(); domain != NULL; domain = domain->next) {
00630 if (domain->primary)
00631 return domain;
00632 }
00633
00634 smb_panic("Could not find our domain\n");
00635 return NULL;
00636 }
00637
00638 struct winbindd_domain *find_root_domain(void)
00639 {
00640 struct winbindd_domain *ours = find_our_domain();
00641
00642 if ( !ours )
00643 return NULL;
00644
00645 if ( strlen(ours->forest_name) == 0 )
00646 return NULL;
00647
00648 return find_domain_from_name( ours->forest_name );
00649 }
00650
00651 struct winbindd_domain *find_builtin_domain(void)
00652 {
00653 DOM_SID sid;
00654 struct winbindd_domain *domain;
00655
00656 string_to_sid(&sid, "S-1-5-32");
00657 domain = find_domain_from_sid(&sid);
00658
00659 if (domain == NULL)
00660 smb_panic("Could not find BUILTIN domain\n");
00661
00662 return domain;
00663 }
00664
00665
00666
00667 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid)
00668 {
00669
00670
00671
00672
00673 DEBUG(10, ("find_lookup_domain_from_sid(%s)\n",
00674 sid_string_static(sid)));
00675
00676 if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) {
00677 DEBUG(10, ("calling find_domain_from_sid\n"));
00678 return find_domain_from_sid(sid);
00679 }
00680
00681
00682
00683
00684 DEBUG(10, ("calling find_our_domain\n"));
00685 return find_our_domain();
00686 }
00687
00688 struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name)
00689 {
00690 if (IS_DC || strequal(domain_name, "BUILTIN") ||
00691 strequal(domain_name, get_global_sam_name()))
00692 return find_domain_from_name_noinit(domain_name);
00693
00694 return find_our_domain();
00695 }
00696
00697
00698
00699 BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx,
00700 struct winbindd_domain *domain,
00701 const char *domain_name,
00702 const char *name, DOM_SID *sid,
00703 enum lsa_SidType *type)
00704 {
00705 NTSTATUS result;
00706
00707
00708 result = domain->methods->name_to_sid(domain, mem_ctx, domain_name, name, sid, type);
00709
00710
00711 if (!NT_STATUS_IS_OK(result)) {
00712 *type = SID_NAME_UNKNOWN;
00713 }
00714
00715 return NT_STATUS_IS_OK(result);
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 BOOL winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx,
00730 DOM_SID *sid,
00731 char **dom_name,
00732 char **name,
00733 enum lsa_SidType *type)
00734 {
00735 NTSTATUS result;
00736 struct winbindd_domain *domain;
00737
00738 *dom_name = NULL;
00739 *name = NULL;
00740
00741 domain = find_lookup_domain_from_sid(sid);
00742
00743 if (!domain) {
00744 DEBUG(1,("Can't find domain from sid\n"));
00745 return False;
00746 }
00747
00748
00749
00750 result = domain->methods->sid_to_name(domain, mem_ctx, sid, dom_name, name, type);
00751
00752
00753
00754 if (NT_STATUS_IS_OK(result)) {
00755 return True;
00756 }
00757
00758 *type = SID_NAME_UNKNOWN;
00759
00760 return False;
00761 }
00762
00763
00764
00765 void free_getent_state(struct getent_state *state)
00766 {
00767 struct getent_state *temp;
00768
00769
00770
00771 temp = state;
00772
00773 while(temp != NULL) {
00774 struct getent_state *next;
00775
00776
00777
00778 SAFE_FREE(state->sam_entries);
00779 DLIST_REMOVE(state, state);
00780 next = temp->next;
00781
00782 SAFE_FREE(temp);
00783 temp = next;
00784 }
00785 }
00786
00787
00788
00789 static BOOL assume_domain(const char *domain)
00790 {
00791
00792
00793 if ( lp_server_role() == ROLE_STANDALONE )
00794 return False;
00795
00796
00797
00798 if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {
00799 if ( !strequal(lp_workgroup(), domain) )
00800 return False;
00801
00802 if ( lp_winbind_use_default_domain() || lp_winbind_trusted_domains_only() )
00803 return True;
00804 }
00805
00806
00807
00808 if ( strequal(get_global_sam_name(), domain) ) {
00809 return True;
00810 }
00811
00812 return False;
00813 }
00814
00815
00816
00817 BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
00818 {
00819 char *p = strchr(domuser,*lp_winbind_separator());
00820
00821 if ( !p ) {
00822 fstrcpy(user, domuser);
00823
00824 if ( assume_domain(lp_workgroup())) {
00825 fstrcpy(domain, lp_workgroup());
00826 } else {
00827 return False;
00828 }
00829 } else {
00830 fstrcpy(user, p+1);
00831 fstrcpy(domain, domuser);
00832 domain[PTR_DIFF(p, domuser)] = 0;
00833 }
00834
00835 strupper_m(domain);
00836
00837 return True;
00838 }
00839
00840 BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
00841 char **domain, char **user)
00842 {
00843 fstring fstr_domain, fstr_user;
00844 if (!parse_domain_user(domuser, fstr_domain, fstr_user)) {
00845 return False;
00846 }
00847 *domain = talloc_strdup(mem_ctx, fstr_domain);
00848 *user = talloc_strdup(mem_ctx, fstr_user);
00849 return ((*domain != NULL) && (*user != NULL));
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user)
00862 {
00863 if (!parse_domain_user(username_inout, domain, user)) {
00864 return False;
00865 }
00866 slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s",
00867 domain, *lp_winbind_separator(),
00868 user);
00869 return True;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886 void fill_domain_username(fstring name, const char *domain, const char *user, BOOL can_assume)
00887 {
00888 fstring tmp_user;
00889
00890 fstrcpy(tmp_user, user);
00891 strlower_m(tmp_user);
00892
00893 if (can_assume && assume_domain(domain)) {
00894 strlcpy(name, tmp_user, sizeof(fstring));
00895 } else {
00896 slprintf(name, sizeof(fstring) - 1, "%s%c%s",
00897 domain, *lp_winbind_separator(),
00898 tmp_user);
00899 }
00900 }
00901
00902
00903
00904
00905
00906 char *get_winbind_priv_pipe_dir(void)
00907 {
00908 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
00909 }
00910
00911
00912
00913 static int _winbindd_socket = -1;
00914 static int _winbindd_priv_socket = -1;
00915
00916 int open_winbindd_socket(void)
00917 {
00918 if (_winbindd_socket == -1) {
00919 _winbindd_socket = create_pipe_sock(
00920 WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);
00921 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
00922 _winbindd_socket));
00923 }
00924
00925 return _winbindd_socket;
00926 }
00927
00928 int open_winbindd_priv_socket(void)
00929 {
00930 if (_winbindd_priv_socket == -1) {
00931 _winbindd_priv_socket = create_pipe_sock(
00932 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
00933 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
00934 _winbindd_priv_socket));
00935 }
00936
00937 return _winbindd_priv_socket;
00938 }
00939
00940
00941
00942 void close_winbindd_socket(void)
00943 {
00944 if (_winbindd_socket != -1) {
00945 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
00946 _winbindd_socket));
00947 close(_winbindd_socket);
00948 _winbindd_socket = -1;
00949 }
00950 if (_winbindd_priv_socket != -1) {
00951 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
00952 _winbindd_priv_socket));
00953 close(_winbindd_priv_socket);
00954 _winbindd_priv_socket = -1;
00955 }
00956 }
00957
00958
00959
00960
00961
00962 static struct winbindd_cli_state *_client_list;
00963 static int _num_clients;
00964
00965
00966
00967 struct winbindd_cli_state *winbindd_client_list(void)
00968 {
00969 return _client_list;
00970 }
00971
00972
00973
00974 void winbindd_add_client(struct winbindd_cli_state *cli)
00975 {
00976 DLIST_ADD(_client_list, cli);
00977 _num_clients++;
00978 }
00979
00980
00981
00982 void winbindd_remove_client(struct winbindd_cli_state *cli)
00983 {
00984 DLIST_REMOVE(_client_list, cli);
00985 _num_clients--;
00986 }
00987
00988
00989
00990 void winbindd_kill_all_clients(void)
00991 {
00992 struct winbindd_cli_state *cl = winbindd_client_list();
00993
00994 DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
00995
00996 while (cl) {
00997 struct winbindd_cli_state *next;
00998
00999 next = cl->next;
01000 winbindd_remove_client(cl);
01001 cl = next;
01002 }
01003 }
01004
01005
01006
01007 int winbindd_num_clients(void)
01008 {
01009 return _num_clients;
01010 }
01011
01012 NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
01013 TALLOC_CTX *mem_ctx,
01014 const DOM_SID *user_sid,
01015 uint32 *p_num_groups, DOM_SID **user_sids)
01016 {
01017 NET_USER_INFO_3 *info3 = NULL;
01018 NTSTATUS status = NT_STATUS_NO_MEMORY;
01019 int i;
01020 size_t num_groups = 0;
01021 DOM_SID group_sid, primary_group;
01022
01023 DEBUG(3,(": lookup_usergroups_cached\n"));
01024
01025 *user_sids = NULL;
01026 num_groups = 0;
01027 *p_num_groups = 0;
01028
01029 info3 = netsamlogon_cache_get(mem_ctx, user_sid);
01030
01031 if (info3 == NULL) {
01032 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
01033 }
01034
01035 if (info3->num_groups == 0) {
01036 TALLOC_FREE(info3);
01037 return NT_STATUS_UNSUCCESSFUL;
01038 }
01039
01040
01041 sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid);
01042
01043 if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) {
01044 TALLOC_FREE(info3);
01045 return NT_STATUS_NO_MEMORY;
01046 }
01047
01048 for (i=0; i<info3->num_groups; i++) {
01049 sid_copy(&group_sid, &info3->dom_sid.sid);
01050 sid_append_rid(&group_sid, info3->gids[i].g_rid);
01051
01052 if (!add_sid_to_array(mem_ctx, &group_sid, user_sids,
01053 &num_groups)) {
01054 TALLOC_FREE(info3);
01055 return NT_STATUS_NO_MEMORY;
01056 }
01057 }
01058
01059 TALLOC_FREE(info3);
01060 *p_num_groups = num_groups;
01061 status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
01062
01063 DEBUG(3,(": lookup_usergroups_cached succeeded\n"));
01064
01065 return status;
01066 }
01067
01068
01069
01070
01071
01072 void ws_name_replace( char *name, char replace )
01073 {
01074 char replace_char[2] = { 0x0, 0x0 };
01075
01076 if ( !lp_winbind_normalize_names() || (replace == '\0') )
01077 return;
01078
01079 replace_char[0] = replace;
01080 all_string_sub( name, " ", replace_char, 0 );
01081
01082 return;
01083 }
01084
01085
01086
01087
01088
01089 void ws_name_return( char *name, char replace )
01090 {
01091 char replace_char[2] = { 0x0, 0x0 };
01092
01093 if ( !lp_winbind_normalize_names() || (replace == '\0') )
01094 return;
01095
01096 replace_char[0] = replace;
01097 all_string_sub( name, replace_char, " ", 0 );
01098
01099 return;
01100 }