Changeset 232 for branches/samba-3.2.x/source/winbindd
- Timestamp:
- May 27, 2009, 9:09:42 AM (16 years ago)
- Location:
- branches/samba-3.2.x/source/winbindd
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.2.x/source/winbindd/winbindd.c
r228 r232 171 171 } 172 172 173 static bool do_sigterm;173 static SIG_ATOMIC_T do_sigterm = 0; 174 174 175 175 static void termination_handler(int signum) 176 176 { 177 do_sigterm = True;177 do_sigterm = 1; 178 178 sys_select_signal(signum); 179 179 } 180 180 181 static bool do_sigusr2;181 static SIG_ATOMIC_T do_sigusr2 = 0; 182 182 183 183 static void sigusr2_handler(int signum) 184 184 { 185 do_sigusr2 = True;185 do_sigusr2 = 1; 186 186 sys_select_signal(SIGUSR2); 187 187 } 188 188 189 static bool do_sighup;189 static SIG_ATOMIC_T do_sighup = 0; 190 190 191 191 static void sighup_handler(int signum) 192 192 { 193 do_sighup = True;193 do_sighup = 1; 194 194 sys_select_signal(SIGHUP); 195 195 } 196 196 197 static bool do_sigchld;197 static SIG_ATOMIC_T do_sigchld = 0; 198 198 199 199 static void sigchld_handler(int signum) 200 200 { 201 do_sigchld = True;201 do_sigchld = 1; 202 202 sys_select_signal(SIGCHLD); 203 203 } … … 222 222 DATA_BLOB *data) 223 223 { 224 do_sigterm = True;224 do_sigterm = 1; 225 225 } 226 226 … … 747 747 { 748 748 char c = 0; 749 int nwritten; 749 750 750 751 /* It's a dead client - hold a funeral */ … … 755 756 756 757 /* tell client, we are closing ... */ 757 write(state->sock, &c, sizeof(c)); 758 nwritten = write(state->sock, &c, sizeof(c)); 759 if (nwritten == -1) { 760 DEBUG(2, ("final write to client failed: %s\n", 761 strerror(errno))); 762 } 758 763 759 764 /* Close socket */ … … 823 828 reload_services_file(logfile); 824 829 825 do_sighup = False;830 do_sighup = 0; 826 831 } 827 832 } … … 998 1003 if (do_sigusr2) { 999 1004 print_winbindd_status(); 1000 do_sigusr2 = False;1005 do_sigusr2 = 0; 1001 1006 } 1002 1007 … … 1004 1009 pid_t pid; 1005 1010 1006 do_sigchld = False;1011 do_sigchld = 0; 1007 1012 1008 1013 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) { … … 1218 1223 TimeInit(); 1219 1224 1220 if (!reinit_after_fork(winbind_messaging_context(), false)) { 1225 /* Don't use winbindd_reinit_after_fork here as 1226 * we're just starting up and haven't created any 1227 * winbindd-specific resources we must free yet. JRA. 1228 */ 1229 1230 if (!reinit_after_fork(winbind_messaging_context(), 1231 winbind_event_context(), false)) { 1221 1232 DEBUG(0,("reinit_after_fork() failed\n")); 1222 1233 exit(1); -
branches/samba-3.2.x/source/winbindd/winbindd_cache.c
r204 r232 487 487 488 488 /* see if we have to refetch the domain sequence number */ 489 if (!force && (time_diff < cache_time)) { 489 if (!force && (time_diff < cache_time) && 490 (domain->sequence_number != DOM_SEQUENCE_NONE) && 491 NT_STATUS_IS_OK(domain->last_status)) { 490 492 DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name)); 491 493 goto done; … … 496 498 497 499 status = fetch_cache_seqnum( domain, t ); 498 if ( NT_STATUS_IS_OK(status) ) 499 goto done; 500 if (NT_STATUS_IS_OK(status) && 501 (domain->sequence_number != DOM_SEQUENCE_NONE) && 502 NT_STATUS_IS_OK(domain->last_status)) { 503 goto done; 504 } 500 505 501 506 /* important! make sure that we know if this is a native -
branches/samba-3.2.x/source/winbindd/winbindd_cm.c
r228 r232 174 174 pid_t child_pid; 175 175 pid_t parent_pid = sys_getpid(); 176 char *lfile = NULL; 176 177 177 178 /* Stop zombies */ … … 200 201 /* Leave messages blocked - we will never process one. */ 201 202 202 if (!reinit_after_fork(winbind_messaging_context(), true)) { 203 if (!override_logfile) { 204 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) { 205 DEBUG(0, ("fork_child_dc_connect: out of memory!\n")); 206 _exit(1); 207 } 208 } 209 210 if (!winbindd_reinit_after_fork(lfile)) { 203 211 DEBUG(0,("reinit_after_fork() failed\n")); 204 _exit(0); 205 } 206 207 close_conns_after_fork(); 208 209 if (!override_logfile) { 210 char *logfile; 211 if (asprintf(&logfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) > 0) { 212 lp_set_logfile(logfile); 213 SAFE_FREE(logfile); 214 reopen_logs(); 215 } 216 } 212 messaging_send_buf(winbind_messaging_context(), 213 pid_to_procid(parent_pid), 214 MSG_WINBIND_FAILED_TO_GO_ONLINE, 215 (uint8 *)domain->name, 216 strlen(domain->name) + 1); 217 _exit(1); 218 } 219 220 SAFE_FREE(lfile); 217 221 218 222 mem_ctx = talloc_init("fork_child_dc_connect"); 219 223 if (!mem_ctx) { 220 224 DEBUG(0,("talloc_init failed.\n")); 221 _exit( 0);225 _exit(1); 222 226 } 223 227 … … 378 382 ****************************************************************/ 379 383 384 void ccache_regain_all_now(void); 385 380 386 static void set_domain_online(struct winbindd_domain *domain) 381 387 { 382 struct timeval now;383 388 384 389 DEBUG(10,("set_domain_online: called for domain %s\n", … … 400 405 401 406 /* If we are waiting to get a krb5 ticket, trigger immediately. */ 402 GetTimeOfDay(&now); 403 set_event_dispatch_time(winbind_event_context(), 404 "krb5_ticket_gain_handler", now); 405 407 ccache_regain_all_now(); 408 406 409 /* Ok, we're out of any startup mode now... */ 407 410 domain->startup = False; … … 475 478 Wait at least 5 seconds. Heuristics suck... */ 476 479 480 GetTimeOfDay(&tev); 481 482 /* Go into "startup" mode again. */ 483 domain->startup_time = tev.tv_sec; 484 domain->startup = True; 485 486 tev.tv_sec += 5; 477 487 if (!domain->check_online_event) { 478 488 /* If we've come from being globally offline we … … 480 490 We need to add one now we're trying to go 481 491 back online. */ 482 483 492 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n", 484 493 domain->name )); 485 486 domain->check_online_event = event_add_timed(winbind_event_context(), 487 NULL, 488 timeval_current_ofs(5, 0), 489 "check_domain_online_handler", 490 check_domain_online_handler, 491 domain); 492 493 /* The above *has* to succeed for winbindd to work. */ 494 if (!domain->check_online_event) { 495 smb_panic("set_domain_online_request: failed to add online handler"); 496 } 497 } 498 499 GetTimeOfDay(&tev); 500 501 /* Go into "startup" mode again. */ 502 domain->startup_time = tev.tv_sec; 503 domain->startup = True; 504 505 tev.tv_sec += 5; 506 507 set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev); 494 } 495 496 TALLOC_FREE(domain->check_online_event); 497 498 domain->check_online_event = event_add_timed(winbind_event_context(), 499 NULL, 500 tev, 501 "check_domain_online_handler", 502 check_domain_online_handler, 503 domain); 504 505 /* The above *has* to succeed for winbindd to work. */ 506 if (!domain->check_online_event) { 507 smb_panic("set_domain_online_request: failed to add online handler"); 508 } 508 509 } 509 510 … … 613 614 &domain_info, 614 615 &werr); 615 if ( W_ERROR_IS_OK(werr)) {616 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) { 616 617 tmp = talloc_strdup( 617 618 mem_ctx, domain_info->dc_unc); -
branches/samba-3.2.x/source/winbindd/winbindd_cred_cache.c
r133 r232 35 35 36 36 static struct WINBINDD_CCACHE_ENTRY *ccache_list; 37 static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry, 38 struct timeval t); 37 39 38 40 /* The Krb5 ticket refresh handler should be scheduled … … 71 73 return i; 72 74 } 75 76 void ccache_remove_all_after_fork(void) 77 { 78 struct WINBINDD_CCACHE_ENTRY *cur; 79 cur = ccache_list; 80 while (cur) { 81 DLIST_REMOVE(ccache_list, cur); 82 TALLOC_FREE(cur->event); 83 TALLOC_FREE(cur); 84 cur = ccache_list; 85 } 86 } 87 88 static void krb5_ticket_gain_handler(struct event_context *event_ctx, 89 struct timed_event *te, 90 const struct timeval *now, 91 void *private_data); 92 static void krb5_ticket_refresh_handler(struct event_context *event_ctx, 93 struct timed_event *te, 94 const struct timeval *now, 95 void *private_data); 96 97 void ccache_regain_all_now(void) 98 { 99 struct WINBINDD_CCACHE_ENTRY *cur; 100 struct timeval t = timeval_current(); 101 102 for (cur = ccache_list; cur; cur = cur->next) { 103 struct timed_event *new_event; 104 105 /* 106 * if refresh_time is 0, we know that the 107 * the event has the krb5_ticket_gain_handler 108 */ 109 if (cur->refresh_time == 0) { 110 new_event = event_add_timed(winbind_event_context(), 111 cur, t, 112 "krb5_ticket_gain_handler", 113 krb5_ticket_gain_handler, 114 cur); 115 } else { 116 new_event = event_add_timed(winbind_event_context(), 117 cur, t, 118 "krb5_ticket_refresh_handler", 119 krb5_ticket_refresh_handler, 120 cur); 121 } 122 if (!new_event) { 123 continue; 124 } 125 126 TALLOC_FREE(cur->event); 127 cur->event = new_event; 128 } 129 return; 130 } 131 132 /**************************************************************** 133 The gain initial tikcet case is recongnized as entry->refresh_time 134 is always zero. 135 ****************************************************************/ 136 137 static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry, 138 struct timeval t) 139 { 140 entry->refresh_time = 0; 141 entry->event = event_add_timed(winbind_event_context(), entry, 142 t, 143 "krb5_ticket_gain_handler", 144 krb5_ticket_gain_handler, 145 entry); 146 } 147 73 148 74 149 /**************************************************************** … … 86 161 int ret; 87 162 time_t new_start; 163 time_t expire_time = 0; 88 164 struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr; 89 165 #endif … … 98 174 99 175 /* Kinit again if we have the user password and we can't renew the old 100 * tgt anymore */ 101 102 if ((entry->renew_until < time(NULL)) && cred_ptr && cred_ptr->pass) { 103 104 set_effective_uid(entry->uid); 105 106 ret = kerberos_kinit_password_ext(entry->principal_name, 107 cred_ptr->pass, 108 0, /* hm, can we do time correction here ? */ 109 &entry->refresh_time, 110 &entry->renew_until, 111 entry->ccname, 112 False, /* no PAC required anymore */ 113 True, 114 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, 115 NULL); 116 gain_root_privilege(); 117 118 if (ret) { 119 DEBUG(3,("krb5_ticket_refresh_handler: " 120 "could not re-kinit: %s\n", 121 error_message(ret))); 122 TALLOC_FREE(entry->event); 123 return; 124 } 125 126 DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit " 127 "for: %s in ccache: %s\n", 128 entry->principal_name, entry->ccname)); 129 176 * tgt anymore 177 * NB 178 * This happens when machine are put to sleep for a very long time. */ 179 180 if (entry->renew_until < time(NULL)) { 181 rekinit: 182 if (cred_ptr && cred_ptr->pass) { 183 184 set_effective_uid(entry->uid); 185 186 ret = kerberos_kinit_password_ext(entry->principal_name, 187 cred_ptr->pass, 188 0, /* hm, can we do time correction here ? */ 189 &entry->refresh_time, 190 &entry->renew_until, 191 entry->ccname, 192 False, /* no PAC required anymore */ 193 True, 194 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, 195 NULL); 196 gain_root_privilege(); 197 198 if (ret) { 199 DEBUG(3,("krb5_ticket_refresh_handler: " 200 "could not re-kinit: %s\n", 201 error_message(ret))); 202 /* destroy the ticket because we cannot rekinit 203 * it, ignore error here */ 204 ads_kdestroy(entry->ccname); 205 206 /* Don't break the ticket refresh chain: retry 207 * refreshing ticket sometime later when KDC is 208 * unreachable -- BoYang 209 * */ 210 211 if ((ret == KRB5_KDC_UNREACH) 212 || (ret == KRB5_REALM_CANT_RESOLVE)) { 130 213 #if defined(DEBUG_KRB5_TKT_RENEWAL) 131 new_start = time(NULL) + 30; 132 #else 133 /* The tkt should be refreshed at one-half the period 134 from now to the expiration time */ 135 new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time); 136 #endif 137 goto done; 214 new_start = time(NULL) + 30; 215 #else 216 new_start = time(NULL) + 217 MAX(30, lp_winbind_cache_time()); 218 #endif 219 /* try to regain ticket here */ 220 add_krb5_ticket_gain_handler_event(entry, 221 timeval_set(new_start, 0)); 222 return; 223 } 224 TALLOC_FREE(entry->event); 225 return; 226 } 227 228 DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit " 229 "for: %s in ccache: %s\n", 230 entry->principal_name, entry->ccname)); 231 232 #if defined(DEBUG_KRB5_TKT_RENEWAL) 233 new_start = time(NULL) + 30; 234 #else 235 /* The tkt should be refreshed at one-half the period 236 from now to the expiration time */ 237 expire_time = entry->refresh_time; 238 new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time); 239 #endif 240 goto done; 241 } else { 242 /* can this happen? 243 * No cached credentials 244 * destroy ticket and refresh chain 245 * */ 246 ads_kdestroy(entry->ccname); 247 TALLOC_FREE(entry->event); 248 return; 249 } 138 250 } 139 251 … … 147 259 new_start = time(NULL) + 30; 148 260 #else 261 expire_time = new_start; 149 262 new_start = KRB5_EVENT_REFRESH_TIME(new_start); 150 263 #endif … … 158 271 /* maybe we are beyond the renewing window */ 159 272 273 /* evil rises here, we refresh ticket failed, 274 * but the ticket might be expired. Therefore, 275 * When we refresh ticket failed, destory the 276 * ticket */ 277 278 ads_kdestroy(entry->ccname); 279 160 280 /* avoid breaking the renewal chain: retry in 161 281 * lp_winbind_cache_time() seconds when the KDC was not 162 * available right now. */ 163 164 if (ret == KRB5_KDC_UNREACH) { 282 * available right now. 283 * the return code can be KRB5_REALM_CANT_RESOLVE*/ 284 285 if ((ret == KRB5_KDC_UNREACH) 286 || (ret == KRB5_REALM_CANT_RESOLVE)) { 287 #if defined(DEBUG_KRB5_TKT_RENEWAL) 288 new_start = time(NULL) + 30; 289 #else 165 290 new_start = time(NULL) + 166 291 MAX(30, lp_winbind_cache_time()); 167 goto done; 168 } 292 #endif 293 /* ticket is destroyed here, we have to regain it 294 * if it is possible */ 295 add_krb5_ticket_gain_handler_event(entry, 296 timeval_set(new_start, 0)); 297 return; 298 } 299 300 /* This is evil, if the ticket was already expired. 301 * renew ticket function returns KRB5KRB_AP_ERR_TKT_EXPIRED. 302 * But there is still a chance that we can rekinit it. 303 * 304 * This happens when user login in online mode, and then network 305 * down or something cause winbind goes offline for a very long time, 306 * and then goes online again. ticket expired, renew failed. 307 * This happens when machine are put to sleep for a long time, 308 * but shorter than entry->renew_util. 309 * NB 310 * Looks like the KDC is reachable, we want to rekinit as soon as 311 * possible instead of waiting some time later. */ 312 if ((ret == KRB5KRB_AP_ERR_TKT_EXPIRED) 313 || (ret == KRB5_FCC_NOFILE)) goto rekinit; 169 314 170 315 return; … … 172 317 173 318 done: 174 319 /* in cases that ticket will be unrenewable soon, we don't try to renew ticket 320 * but try to regain ticket if it is possible */ 321 if (entry->renew_until && expire_time 322 && (entry->renew_until <= expire_time)) { 323 /* try to regain ticket 10 seconds beforre expiration */ 324 expire_time -= 10; 325 add_krb5_ticket_gain_handler_event(entry, timeval_set(expire_time, 0)); 326 return; 327 } 328 329 if (!entry->refresh_time) { 330 entry->refresh_time = new_start; 331 } 175 332 entry->event = event_add_timed(winbind_event_context(), entry, 176 333 timeval_set(new_start, 0), … … 240 397 "could not kinit: %s\n", 241 398 error_message(ret))); 399 /* evil. If we cannot do it, destroy any the __maybe__ 400 * __existing__ ticket */ 401 ads_kdestroy(entry->ccname); 242 402 goto retry_later; 243 403 } … … 250 410 251 411 retry_later: 252 412 413 #if defined(DEBUG_KRB5_TKT_REGAIN) 414 t = timeval_set(time(NULL) + 30, 0); 415 #else 253 416 t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0); 254 255 entry->event = event_add_timed(winbind_event_context(), 256 entry, 257 t, 258 "krb5_ticket_gain_handler", 259 krb5_ticket_gain_handler, 260 entry); 417 #endif 418 419 add_krb5_ticket_gain_handler_event(entry, t); 261 420 262 421 return; … … 270 429 #endif 271 430 431 if (!entry->refresh_time) { 432 entry->refresh_time = t.tv_sec; 433 } 272 434 entry->event = event_add_timed(winbind_event_context(), 273 435 entry, … … 332 494 struct WINBINDD_CCACHE_ENTRY *entry = NULL; 333 495 struct timeval t; 496 NTSTATUS ntret; 497 #ifdef HAVE_KRB5 498 int ret; 499 #endif 334 500 335 501 if ((username == NULL && princ_name == NULL) || … … 343 509 return NT_STATUS_NO_MORE_ENTRIES; 344 510 } 511 512 /* If it is cached login, destroy krb5 ticket 513 * to avoid surprise. */ 514 #ifdef HAVE_KRB5 515 if (postponed_request) { 516 /* ignore KRB5_FCC_NOFILE error here */ 517 ret = ads_kdestroy(ccname); 518 if (ret == KRB5_FCC_NOFILE) { 519 ret = 0; 520 } 521 if (ret) { 522 DEBUG(0, ("add_ccache_to_list: failed to destroy " 523 "user krb5 ccache %s with %s\n", ccname, 524 error_message(ret))); 525 return krb5_to_nt_status(ret); 526 } else { 527 DEBUG(10, ("add_ccache_to_list: successfully destroyed " 528 "krb5 ccache %s for user %s\n", ccname, 529 username)); 530 } 531 } 532 #endif 345 533 346 534 /* Reference count old entries */ … … 356 544 username, entry->ref_count)); 357 545 /* FIXME: in this case we still might want to have a krb5 cred 358 * event handler created - gd*/ 546 * event handler created - gd 547 * Add ticket refresh handler here */ 548 549 if (!lp_winbind_refresh_tickets() || renew_until <= 0) { 550 return NT_STATUS_OK; 551 } 552 553 if (!entry->event) { 554 if (postponed_request) { 555 t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0); 556 add_krb5_ticket_gain_handler_event(entry, t); 557 } else { 558 /* Renew at 1/2 the ticket expiration time */ 559 #if defined(DEBUG_KRB5_TKT_RENEWAL) 560 t = timeval_set(time(NULL)+30, 0); 561 #else 562 t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0); 563 #endif 564 if (!entry->refresh_time) { 565 entry->refresh_time = t.tv_sec; 566 } 567 entry->event = event_add_timed(winbind_event_context(), 568 entry, 569 t, 570 "krb5_ticket_refresh_handler", 571 krb5_ticket_refresh_handler, 572 entry); 573 } 574 575 if (!entry->event) { 576 ntret = remove_ccache(username); 577 if (!NT_STATUS_IS_OK(ntret)) { 578 DEBUG(0, ("add_ccache_to_list: Failed to remove krb5 " 579 "ccache %s for user %s\n", entry->ccname, 580 entry->username)); 581 DEBUG(0, ("add_ccache_to_list: error is %s\n", 582 nt_errstr(ntret))); 583 return ntret; 584 } 585 return NT_STATUS_NO_MEMORY; 586 } 587 588 DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n")); 589 } 590 359 591 return NT_STATUS_OK; 360 592 } … … 407 639 if (postponed_request) { 408 640 t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0); 409 entry->event = event_add_timed(winbind_event_context(), 410 entry, 411 t, 412 "krb5_ticket_gain_handler", 413 krb5_ticket_gain_handler, 414 entry); 641 add_krb5_ticket_gain_handler_event(entry, t); 415 642 } else { 416 643 /* Renew at 1/2 the ticket expiration time */ … … 420 647 t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0); 421 648 #endif 649 if (!entry->refresh_time) { 650 entry->refresh_time = t.tv_sec; 651 } 652 422 653 entry->event = event_add_timed(winbind_event_context(), 423 654 entry, -
branches/samba-3.2.x/source/winbindd/winbindd_dual.c
r228 r232 881 881 { 882 882 struct winbindd_domain *domain; 883 struct winbindd_domain *primary_domain = NULL; 883 884 const char *domainname = (const char *)data->data; 884 885 … … 893 894 return; 894 895 } 896 897 primary_domain = find_our_domain(); 895 898 896 899 /* Mark the requested domain offline. */ … … 903 906 DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name)); 904 907 set_domain_offline(domain); 908 /* we are in the trusted domain, set the primary domain 909 * offline too */ 910 if (domain != primary_domain) { 911 set_domain_offline(primary_domain); 912 } 905 913 } 906 914 } … … 916 924 { 917 925 struct winbindd_domain *domain; 926 struct winbindd_domain *primary_domain = NULL; 918 927 const char *domainname = (const char *)data->data; 919 928 … … 928 937 return; 929 938 } 939 940 primary_domain = find_our_domain(); 930 941 931 942 /* Set our global state as online. */ … … 943 954 winbindd_flush_negative_conn_cache(domain); 944 955 set_domain_online_request(domain); 956 957 /* we can be in trusted domain, which will contact primary domain 958 * we have to bring primary domain online in trusted domain process 959 * see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon() 960 * --> contact_domain = find_our_domain() 961 * */ 962 if (domain != primary_domain) { 963 winbindd_flush_negative_conn_cache(primary_domain); 964 set_domain_online_request(primary_domain); 965 } 945 966 } 946 967 } … … 1020 1041 } 1021 1042 1022 1023 static bool fork_domain_child(struct winbindd_child *child) 1024 { 1025 int fdpair[2]; 1026 struct winbindd_cli_state state; 1043 void ccache_remove_all_after_fork(void); 1044 1045 bool winbindd_reinit_after_fork(const char *logfilename) 1046 { 1027 1047 struct winbindd_domain *domain; 1028 struct winbindd_domain *primary_domain = NULL; 1029 1030 if (child->domain) { 1031 DEBUG(10, ("fork_domain_child called for domain '%s'\n", 1032 child->domain->name)); 1033 } else { 1034 DEBUG(10, ("fork_domain_child called without domain.\n")); 1035 } 1036 1037 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { 1038 DEBUG(0, ("Could not open child pipe: %s\n", 1039 strerror(errno))); 1040 return False; 1041 } 1042 1043 ZERO_STRUCT(state); 1044 state.pid = sys_getpid(); 1045 1046 child->pid = sys_fork(); 1047 1048 if (child->pid == -1) { 1049 DEBUG(0, ("Could not fork: %s\n", strerror(errno))); 1050 return False; 1051 } 1052 1053 if (child->pid != 0) { 1054 /* Parent */ 1055 close(fdpair[0]); 1056 child->next = child->prev = NULL; 1057 DLIST_ADD(children, child); 1058 child->event.fd = fdpair[1]; 1059 child->event.flags = 0; 1060 child->requests = NULL; 1061 add_fd_event(&child->event); 1062 return True; 1063 } 1064 1065 /* Child */ 1066 1067 /* Stop zombies in children */ 1068 CatchChild(); 1069 1070 state.sock = fdpair[0]; 1071 close(fdpair[1]); 1072 1073 if (!reinit_after_fork(winbind_messaging_context(), true)) { 1048 struct winbindd_child *cl; 1049 1050 if (!reinit_after_fork(winbind_messaging_context(), 1051 winbind_event_context(), true)) { 1074 1052 DEBUG(0,("reinit_after_fork() failed\n")); 1075 _exit(0);1053 return false; 1076 1054 } 1077 1055 1078 1056 close_conns_after_fork(); 1079 1057 1080 if (!override_logfile ) {1081 lp_set_logfile( child->logfilename);1058 if (!override_logfile && logfilename) { 1059 lp_set_logfile(logfilename); 1082 1060 reopen_logs(); 1083 1061 } 1084 1085 /*1086 * For clustering, we need to re-init our ctdbd connection after the1087 * fork1088 */1089 if (!NT_STATUS_IS_OK(messaging_reinit(winbind_messaging_context())))1090 exit(1);1091 1062 1092 1063 /* Don't handle the same messages as our parent. */ … … 1108 1079 MSG_DEBUG, NULL); 1109 1080 1110 /* Handle online/offline messages. */ 1111 messaging_register(winbind_messaging_context(), NULL, 1112 MSG_WINBIND_OFFLINE, child_msg_offline); 1113 messaging_register(winbind_messaging_context(), NULL, 1114 MSG_WINBIND_ONLINE, child_msg_online); 1115 messaging_register(winbind_messaging_context(), NULL, 1116 MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus); 1117 messaging_register(winbind_messaging_context(), NULL, 1118 MSG_DUMP_EVENT_LIST, child_msg_dump_event_list); 1119 messaging_register(winbind_messaging_context(), NULL, 1120 MSG_DEBUG, debug_message); 1121 1081 /* We have destroyed all events in the winbindd_event_context 1082 * in reinit_after_fork(), so clean out all possible pending 1083 * event pointers. */ 1084 1085 /* Deal with check_online_events. */ 1086 1087 for (domain = domain_list(); domain; domain = domain->next) { 1088 TALLOC_FREE(domain->check_online_event); 1089 } 1090 1091 /* Ensure we're not handling a credential cache event inherited 1092 * from our parent. */ 1093 1094 ccache_remove_all_after_fork(); 1095 1096 /* Destroy all possible events in child list. */ 1097 for (cl = children; cl != NULL; cl = cl->next) { 1098 struct winbindd_async_request *request; 1099 1100 for (request = cl->requests; request; request = request->next) { 1101 TALLOC_FREE(request->reply_timeout_event); 1102 } 1103 TALLOC_FREE(cl->lockout_policy_event); 1104 1105 /* Children should never be able to send 1106 * each other messages, all messages must 1107 * go through the parent. 1108 */ 1109 cl->pid = (pid_t)0; 1110 } 1111 /* 1112 * This is a little tricky, children must not 1113 * send an MSG_WINBIND_ONLINE message to idmap_child(). 1114 * If we are in a child of our primary domain or 1115 * in the process created by fork_child_dc_connect(), 1116 * and the primary domain cannot go online, 1117 * fork_child_dc_connection() sends MSG_WINBIND_ONLINE 1118 * periodically to idmap_child(). 1119 * 1120 * The sequence is, fork_child_dc_connect() ---> getdcs() ---> 1121 * get_dc_name_via_netlogon() ---> cm_connect_netlogon() 1122 * ---> init_dc_connection() ---> cm_open_connection ---> 1123 * set_domain_online(), sends MSG_WINBIND_ONLINE to 1124 * idmap_child(). Disallow children sending messages 1125 * to each other, all messages must go through the parent. 1126 */ 1127 cl = idmap_child(); 1128 cl->pid = (pid_t)0; 1129 1130 return true; 1131 } 1132 1133 static bool fork_domain_child(struct winbindd_child *child) 1134 { 1135 int fdpair[2]; 1136 struct winbindd_cli_state state; 1137 struct winbindd_domain *primary_domain = NULL; 1138 1139 if (child->domain) { 1140 DEBUG(10, ("fork_domain_child called for domain '%s'\n", 1141 child->domain->name)); 1142 } else { 1143 DEBUG(10, ("fork_domain_child called without domain.\n")); 1144 } 1145 1146 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { 1147 DEBUG(0, ("Could not open child pipe: %s\n", 1148 strerror(errno))); 1149 return False; 1150 } 1151 1152 ZERO_STRUCT(state); 1153 state.pid = sys_getpid(); 1154 1155 child->pid = sys_fork(); 1156 1157 if (child->pid == -1) { 1158 DEBUG(0, ("Could not fork: %s\n", strerror(errno))); 1159 return False; 1160 } 1161 1162 if (child->pid != 0) { 1163 /* Parent */ 1164 close(fdpair[0]); 1165 child->next = child->prev = NULL; 1166 DLIST_ADD(children, child); 1167 child->event.fd = fdpair[1]; 1168 child->event.flags = 0; 1169 add_fd_event(&child->event); 1170 return True; 1171 } 1172 1173 /* Child */ 1174 1175 /* Stop zombies in children */ 1176 CatchChild(); 1177 1178 state.sock = fdpair[0]; 1179 close(fdpair[1]); 1180 1181 if (!winbindd_reinit_after_fork(child->logfilename)) { 1182 DEBUG(0, ("winbindd_reinit_after_fork failed.\n")); 1183 _exit(0); 1184 } 1185 1186 /* Handle online/offline messages. */ 1187 messaging_register(winbind_messaging_context(), NULL, 1188 MSG_WINBIND_OFFLINE, child_msg_offline); 1189 messaging_register(winbind_messaging_context(), NULL, 1190 MSG_WINBIND_ONLINE, child_msg_online); 1191 messaging_register(winbind_messaging_context(), NULL, 1192 MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus); 1193 messaging_register(winbind_messaging_context(), NULL, 1194 MSG_DUMP_EVENT_LIST, child_msg_dump_event_list); 1195 messaging_register(winbind_messaging_context(), NULL, 1196 MSG_DEBUG, debug_message); 1197 1198 primary_domain = find_our_domain(); 1199 1200 if (primary_domain == NULL) { 1201 smb_panic("no primary domain found"); 1202 } 1203 1204 /* It doesn't matter if we allow cache login, 1205 * try to bring domain online after fork. */ 1122 1206 if ( child->domain ) { 1123 1207 child->domain->startup = True; 1124 1208 child->domain->startup_time = time(NULL); 1125 } 1126 1127 /* Ensure we have no pending check_online events other 1128 than one for this domain or the primary domain. */ 1129 1130 for (domain = domain_list(); domain; domain = domain->next) { 1131 if (domain->primary) { 1132 primary_domain = domain; 1133 } 1134 if ((domain != child->domain) && !domain->primary) { 1135 TALLOC_FREE(domain->check_online_event); 1136 } 1137 } 1138 1139 /* Ensure we're not handling an event inherited from 1140 our parent. */ 1141 1142 cancel_named_event(winbind_event_context(), 1143 "krb5_ticket_refresh_handler"); 1209 /* we can be in primary domain or in trusted domain 1210 * If we are in trusted domain, set the primary domain 1211 * in start-up mode */ 1212 if (!(child->domain->internal)) { 1213 set_domain_online_request(child->domain); 1214 if (!(child->domain->primary)) { 1215 primary_domain->startup = True; 1216 primary_domain->startup_time = time(NULL); 1217 set_domain_online_request(primary_domain); 1218 } 1219 } 1220 } 1221 1222 /* 1223 * We are in idmap child, make sure that we set the 1224 * check_online_event to bring primary domain online. 1225 */ 1226 if (child == idmap_child()) { 1227 set_domain_online_request(primary_domain); 1228 } 1144 1229 1145 1230 /* We might be in the idmap child...*/ … … 1225 1310 TALLOC_FREE(frame); 1226 1311 perror("select"); 1227 return False;1312 _exit(1); 1228 1313 } 1229 1314 … … 1233 1318 if (state.finished) { 1234 1319 /* we lost contact with our parent */ 1235 exit(0);1320 _exit(0); 1236 1321 } 1237 1322 -
branches/samba-3.2.x/source/winbindd/winbindd_util.c
r228 r232 507 507 { 508 508 time_t now = time(NULL); 509 509 510 /* Check that we allow trusted domains at all */ 511 if (!lp_allow_trusted_domains()) 512 return; 513 510 514 /* see if the time has come... */ 511 515 … … 763 767 DOM_SID dom_sid; 764 768 uint32 rid; 765 769 770 /* Check if we even care */ 771 772 if (!lp_allow_trusted_domains()) 773 return; 774 766 775 domain = find_domain_from_name_noinit( name ); 767 776 if ( domain )
Note:
See TracChangeset
for help on using the changeset viewer.