From 868ffe754db8ab59341c71b3cce2cd9600939185 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 15 Feb 2009 18:23:09 -0800 Subject: [PATCH] Attempt to fix bug #6099. According to Microsoft Windows 7 looks at the negotiate_flags returned in this structure *even if the call fails with access denied ! So in order to allow Win7 to connect to a Samba NT style PDC we set the flags before we know if it's an error or not. Jeremy. (cherry picked from commit 194fdee65f91e8ea88196d2cff1c678f868bb3df) --- source/nsswitch/wins.c | 82 ++++++++++++++++++++++++------- source/rpc_server/srv_netlog_nt.c | 27 +++++++--- 2 files changed, 83 insertions(+), 26 deletions(-) diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c index 697bc15f97a..a8736f041c8 100644 --- a/source/nsswitch/wins.c +++ b/source/nsswitch/wins.c @@ -26,6 +26,14 @@ #include #endif +#if HAVE_PTHREAD_H +#include +#endif + +#if HAVE_PTHREAD +static pthread_mutex_t wins_nss_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + #ifndef INADDRSZ #define INADDRSZ 4 #endif @@ -297,11 +305,16 @@ NSS_STATUS _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status = NSS_STATUS_SUCCESS; struct in_addr *ip_list; int i, count; fstring name; size_t namelen; +#if HAVE_PTHREAD + pthread_mutex_lock(&wins_nss_mutex); +#endif + memset(he, '\0', sizeof(*he)); fstrcpy(name, hostname); @@ -309,15 +322,19 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, ip_list = lookup_byname_backend(name, &count); - if (!ip_list) - return NSS_STATUS_NOTFOUND; + if (!ip_list) { + nss_status = NSS_STATUS_NOTFOUND; + goto out; + } /* Copy h_name */ namelen = strlen(name) + 1; - if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) - return NSS_STATUS_TRYAGAIN; + if ((he->h_name = get_static(&buffer, &buflen, namelen)) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } memcpy(he->h_name, name, namelen); @@ -326,17 +343,23 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0) i = sizeof(char*) - i; - if (get_static(&buffer, &buflen, i) == NULL) - return NSS_STATUS_TRYAGAIN; + if (get_static(&buffer, &buflen, i) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } if ((he->h_addr_list = (char **)get_static( - &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) - return NSS_STATUS_TRYAGAIN; + &buffer, &buflen, (count + 1) * sizeof(char *))) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } for (i = 0; i < count; i++) { if ((he->h_addr_list[i] = get_static(&buffer, &buflen, - INADDRSZ)) == NULL) - return NSS_STATUS_TRYAGAIN; + INADDRSZ)) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } memcpy(he->h_addr_list[i], &ip_list[i], INADDRSZ); } @@ -355,16 +378,27 @@ _nss_wins_gethostbyname_r(const char *hostname, struct hostent *he, if ((i = (unsigned long)(buffer) % sizeof(char*)) != 0) i = sizeof(char*) - i; - if (get_static(&buffer, &buflen, i) == NULL) - return NSS_STATUS_TRYAGAIN; + if (get_static(&buffer, &buflen, i) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } if ((he->h_aliases = (char **)get_static( - &buffer, &buflen, sizeof(char *))) == NULL) - return NSS_STATUS_TRYAGAIN; + &buffer, &buflen, sizeof(char *))) == NULL) { + nss_status = NSS_STATUS_TRYAGAIN; + goto out; + } he->h_aliases[0] = NULL; - return NSS_STATUS_SUCCESS; + nss_status = NSS_STATUS_SUCCESS; + + out: + +#if HAVE_PTHREAD + pthread_mutex_unlock(&wins_nss_mutex); +#endif + return nss_status; } @@ -372,12 +406,22 @@ NSS_STATUS _nss_wins_gethostbyname2_r(const char *name, int af, struct hostent *he, char *buffer, size_t buflen, int *h_errnop) { + NSS_STATUS nss_status; + +#if HAVE_PTHREAD + pthread_mutex_lock(&wins_nss_mutex); +#endif + if(af!=AF_INET) { *h_errnop = NO_DATA; - return NSS_STATUS_UNAVAIL; + nss_status = NSS_STATUS_UNAVAIL; + } else { + nss_status = _nss_wins_gethostbyname_r( + name, he, buffer, buflen, h_errnop); } - - return _nss_wins_gethostbyname_r( - name, he, buffer, buflen, h_errnop); +#if HAVE_PTHREAD + pthread_mutex_unlock(&wins_nss_mutex); +#endif + return nss_status; } #endif diff --git a/source/rpc_server/srv_netlog_nt.c b/source/rpc_server/srv_netlog_nt.c index 605fae71279..4bf9c13dc45 100644 --- a/source/rpc_server/srv_netlog_nt.c +++ b/source/rpc_server/srv_netlog_nt.c @@ -431,6 +431,25 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) fstring remote_machine; DOM_CHAL srv_chal_out; + /* According to Microsoft (see bugid #6099) + * Windows 7 looks at the negotiate_flags + * returned in this structure *even if the + * call fails with access denied ! So in order + * to allow Win7 to connect to a Samba NT style + * PDC we set the flags before we know if it's + * an error or not. + */ + + srv_flgs.neg_flags = 0x000001ff; + + if (lp_server_schannel() != False) { + srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL; + } + + /* set up the initial LSA AUTH 2 response */ + ZERO_STRUCT(srv_chal_out); + init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK); + rpcstr_pull(mach_acct, q_u->clnt_id.uni_acct_name.buffer,sizeof(fstring), q_u->clnt_id.uni_acct_name.uni_str_len*2,0); @@ -479,13 +498,7 @@ NTSTATUS _net_auth_2(pipes_struct *p, NET_Q_AUTH_2 *q_u, NET_R_AUTH_2 *r_u) return NT_STATUS_ACCESS_DENIED; } - srv_flgs.neg_flags = 0x000001ff; - - if (lp_server_schannel() != False) { - srv_flgs.neg_flags |= NETLOGON_NEG_SCHANNEL; - } - - /* set up the LSA AUTH 2 response */ + /* set up the real LSA AUTH 2 response */ init_net_r_auth_2(r_u, &srv_chal_out, &srv_flgs, NT_STATUS_OK); fstrcpy(p->dc->mach_acct, mach_acct); -- 2.34.1