Author: ab Date: 2006-10-10 07:57:01 +0000 (Tue, 10 Oct 2006) New Revision: 19222
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=19222 Log: merge -r 19196:19220 with SAMBA_3_0 Modified: branches/tmp/vl-messaging/source/include/ntdomain.h branches/tmp/vl-messaging/source/nsswitch/winbindd_cache.c branches/tmp/vl-messaging/source/nsswitch/winbindd_ccache_access.c branches/tmp/vl-messaging/source/nsswitch/winbindd_cm.c branches/tmp/vl-messaging/source/nsswitch/winbindd_dual.c branches/tmp/vl-messaging/source/nsswitch/winbindd_pam.c branches/tmp/vl-messaging/source/nsswitch/winbindd_util.c branches/tmp/vl-messaging/source/rpc_server/srv_pipe.c branches/tmp/vl-messaging/source/smbd/lanman.c branches/tmp/vl-messaging/source/utils/smbcontrol.c Changeset: Modified: branches/tmp/vl-messaging/source/include/ntdomain.h =================================================================== --- branches/tmp/vl-messaging/source/include/ntdomain.h 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/include/ntdomain.h 2006-10-10 07:57:01 UTC (rev 19222) @@ -257,6 +257,12 @@ */ BOOL bad_handle_fault_state; + + /* + * Set to true when the backend does not support a call. + */ + + BOOL rng_fault_state; /* * Set to RPC_BIG_ENDIAN when dealing with big-endian PDU's Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_cache.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_cache.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_cache.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -2523,7 +2523,6 @@ BOOL set_global_winbindd_state_offline(void) { TDB_DATA data; - int err; DEBUG(10,("set_global_winbindd_state_offline: offline requested.\n")); @@ -2545,21 +2544,16 @@ return True; } -/* wcache->tdb->ecode = 0; */ - data = tdb_fetch_bystring( wcache->tdb, "WINBINDD_OFFLINE" ); - /* As this is a key with no data we don't need to free, we - check for existence by looking at tdb_err. */ - - err = tdb_error(wcache->tdb); - - if (err == TDB_ERR_NOEXIST) { + if (!data.dptr || data.dsize != 4) { DEBUG(10,("set_global_winbindd_state_offline: offline state not set.\n")); + SAFE_FREE(data.dptr); return False; } else { DEBUG(10,("set_global_winbindd_state_offline: offline state set.\n")); global_winbindd_offline_state = True; + SAFE_FREE(data.dptr); return True; } } Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_ccache_access.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_ccache_access.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_ccache_access.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -161,7 +161,7 @@ /* Parse domain and username */ - if (!parse_domain_user(state->request.data.ccache_ntlm_auth.user, + if (!canonicalize_username(state->request.data.ccache_ntlm_auth.user, name_domain, name_user)) { DEBUG(5,("winbindd_ccache_ntlm_auth: cannot parse domain and user from name [%s]\n", state->request.data.ccache_ntlm_auth.user)); Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_cm.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_cm.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_cm.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -122,6 +122,12 @@ TALLOC_FREE(domain->check_online_event); } + if (domain->internal) { + DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n", + domain->name )); + return; + } + domain->online = False; /* We only add the timeout handler that checks and @@ -166,6 +172,12 @@ DEBUG(10,("set_domain_online: called for domain %s\n", domain->name )); + if (domain->internal) { + DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n", + domain->name )); + return; + } + if (get_global_winbindd_state_offline()) { DEBUG(10,("set_domain_online: domain %s remaining globally offline\n", domain->name )); @@ -1197,6 +1209,12 @@ { NTSTATUS result; + /* Internal connections never use the network. */ + if (domain->internal) { + domain->initialized = True; + return NT_STATUS_OK; + } + if (connection_ok(domain)) { if (!domain->initialized) { set_dc_type_and_flags(domain); @@ -1237,11 +1255,6 @@ ZERO_STRUCT( ctr ); - if (domain->internal) { - domain->initialized = True; - return; - } - if (!connection_ok(domain)) { return; } Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_dual.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_dual.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_dual.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -454,10 +454,22 @@ schedule_async_request(child); } -/* Forward the online/offline messages to our children. */ +/* Ensure any negative cache entries with the netbios or realm names are removed. */ + +void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain) +{ + flush_negative_conn_cache_for_domain(domain->name); + if (*domain->alt_name) { + flush_negative_conn_cache_for_domain(domain->alt_name); + } +} + +/* Set our domains as offline and forward the offline message to our children. */ + void winbind_msg_offline(int msg_type, struct process_id src, void *buf, size_t len) { struct winbindd_child *child; + struct winbindd_domain *domain; DEBUG(10,("winbind_msg_offline: got offline message.\n")); @@ -472,17 +484,43 @@ return; } + /* Set all our domains as offline. */ + for (domain = domain_list(); domain; domain = domain->next) { + if (domain->internal) { + continue; + } + DEBUG(5,("winbind_msg_offline: marking %s offline.\n", domain->name)); + set_domain_offline(domain); + } + for (child = children; child != NULL; child = child->next) { - DEBUG(10,("winbind_msg_offline: sending message to pid %u.\n", - (unsigned int)child->pid )); - message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_OFFLINE, NULL, 0, False); + /* Don't send message to idmap child. */ + if (!child->domain || (child == idmap_child())) { + continue; + } + + /* Or internal domains (this should not be possible....) */ + if (child->domain->internal) { + continue; + } + + /* Each winbindd child should only process requests for one domain - make sure + we only set it online / offline for that domain. */ + + DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n", + (unsigned int)child->pid, domain->name )); + + message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_OFFLINE, domain->name, + strlen(domain->name)+1, False); } } -/* Forward the online/offline messages to our children. */ +/* Set our domains as online and forward the online message to our children. */ + void winbind_msg_online(int msg_type, struct process_id src, void *buf, size_t len) { struct winbindd_child *child; + struct winbindd_domain *domain; DEBUG(10,("winbind_msg_online: got online message.\n")); @@ -497,10 +535,36 @@ smb_nscd_flush_user_cache(); smb_nscd_flush_group_cache(); + /* Set all our domains as online. */ + for (domain = domain_list(); domain; domain = domain->next) { + if (domain->internal) { + continue; + } + DEBUG(5,("winbind_msg_online: requesting %s to go online.\n", domain->name)); + + winbindd_flush_negative_conn_cache(domain); + set_domain_online_request(domain); + } + for (child = children; child != NULL; child = child->next) { - DEBUG(10,("winbind_msg_online: sending message to pid %u.\n", - (unsigned int)child->pid )); - message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_ONLINE, NULL, 0, False); + /* Don't send message to idmap child. */ + if (!child->domain || (child == idmap_child())) { + continue; + } + + /* Or internal domains (this should not be possible....) */ + if (child->domain->internal) { + continue; + } + + /* Each winbindd child should only process requests for one domain - make sure + we only set it online / offline for that domain. */ + + DEBUG(10,("winbind_msg_online: sending message to pid %u for domain %s.\n", + (unsigned int)child->pid, domain->name )); + + message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_ONLINE, domain->name, + strlen(domain->name)+1, False); } } @@ -561,9 +625,14 @@ static void child_msg_offline(int msg_type, struct process_id src, void *buf, size_t len) { struct winbindd_domain *domain; + const char *domainname = (const char *)buf; - DEBUG(5,("child_msg_offline received.\n")); + if (buf == NULL || len == 0) { + return; + } + DEBUG(5,("child_msg_offline received for domain %s.\n", domainname)); + if (!lp_winbind_offline_logon()) { DEBUG(10,("child_msg_offline: rejecting offline message.\n")); return; @@ -575,32 +644,32 @@ return; } - /* Mark all our domains as offline. */ + /* Mark the requested domain offline. */ for (domain = domain_list(); domain; domain = domain->next) { - DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name)); - set_domain_offline(domain); + if (domain->internal) { + continue; + } + if (strequal(domain->name, domainname)) { + DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name)); + set_domain_offline(domain); + } } } -/* Ensure any negative cache entries with the netbios or realm names are removed. */ - -void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain) -{ - flush_negative_conn_cache_for_domain(domain->name); - if (*domain->alt_name) { - flush_negative_conn_cache_for_domain(domain->alt_name); - } -} - /* Deal with a request to go online. */ static void child_msg_online(int msg_type, struct process_id src, void *buf, size_t len) { struct winbindd_domain *domain; + const char *domainname = (const char *)buf; - DEBUG(5,("child_msg_online received.\n")); + if (buf == NULL || len == 0) { + return; + } + DEBUG(5,("child_msg_online received for domain %s.\n", domainname)); + if (!lp_winbind_offline_logon()) { DEBUG(10,("child_msg_online: rejecting online message.\n")); return; @@ -613,9 +682,14 @@ to force a reconnect now. */ for (domain = domain_list(); domain; domain = domain->next) { - DEBUG(5,("child_msg_online: requesting %s to go online.\n", domain->name)); - winbindd_flush_negative_conn_cache(domain); - set_domain_online_request(domain); + if (domain->internal) { + continue; + } + if (strequal(domain->name, domainname)) { + DEBUG(5,("child_msg_online: requesting %s to go online.\n", domain->name)); + winbindd_flush_negative_conn_cache(domain); + set_domain_online_request(domain); + } } } Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_pam.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_pam.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_pam.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -677,7 +677,7 @@ /* Parse domain and username */ - if (!parse_domain_user(state->request.data.auth.user, + if (!canonicalize_username(state->request.data.auth.user, name_domain, name_user)) { set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); DEBUG(5, ("Plain text authentication for %s returned %s " @@ -1806,7 +1806,16 @@ /* Setup crap */ - parse_domain_user(state->request.data.chauthtok.user, domain, user); + if (!canonicalize_username(state->request.data.chauthtok.user, domain, user)) { + set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); + DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s" + "(PAM: %d)\n", + state->request.data.auth.user, + state->response.data.auth.nt_status_string, + state->response.data.auth.pam_error)); + request_error(state); + return; + } contact_domain = find_domain_from_name(domain); if (!contact_domain) { @@ -1941,7 +1950,7 @@ state->request.data.logoff.krb5ccname [sizeof(state->request.data.logoff.krb5ccname)-1]='\0'; - if (!parse_domain_user(state->request.data.logoff.user, name_domain, user)) { + if (!canonicalize_username(state->request.data.logoff.user, name_domain, user)) { goto failed; } Modified: branches/tmp/vl-messaging/source/nsswitch/winbindd_util.c =================================================================== --- branches/tmp/vl-messaging/source/nsswitch/winbindd_util.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/nsswitch/winbindd_util.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -462,16 +462,18 @@ fstrcpy(domain->dcname, state->request.data.init_conn.dcname); } - if (strlen(domain->dcname) > 0) { - if (!resolve_name(domain->dcname, &ipaddr, 0x20)) { - DEBUG(2, ("Could not resolve DC name %s for domain %s\n", - domain->dcname, domain->name)); - return WINBINDD_ERROR; + if (!domain->internal) { + if (strlen(domain->dcname) > 0) { + if (!resolve_name(domain->dcname, &ipaddr, 0x20)) { + DEBUG(2, ("Could not resolve DC name %s for domain %s\n", + domain->dcname, domain->name)); + return WINBINDD_ERROR; + } + + domain->dcaddr.sin_family = PF_INET; + putip((char *)&(domain->dcaddr.sin_addr), (char *)&ipaddr); + domain->dcaddr.sin_port = 0; } - - domain->dcaddr.sin_family = PF_INET; - putip((char *)&(domain->dcaddr.sin_addr), (char *)&ipaddr); - domain->dcaddr.sin_port = 0; } init_dc_connection(domain); @@ -888,6 +890,26 @@ return ((*domain != NULL) && (*user != NULL)); } +/* Ensure an incoming username from NSS is fully qualified. Replace the + incoming fstring with DOMAIN <separator> user. Returns the same + values as parse_domain_user() but also replaces the incoming username. + Used to ensure all names are fully qualified within winbindd. + Used by the NSS protocols of auth, chauthtok, logoff and ccache_ntlm_auth. + The protocol definitions of auth_crap, chng_pswd_auth_crap + really should be changed to use this instead of doing things + by hand. JRA. */ + +BOOL canonicalize_username(fstring username_inout, fstring domain, fstring user) +{ + if (!parse_domain_user(username_inout, domain, user)) { + return False; + } + slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s", + domain, *lp_winbind_separator(), + user); + return True; +} + /* Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and 'winbind separator' options. Modified: branches/tmp/vl-messaging/source/rpc_server/srv_pipe.c =================================================================== --- branches/tmp/vl-messaging/source/rpc_server/srv_pipe.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/rpc_server/srv_pipe.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -2310,6 +2310,13 @@ return True; } + if (p->rng_fault_state) { + DEBUG(4, ("api_rpcTNP: rng fault return\n")); + p->rng_fault_state = False; + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); + return True; + } + slprintf(name, sizeof(name)-1, "out_%s", rpc_name); offset2 = prs_offset(&p->out_data.rdata); prs_set_offset(&p->out_data.rdata, offset1); Modified: branches/tmp/vl-messaging/source/smbd/lanman.c =================================================================== --- branches/tmp/vl-messaging/source/smbd/lanman.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/smbd/lanman.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -2691,7 +2691,7 @@ if ((count=get_server_info(SV_TYPE_ALL,&servers,lp_workgroup()))>0) { for (i=0;i<count;i++) { - if (strequal(servers[i].name,get_local_machine_name())) { + if (strequal(servers[i].name,global_myname())) { servertype = servers[i].type; push_ascii(comment,servers[i].comment,sizeof(pstring),STR_TERMINATE); } Modified: branches/tmp/vl-messaging/source/utils/smbcontrol.c =================================================================== --- branches/tmp/vl-messaging/source/utils/smbcontrol.c 2006-10-10 07:55:46 UTC (rev 19221) +++ branches/tmp/vl-messaging/source/utils/smbcontrol.c 2006-10-10 07:57:01 UTC (rev 19222) @@ -883,25 +883,27 @@ 5 times. */ for (retry = 0; retry < 5; retry++) { - int err; TDB_DATA d; + char buf[4]; + ZERO_STRUCT(d); + + SIVAL(buf, 0, time(NULL)); + d.dptr = buf; + d.dsize = 4; + tdb_store_bystring(tdb, "WINBINDD_OFFLINE", d, TDB_INSERT); ret = send_message(pid, MSG_WINBIND_OFFLINE, NULL, 0, False); /* Check that the entry "WINBINDD_OFFLINE" still exists. */ - /* tdb->ecode = TDB_SUCCESS; */ d = tdb_fetch_bystring( tdb, "WINBINDD_OFFLINE" ); - - /* As this is a key with no data we don't need to free, we - check for existence by looking at tdb_err. */ - - err = tdb_error(tdb); - - if (err == TDB_ERR_NOEXIST) { + + if (!d.dptr || d.dsize != 4) { + SAFE_FREE(d.dptr); DEBUG(10,("do_winbind_offline: offline state not set - retrying.\n")); } else { + SAFE_FREE(d.dptr); break; } }