00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #include "includes.h"
00063 #include "winbindd.h"
00064
00065 #undef DBGC_CLASS
00066 #define DBGC_CLASS DBGC_WINBIND
00067
00068 struct dc_name_ip {
00069 fstring name;
00070 struct in_addr ip;
00071 };
00072
00073 extern struct winbindd_methods reconnect_methods;
00074 extern BOOL override_logfile;
00075
00076 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
00077 static void set_dc_type_and_flags( struct winbindd_domain *domain );
00078 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
00079 struct dc_name_ip **dcs, int *num_dcs);
00080
00081
00082
00083
00084
00085 static void msg_failed_to_go_online(int msg_type, struct process_id src,
00086 void *buf, size_t len, void *private_data)
00087 {
00088 struct winbindd_domain *domain;
00089 const char *domainname = (const char *)buf;
00090
00091 if (buf == NULL || len == 0) {
00092 return;
00093 }
00094
00095 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
00096
00097 for (domain = domain_list(); domain; domain = domain->next) {
00098 if (domain->internal) {
00099 continue;
00100 }
00101
00102 if (strequal(domain->name, domainname)) {
00103 if (domain->online) {
00104
00105 DEBUG(5,("msg_fail_to_go_online: domain %s "
00106 "already online.\n", domainname));
00107 continue;
00108 }
00109
00110
00111 set_domain_offline(domain);
00112 break;
00113 }
00114 }
00115 }
00116
00117
00118
00119
00120
00121 static void msg_try_to_go_online(int msg_type, struct process_id src,
00122 void *buf, size_t len, void *private_data)
00123 {
00124 struct winbindd_domain *domain;
00125 const char *domainname = (const char *)buf;
00126
00127 if (buf == NULL || len == 0) {
00128 return;
00129 }
00130
00131 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
00132
00133 for (domain = domain_list(); domain; domain = domain->next) {
00134 if (domain->internal) {
00135 continue;
00136 }
00137
00138 if (strequal(domain->name, domainname)) {
00139
00140 if (domain->online) {
00141
00142 DEBUG(5,("msg_try_to_go_online: domain %s "
00143 "already online.\n", domainname));
00144 continue;
00145 }
00146
00147
00148
00149
00150
00151
00152 init_dc_connection_network(domain);
00153 break;
00154 }
00155 }
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 static BOOL fork_child_dc_connect(struct winbindd_domain *domain)
00165 {
00166 struct dc_name_ip *dcs = NULL;
00167 int num_dcs = 0;
00168 TALLOC_CTX *mem_ctx = NULL;
00169 pid_t child_pid;
00170 pid_t parent_pid = sys_getpid();
00171
00172
00173 CatchChild();
00174
00175 message_block();
00176
00177 child_pid = sys_fork();
00178
00179 if (child_pid == -1) {
00180 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
00181 message_unblock();
00182 return False;
00183 }
00184
00185 if (child_pid != 0) {
00186
00187 message_register(MSG_WINBIND_TRY_TO_GO_ONLINE,
00188 msg_try_to_go_online, NULL);
00189 message_register(MSG_WINBIND_FAILED_TO_GO_ONLINE,
00190 msg_failed_to_go_online, NULL);
00191 message_unblock();
00192 return True;
00193 }
00194
00195
00196
00197
00198
00199
00200 if (tdb_reopen_all(1) == -1) {
00201 DEBUG(0,("tdb_reopen_all failed.\n"));
00202 _exit(0);
00203 }
00204
00205 close_conns_after_fork();
00206
00207 if (!override_logfile) {
00208 pstring logfile;
00209 pstr_sprintf(logfile, "%s/winbindd-dc-connect.log", dyn_LOGFILEBASE);
00210 lp_set_logfile(logfile);
00211 reopen_logs();
00212 }
00213
00214 mem_ctx = talloc_init("fork_child_dc_connect");
00215 if (!mem_ctx) {
00216 DEBUG(0,("talloc_init failed.\n"));
00217 _exit(0);
00218 }
00219
00220 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
00221
00222 message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_FAILED_TO_GO_ONLINE,
00223 domain->name,
00224 strlen(domain->name)+1, False);
00225 _exit(0);
00226 }
00227
00228
00229
00230
00231 message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_TRY_TO_GO_ONLINE,
00232 domain->name,
00233 strlen(domain->name)+1, False);
00234 _exit(0);
00235 }
00236
00237
00238
00239
00240
00241 static void check_domain_online_handler(struct event_context *ctx,
00242 struct timed_event *te,
00243 const struct timeval *now,
00244 void *private_data)
00245 {
00246 struct winbindd_domain *domain =
00247 (struct winbindd_domain *)private_data;
00248
00249 DEBUG(10,("check_domain_online_handler: called for domain %s\n",
00250 domain->name ));
00251
00252 TALLOC_FREE(domain->check_online_event);
00253
00254
00255
00256 if (domain->startup && (now->tv_sec > domain->startup_time + 30)) {
00257
00258 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
00259 domain->name ));
00260 domain->startup = False;
00261 }
00262
00263
00264
00265
00266 if (get_global_winbindd_state_offline()) {
00267 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
00268 domain->name ));
00269 return;
00270 }
00271
00272
00273
00274
00275
00276 fork_child_dc_connect(domain);
00277 }
00278
00279
00280
00281
00282
00283 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
00284 {
00285 int wbc = lp_winbind_cache_time();
00286
00287 if (domain->startup) {
00288 domain->check_online_timeout = 10;
00289 } else if (domain->check_online_timeout < wbc) {
00290 domain->check_online_timeout = wbc;
00291 }
00292 }
00293
00294
00295
00296
00297
00298
00299 void set_domain_offline(struct winbindd_domain *domain)
00300 {
00301 DEBUG(10,("set_domain_offline: called for domain %s\n",
00302 domain->name ));
00303
00304 TALLOC_FREE(domain->check_online_event);
00305
00306 if (domain->internal) {
00307 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
00308 domain->name ));
00309 return;
00310 }
00311
00312 domain->online = False;
00313
00314
00315
00316
00317 domain->initialized = True;
00318
00319
00320
00321
00322
00323 if (get_global_winbindd_state_offline()) {
00324 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
00325 domain->name ));
00326 return;
00327 }
00328
00329
00330
00331
00332 calc_new_online_timeout_check(domain);
00333
00334 domain->check_online_event = event_add_timed(winbind_event_context(),
00335 NULL,
00336 timeval_current_ofs(domain->check_online_timeout,0),
00337 "check_domain_online_handler",
00338 check_domain_online_handler,
00339 domain);
00340
00341
00342 if (!domain->check_online_event) {
00343 smb_panic("set_domain_offline: failed to add online handler.\n");
00344 }
00345
00346 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
00347 domain->name ));
00348 }
00349
00350
00351
00352
00353
00354 static void set_domain_online(struct winbindd_domain *domain)
00355 {
00356 struct timeval now;
00357
00358 DEBUG(10,("set_domain_online: called for domain %s\n",
00359 domain->name ));
00360
00361 if (domain->internal) {
00362 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
00363 domain->name ));
00364 return;
00365 }
00366
00367 if (get_global_winbindd_state_offline()) {
00368 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
00369 domain->name ));
00370 return;
00371 }
00372
00373
00374 GetTimeOfDay(&now);
00375 set_event_dispatch_time(winbind_event_context(),
00376 "krb5_ticket_gain_handler", now);
00377
00378
00379 domain->startup = False;
00380
00381 if (domain->online == False) {
00382
00383
00384
00385
00386
00387
00388
00389 domain->initialized = False;
00390
00391
00392 if (domain->backend == &reconnect_methods) {
00393 domain->backend = NULL;
00394 }
00395 }
00396
00397
00398 domain->check_online_timeout = 0;
00399 TALLOC_FREE(domain->check_online_event);
00400
00401
00402 message_deregister(MSG_WINBIND_TRY_TO_GO_ONLINE);
00403 message_deregister(MSG_WINBIND_FAILED_TO_GO_ONLINE);
00404
00405 domain->online = True;
00406 }
00407
00408
00409
00410
00411
00412 void set_domain_online_request(struct winbindd_domain *domain)
00413 {
00414 struct timeval tev;
00415
00416 DEBUG(10,("set_domain_online_request: called for domain %s\n",
00417 domain->name ));
00418
00419 if (get_global_winbindd_state_offline()) {
00420 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
00421 domain->name ));
00422 return;
00423 }
00424
00425
00426
00427
00428
00429
00430 if (!domain->check_online_event) {
00431
00432
00433
00434
00435
00436 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
00437 domain->name ));
00438
00439 domain->check_online_event = event_add_timed(winbind_event_context(),
00440 NULL,
00441 timeval_current_ofs(5, 0),
00442 "check_domain_online_handler",
00443 check_domain_online_handler,
00444 domain);
00445
00446
00447 if (!domain->check_online_event) {
00448 smb_panic("set_domain_online_request: failed to add online handler.\n");
00449 }
00450 }
00451
00452 GetTimeOfDay(&tev);
00453
00454
00455 domain->startup_time = tev.tv_sec;
00456 domain->startup = True;
00457
00458 tev.tv_sec += 5;
00459
00460 set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev);
00461 }
00462
00463
00464
00465
00466
00467 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
00468 const char *server,
00469 NTSTATUS result)
00470 {
00471 add_failed_connection_entry(domain->name, server, result);
00472
00473
00474 saf_delete(domain->name);
00475 if (*domain->alt_name) {
00476 add_failed_connection_entry(domain->alt_name, server, result);
00477 saf_delete(domain->alt_name);
00478 }
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
00490 {
00491 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
00492 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
00493 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
00494
00495 if (*username && **username) {
00496
00497 if (!*domain || !**domain)
00498 *domain = smb_xstrdup(lp_workgroup());
00499
00500 if (!*password || !**password)
00501 *password = smb_xstrdup("");
00502
00503 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
00504 *domain, *username));
00505
00506 } else {
00507 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
00508 *username = smb_xstrdup("");
00509 *domain = smb_xstrdup("");
00510 *password = smb_xstrdup("");
00511 }
00512 }
00513
00514 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
00515 fstring dcname, struct in_addr *dc_ip)
00516 {
00517 struct winbindd_domain *our_domain = NULL;
00518 struct rpc_pipe_client *netlogon_pipe = NULL;
00519 NTSTATUS result;
00520 WERROR werr;
00521 TALLOC_CTX *mem_ctx;
00522 unsigned int orig_timeout;
00523 fstring tmp;
00524 char *p;
00525
00526
00527
00528
00529 if (IS_DC) {
00530 return False;
00531 }
00532
00533 if (domain->primary) {
00534 return False;
00535 }
00536
00537 our_domain = find_our_domain();
00538
00539 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
00540 return False;
00541 }
00542
00543 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
00544 if (!NT_STATUS_IS_OK(result)) {
00545 talloc_destroy(mem_ctx);
00546 return False;
00547 }
00548
00549
00550
00551
00552 orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
00553
00554 werr = rpccli_netlogon_getanydcname(netlogon_pipe, mem_ctx, our_domain->dcname,
00555 domain->name, tmp);
00556
00557
00558 cli_set_timeout(netlogon_pipe->cli, orig_timeout);
00559
00560 talloc_destroy(mem_ctx);
00561
00562 if (!W_ERROR_IS_OK(werr)) {
00563 DEBUG(10, ("rpccli_netlogon_getanydcname failed: %s\n",
00564 dos_errstr(werr)));
00565 return False;
00566 }
00567
00568
00569 p = tmp;
00570 if (*p == '\\') {
00571 p+=1;
00572 }
00573 if (*p == '\\') {
00574 p+=1;
00575 }
00576
00577 fstrcpy(dcname, p);
00578
00579 DEBUG(10, ("rpccli_netlogon_getanydcname returned %s\n", dcname));
00580
00581 if (!resolve_name(dcname, dc_ip, 0x20)) {
00582 return False;
00583 }
00584
00585 return True;
00586 }
00587
00588
00589
00590
00591 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
00592 char **machine_password,
00593 char **machine_account,
00594 char **machine_krb5_principal)
00595 {
00596 const char *account_name;
00597
00598 if (!get_trust_pw_clear(domain->name, machine_password,
00599 &account_name, NULL))
00600 {
00601 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
00602 }
00603
00604 if ((machine_account != NULL) &&
00605 (asprintf(machine_account, "%s$", account_name) == -1))
00606 {
00607 return NT_STATUS_NO_MEMORY;
00608 }
00609
00610
00611
00612 if (machine_krb5_principal != NULL)
00613 {
00614 if (asprintf(machine_krb5_principal, "%s$@%s",
00615 account_name, lp_realm()) == -1)
00616 {
00617 return NT_STATUS_NO_MEMORY;
00618 }
00619
00620 strupper_m(*machine_krb5_principal);
00621 }
00622
00623 return NT_STATUS_OK;
00624 }
00625
00626
00627
00628
00629
00630
00631 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
00632 const int sockfd,
00633 const char *controller,
00634 struct cli_state **cli,
00635 BOOL *retry)
00636 {
00637 char *machine_password = NULL;
00638 char *machine_krb5_principal = NULL;
00639 char *machine_account = NULL;
00640 char *ipc_username = NULL;
00641 char *ipc_domain = NULL;
00642 char *ipc_password = NULL;
00643
00644 BOOL got_mutex;
00645
00646 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
00647
00648 struct sockaddr peeraddr;
00649 socklen_t peeraddr_len;
00650
00651 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
00652
00653 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
00654 controller, domain->name ));
00655
00656 *retry = True;
00657
00658 got_mutex = secrets_named_mutex(controller,
00659 WINBIND_SERVER_MUTEX_WAIT_TIME);
00660
00661 if (!got_mutex) {
00662 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
00663 controller));
00664 result = NT_STATUS_POSSIBLE_DEADLOCK;
00665 goto done;
00666 }
00667
00668 if ((*cli = cli_initialise()) == NULL) {
00669 DEBUG(1, ("Could not cli_initialize\n"));
00670 result = NT_STATUS_NO_MEMORY;
00671 goto done;
00672 }
00673
00674 (*cli)->timeout = 10000;
00675 (*cli)->fd = sockfd;
00676 fstrcpy((*cli)->desthost, controller);
00677 (*cli)->use_kerberos = True;
00678
00679 peeraddr_len = sizeof(peeraddr);
00680
00681 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
00682 (peeraddr_len != sizeof(struct sockaddr_in)) ||
00683 (peeraddr_in->sin_family != PF_INET))
00684 {
00685 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
00686 result = NT_STATUS_UNSUCCESSFUL;
00687 goto done;
00688 }
00689
00690 if (ntohs(peeraddr_in->sin_port) == 139) {
00691 struct nmb_name calling;
00692 struct nmb_name called;
00693
00694 make_nmb_name(&calling, global_myname(), 0x0);
00695 make_nmb_name(&called, "*SMBSERVER", 0x20);
00696
00697 if (!cli_session_request(*cli, &calling, &called)) {
00698 DEBUG(8, ("cli_session_request failed for %s\n",
00699 controller));
00700 result = NT_STATUS_UNSUCCESSFUL;
00701 goto done;
00702 }
00703 }
00704
00705 cli_setup_signing_state(*cli, Undefined);
00706
00707 if (!cli_negprot(*cli)) {
00708 DEBUG(1, ("cli_negprot failed\n"));
00709 result = NT_STATUS_UNSUCCESSFUL;
00710 goto done;
00711 }
00712
00713 if (!is_trusted_domain_situation(domain->name) &&
00714 (*cli)->protocol >= PROTOCOL_NT1 &&
00715 (*cli)->capabilities & CAP_EXTENDED_SECURITY)
00716 {
00717 ADS_STATUS ads_status;
00718
00719 result = get_trust_creds(domain, &machine_password,
00720 &machine_account,
00721 &machine_krb5_principal);
00722 if (!NT_STATUS_IS_OK(result)) {
00723 goto anon_fallback;
00724 }
00725
00726 if (lp_security() == SEC_ADS) {
00727
00728
00729
00730 (*cli)->use_kerberos = True;
00731 DEBUG(5, ("connecting to %s from %s with kerberos principal "
00732 "[%s] and realm [%s]\n", controller, global_myname(),
00733 machine_krb5_principal, domain->alt_name));
00734
00735 ads_status = cli_session_setup_spnego(*cli,
00736 machine_krb5_principal,
00737 machine_password,
00738 lp_workgroup(),
00739 domain->alt_name);
00740
00741 if (!ADS_ERR_OK(ads_status)) {
00742 DEBUG(4,("failed kerberos session setup with %s\n",
00743 ads_errstr(ads_status)));
00744 }
00745
00746 result = ads_ntstatus(ads_status);
00747 if (NT_STATUS_IS_OK(result)) {
00748
00749 cli_init_creds(*cli, machine_account, domain->name, machine_password);
00750 goto session_setup_done;
00751 }
00752 }
00753
00754
00755 (*cli)->use_kerberos = False;
00756
00757 DEBUG(5, ("connecting to %s from %s with username "
00758 "[%s]\\[%s]\n", controller, global_myname(),
00759 lp_workgroup(), machine_account));
00760
00761 ads_status = cli_session_setup_spnego(*cli,
00762 machine_account,
00763 machine_password,
00764 lp_workgroup(),
00765 NULL);
00766 if (!ADS_ERR_OK(ads_status)) {
00767 DEBUG(4, ("authenticated session setup failed with %s\n",
00768 ads_errstr(ads_status)));
00769 }
00770
00771 result = ads_ntstatus(ads_status);
00772 if (NT_STATUS_IS_OK(result)) {
00773
00774 cli_init_creds(*cli, machine_account, domain->name, machine_password);
00775 goto session_setup_done;
00776 }
00777 }
00778
00779
00780
00781 (*cli)->use_kerberos = False;
00782
00783 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
00784
00785 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
00786 (strlen(ipc_username) > 0)) {
00787
00788
00789
00790 DEBUG(5, ("connecting to %s from %s with username "
00791 "[%s]\\[%s]\n", controller, global_myname(),
00792 ipc_domain, ipc_username));
00793
00794 if (NT_STATUS_IS_OK(cli_session_setup(
00795 *cli, ipc_username,
00796 ipc_password, strlen(ipc_password)+1,
00797 ipc_password, strlen(ipc_password)+1,
00798 ipc_domain))) {
00799
00800 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
00801 goto session_setup_done;
00802 } else {
00803 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
00804 ipc_domain, ipc_username ));
00805 }
00806 }
00807
00808 anon_fallback:
00809
00810
00811
00812 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
00813 NULL, 0, ""))) {
00814 DEBUG(5, ("Connected anonymously\n"));
00815 cli_init_creds(*cli, "", "", "");
00816 goto session_setup_done;
00817 }
00818
00819 result = cli_nt_error(*cli);
00820
00821 if (NT_STATUS_IS_OK(result))
00822 result = NT_STATUS_UNSUCCESSFUL;
00823
00824
00825
00826 goto done;
00827
00828 session_setup_done:
00829
00830
00831
00832 saf_store( domain->name, (*cli)->desthost );
00833 if (domain->alt_name && (*cli)->use_kerberos) {
00834 saf_store( domain->alt_name, (*cli)->desthost );
00835 }
00836
00837 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
00838
00839 result = cli_nt_error(*cli);
00840
00841 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
00842
00843 if (NT_STATUS_IS_OK(result))
00844 result = NT_STATUS_UNSUCCESSFUL;
00845
00846 goto done;
00847 }
00848
00849 secrets_named_mutex_release(controller);
00850 got_mutex = False;
00851 *retry = False;
00852
00853
00854 if ( !*(*cli)->domain ) {
00855 fstrcpy( (*cli)->domain, domain->name );
00856 }
00857
00858 result = NT_STATUS_OK;
00859
00860 done:
00861 if (got_mutex) {
00862 secrets_named_mutex_release(controller);
00863 }
00864
00865 SAFE_FREE(machine_account);
00866 SAFE_FREE(machine_password);
00867 SAFE_FREE(machine_krb5_principal);
00868 SAFE_FREE(ipc_username);
00869 SAFE_FREE(ipc_domain);
00870 SAFE_FREE(ipc_password);
00871
00872 if (!NT_STATUS_IS_OK(result)) {
00873 winbind_add_failed_connection_entry(domain, controller, result);
00874 if ((*cli) != NULL) {
00875 cli_shutdown(*cli);
00876 *cli = NULL;
00877 }
00878 }
00879
00880 return result;
00881 }
00882
00883 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
00884 const char *dcname, struct in_addr ip,
00885 struct dc_name_ip **dcs, int *num)
00886 {
00887 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
00888 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
00889 return False;
00890 }
00891
00892 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
00893
00894 if (*dcs == NULL)
00895 return False;
00896
00897 fstrcpy((*dcs)[*num].name, dcname);
00898 (*dcs)[*num].ip = ip;
00899 *num += 1;
00900 return True;
00901 }
00902
00903 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
00904 struct in_addr ip, uint16 port,
00905 struct sockaddr_in **addrs, int *num)
00906 {
00907 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
00908
00909 if (*addrs == NULL) {
00910 *num = 0;
00911 return False;
00912 }
00913
00914 (*addrs)[*num].sin_family = PF_INET;
00915 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
00916 (*addrs)[*num].sin_port = htons(port);
00917
00918 *num += 1;
00919 return True;
00920 }
00921
00922 static void mailslot_name(struct in_addr dc_ip, fstring name)
00923 {
00924 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
00925 }
00926
00927 static BOOL send_getdc_request(struct in_addr dc_ip,
00928 const char *domain_name,
00929 const DOM_SID *sid)
00930 {
00931 pstring outbuf;
00932 char *p;
00933 fstring my_acct_name;
00934 fstring my_mailslot;
00935
00936 mailslot_name(dc_ip, my_mailslot);
00937
00938 memset(outbuf, '\0', sizeof(outbuf));
00939
00940 p = outbuf;
00941
00942 SCVAL(p, 0, SAMLOGON);
00943 p++;
00944
00945 SCVAL(p, 0, 0);
00946 p++;
00947
00948 SIVAL(p, 0, 0);
00949 p += 2;
00950
00951 p += dos_PutUniCode(p, global_myname(),
00952 sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
00953 fstr_sprintf(my_acct_name, "%s$", global_myname());
00954 p += dos_PutUniCode(p, my_acct_name,
00955 sizeof(outbuf) - PTR_DIFF(p, outbuf), True);
00956
00957 if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
00958 return False;
00959 }
00960
00961 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
00962 p += strlen(my_mailslot)+1;
00963
00964 if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) {
00965 return False;
00966 }
00967 SIVAL(p, 0, 0x80);
00968 p+=4;
00969
00970 SIVAL(p, 0, sid_size(sid));
00971 p+=4;
00972
00973 p = ALIGN4(p, outbuf);
00974
00975 if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) {
00976 return False;
00977 }
00978
00979 if (sid_size(sid) + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) {
00980 return False;
00981 }
00982
00983 sid_linearize(p, sizeof(outbuf) - PTR_DIFF(p, outbuf), sid);
00984 p += sid_size(sid);
00985
00986 SIVAL(p, 0, 1);
00987 SSVAL(p, 4, 0xffff);
00988 SSVAL(p, 6, 0xffff);
00989 p+=8;
00990
00991 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
00992 outbuf, PTR_DIFF(p, outbuf),
00993 global_myname(), 0, domain_name, 0x1c,
00994 dc_ip);
00995 }
00996
00997 static BOOL receive_getdc_response(struct in_addr dc_ip,
00998 const char *domain_name,
00999 fstring dc_name)
01000 {
01001 struct packet_struct *packet;
01002 fstring my_mailslot;
01003 char *buf, *p;
01004 fstring dcname, user, domain;
01005 int len;
01006
01007 mailslot_name(dc_ip, my_mailslot);
01008
01009 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
01010
01011 if (packet == NULL) {
01012 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
01013 return False;
01014 }
01015
01016 DEBUG(5, ("Received packet for %s\n", my_mailslot));
01017
01018 buf = packet->packet.dgram.data;
01019 len = packet->packet.dgram.datasize;
01020
01021 if (len < 70) {
01022
01023
01024 DEBUG(3, ("GetDC got short response\n"));
01025 return False;
01026 }
01027
01028
01029 p = buf+SVAL(buf, smb_vwv10);
01030
01031 if (CVAL(p,0) != SAMLOGON_R) {
01032 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
01033 return False;
01034 }
01035
01036 p+=2;
01037 pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
01038 STR_TERMINATE|STR_NOALIGN);
01039 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
01040 pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
01041 STR_TERMINATE|STR_NOALIGN);
01042 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
01043 pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
01044 STR_TERMINATE|STR_NOALIGN);
01045 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
01046
01047 if (!strequal(domain, domain_name)) {
01048 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
01049 domain_name, domain));
01050 return False;
01051 }
01052
01053 p = dcname;
01054 if (*p == '\\') p += 1;
01055 if (*p == '\\') p += 1;
01056
01057 fstrcpy(dc_name, p);
01058
01059 DEBUG(10, ("GetDC gave name %s for domain %s\n",
01060 dc_name, domain));
01061
01062 return True;
01063 }
01064
01065
01066
01067
01068
01069 static BOOL dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip, fstring name )
01070 {
01071 struct ip_service ip_list;
01072
01073 ip_list.ip = ip;
01074 ip_list.port = 0;
01075
01076 #ifdef WITH_ADS
01077
01078
01079
01080 if (lp_security() == SEC_ADS) {
01081 ADS_STRUCT *ads;
01082
01083 ads = ads_init(domain->alt_name, domain->name, NULL);
01084 ads->auth.flags |= ADS_AUTH_NO_BIND;
01085
01086 if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
01087
01088 fstrcpy(name, ads->config.ldap_server_name);
01089 namecache_store(name, 0x20, 1, &ip_list);
01090
01091 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
01092
01093 if (domain->primary && (ads->config.flags & ADS_KDC)) {
01094 if (ads_closest_dc(ads)) {
01095 char *sitename = sitename_fetch(ads->config.realm);
01096
01097
01098
01099
01100
01101 create_local_private_krb5_conf_for_domain(domain->alt_name,
01102 domain->name,
01103 sitename,
01104 ip);
01105
01106 SAFE_FREE(sitename);
01107 } else {
01108
01109 create_local_private_krb5_conf_for_domain(domain->alt_name,
01110 domain->name,
01111 NULL,
01112 ip);
01113 }
01114
01115 saf_store( domain->name, name);
01116 saf_store( domain->alt_name, name);
01117 }
01118
01119 ads_destroy( &ads );
01120 return True;
01121 }
01122
01123 ads_destroy( &ads );
01124 }
01125 #endif
01126
01127
01128
01129 if (send_getdc_request(ip, domain->name, &domain->sid)) {
01130 int i;
01131 smb_msleep(100);
01132 for (i=0; i<5; i++) {
01133 if (receive_getdc_response(ip, domain->name, name)) {
01134 namecache_store(name, 0x20, 1, &ip_list);
01135 return True;
01136 }
01137 smb_msleep(500);
01138 }
01139 }
01140
01141
01142
01143 if ( name_status_find(domain->name, 0x1c, 0x20, ip, name) ) {
01144 namecache_store(name, 0x20, 1, &ip_list);
01145 return True;
01146 }
01147 return False;
01148 }
01149
01150
01151
01152
01153
01154
01155 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
01156 struct dc_name_ip **dcs, int *num_dcs)
01157 {
01158 fstring dcname;
01159 struct in_addr ip;
01160 struct ip_service *ip_list = NULL;
01161 int iplist_size = 0;
01162 int i;
01163 BOOL is_our_domain;
01164 enum security_types sec = (enum security_types)lp_security();
01165
01166 is_our_domain = strequal(domain->name, lp_workgroup());
01167
01168 if ( !is_our_domain
01169 && get_dc_name_via_netlogon(domain, dcname, &ip)
01170 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
01171 {
01172 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
01173 dcname, inet_ntoa(ip)));
01174 return True;
01175 }
01176
01177 if (sec == SEC_ADS) {
01178 char *sitename = NULL;
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189 get_dc_name(domain->name, domain->alt_name, dcname, &ip);
01190
01191 sitename = sitename_fetch(domain->alt_name);
01192 if (sitename) {
01193
01194
01195 get_sorted_dc_list(domain->alt_name, sitename, &ip_list, &iplist_size, True);
01196
01197 for ( i=0; i<iplist_size; i++ ) {
01198 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
01199 ip_list[i].ip, dcs, num_dcs);
01200 }
01201
01202 SAFE_FREE(ip_list);
01203 SAFE_FREE(sitename);
01204 iplist_size = 0;
01205 }
01206
01207
01208 get_sorted_dc_list(domain->alt_name, NULL, &ip_list, &iplist_size, True);
01209
01210 for ( i=0; i<iplist_size; i++ ) {
01211 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
01212 ip_list[i].ip, dcs, num_dcs);
01213 }
01214 }
01215
01216
01217
01218 if (iplist_size==0) {
01219 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size, False);
01220 }
01221
01222
01223
01224
01225
01226
01227
01228 for ( i=0; i<iplist_size; i++ ) {
01229 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
01230 ip_list[i].ip, dcs, num_dcs);
01231 }
01232
01233 SAFE_FREE( ip_list );
01234
01235 return True;
01236 }
01237
01238 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
01239 const struct winbindd_domain *domain,
01240 fstring dcname, struct sockaddr_in *addr, int *fd)
01241 {
01242 struct dc_name_ip *dcs = NULL;
01243 int num_dcs = 0;
01244
01245 const char **dcnames = NULL;
01246 int num_dcnames = 0;
01247
01248 struct sockaddr_in *addrs = NULL;
01249 int num_addrs = 0;
01250
01251 int i, fd_index;
01252
01253 *fd = -1;
01254
01255 again:
01256 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
01257 return False;
01258
01259 for (i=0; i<num_dcs; i++) {
01260
01261 if (!add_string_to_array(mem_ctx, dcs[i].name,
01262 &dcnames, &num_dcnames)) {
01263 return False;
01264 }
01265 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
01266 &addrs, &num_addrs)) {
01267 return False;
01268 }
01269
01270 if (!add_string_to_array(mem_ctx, dcs[i].name,
01271 &dcnames, &num_dcnames)) {
01272 return False;
01273 }
01274 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
01275 &addrs, &num_addrs)) {
01276 return False;
01277 }
01278 }
01279
01280 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
01281 return False;
01282
01283 if ((addrs == NULL) || (dcnames == NULL))
01284 return False;
01285
01286
01287 if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
01288 {
01289 for (i=0; i<num_dcs; i++) {
01290 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
01291 "domain %s address %s. Error was %s\n",
01292 domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
01293 winbind_add_failed_connection_entry(domain,
01294 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
01295 }
01296 return False;
01297 }
01298
01299 *addr = addrs[fd_index];
01300
01301 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
01302
01303 fstrcpy(dcname, dcnames[fd_index]);
01304 return True;
01305 }
01306
01307
01308 if (dcip_to_name( domain, addr->sin_addr, dcname )) {
01309 return True;
01310 }
01311
01312
01313 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
01314 NT_STATUS_UNSUCCESSFUL);
01315
01316
01317 TALLOC_FREE(dcs);
01318 num_dcs = 0;
01319
01320 TALLOC_FREE(dcnames);
01321 num_dcnames = 0;
01322
01323 TALLOC_FREE(addrs);
01324 num_addrs = 0;
01325
01326 *fd = -1;
01327
01328 goto again;
01329 }
01330
01331 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
01332 struct winbindd_cm_conn *new_conn)
01333 {
01334 TALLOC_CTX *mem_ctx;
01335 NTSTATUS result;
01336 char *saf_servername = saf_fetch( domain->name );
01337 int retries;
01338
01339 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
01340 SAFE_FREE(saf_servername);
01341 set_domain_offline(domain);
01342 return NT_STATUS_NO_MEMORY;
01343 }
01344
01345
01346
01347
01348
01349
01350
01351
01352 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
01353
01354 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
01355 saf_servername, domain->name ));
01356
01357
01358 if ( is_ipaddress( saf_servername ) ) {
01359 fstring saf_name;
01360 struct in_addr ip;
01361
01362 ip = *interpret_addr2( saf_servername );
01363 if (dcip_to_name( domain, ip, saf_name )) {
01364 fstrcpy( domain->dcname, saf_name );
01365 } else {
01366 winbind_add_failed_connection_entry(
01367 domain, saf_servername,
01368 NT_STATUS_UNSUCCESSFUL);
01369 }
01370 } else {
01371 fstrcpy( domain->dcname, saf_servername );
01372 }
01373
01374 SAFE_FREE( saf_servername );
01375 }
01376
01377 for (retries = 0; retries < 3; retries++) {
01378
01379 int fd = -1;
01380 BOOL retry = False;
01381
01382 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
01383
01384 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
01385 domain->dcname, domain->name ));
01386
01387 if (*domain->dcname
01388 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
01389 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
01390 {
01391 struct sockaddr_in *addrs = NULL;
01392 int num_addrs = 0;
01393 int dummy = 0;
01394
01395 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
01396 set_domain_offline(domain);
01397 talloc_destroy(mem_ctx);
01398 return NT_STATUS_NO_MEMORY;
01399 }
01400 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
01401 set_domain_offline(domain);
01402 talloc_destroy(mem_ctx);
01403 return NT_STATUS_NO_MEMORY;
01404 }
01405
01406
01407 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
01408 fd = -1;
01409 }
01410 }
01411
01412 if ((fd == -1)
01413 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
01414 {
01415
01416
01417
01418
01419 set_global_winbindd_state_offline();
01420 break;
01421 }
01422
01423 new_conn->cli = NULL;
01424
01425 result = cm_prepare_connection(domain, fd, domain->dcname,
01426 &new_conn->cli, &retry);
01427
01428 if (!retry)
01429 break;
01430 }
01431
01432 if (NT_STATUS_IS_OK(result)) {
01433 if (domain->online == False) {
01434
01435 set_global_winbindd_state_online();
01436 }
01437 set_domain_online(domain);
01438 } else {
01439
01440 set_domain_offline(domain);
01441 }
01442
01443 talloc_destroy(mem_ctx);
01444 return result;
01445 }
01446
01447
01448
01449 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
01450 {
01451
01452
01453
01454 if (conn->cli) {
01455 cli_set_timeout(conn->cli, 1000);
01456 }
01457
01458 if (conn->samr_pipe != NULL) {
01459 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
01460
01461 if (conn->cli) {
01462 cli_set_timeout(conn->cli, 500);
01463 }
01464 }
01465 conn->samr_pipe = NULL;
01466 }
01467
01468 if (conn->lsa_pipe != NULL) {
01469 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
01470
01471 if (conn->cli) {
01472 cli_set_timeout(conn->cli, 500);
01473 }
01474 }
01475 conn->lsa_pipe = NULL;
01476 }
01477
01478 if (conn->netlogon_pipe != NULL) {
01479 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
01480
01481 if (conn->cli) {
01482 cli_set_timeout(conn->cli, 500);
01483 }
01484 }
01485 conn->netlogon_pipe = NULL;
01486 }
01487
01488 if (conn->cli) {
01489 cli_shutdown(conn->cli);
01490 }
01491
01492 conn->cli = NULL;
01493 }
01494
01495 void close_conns_after_fork(void)
01496 {
01497 struct winbindd_domain *domain;
01498
01499 for (domain = domain_list(); domain; domain = domain->next) {
01500 if (domain->conn.cli == NULL)
01501 continue;
01502
01503 if (domain->conn.cli->fd == -1)
01504 continue;
01505
01506 close(domain->conn.cli->fd);
01507 domain->conn.cli->fd = -1;
01508 }
01509 }
01510
01511 static BOOL connection_ok(struct winbindd_domain *domain)
01512 {
01513 if (domain->conn.cli == NULL) {
01514 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
01515 "cli!\n", domain->dcname, domain->name));
01516 return False;
01517 }
01518
01519 if (!domain->conn.cli->initialised) {
01520 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
01521 "initialised!\n", domain->dcname, domain->name));
01522 return False;
01523 }
01524
01525 if (domain->conn.cli->fd == -1) {
01526 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
01527 "never started (fd == -1)\n",
01528 domain->dcname, domain->name));
01529 return False;
01530 }
01531
01532 if (domain->online == False) {
01533 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
01534 return False;
01535 }
01536
01537 return True;
01538 }
01539
01540
01541
01542
01543 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
01544 {
01545 NTSTATUS result;
01546
01547
01548 if (domain->internal) {
01549 domain->initialized = True;
01550 return NT_STATUS_OK;
01551 }
01552
01553 if (connection_ok(domain)) {
01554 if (!domain->initialized) {
01555 set_dc_type_and_flags(domain);
01556 }
01557 return NT_STATUS_OK;
01558 }
01559
01560 invalidate_cm_connection(&domain->conn);
01561
01562 result = cm_open_connection(domain, &domain->conn);
01563
01564 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
01565 set_dc_type_and_flags(domain);
01566 }
01567
01568 return result;
01569 }
01570
01571 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
01572 {
01573 if (domain->initialized && !domain->online) {
01574
01575 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
01576 }
01577
01578 return init_dc_connection_network(domain);
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589 static void set_dc_type_and_flags( struct winbindd_domain *domain )
01590 {
01591 NTSTATUS result;
01592 DS_DOMINFO_CTR ctr;
01593 TALLOC_CTX *mem_ctx = NULL;
01594 struct rpc_pipe_client *cli;
01595 POLICY_HND pol;
01596
01597 char *domain_name = NULL;
01598 char *dns_name = NULL;
01599 char *forest_name = NULL;
01600 DOM_SID *dom_sid = NULL;
01601
01602 ZERO_STRUCT( ctr );
01603
01604 if (!connection_ok(domain)) {
01605 return;
01606 }
01607
01608 DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
01609
01610 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
01611 &result);
01612
01613 if (cli == NULL) {
01614 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
01615 "PI_LSARPC_DS on domain %s: (%s)\n",
01616 domain->name, nt_errstr(result)));
01617
01618
01619
01620
01621
01622 goto no_lsarpc_ds;
01623 }
01624
01625 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
01626 DsRolePrimaryDomainInfoBasic,
01627 &ctr);
01628 cli_rpc_pipe_close(cli);
01629
01630 if (!NT_STATUS_IS_OK(result)) {
01631 DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
01632 "on domain %s failed: (%s)\n",
01633 domain->name, nt_errstr(result)));
01634
01635
01636
01637
01638
01639
01640 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
01641 goto no_lsarpc_ds;
01642 }
01643
01644 return;
01645 }
01646
01647 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
01648 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
01649 domain->native_mode = True;
01650 } else {
01651 domain->native_mode = False;
01652 }
01653
01654 no_lsarpc_ds:
01655 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
01656
01657 if (cli == NULL) {
01658 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
01659 "PI_LSARPC on domain %s: (%s)\n",
01660 domain->name, nt_errstr(result)));
01661 cli_rpc_pipe_close(cli);
01662 return;
01663 }
01664
01665 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
01666 domain->name);
01667 if (!mem_ctx) {
01668 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
01669 cli_rpc_pipe_close(cli);
01670 return;
01671 }
01672
01673 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
01674 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
01675
01676 if (NT_STATUS_IS_OK(result)) {
01677
01678
01679 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
01680 12, &domain_name,
01681 &dns_name, &forest_name,
01682 NULL, &dom_sid);
01683 }
01684
01685 if (NT_STATUS_IS_OK(result)) {
01686 domain->active_directory = True;
01687
01688 if (domain_name)
01689 fstrcpy(domain->name, domain_name);
01690
01691 if (dns_name)
01692 fstrcpy(domain->alt_name, dns_name);
01693
01694 if ( forest_name )
01695 fstrcpy(domain->forest_name, forest_name);
01696
01697 if (dom_sid)
01698 sid_copy(&domain->sid, dom_sid);
01699 } else {
01700 domain->active_directory = False;
01701
01702 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
01703 SEC_RIGHTS_MAXIMUM_ALLOWED,
01704 &pol);
01705
01706 if (!NT_STATUS_IS_OK(result))
01707 goto done;
01708
01709 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
01710 &pol, 5, &domain_name,
01711 &dom_sid);
01712
01713 if (NT_STATUS_IS_OK(result)) {
01714 if (domain_name)
01715 fstrcpy(domain->name, domain_name);
01716
01717 if (dom_sid)
01718 sid_copy(&domain->sid, dom_sid);
01719 }
01720 }
01721 done:
01722
01723 DEBUG(5, ("set_dc_type_and_flags: domain %s is %sin native mode.\n",
01724 domain->name, domain->native_mode ? "" : "NOT "));
01725
01726 DEBUG(5,("set_dc_type_and_flags: domain %s is %srunning active directory.\n",
01727 domain->name, domain->active_directory ? "" : "NOT "));
01728
01729 cli_rpc_pipe_close(cli);
01730
01731 talloc_destroy(mem_ctx);
01732
01733 domain->initialized = True;
01734 }
01735
01736 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
01737 struct dcinfo **ppdc)
01738 {
01739 NTSTATUS result;
01740 struct rpc_pipe_client *netlogon_pipe;
01741
01742 if (lp_client_schannel() == False) {
01743 return False;
01744 }
01745
01746 result = cm_connect_netlogon(domain, &netlogon_pipe);
01747 if (!NT_STATUS_IS_OK(result)) {
01748 return False;
01749 }
01750
01751
01752
01753
01754 *ppdc = domain->conn.netlogon_pipe->dc;
01755 return True;
01756 }
01757
01758 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
01759 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
01760 {
01761 struct winbindd_cm_conn *conn;
01762 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01763 fstring conn_pwd;
01764 struct dcinfo *p_dcinfo;
01765 char *machine_password = NULL;
01766 char *machine_account = NULL;
01767 char *domain_name = NULL;
01768
01769 result = init_dc_connection(domain);
01770 if (!NT_STATUS_IS_OK(result)) {
01771 return result;
01772 }
01773
01774 conn = &domain->conn;
01775
01776 if (conn->samr_pipe != NULL) {
01777 goto done;
01778 }
01779
01780
01781
01782
01783
01784
01785
01786
01787 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
01788 if ((conn->cli->user_name[0] == '\0') ||
01789 (conn->cli->domain[0] == '\0') ||
01790 (conn_pwd[0] == '\0'))
01791 {
01792 result = get_trust_creds(domain, &machine_password,
01793 &machine_account, NULL);
01794 if (!NT_STATUS_IS_OK(result)) {
01795 DEBUG(10, ("cm_connect_sam: No no user available for "
01796 "domain %s, trying schannel\n", conn->cli->domain));
01797 goto schannel;
01798 }
01799 domain_name = domain->name;
01800 } else {
01801 machine_password = SMB_STRDUP(conn_pwd);
01802 machine_account = SMB_STRDUP(conn->cli->user_name);
01803 domain_name = conn->cli->domain;
01804 }
01805
01806 if (!machine_password || !machine_account) {
01807 result = NT_STATUS_NO_MEMORY;
01808 goto done;
01809 }
01810
01811
01812
01813 conn->samr_pipe =
01814 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
01815 PIPE_AUTH_LEVEL_PRIVACY,
01816 domain_name,
01817 machine_account,
01818 machine_password, &result);
01819
01820 if (conn->samr_pipe == NULL) {
01821 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
01822 "pipe for domain %s using NTLMSSP "
01823 "authenticated pipe: user %s\\%s. Error was "
01824 "%s\n", domain->name, domain_name,
01825 machine_account, nt_errstr(result)));
01826 goto schannel;
01827 }
01828
01829 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
01830 "domain %s using NTLMSSP authenticated "
01831 "pipe: user %s\\%s\n", domain->name,
01832 domain_name, machine_account));
01833
01834 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
01835 SEC_RIGHTS_MAXIMUM_ALLOWED,
01836 &conn->sam_connect_handle);
01837 if (NT_STATUS_IS_OK(result)) {
01838 goto open_domain;
01839 }
01840 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
01841 "failed for domain %s, error was %s. Trying schannel\n",
01842 domain->name, nt_errstr(result) ));
01843 cli_rpc_pipe_close(conn->samr_pipe);
01844
01845 schannel:
01846
01847
01848
01849 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
01850
01851 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
01852 "for domain %s, trying anon\n", domain->name));
01853 goto anonymous;
01854 }
01855 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
01856 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
01857 domain->name, p_dcinfo, &result);
01858
01859 if (conn->samr_pipe == NULL) {
01860 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
01861 "domain %s using schannel. Error was %s\n",
01862 domain->name, nt_errstr(result) ));
01863 goto anonymous;
01864 }
01865 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
01866 "schannel.\n", domain->name ));
01867
01868 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
01869 SEC_RIGHTS_MAXIMUM_ALLOWED,
01870 &conn->sam_connect_handle);
01871 if (NT_STATUS_IS_OK(result)) {
01872 goto open_domain;
01873 }
01874 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
01875 "for domain %s, error was %s. Trying anonymous\n",
01876 domain->name, nt_errstr(result) ));
01877 cli_rpc_pipe_close(conn->samr_pipe);
01878
01879 anonymous:
01880
01881
01882 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
01883 &result);
01884
01885 if (conn->samr_pipe == NULL) {
01886 result = NT_STATUS_PIPE_NOT_AVAILABLE;
01887 goto done;
01888 }
01889
01890 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
01891 SEC_RIGHTS_MAXIMUM_ALLOWED,
01892 &conn->sam_connect_handle);
01893 if (!NT_STATUS_IS_OK(result)) {
01894 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
01895 "for domain %s Error was %s\n",
01896 domain->name, nt_errstr(result) ));
01897 goto done;
01898 }
01899
01900 open_domain:
01901 result = rpccli_samr_open_domain(conn->samr_pipe,
01902 mem_ctx,
01903 &conn->sam_connect_handle,
01904 SEC_RIGHTS_MAXIMUM_ALLOWED,
01905 &domain->sid,
01906 &conn->sam_domain_handle);
01907
01908 done:
01909
01910 if (!NT_STATUS_IS_OK(result)) {
01911 invalidate_cm_connection(conn);
01912 return result;
01913 }
01914
01915 *cli = conn->samr_pipe;
01916 *sam_handle = conn->sam_domain_handle;
01917 SAFE_FREE(machine_password);
01918 SAFE_FREE(machine_account);
01919 return result;
01920 }
01921
01922 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
01923 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
01924 {
01925 struct winbindd_cm_conn *conn;
01926 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
01927 fstring conn_pwd;
01928 struct dcinfo *p_dcinfo;
01929
01930 result = init_dc_connection(domain);
01931 if (!NT_STATUS_IS_OK(result))
01932 return result;
01933
01934 conn = &domain->conn;
01935
01936 if (conn->lsa_pipe != NULL) {
01937 goto done;
01938 }
01939
01940 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
01941 if ((conn->cli->user_name[0] == '\0') ||
01942 (conn->cli->domain[0] == '\0') ||
01943 (conn_pwd[0] == '\0')) {
01944 DEBUG(10, ("cm_connect_lsa: No no user available for "
01945 "domain %s, trying schannel\n", conn->cli->domain));
01946 goto schannel;
01947 }
01948
01949
01950
01951 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
01952 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
01953 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
01954
01955 if (conn->lsa_pipe == NULL) {
01956 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
01957 "domain %s using NTLMSSP authenticated pipe: user "
01958 "%s\\%s. Error was %s. Trying schannel.\n",
01959 domain->name, conn->cli->domain,
01960 conn->cli->user_name, nt_errstr(result)));
01961 goto schannel;
01962 }
01963
01964 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
01965 "NTLMSSP authenticated pipe: user %s\\%s\n",
01966 domain->name, conn->cli->domain, conn->cli->user_name ));
01967
01968 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
01969 SEC_RIGHTS_MAXIMUM_ALLOWED,
01970 &conn->lsa_policy);
01971 if (NT_STATUS_IS_OK(result)) {
01972 goto done;
01973 }
01974
01975 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
01976 "schannel\n"));
01977
01978 cli_rpc_pipe_close(conn->lsa_pipe);
01979
01980 schannel:
01981
01982
01983
01984 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
01985
01986 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
01987 "for domain %s, trying anon\n", domain->name));
01988 goto anonymous;
01989 }
01990 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
01991 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
01992 domain->name, p_dcinfo, &result);
01993
01994 if (conn->lsa_pipe == NULL) {
01995 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
01996 "domain %s using schannel. Error was %s\n",
01997 domain->name, nt_errstr(result) ));
01998 goto anonymous;
01999 }
02000 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
02001 "schannel.\n", domain->name ));
02002
02003 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
02004 SEC_RIGHTS_MAXIMUM_ALLOWED,
02005 &conn->lsa_policy);
02006 if (NT_STATUS_IS_OK(result)) {
02007 goto done;
02008 }
02009
02010 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
02011 "anonymous\n"));
02012
02013 cli_rpc_pipe_close(conn->lsa_pipe);
02014
02015 anonymous:
02016
02017 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
02018 &result);
02019 if (conn->lsa_pipe == NULL) {
02020 result = NT_STATUS_PIPE_NOT_AVAILABLE;
02021 goto done;
02022 }
02023
02024 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
02025 SEC_RIGHTS_MAXIMUM_ALLOWED,
02026 &conn->lsa_policy);
02027 done:
02028 if (!NT_STATUS_IS_OK(result)) {
02029 invalidate_cm_connection(conn);
02030 return result;
02031 }
02032
02033 *cli = conn->lsa_pipe;
02034 *lsa_policy = conn->lsa_policy;
02035 return result;
02036 }
02037
02038
02039
02040
02041
02042
02043 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
02044 struct rpc_pipe_client **cli)
02045 {
02046 struct winbindd_cm_conn *conn;
02047 NTSTATUS result;
02048
02049 uint32 neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
02050 uint8 mach_pwd[16];
02051 uint32 sec_chan_type;
02052 const char *account_name;
02053 struct rpc_pipe_client *netlogon_pipe = NULL;
02054
02055 *cli = NULL;
02056
02057 result = init_dc_connection(domain);
02058 if (!NT_STATUS_IS_OK(result)) {
02059 return result;
02060 }
02061
02062 conn = &domain->conn;
02063
02064 if (conn->netlogon_pipe != NULL) {
02065 *cli = conn->netlogon_pipe;
02066 return NT_STATUS_OK;
02067 }
02068
02069 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
02070 &result);
02071 if (netlogon_pipe == NULL) {
02072 return result;
02073 }
02074
02075 if ((!IS_DC) && (!domain->primary)) {
02076
02077 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
02078 goto no_schannel;
02079 }
02080
02081 if (lp_client_schannel() != False) {
02082 neg_flags |= NETLOGON_NEG_SCHANNEL;
02083 }
02084
02085 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
02086 &sec_chan_type))
02087 {
02088 cli_rpc_pipe_close(netlogon_pipe);
02089 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
02090 }
02091
02092 result = rpccli_netlogon_setup_creds(
02093 netlogon_pipe,
02094 domain->dcname,
02095 domain->name,
02096 global_myname(),
02097 account_name,
02098 mach_pwd,
02099 sec_chan_type,
02100 &neg_flags);
02101
02102 if (!NT_STATUS_IS_OK(result)) {
02103 cli_rpc_pipe_close(netlogon_pipe);
02104 return result;
02105 }
02106
02107 if ((lp_client_schannel() == True) &&
02108 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
02109 DEBUG(3, ("Server did not offer schannel\n"));
02110 cli_rpc_pipe_close(netlogon_pipe);
02111 return NT_STATUS_ACCESS_DENIED;
02112 }
02113
02114 no_schannel:
02115 if ((lp_client_schannel() == False) ||
02116 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
02117
02118
02119 conn->netlogon_pipe = netlogon_pipe;
02120 *cli = conn->netlogon_pipe;
02121 return NT_STATUS_OK;
02122 }
02123
02124
02125
02126
02127
02128
02129 conn->netlogon_pipe =
02130 cli_rpc_pipe_open_schannel_with_key(conn->cli,
02131 PI_NETLOGON,
02132 PIPE_AUTH_LEVEL_PRIVACY,
02133 domain->name,
02134 netlogon_pipe->dc,
02135 &result);
02136
02137
02138 cli_rpc_pipe_close(netlogon_pipe);
02139
02140 if (conn->netlogon_pipe == NULL) {
02141 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
02142 "was %s\n", nt_errstr(result)));
02143
02144
02145 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
02146 }
02147
02148 *cli = conn->netlogon_pipe;
02149 return NT_STATUS_OK;
02150 }