[SCM] SAMBA-CTDB repository - branch v3-4-ctdb updated - 3.4.2-ctdb-12-8-g833f9f8

Michael Adam obnox at samba.org
Fri Nov 20 03:33:05 MST 2009


The branch, v3-4-ctdb has been updated
       via  833f9f89f8ce8ad447ad79e6ab6c9b3a5479d16d (commit)
       via  13925751093030f041fa3665c01fa07a354d81ee (commit)
       via  9d904fa590d34f5836140725882521aa50ec4e72 (commit)
       via  18f360047a89d21bdc453539db66c6c9be2c510a (commit)
       via  f38a513cdc20af38743f68c4cf3cf94ab58ed27b (commit)
       via  2e250bbf8726fc465ec426766589aa1ca67a38e3 (commit)
       via  3c6dc1fd8fc81a43ec0bb014974180c7af382022 (commit)
       via  46fd4fbe1d11bf6834ad26e1376068957a7b7725 (commit)
      from  2db5f5bbda842611f9b58a18f0b9dc9d6438d770 (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-4-ctdb


- Log -----------------------------------------------------------------
commit 833f9f89f8ce8ad447ad79e6ab6c9b3a5479d16d
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Fri Nov 20 10:39:57 2009 +0100

    gpfs: fix logic when gpfs:winattr is false (the default!)
    
    On my autocluster setup, it's not set.  Maybe it should be?  Otherwise
    smbclient and some Windows client programs will get errors like:
    
            # smbclient //localhost/data -Uadministrator%XXX
            Domain=[VSOFS1] OS=[Unix] Server=[Samba 3.4.2-ctdb-10]
            smb: \> put /etc/resolv.conf resolv.conf
            NT_STATUS_ACCESS_DENIED closing remote file \resolv.conf
            smb: \>
    
    Caused by attempting to update the time on close.
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 13925751093030f041fa3665c01fa07a354d81ee
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 17:22:27 2009 +0100

    s3: Avoid races to change the machine password in winbind
    
    The machine password handler has code to deal with every node in the cluster
    trying to change the machine password at the same time. However, it is not very
    nice to the DC if everyone tries this simultaneously. This adds a random 0-255
    second offset to our timed event. When this fires a bit later than strictly
    calculated, someone else might have stepped in and have already changed it. The
    timed event handler will handle this gracefully, it won't even try to do it
    again.
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 9d904fa590d34f5836140725882521aa50ec4e72
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 17:20:47 2009 +0100

    s3: Protect against flooding the DC with pwchange requests
    
    When there is a temporary problem changing passwords we flooded the DC with
    pwchange requests. This gives the DC a 60-second break to recover.
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 18f360047a89d21bdc453539db66c6c9be2c510a
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 17:16:54 2009 +0100

    s3: Deal with races for password changes
    
    When two winbinds (in a cluster) change the password at the same time, the
    later one gets an NT_STATUS_ACCESS_DENIED. The netlogon session works fine, but
    the next time we retry the pwchange, we again get NT_STATUS_ACCESS_DENIED. This
    code deals with this race by dropping just the NETLOGON pipe. The next caller
    will re-open it automatically with the changed machine credentials.
    
    With this race in place, we also have to recalculate the timeout for the next
    pwchange event.
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit f38a513cdc20af38743f68c4cf3cf94ab58ed27b
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 17:14:40 2009 +0100

    s3: Re-check the timeout in machine_password_change_handler()
    
    Someone else might have come in between and changed the password since we
    created that timed request
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 2e250bbf8726fc465ec426766589aa1ca67a38e3
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 17:11:32 2009 +0100

    s3: Add some debugs to the winbind machine pwchange machinery
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 3c6dc1fd8fc81a43ec0bb014974180c7af382022
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Nov 19 11:50:13 2009 +0100

    s3: Factor timeval_string out of current_timestring()
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 46fd4fbe1d11bf6834ad26e1376068957a7b7725
Author: Günther Deschner <gd at samba.org>
Date:   Mon Oct 5 17:04:52 2009 +0200

    s3-netlogon: setup NETLOGON credential chain in rpccli_netlogon_set_trust_password() only when needed.
    
    Guenther
    
    Signed-off-by: Michael Adam <obnox at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h           |    1 +
 source3/lib/time.c                |   25 +++++++-------
 source3/modules/vfs_gpfs.c        |   12 ++++++-
 source3/rpc_client/cli_netlogon.c |   27 ++++++++-------
 source3/winbindd/winbindd_dual.c  |   67 +++++++++++++++++++++++++++++++++---
 5 files changed, 100 insertions(+), 32 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 14bf014..bf9164b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1027,6 +1027,7 @@ bool nt_time_is_zero(const NTTIME *nt);
 time_t generalized_to_unix_time(const char *str);
 int get_server_zone_offset(void);
 int set_server_zone_offset(time_t t);
+char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires);
 char *current_timestring(TALLOC_CTX *ctx, bool hires);
 void srv_put_dos_date(char *buf,int offset,time_t unixdate);
 void srv_put_dos_date2(char *buf,int offset, time_t unixdate);
