データ構造 | |
struct | dc_name_ip |
関数 | |
static NTSTATUS | init_dc_connection_network (struct winbindd_domain *domain) |
static void | set_dc_type_and_flags (struct winbindd_domain *domain) |
static BOOL | get_dcs (TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain, struct dc_name_ip **dcs, int *num_dcs) |
static void | msg_failed_to_go_online (int msg_type, struct process_id src, void *buf, size_t len, void *private_data) |
static void | msg_try_to_go_online (int msg_type, struct process_id src, void *buf, size_t len, void *private_data) |
static BOOL | fork_child_dc_connect (struct winbindd_domain *domain) |
static void | check_domain_online_handler (struct event_context *ctx, struct timed_event *te, const struct timeval *now, void *private_data) |
static void | calc_new_online_timeout_check (struct winbindd_domain *domain) |
void | set_domain_offline (struct winbindd_domain *domain) |
static void | set_domain_online (struct winbindd_domain *domain) |
void | set_domain_online_request (struct winbindd_domain *domain) |
void | winbind_add_failed_connection_entry (const struct winbindd_domain *domain, const char *server, NTSTATUS result) |
static void | cm_get_ipc_userpass (char **username, char **domain, char **password) |
static BOOL | get_dc_name_via_netlogon (const struct winbindd_domain *domain, fstring dcname, struct in_addr *dc_ip) |
static NTSTATUS | get_trust_creds (const struct winbindd_domain *domain, char **machine_password, char **machine_account, char **machine_krb5_principal) |
Helper function to assemble trust password and account name | |
static NTSTATUS | cm_prepare_connection (const struct winbindd_domain *domain, const int sockfd, const char *controller, struct cli_state **cli, BOOL *retry) |
static BOOL | add_one_dc_unique (TALLOC_CTX *mem_ctx, const char *domain_name, const char *dcname, struct in_addr ip, struct dc_name_ip **dcs, int *num) |
static BOOL | add_sockaddr_to_array (TALLOC_CTX *mem_ctx, struct in_addr ip, uint16 port, struct sockaddr_in **addrs, int *num) |
static void | mailslot_name (struct in_addr dc_ip, fstring name) |
static BOOL | send_getdc_request (struct in_addr dc_ip, const char *domain_name, const DOM_SID *sid) |
static BOOL | receive_getdc_response (struct in_addr dc_ip, const char *domain_name, fstring dc_name) |
static BOOL | dcip_to_name (const struct winbindd_domain *domain, struct in_addr ip, fstring name) |
static BOOL | find_new_dc (TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain, fstring dcname, struct sockaddr_in *addr, int *fd) |
static NTSTATUS | cm_open_connection (struct winbindd_domain *domain, struct winbindd_cm_conn *new_conn) |
void | invalidate_cm_connection (struct winbindd_cm_conn *conn) |
void | close_conns_after_fork (void) |
static BOOL | connection_ok (struct winbindd_domain *domain) |
NTSTATUS | init_dc_connection (struct winbindd_domain *domain) |
static BOOL | cm_get_schannel_dcinfo (struct winbindd_domain *domain, struct dcinfo **ppdc) |
NTSTATUS | cm_connect_sam (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, struct rpc_pipe_client **cli, POLICY_HND *sam_handle) |
NTSTATUS | cm_connect_lsa (struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, struct rpc_pipe_client **cli, POLICY_HND *lsa_policy) |
NTSTATUS | cm_connect_netlogon (struct winbindd_domain *domain, struct rpc_pipe_client **cli) |
変数 | |
winbindd_methods | reconnect_methods |
BOOL | override_logfile |
static NTSTATUS init_dc_connection_network | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 1543 行で定義されています。
参照先 cm_open_connection()・winbindd_domain::conn・connection_ok()・winbindd_domain::initialized・winbindd_domain::internal・invalidate_cm_connection()・result・set_dc_type_and_flags().
参照元 init_dc_connection().
01544 { 01545 NTSTATUS result; 01546 01547 /* Internal connections never use the network. */ 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 }
static void set_dc_type_and_flags | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 1589 行で定義されています。
参照先 DS_DOMINFO_CTR::basic・cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・connection_ok()・rpc_pipe_client::domain・domain_name・DSROLE_PRIMARY_DOMAIN_INFO_BASIC::flags・cli_state::mem_ctx・nt_errstr()・pol・result・rpccli_ds_getprimarydominfo()・rpccli_lsa_open_policy()・rpccli_lsa_open_policy2()・rpccli_lsa_query_info_policy()・rpccli_lsa_query_info_policy2()・sid_copy()・talloc_init().
参照元 init_dc_connection_network().
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 /* if this is just a non-AD domain we need to continue 01619 * identifying so that we can in the end return with 01620 * domain->initialized = True - gd */ 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 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for 01636 * every opcode on the LSARPC_DS pipe, continue with 01637 * no_lsarpc_ds mode here as well to get domain->initialized 01638 * set - gd */ 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 /* This particular query is exactly what Win2k clients use 01678 to determine that the DC is active directory */ 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 }
static BOOL get_dcs | ( | TALLOC_CTX * | mem_ctx, | |
const struct winbindd_domain * | domain, | |||
struct dc_name_ip ** | dcs, | |||
int * | num_dcs | |||
) | [static] |
winbindd_cm.c の 1155 行で定義されています。
参照先 add_one_dc_unique()・winbindd_domain::alt_name・get_dc_name()・get_dc_name_via_netlogon()・get_sorted_dc_list()・lp_workgroup()・winbindd_domain::name・SEC_ADS・sitename_fetch()・strequal().
参照元 find_new_dc()・fork_child_dc_connect().
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 /* We need to make sure we know the local site before 01181 doing any DNS queries, as this will restrict the 01182 get_sorted_dc_list() call below to only fetching 01183 DNS records for the correct site. */ 01184 01185 /* Find any DC to get the site record. 01186 We deliberately don't care about the 01187 return here. */ 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 /* Do the site-specific AD dns lookup first. */ 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 /* Now we add DCs from the main AD dns lookup. */ 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 /* try standard netbios queries if no ADS */ 01217 01218 if (iplist_size==0) { 01219 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size, False); 01220 } 01221 01222 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */ 01223 01224 /* now add to the dc array. We'll wait until the last minute 01225 to look up the name of the DC. But we fill in the char* for 01226 the ip now in to make the failed connection cache work */ 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 }
static void msg_failed_to_go_online | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
winbindd_cm.c の 85 行で定義されています。
参照先 domain_list()・winbindd_domain::internal・winbindd_domain::name・winbindd_domain::next・winbindd_domain::online・strequal().
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 /* We're already online, ignore. */ 00105 DEBUG(5,("msg_fail_to_go_online: domain %s " 00106 "already online.\n", domainname)); 00107 continue; 00108 } 00109 00110 /* Reschedule the online check. */ 00111 set_domain_offline(domain); 00112 break; 00113 } 00114 } 00115 }
static void msg_try_to_go_online | ( | int | msg_type, | |
struct process_id | src, | |||
void * | buf, | |||
size_t | len, | |||
void * | private_data | |||
) | [static] |
winbindd_cm.c の 121 行で定義されています。
参照先 domain_list()・winbindd_domain::internal・winbindd_domain::name・winbindd_domain::next・winbindd_domain::online・strequal().
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 /* We're already online, ignore. */ 00142 DEBUG(5,("msg_try_to_go_online: domain %s " 00143 "already online.\n", domainname)); 00144 continue; 00145 } 00146 00147 /* This call takes care of setting the online 00148 flag to true if we connected, or re-adding 00149 the offline handler if false. Bypasses online 00150 check so always does network calls. */ 00151 00152 init_dc_connection_network(domain); 00153 break; 00154 } 00155 } 00156 }
static BOOL fork_child_dc_connect | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 164 行で定義されています。
参照先 CatchChild()・close_conns_after_fork()・dyn_LOGFILEBASE・errno・get_dcs()・message_block()・message_register()・message_send_pid()・message_unblock()・msg_failed_to_go_online()・msg_try_to_go_online()・winbindd_domain::name・override_logfile・pid_to_procid()・pstr_sprintf()・reopen_logs()・strerror()・sys_fork()・sys_getpid()・talloc_init()・tdb_reopen_all().
参照元 check_domain_online_handler().
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 /* Stop zombies */ 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 /* Parent */ 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 /* Child. */ 00196 00197 /* Leave messages blocked - we will never process one. */ 00198 00199 /* tdb needs special fork handling */ 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 /* Still offline ? Can't find DC's. */ 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 /* We got a DC. Send a message to our parent to get it to 00229 try and do the same. */ 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 }
static void check_domain_online_handler | ( | struct event_context * | ctx, | |
struct timed_event * | te, | |||
const struct timeval * | now, | |||
void * | private_data | |||
) | [static] |
winbindd_cm.c の 241 行で定義されています。
参照先 winbindd_domain::check_online_event・fork_child_dc_connect()・get_global_winbindd_state_offline()・winbindd_domain::name・winbindd_domain::startup・winbindd_domain::startup_time.
参照元 set_domain_offline()・set_domain_online_request().
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 /* Are we still in "startup" mode ? */ 00255 00256 if (domain->startup && (now->tv_sec > domain->startup_time + 30)) { 00257 /* No longer in "startup" mode. */ 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 /* We've been told to stay offline, so stay 00264 that way. */ 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 /* Fork a child to test if it can contact a DC. 00273 If it can then send ourselves a message to 00274 cause a reconnect. */ 00275 00276 fork_child_dc_connect(domain); 00277 }
static void calc_new_online_timeout_check | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 283 行で定義されています。
参照先 winbindd_domain::check_online_timeout・winbindd_domain::startup.
参照元 set_domain_offline().
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 }
void set_domain_offline | ( | struct winbindd_domain * | domain | ) |
winbindd_cm.c の 299 行で定義されています。
参照先 calc_new_online_timeout_check()・check_domain_online_handler()・winbindd_domain::check_online_event・winbindd_domain::check_online_timeout・event_add_timed()・get_global_winbindd_state_offline()・winbindd_domain::initialized・winbindd_domain::internal・winbindd_domain::name・winbindd_domain::online・smb_panic()・timeval_current_ofs()・winbind_event_context().
参照元 child_msg_offline()・cm_open_connection()・winbind_msg_offline()・winbindd_dual_pam_auth().
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 /* Offline domains are always initialized. They're 00315 re-initialized when they go back online. */ 00316 00317 domain->initialized = True; 00318 00319 /* We only add the timeout handler that checks and 00320 allows us to go back online when we've not 00321 been told to remain offline. */ 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 /* If we're in statup mode, check again in 10 seconds, not in 00330 lp_winbind_cache_time() seconds (which is 5 mins by default). */ 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 /* The above *has* to succeed for winbindd to work. */ 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 }
static void set_domain_online | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 354 行で定義されています。
参照先 winbindd_domain::backend・winbindd_domain::check_online_event・winbindd_domain::check_online_timeout・get_global_winbindd_state_offline()・GetTimeOfDay()・winbindd_domain::initialized・winbindd_domain::internal・message_deregister()・winbindd_domain::name・winbindd_domain::online・reconnect_methods・set_event_dispatch_time()・winbindd_domain::startup・winbind_event_context().
参照元 cm_open_connection().
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 /* If we are waiting to get a krb5 ticket, trigger immediately. */ 00374 GetTimeOfDay(&now); 00375 set_event_dispatch_time(winbind_event_context(), 00376 "krb5_ticket_gain_handler", now); 00377 00378 /* Ok, we're out of any startup mode now... */ 00379 domain->startup = False; 00380 00381 if (domain->online == False) { 00382 /* We were offline - now we're online. We default to 00383 using the MS-RPC backend if we started offline, 00384 and if we're going online for the first time we 00385 should really re-initialize the backends and the 00386 checks to see if we're talking to an AD or NT domain. 00387 */ 00388 00389 domain->initialized = False; 00390 00391 /* 'reconnect_methods' is the MS-RPC backend. */ 00392 if (domain->backend == &reconnect_methods) { 00393 domain->backend = NULL; 00394 } 00395 } 00396 00397 /* Ensure we have no online timeout checks. */ 00398 domain->check_online_timeout = 0; 00399 TALLOC_FREE(domain->check_online_event); 00400 00401 /* Ensure we ignore any pending child messages. */ 00402 message_deregister(MSG_WINBIND_TRY_TO_GO_ONLINE); 00403 message_deregister(MSG_WINBIND_FAILED_TO_GO_ONLINE); 00404 00405 domain->online = True; 00406 }
void set_domain_online_request | ( | struct winbindd_domain * | domain | ) |
winbindd_cm.c の 412 行で定義されています。
参照先 check_domain_online_handler()・winbindd_domain::check_online_event・event_add_timed()・get_global_winbindd_state_offline()・GetTimeOfDay()・winbindd_domain::name・set_event_dispatch_time()・smb_panic()・winbindd_domain::startup・winbindd_domain::startup_time・timeval_current_ofs()・winbind_event_context().
参照元 child_msg_online()・init_domain_list()・winbind_msg_online().
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 /* We've been told it's safe to go online and 00426 try and connect to a DC. But I don't believe it 00427 because network manager seems to lie. 00428 Wait at least 5 seconds. Heuristics suck... */ 00429 00430 if (!domain->check_online_event) { 00431 /* If we've come from being globally offline we 00432 don't have a check online event handler set. 00433 We need to add one now we're trying to go 00434 back online. */ 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 /* The above *has* to succeed for winbindd to work. */ 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 /* Go into "startup" mode again. */ 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 }
void winbind_add_failed_connection_entry | ( | const struct winbindd_domain * | domain, | |
const char * | server, | |||
NTSTATUS | result | |||
) |
winbindd_cm.c の 467 行で定義されています。
参照先 add_failed_connection_entry()・winbindd_domain::alt_name・winbindd_domain::name・result・saf_delete().
参照元 cm_open_connection()・cm_prepare_connection()・find_new_dc().
00470 { 00471 add_failed_connection_entry(domain->name, server, result); 00472 /* If this was the saf name for the last thing we talked to, 00473 remove it. */ 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 }
static void cm_get_ipc_userpass | ( | char ** | username, | |
char ** | domain, | |||
char ** | password | |||
) | [static] |
winbindd_cm.c の 489 行で定義されています。
参照先 lp_workgroup()・secrets_fetch()・smb_xstrdup().
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 }
static BOOL get_dc_name_via_netlogon | ( | const struct winbindd_domain * | domain, | |
fstring | dcname, | |||
struct in_addr * | dc_ip | |||
) | [static] |
winbindd_cm.c の 514 行で定義されています。
参照先 rpc_pipe_client::cli・cli_set_timeout()・cm_connect_netlogon()・winbindd_domain::dcname・rpc_pipe_client::domain・dos_errstr()・find_our_domain()・rpc_pipe_client::mem_ctx・resolve_name()・result・rpccli_netlogon_getanydcname()・talloc_init().
参照元 get_dcs().
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 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the 00527 * moment.... */ 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 /* This call can take a long time - allow the server to time out. 00550 35 seconds should do it. */ 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 /* And restore our original timeout. */ 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 /* cli_netlogon_getanydcname gives us a name with \\ */ 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 }
static NTSTATUS get_trust_creds | ( | const struct winbindd_domain * | domain, | |
char ** | machine_password, | |||
char ** | machine_account, | |||
char ** | machine_krb5_principal | |||
) | [static] |
Helper function to assemble trust password and account name
winbindd_cm.c の 591 行で定義されています。
参照先 asprintf()・rpc_pipe_client::domain・get_trust_pw_clear()・strupper_m().
参照元 cm_connect_sam()・cm_prepare_connection().
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 /* For now assume our machine account only exists in our domain */ 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 }
static NTSTATUS cm_prepare_connection | ( | const struct winbindd_domain * | domain, | |
const int | sockfd, | |||
const char * | controller, | |||
struct cli_state ** | cli, | |||
BOOL * | retry | |||
) | [static] |
winbindd_cm.c の 631 行で定義されています。
参照先 ads_errstr()・ads_ntstatus()・winbindd_domain::alt_name・cli・cli_init_creds()・cli_initialise()・cli_negprot()・cli_nt_error()・cli_send_tconX()・cli_session_request()・cli_session_setup()・cli_session_setup_spnego()・cli_setup_signing_state()・cli_shutdown()・cm_get_ipc_userpass()・errno・get_trust_creds()・global_myname・is_trusted_domain_situation()・lp_workgroup()・make_nmb_name()・winbindd_domain::name・nt_errstr()・PROTOCOL_NT1・result・saf_store()・SEC_ADS・secrets_named_mutex()・secrets_named_mutex_release()・strerror()・winbind_add_failed_connection_entry().
参照元 cm_open_connection().
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; /* 10 seconds */ 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 /* Try a krb5 session */ 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 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ 00749 cli_init_creds(*cli, machine_account, domain->name, machine_password); 00750 goto session_setup_done; 00751 } 00752 } 00753 00754 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */ 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 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ 00774 cli_init_creds(*cli, machine_account, domain->name, machine_password); 00775 goto session_setup_done; 00776 } 00777 } 00778 00779 /* Fall back to non-kerberos session setup with auth_user */ 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 /* Only try authenticated if we have a username */ 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 /* Successful logon with given username. */ 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 /* Fall back to anonymous connection, this might fail later */ 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 /* We can't session setup */ 00825 00826 goto done; 00827 00828 session_setup_done: 00829 00830 /* cache the server name for later connections */ 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 /* set the domain if empty; needed for schannel connections */ 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 }
static BOOL add_one_dc_unique | ( | TALLOC_CTX * | mem_ctx, | |
const char * | domain_name, | |||
const char * | dcname, | |||
struct in_addr | ip, | |||
struct dc_name_ip ** | dcs, | |||
int * | num | |||
) | [static] |
winbindd_cm.c の 883 行で定義されています。
参照先 check_negative_conn_cache()・name.
参照元 get_dcs().
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 }
static BOOL add_sockaddr_to_array | ( | TALLOC_CTX * | mem_ctx, | |
struct in_addr | ip, | |||
uint16 | port, | |||
struct sockaddr_in ** | addrs, | |||
int * | num | |||
) | [static] |
winbindd_cm.c の 903 行で定義されています。
参照元 cm_open_connection()・find_new_dc().
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 }
static void mailslot_name | ( | struct in_addr | dc_ip, | |
fstring | name | |||
) | [static] |
winbindd_cm.c の 922 行で定義されています。
参照先 fstr_sprintf().
参照元 receive_getdc_response()・send_getdc_request().
00923 { 00924 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr); 00925 }
static BOOL send_getdc_request | ( | struct in_addr | dc_ip, | |
const char * | domain_name, | |||
const DOM_SID * | sid | |||
) | [static] |
winbindd_cm.c の 927 行で定義されています。
参照先 cli_send_mailslot()・dos_PutUniCode()・fstr_sprintf()・global_myname・mailslot_name()・sid_linearize()・sid_size().
参照元 dcip_to_name().
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); /* Count pointer ... */ 00946 p++; 00947 00948 SIVAL(p, 0, 0); /* The sender's token ... */ 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 }
static BOOL receive_getdc_response | ( | struct in_addr | dc_ip, | |
const char * | domain_name, | |||
fstring | dc_name | |||
) | [static] |
winbindd_cm.c の 997 行で定義されています。
参照先 buf・DGRAM_PACKET・len・mailslot_name()・packet・pull_ucs2()・receive_unexpected()・skip_unibuf()・strequal().
参照元 dcip_to_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 /* 70 is a completely arbitrary value to make sure 01023 the SVAL below does not read uninitialized memory */ 01024 DEBUG(3, ("GetDC got short response\n")); 01025 return False; 01026 } 01027 01028 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */ 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 }
static BOOL dcip_to_name | ( | const struct winbindd_domain * | domain, | |
struct in_addr | ip, | |||
fstring | name | |||
) | [static] |
winbindd_cm.c の 1069 行で定義されています。
参照先 ads_closest_dc()・ads_destroy()・ads_init()・ads_try_connect()・winbindd_domain::alt_name・ADS_STRUCT::auth・ADS_STRUCT::config・create_local_private_krb5_conf_for_domain()・ADS_STRUCT::flags・ip_service::ip・ADS_STRUCT::ldap_server_name・winbindd_domain::name・namecache_store()・ip_service::port・winbindd_domain::primary・receive_getdc_response()・saf_store()・SEC_ADS・send_getdc_request()・winbindd_domain::sid・sitename_fetch()・smb_msleep().
参照元 cm_open_connection()・find_new_dc().
01070 { 01071 struct ip_service ip_list; 01072 01073 ip_list.ip = ip; 01074 ip_list.port = 0; 01075 01076 #ifdef WITH_ADS 01077 /* For active directory servers, try to get the ldap server name. 01078 None of these failures should be considered critical for now */ 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 /* We got a cldap packet. */ 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 /* We're going to use this KDC for this realm/domain. 01098 If we are using sites, then force the krb5 libs 01099 to use this KDC. */ 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 /* use an off site KDC */ 01109 create_local_private_krb5_conf_for_domain(domain->alt_name, 01110 domain->name, 01111 NULL, 01112 ip); 01113 } 01114 /* Ensure we contact this DC also. */ 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 /* try GETDC requests next */ 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 /* try node status request */ 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 }
static BOOL find_new_dc | ( | TALLOC_CTX * | mem_ctx, | |
const struct winbindd_domain * | domain, | |||
fstring | dcname, | |||
struct sockaddr_in * | addr, | |||
int * | fd | |||
) | [static] |
winbindd_cm.c の 1238 行で定義されています。
参照先 add_sockaddr_to_array()・add_string_to_array()・dcip_to_name()・errno・get_dcs()・is_ipaddress()・winbindd_domain::name・name・open_any_socket_out()・strerror()・winbind_add_failed_connection_entry().
参照元 cm_open_connection().
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 /* 5 second timeout. */ 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 /* Ok, we've got a name for the DC */ 01303 fstrcpy(dcname, dcnames[fd_index]); 01304 return True; 01305 } 01306 01307 /* Try to figure out the name */ 01308 if (dcip_to_name( domain, addr->sin_addr, dcname )) { 01309 return True; 01310 } 01311 01312 /* We can not continue without the DC's name */ 01313 winbind_add_failed_connection_entry(domain, dcs[fd_index].name, 01314 NT_STATUS_UNSUCCESSFUL); 01315 01316 /* Throw away all arrays as we're doing this again. */ 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 }
static NTSTATUS cm_open_connection | ( | struct winbindd_domain * | domain, | |
struct winbindd_cm_conn * | new_conn | |||
) | [static] |
winbindd_cm.c の 1331 行で定義されています。
参照先 add_sockaddr_to_array()・check_negative_conn_cache()・winbindd_cm_conn::cli・cm_prepare_connection()・winbindd_domain::dcaddr・dcip_to_name()・winbindd_domain::dcname・fd・find_new_dc()・interpret_addr2()・is_ipaddress()・winbindd_domain::name・winbindd_domain::online・open_any_socket_out()・resolve_name()・result・saf_fetch()・set_domain_offline()・set_domain_online()・set_global_winbindd_state_offline()・set_global_winbindd_state_online()・talloc_init()・winbind_add_failed_connection_entry().
参照元 init_dc_connection_network().
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 /* we have to check the server affinity cache here since 01346 later we selecte a DC based on response time and not preference */ 01347 01348 /* Check the negative connection cache 01349 before talking to it. It going down may have 01350 triggered the reconnection. */ 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 /* convert an ip address to a name */ 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 /* 5 second timeout. */ 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 /* This is the one place where we will 01416 set the global winbindd offline state 01417 to true, if a "WINBINDD_OFFLINE" entry 01418 is found in the winbindd cache. */ 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 /* We're changing state from offline to online. */ 01435 set_global_winbindd_state_online(); 01436 } 01437 set_domain_online(domain); 01438 } else { 01439 /* Ensure we setup the retry handler. */ 01440 set_domain_offline(domain); 01441 } 01442 01443 talloc_destroy(mem_ctx); 01444 return result; 01445 }
void invalidate_cm_connection | ( | struct winbindd_cm_conn * | conn | ) |
winbindd_cm.c の 1449 行で定義されています。
参照先 winbindd_cm_conn::cli・cli_rpc_pipe_close()・cli_set_timeout()・cli_shutdown()・winbindd_cm_conn::lsa_pipe・winbindd_cm_conn::netlogon_pipe・winbindd_cm_conn::samr_pipe.
参照元 cm_connect_lsa()・cm_connect_sam()・init_dc_connection_network()・query_user_list()・winbindd_dual_check_machine_acct()・winbindd_dual_pam_auth_crap()・winbindd_dual_pam_auth_samlogon().
01450 { 01451 /* We're closing down a possibly dead 01452 connection. Don't have impossibly long (10s) timeouts. */ 01453 01454 if (conn->cli) { 01455 cli_set_timeout(conn->cli, 1000); /* 1 second. */ 01456 } 01457 01458 if (conn->samr_pipe != NULL) { 01459 if (!cli_rpc_pipe_close(conn->samr_pipe)) { 01460 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ 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 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ 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 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ 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 }
void close_conns_after_fork | ( | void | ) |
winbindd_cm.c の 1495 行で定義されています。
参照先 winbindd_cm_conn::cli・winbindd_domain::conn・domain_list()・cli_state::fd・winbindd_domain::next.
参照元 fork_child_dc_connect()・fork_domain_child().
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 }
static BOOL connection_ok | ( | struct winbindd_domain * | domain | ) | [static] |
winbindd_cm.c の 1511 行で定義されています。
参照先 winbindd_cm_conn::cli・winbindd_domain::conn・winbindd_domain::dcname・cli_state::fd・cli_state::initialised・winbindd_domain::name・winbindd_domain::online.
参照元 init_dc_connection_network()・set_dc_type_and_flags().
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 }
NTSTATUS init_dc_connection | ( | struct winbindd_domain * | domain | ) |
winbindd_cm.c の 1571 行で定義されています。
参照先 init_dc_connection_network()・winbindd_domain::initialized・winbindd_domain::online.
参照元 cm_connect_lsa()・cm_connect_netlogon()・cm_connect_sam()・find_domain_from_name()・find_domain_from_sid()・get_cache()・init_child_recv()・winbindd_dual_init_connection()・winbindd_dual_pam_auth()・winbindd_dual_pam_auth_kerberos().
01572 { 01573 if (domain->initialized && !domain->online) { 01574 /* We check for online status elsewhere. */ 01575 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 01576 } 01577 01578 return init_dc_connection_network(domain); 01579 }
static BOOL cm_get_schannel_dcinfo | ( | struct winbindd_domain * | domain, | |
struct dcinfo ** | ppdc | |||
) | [static] |
winbindd_cm.c の 1736 行で定義されています。
参照先 cm_connect_netlogon()・rpc_pipe_client::domain・result.
参照元 cm_connect_lsa()・cm_connect_sam().
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 /* Return a pointer to the struct dcinfo from the 01752 netlogon pipe. */ 01753 01754 *ppdc = domain->conn.netlogon_pipe->dc; 01755 return True; 01756 }
NTSTATUS cm_connect_sam | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
struct rpc_pipe_client ** | cli, | |||
POLICY_HND * | sam_handle | |||
) |
winbindd_cm.c の 1758 行で定義されています。
参照先 cli・winbindd_cm_conn::cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・cli_rpc_pipe_open_schannel_with_key()・cli_rpc_pipe_open_spnego_ntlmssp()・cm_get_schannel_dcinfo()・cli_state::domain・dcinfo::domain・domain_name・get_trust_creds()・init_dc_connection()・invalidate_cm_connection()・nt_errstr()・PIPE_AUTH_LEVEL_PRIVACY・cli_state::pwd・pwd_get_cleartext()・result・rpccli_samr_connect()・rpccli_samr_open_domain()・winbindd_cm_conn::sam_connect_handle・winbindd_cm_conn::sam_domain_handle・winbindd_cm_conn::samr_pipe・cli_state::user_name.
参照元 enum_dom_groups()・enum_local_groups()・lookup_groupmem()・lookup_usergroups()・msrpc_lockout_policy()・msrpc_lookup_useraliases()・msrpc_password_policy()・query_user()・query_user_list()・sequence_number()・winbindd_dual_pam_auth_samlogon()・winbindd_dual_pam_chauthtok()・winbindd_dual_pam_chng_pswd_auth_crap().
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 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated 01782 * sign and sealed pipe using the machine account password by 01783 * preference. If we can't - try schannel, if that fails, try 01784 * anonymous. 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 /* We have an authenticated connection. Use a NTLMSSP SPNEGO 01812 authenticated SAMR pipe with sign & seal. */ 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 /* Fall back to schannel if it's a W2K pre-SP1 box. */ 01848 01849 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) { 01850 /* If this call fails - conn->cli can now be NULL ! */ 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 /* Finally fall back to anonymous. */ 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 }
NTSTATUS cm_connect_lsa | ( | struct winbindd_domain * | domain, | |
TALLOC_CTX * | mem_ctx, | |||
struct rpc_pipe_client ** | cli, | |||
POLICY_HND * | lsa_policy | |||
) |
winbindd_cm.c の 1922 行で定義されています。
参照先 cli・winbindd_cm_conn::cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・cli_rpc_pipe_open_schannel_with_key()・cli_rpc_pipe_open_spnego_ntlmssp()・cm_get_schannel_dcinfo()・cli_state::domain・dcinfo::domain・init_dc_connection()・invalidate_cm_connection()・winbindd_cm_conn::lsa_pipe・winbindd_cm_conn::lsa_policy・nt_errstr()・PIPE_AUTH_LEVEL_PRIVACY・cli_state::pwd・pwd_get_cleartext()・result・rpccli_lsa_open_policy()・cli_state::user_name.
参照元 msrpc_name_to_sid()・msrpc_rids_to_names()・msrpc_sid_to_name()・trusted_domains().
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 /* We have an authenticated connection. Use a NTLMSSP SPNEGO 01950 * authenticated LSA pipe with sign & seal. */ 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 /* Fall back to schannel if it's a W2K pre-SP1 box. */ 01983 01984 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) { 01985 /* If this call fails - conn->cli can now be NULL ! */ 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 }
NTSTATUS cm_connect_netlogon | ( | struct winbindd_domain * | domain, | |
struct rpc_pipe_client ** | cli | |||
) |
winbindd_cm.c の 2043 行で定義されています。
参照先 winbindd_cm_conn::cli・cli・cli_rpc_pipe_close()・cli_rpc_pipe_open_noauth()・cli_rpc_pipe_open_schannel_with_key()・rpc_pipe_client::dc・rpc_pipe_client::domain・get_trust_pw_hash()・global_myname・init_dc_connection()・winbindd_cm_conn::netlogon_pipe・nt_errstr()・PIPE_AUTH_LEVEL_PRIVACY・result・rpccli_netlogon_setup_creds().
参照元 cm_get_schannel_dcinfo()・get_dc_name_via_netlogon()・trusted_domains()・winbindd_dual_check_machine_acct()・winbindd_dual_getdcname()・winbindd_dual_pam_auth_crap()・winbindd_dual_pam_auth_samlogon().
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 /* Clear the schannel request bit and drop down */ 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, /* server name. */ 02095 domain->name, /* domain name */ 02096 global_myname(), /* client name */ 02097 account_name, /* machine account */ 02098 mach_pwd, /* machine password */ 02099 sec_chan_type, /* from get_trust_pw */ 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 /* We're done - just keep the existing connection to NETLOGON 02118 * open */ 02119 conn->netlogon_pipe = netlogon_pipe; 02120 *cli = conn->netlogon_pipe; 02121 return NT_STATUS_OK; 02122 } 02123 02124 /* Using the credentials from the first pipe, open a signed and sealed 02125 second netlogon pipe. The session key is stored in the schannel 02126 part of the new pipe auth struct. 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 /* We can now close the initial netlogon pipe. */ 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 /* make sure we return something besides OK */ 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 }
winbindd_reconnect.c の 300 行で定義されています。