summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-02-15 18:23:09 -0800
committerKarolin Seeger <kseeger@samba.org>2009-07-30 09:22:12 +0200
commit868ffe754db8ab59341c71b3cce2cd9600939185 (patch)
tree62f826dac257fa96432c288c656822934dd096d5
parent767f2dd0eb73f616351d54ea350b8b6de97334b9 (diff)
downloadsamba-868ffe754db8ab59341c71b3cce2cd9600939185.tar.gz
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)
-rw-r--r--source/nsswitch/wins.c82
-rw-r--r--source/rpc_server/srv_netlog_nt.c27
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 <ns_daemon.h>
#endif
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+#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);