diff --git a/source3/lib/time.c b/source3/lib/time.c
index d48ab68..f8468ca 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -188,27 +188,21 @@ int set_server_zone_offset(time_t t)
  Return the date and time as a string
 ****************************************************************************/
 
-char *current_timestring(TALLOC_CTX *ctx, bool hires)
+char *timeval_string(TALLOC_CTX *ctx, const struct timeval *tp, bool hires)
 {
 	fstring TimeBuf;
-	struct timeval tp;
 	time_t t;
 	struct tm *tm;
 
-	if (hires) {
-		GetTimeOfDay(&tp);
-		t = (time_t)tp.tv_sec;
-	} else {
-		t = time(NULL);
-	}
+	t = (time_t)tp->tv_sec;
 	tm = localtime(&t);
 	if (!tm) {
 		if (hires) {
 			slprintf(TimeBuf,
 				 sizeof(TimeBuf)-1,
 				 "%ld.%06ld seconds since the Epoch",
-				 (long)tp.tv_sec, 
-				 (long)tp.tv_usec);
+				 (long)tp->tv_sec,
+				 (long)tp->tv_usec);
 		} else {
 			slprintf(TimeBuf,
 				 sizeof(TimeBuf)-1,
@@ -222,7 +216,7 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires)
 			slprintf(TimeBuf+strlen(TimeBuf),
 				 sizeof(TimeBuf)-1 - strlen(TimeBuf), 
 				 ".%06ld", 
-				 (long)tp.tv_usec);
+				 (long)tp->tv_usec);
 		} else {
 			strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
 		}
@@ -233,7 +227,7 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires)
 				 sizeof(TimeBuf)-1, 
 				 "%s.%06ld", 
 				 asct ? asct : "unknown", 
-				 (long)tp.tv_usec);
+				 (long)tp->tv_usec);
 		} else {
 			const char *asct = asctime(tm);
 			fstrcpy(TimeBuf, asct ? asct : "unknown");
@@ -243,6 +237,13 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires)
 	return talloc_strdup(ctx, TimeBuf);
 }
 
+char *current_timestring(TALLOC_CTX *ctx, bool hires)
+{
+	struct timeval tv;
+
+	GetTimeOfDay(&tv);
+	return timeval_string(ctx, &tv, hires);
+}
 
 /*******************************************************************
  Put a dos date into a buffer (time/date format).
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 4cbffcf..4c86aa6 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -923,6 +923,11 @@ static int gpfs_set_xattr(struct vfs_handle_struct *handle,  const char *path,
         ret = set_gpfs_winattrs(CONST_DISCARD(char *, path),
 				GPFS_WINATTR_SET_ATTRS, &attrs);
         if ( ret == -1){
+		if (errno == ENOSYS) {
+			return SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
+						     size, flags);
+		}
+
                 DEBUG(1, ("gpfs_set_xattr:Set GPFS attributes failed %d\n",ret));
                 return -1;
         }
@@ -948,6 +953,11 @@ static size_t gpfs_get_xattr(struct vfs_handle_struct *handle,  const char *path
 
         ret = get_gpfs_winattrs(CONST_DISCARD(char *, path), &attrs);
         if ( ret == -1){
+		if (errno == ENOSYS) {
+			return SMB_VFS_NEXT_GETXATTR(handle, path, name, value,
+						     size);
+		}
+
                 DEBUG(1, ("gpfs_get_xattr: Get GPFS attributes failed: %d\n",ret));
                 return -1;
         }
@@ -1065,7 +1075,7 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle,
 
         ret = set_gpfs_winattrs(CONST_DISCARD(char *, path),
                                 GPFS_WINATTR_SET_CREATION_TIME, &attrs);
-        if(ret == -1){
+        if(ret == -1 && errno != ENOSYS){
                 DEBUG(1,("vfs_gpfs_ntimes: set GPFS ntimes failed %d\n",ret));
                 return -1;
         }
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 4d7347f..683abfe 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -559,19 +559,20 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
 	uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
 	struct netr_Authenticator clnt_creds, srv_cred;
 
-	result = rpccli_netlogon_setup_creds(cli,
-					     cli->desthost, /* server name */
-					     lp_workgroup(), /* domain */
-					     global_myname(), /* client name */
-					     global_myname(), /* machine account name */
-					     orig_trust_passwd_hash,
-					     sec_channel_type,
-					     &neg_flags);
-
-	if (!NT_STATUS_IS_OK(result)) {
-		DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n",
-			 nt_errstr(result)));
-		return result;
+	if (!cli->dc) {
+		result = rpccli_netlogon_setup_creds(cli,
+						     cli->desthost, /* server name */
+						     lp_workgroup(), /* domain */
+						     global_myname(), /* client name */
+						     global_myname(), /* machine account name */
+						     orig_trust_passwd_hash,
+						     sec_channel_type,
+						     &neg_flags);
+		if (!NT_STATUS_IS_OK(result)) {
+			DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n",
+				 nt_errstr(result)));
+			return result;
+		}
 	}
 
 	netlogon_creds_client_step(cli->dc, &clnt_creds);
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index b6287dd..76485a3 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -881,6 +881,7 @@ static bool calculate_next_machine_pwd_change(const char *domain,
 	time_t pass_last_set_time;
 	time_t timeout;
 	time_t next_change;
+	struct timeval tv;
 	char *pw;
 
 	pw = secrets_fetch_machine_password(domain,
@@ -900,11 +901,36 @@ static bool calculate_next_machine_pwd_change(const char *domain,
 		return false;
 	}
 
+	tv.tv_sec = pass_last_set_time;
+	DEBUG(10, ("password last changed %s\n",
+		   timeval_string(talloc_tos(), &tv, false)));
+	tv.tv_sec += timeout;
+	DEBUGADD(10, ("password valid until %s\n",
+		      timeval_string(talloc_tos(), &tv, false)));
+
 	if (time(NULL) < (pass_last_set_time + timeout)) {
 		next_change = pass_last_set_time + timeout;
 		DEBUG(10,("machine password still valid until: %s\n",
 			http_timestring(talloc_tos(), next_change)));
 		*t = timeval_set(next_change, 0);
+
+		if (lp_clustering()) {
+			uint8_t randbuf;
+			/*
+			 * When having a cluster, we have several
+			 * winbinds racing for the password change. In
+			 * the machine_password_change_handler()
+			 * function we check if someone else was
+			 * faster when the event triggers. We add a
+			 * 255-second random delay here, so that we
+			 * don't run to change the password at the
+			 * exact same moment.
+			 */
+			generate_random_buffer(&randbuf, sizeof(randbuf));
+			DEBUG(10, ("adding %d seconds randomness\n",
+				   (int)randbuf));
+			t->tv_sec += randbuf;
+		}
 		return true;
 	}
 
@@ -933,9 +959,18 @@ static void machine_password_change_handler(struct event_context *ctx,
 
 	if (!calculate_next_machine_pwd_change(child->domain->name,
 					       &next_change)) {
+		DEBUG(10, ("calculate_next_machine_pwd_change failed\n"));
 		return;
 	}
 
+	DEBUG(10, ("calculate_next_machine_pwd_change returned %s\n",
+		   timeval_string(talloc_tos(), &next_change, false)));
+
+	if (!timeval_expired(&next_change)) {
+		DEBUG(10, ("Someone else has already changed the pw\n"));
+		goto done;
+	}
+
 	if (!winbindd_can_contact_domain(child->domain)) {
 		DEBUG(10,("machine_password_change_handler: Removing myself since I "
 			  "do not have an incoming trust to domain %s\n",
@@ -958,15 +993,35 @@ static void machine_password_change_handler(struct event_context *ctx,
 						   child->domain->name);
 	TALLOC_FREE(frame);
 
+	DEBUG(10, ("machine_password_change_handler: "
+		   "trust_pw_find_change_and_store_it returned %s\n",
+		   nt_errstr(result)));
+
+	if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
+		DEBUG(10, ("Dropping the NETLOGON connection, someone else "
+			   "changed the machine password simultaneously\n"));
+		TALLOC_FREE(child->domain->conn.netlogon_pipe);
+	}
+
+	if (!calculate_next_machine_pwd_change(child->domain->name,
+					       &next_change)) {
+		DEBUG(10, ("calculate_next_machine_pwd_change failed\n"));
+		return;
+	}
+
+	DEBUG(10, ("calculate_next_machine_pwd_change returned %s\n",
+		   timeval_string(talloc_tos(), &next_change, false)));
+
 	if (!NT_STATUS_IS_OK(result)) {
-		DEBUG(10,("machine_password_change_handler: "
-			"failed to change machine password: %s\n",
-			 nt_errstr(result)));
-	} else {
-		DEBUG(10,("machine_password_change_handler: "
-			"successfully changed machine password\n"));
+		struct timeval tmp;
+		/*
+		 * In case of failure, give the DC a minute to recover
+		 */
+		tmp = timeval_current_ofs(60, 0);
+		next_change = timeval_max(&next_change, &tmp);
 	}
 
+done:
 	child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL,
 							      next_change,
 							      machine_password_change_handler,


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list