[SCM] SAMBA-CTDB repository - branch v3-2-ctdb updated - build_3.2.6_ctdb.52-3348-g9bacd97

Michael Adam obnox at samba.org
Mon Jan 12 14:05:38 GMT 2009


The branch, v3-2-ctdb has been updated
       via  9bacd9797d54bb80b4026e5c5198100b8b9ed20a (commit)
       via  38b297f99ec166e5c40ba33774222b37b45b4fec (commit)
       via  a77b622f05c50512626b2636343eb8da6d5e4549 (commit)
       via  d50a487b11c4c256c674327344a824e97eeb620e (commit)
       via  e0b70923298a0f33d92b9a2901098328d914ab1e (commit)
       via  80a37595ef5c289fcc02a8902e18eb9ab289b28c (commit)
       via  9811454d8ae3f09d9a206f14ed533fa6382a914c (commit)
       via  3bb5e3e0b44c25eede60925cfdc89d7df0d0e486 (commit)
      from  31be3d3868e89f3a508c1013e92d16d6b1ce8577 (commit)

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


- Log -----------------------------------------------------------------
commit 9bacd9797d54bb80b4026e5c5198100b8b9ed20a
Merge: 31be3d3868e89f3a508c1013e92d16d6b1ce8577 38b297f99ec166e5c40ba33774222b37b45b4fec
Author: Michael Adam <obnox at samba.org>
Date:   Mon Jan 12 15:06:40 2009 +0100

    Merge commit 'origin/v3-2-test' into v3-2-ctdb

commit 38b297f99ec166e5c40ba33774222b37b45b4fec
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Jan 12 12:32:46 2009 +0100

    s3:libsmb: handle the smb signing states the same in the krb5 and ntlmssp cases
    
    SMB signing works the same regardless of the used auth mech.
    
    We need to start with the temp signing ("BSRSPYL ")
    and the session setup response with NT_STATUS_OK
    is the first signed packet.
    
    Now we set the krb5 session key if we got the NT_STATUS_OK
    from the server and then recheck the packet.
    
    All this is needed to make the fallback from krb5 to
    ntlmssp possible. This commit also resets the cli->vuid
    value to 0, if the krb5 auth didn't succeed. Otherwise
    the server handles NTLMSSP packets as krb5 packets.
    
    The restructuring of the SMB signing code is needed to
    make sure the krb5 code only starts the signing engine
    on success. Otherwise the NTLMSSP fallback could not initialize
    the signing engine (again).
    
    metze
    (cherry picked from commit 7d9fd64f38aa5821b38c1223cf87979fc87bfb71)
    (cherry picked from commit 8e29070ccd0b5103af2e6da75644169f46700313)

commit a77b622f05c50512626b2636343eb8da6d5e4549
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Jan 10 17:59:43 2009 +0100

    Even for srclen == 0 we have to return something
    
    This fixes a regression reported by Corinna Vinschen <corinna at vinschen.de>
    
    Thanks,
    
    Volker

commit d50a487b11c4c256c674327344a824e97eeb620e
Author: Bo Yang <boyang at novell.com>
Date:   Mon Jan 12 15:41:02 2009 +0800

    Fix null pointer refrence in event context in backport from v3-3-test
    
    Signed-off-by: Bo Yang <boyang at novell.com>

commit e0b70923298a0f33d92b9a2901098328d914ab1e
Author: Jeremy Allison <jra at samba.org>
Date:   Sat Jan 10 20:02:09 2009 -0800

    Fix logic bug introduce in backport of ccache_regain_all_now, sync with
    3.3 implementation.
    Jeremy.

commit 80a37595ef5c289fcc02a8902e18eb9ab289b28c
Author: Bo Yang <boyang at novell.com>
Date:   Sat Jan 10 14:33:36 2009 -0800

    Backport of the clean event context after fork and
    krb5 refresh chain fixes.

commit 9811454d8ae3f09d9a206f14ed533fa6382a914c
Author: Bo Yang <boyang at novell.com>
Date:   Sat Jan 10 14:09:48 2009 -0800

    Don't set child->requests to NULL in parent after fork

commit 3bb5e3e0b44c25eede60925cfdc89d7df0d0e486
Author: Karolin Seeger <kseeger at samba.org>
Date:   Fri Jan 9 19:43:13 2009 -0800

    s3/smbpasswd: Check if Unix account exists before asking for the password.
    
    Admins shouldn't have to type in the password twice when the passdb account
    cannot be created because the Unix account is missing.
    
    Karolin

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

Summary of changes:
 source/lib/charcnv.c                  |    6 +
 source/lib/events.c                   |   40 +----
 source/libsmb/cliconnect.c            |   51 ++++--
 source/utils/smbpasswd.c              |    9 +
 source/winbindd/winbindd.c            |    5 +
 source/winbindd/winbindd_cm.c         |   80 ++++----
 source/winbindd/winbindd_cred_cache.c |  333 ++++++++++++++++++++++++++++-----
 source/winbindd/winbindd_dual.c       |  166 ++++++++++------
 8 files changed, 486 insertions(+), 204 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index f4efcb2..e51c33d 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -547,6 +547,12 @@ bool convert_string_allocate(TALLOC_CTX *ctx, charset_t from, charset_t to,
 		return false;
 	}
 	if (srclen == 0) {
+		ob = ((ctx != NULL) ? talloc_strdup(ctx, "") : SMB_STRDUP(""));
+		if (ob == NULL) {
+			errno = ENOMEM;
+			return false;
+		}
+		*dest = ob;
 		*converted_size = 0;
 		return true;
 	}
diff --git a/source/lib/events.c b/source/lib/events.c
index 2dae56e..229e7e2 100644
--- a/source/lib/events.c
+++ b/source/lib/events.c
@@ -63,7 +63,9 @@ static int timed_event_destructor(struct timed_event *te)
 {
 	DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
 		te->event_name));
-	DLIST_REMOVE(te->event_ctx->timed_events, te);
+	if (te->event_ctx) {
+		DLIST_REMOVE(te->event_ctx->timed_events, te);
+	}
 	return 0;
 }
 
@@ -133,7 +135,9 @@ static int fd_event_destructor(struct fd_event *fde)
 {
 	struct event_context *event_ctx = fde->event_ctx;
 
-	DLIST_REMOVE(event_ctx->fd_events, fde);
+	if (event_ctx) {
+		DLIST_REMOVE(event_ctx->fd_events, fde);
+	}
 	return 0;
 }
 
@@ -386,38 +390,6 @@ struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
 	return result;
 }
 
-int set_event_dispatch_time(struct event_context *event_ctx,
-			    const char *event_name, struct timeval when)
-{
-	struct timed_event *te;
-
-	for (te = event_ctx->timed_events; te; te = te->next) {
-		if (strcmp(event_name, te->event_name) == 0) {
-			DLIST_REMOVE(event_ctx->timed_events, te);
-			te->when = when;
-			add_event_by_time(te);
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/* Returns 1 if event was found and cancelled, 0 otherwise. */
-
-int cancel_named_event(struct event_context *event_ctx,
-		       const char *event_name)
-{
-	struct timed_event *te;
-
-	for (te = event_ctx->timed_events; te; te = te->next) {
-		if (strcmp(event_name, te->event_name) == 0) {
-			TALLOC_FREE(te);
-			return 1;
-		}
-	}
-	return 0;
-}
-
 void dump_event_list(struct event_context *event_ctx)
 {
 	struct timed_event *te;
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index ded5dc6..c0c39cf 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -536,7 +536,7 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
 
 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
 
-static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5)
+static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
 {
 	int32 remaining = blob.length;
 	int32 cur = 0;
@@ -560,13 +560,8 @@ static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B
 			send_blob.length = max_blob_size;
 			remaining -= max_blob_size;
 		} else {
-			DATA_BLOB null_blob = data_blob_null;
-
 			send_blob.length = remaining; 
                         remaining = 0;
-
-			/* This is the last packet in the sequence - turn signing on. */
-			cli_simple_set_signing(cli, session_key_krb5, null_blob); 
 		}
 
 		send_blob.data =  &blob.data[cur];
@@ -614,8 +609,11 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
 {
 	DATA_BLOB negTokenTarg;
 	DATA_BLOB session_key_krb5;
+	NTSTATUS nt_status;
 	int rc;
 
+	cli_temp_set_signing(cli);
+
 	DEBUG(2,("Doing kerberos session setup\n"));
 
 	/* generate the encapsulated kerberos5 ticket */
@@ -631,23 +629,44 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *
 	file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
 #endif
 
-	if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) {
-		data_blob_free(&negTokenTarg);
-		data_blob_free(&session_key_krb5);
-		return ADS_ERROR_NT(cli_nt_error(cli));
+	if (!cli_session_setup_blob(cli, negTokenTarg)) {
+		nt_status = cli_nt_error(cli);
+		goto nt_error;
+	}
+
+	if (cli_is_error(cli)) {
+		nt_status = cli_nt_error(cli);
+		if (NT_STATUS_IS_OK(nt_status)) {
+			nt_status = NT_STATUS_UNSUCCESSFUL;
+		}
+		goto nt_error;
 	}
 
 	cli_set_session_key(cli, session_key_krb5);
 
+	if (cli_simple_set_signing(
+		    cli, session_key_krb5, data_blob_null)) {
+
+		/* 'resign' the last message, so we get the right sequence numbers
+		   for checking the first reply from the server */
+		cli_calculate_sign_mac(cli, cli->outbuf);
+
+		if (!cli_check_sign_mac(cli, cli->inbuf)) {
+			nt_status = NT_STATUS_ACCESS_DENIED;
+			goto nt_error;
+		}
+	}
+
 	data_blob_free(&negTokenTarg);
 	data_blob_free(&session_key_krb5);
 
-	if (cli_is_error(cli)) {
-		if (NT_STATUS_IS_OK(cli_nt_error(cli))) {
-			return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
-		}
-	} 
-	return ADS_ERROR_NT(cli_nt_error(cli));
+	return ADS_ERROR_NT(NT_STATUS_OK);
+
+nt_error:
+	data_blob_free(&negTokenTarg);
+	data_blob_free(&session_key_krb5);
+	cli->vuid = 0;
+	return ADS_ERROR_NT(nt_status);
 }
 #endif	/* HAVE_KRB5 */
 
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 493a249..041b02a 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -430,6 +430,15 @@ static int process_root(int local_flags)
 		}
 		
 		if((local_flags & LOCAL_SET_PASSWORD) && (new_passwd == NULL)) {
+			struct passwd *passwd = getpwnam_alloc(NULL, user_name);
+
+			if (!passwd) {
+				fprintf(stderr, "Cannot locate Unix account for "
+					"'%s'!\n", user_name);
+				exit(1);
+			}
+			TALLOC_FREE(passwd);
+
 			new_passwd = prompt_for_new_password(stdin_passwd_get);
 			
 			if(!new_passwd) {
diff --git a/source/winbindd/winbindd.c b/source/winbindd/winbindd.c
index 975df88..6453b8f 100644
--- a/source/winbindd/winbindd.c
+++ b/source/winbindd/winbindd.c
@@ -1211,6 +1211,11 @@ int main(int argc, char **argv, char **envp)
 
 	TimeInit();
 
+	/* Don't use winbindd_reinit_after_fork here as
+	 * we're just starting up and haven't created any
+	 * winbindd-specific resources we must free yet. JRA.
+	 */
+
 	if (!reinit_after_fork(winbind_messaging_context(),
 			       winbind_event_context(), false)) {
 		DEBUG(0,("reinit_after_fork() failed\n"));
diff --git a/source/winbindd/winbindd_cm.c b/source/winbindd/winbindd_cm.c
index d49de31..99effb0 100644
--- a/source/winbindd/winbindd_cm.c
+++ b/source/winbindd/winbindd_cm.c
@@ -173,6 +173,7 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
 	TALLOC_CTX *mem_ctx = NULL;
 	pid_t child_pid;
 	pid_t parent_pid = sys_getpid();
+	char *lfile = NULL;
 
 	/* Stop zombies */
 	CatchChild();
@@ -199,22 +200,24 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
 
 	/* Leave messages blocked - we will never process one. */
 
-	if (!reinit_after_fork(winbind_messaging_context(),
-			       winbind_event_context(), true)) {
+	if (!override_logfile) {
+		if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
+			DEBUG(0, ("fork_child_dc_connect: out of memory!\n"));
+			return false;
+		}
+	}
+
+	if (!winbindd_reinit_after_fork(lfile)) {
 		DEBUG(0,("reinit_after_fork() failed\n"));
+		messaging_send_buf(winbind_messaging_context(),
+				   pid_to_procid(parent_pid),
+				   MSG_WINBIND_FAILED_TO_GO_ONLINE,
+				   (uint8 *)domain->name,
+				   strlen(domain->name) + 1);
 		_exit(0);
 	}
 
-	close_conns_after_fork();
-
-	if (!override_logfile) {
-		char *logfile;
-		if (asprintf(&logfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) > 0) {
-			lp_set_logfile(logfile);
-			SAFE_FREE(logfile);
-			reopen_logs();
-		}
-	}
+	SAFE_FREE(lfile);
 
 	mem_ctx = talloc_init("fork_child_dc_connect");
 	if (!mem_ctx) {
@@ -394,9 +397,10 @@ void set_domain_offline(struct winbindd_domain *domain)
  Set domain online - if allowed.
 ****************************************************************/
 
+void ccache_regain_all_now(void);
+
 static void set_domain_online(struct winbindd_domain *domain)
 {
-	struct timeval now;
 
 	DEBUG(10,("set_domain_online: called for domain %s\n",
 		domain->name ));
@@ -416,10 +420,8 @@ static void set_domain_online(struct winbindd_domain *domain)
 	winbindd_set_locator_kdc_envs(domain);
 
 	/* If we are waiting to get a krb5 ticket, trigger immediately. */
-	GetTimeOfDay(&now);
-	set_event_dispatch_time(winbind_event_context(),
-				"krb5_ticket_gain_handler", now);
-
+	ccache_regain_all_now();
+	
 	/* Ok, we're out of any startup mode now... */
 	domain->startup = False;
 
@@ -491,37 +493,35 @@ void set_domain_online_request(struct winbindd_domain *domain)
 	   because network manager seems to lie.
 	   Wait at least 5 seconds. Heuristics suck... */
 
+	GetTimeOfDay(&tev);
+
+	/* Go into "startup" mode again. */
+	domain->startup_time = tev.tv_sec;
+	domain->startup = True;
+
+	tev.tv_sec += 5;
 	if (!domain->check_online_event) {
 		/* If we've come from being globally offline we
 		   don't have a check online event handler set.
 		   We need to add one now we're trying to go
 		   back online. */
-
 		DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
 			domain->name ));
-
-		domain->check_online_event = event_add_timed(winbind_event_context(),
-								NULL,
-								timeval_current_ofs(5, 0),
-								"check_domain_online_handler",
-								check_domain_online_handler,
-								domain);
-
-		/* The above *has* to succeed for winbindd to work. */
-		if (!domain->check_online_event) {
-			smb_panic("set_domain_online_request: failed to add online handler");
-		}
 	}
-
-	GetTimeOfDay(&tev);
-
-	/* Go into "startup" mode again. */
-	domain->startup_time = tev.tv_sec;
-	domain->startup = True;
-
-	tev.tv_sec += 5;
-
-	set_event_dispatch_time(winbind_event_context(), "check_domain_online_handler", tev);
+	
+	TALLOC_FREE(domain->check_online_event);
+	
+	domain->check_online_event = event_add_timed(winbind_event_context(),
+							NULL,
+							tev,
+							"check_domain_online_handler",
+							check_domain_online_handler,
+							domain);
+	
+	/* The above *has* to succeed for winbindd to work. */
+	if (!domain->check_online_event) {
+		smb_panic("set_domain_online_request: failed to add online handler");
+	}
 }
 
 /****************************************************************
diff --git a/source/winbindd/winbindd_cred_cache.c b/source/winbindd/winbindd_cred_cache.c
index 311b1d1..b867641 100644
--- a/source/winbindd/winbindd_cred_cache.c
+++ b/source/winbindd/winbindd_cred_cache.c
@@ -34,6 +34,8 @@
 #define MAX_CCACHES 100
 
 static struct WINBINDD_CCACHE_ENTRY *ccache_list;
+static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry,
+						struct timeval t);
 
 /* The Krb5 ticket refresh handler should be scheduled
    at one-half of the period from now till the tkt
@@ -71,6 +73,79 @@ static int ccache_entry_count(void)
 	return i;
 }
 
+void ccache_remove_all_after_fork(void)
+{
+	struct WINBINDD_CCACHE_ENTRY *cur;
+	cur = ccache_list;
+	while (cur) {
+		DLIST_REMOVE(ccache_list, cur);
+		TALLOC_FREE(cur->event);
+		TALLOC_FREE(cur);
+		cur = ccache_list;
+	}
+}
+
+static void krb5_ticket_gain_handler(struct event_context *event_ctx,
+				     struct timed_event *te,
+				     const struct timeval *now,
+				     void *private_data);
+static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
+					struct timed_event *te,
+					const struct timeval *now,
+					void *private_data);
+
+void ccache_regain_all_now(void)
+{
+	struct WINBINDD_CCACHE_ENTRY *cur;
+	struct timeval t = timeval_current();
+
+	for (cur = ccache_list; cur; cur = cur->next) {
+		struct timed_event *new_event;
+
+		/*
+		 * if refresh_time is 0, we know that the
+		 * the event has the krb5_ticket_gain_handler
+		 */
+		if (cur->refresh_time == 0) {
+			new_event = event_add_timed(winbind_event_context(),
+						      cur, t,
+						      "krb5_ticket_gain_handler",
+						      krb5_ticket_gain_handler,
+						      cur);
+		} else {
+			new_event = event_add_timed(winbind_event_context(),
+						     cur, t,
+						     "krb5_ticket_refresh_handler",
+						     krb5_ticket_refresh_handler,
+						     cur);
+		}
+		if (!new_event) {
+			continue;
+		}
+
+		TALLOC_FREE(cur->event);
+		cur->event = new_event;
+	}
+	return;
+}
+
+/****************************************************************
+ The gain initial tikcet case is recongnized as entry->refresh_time
+ is always zero.
+****************************************************************/
+
+static void add_krb5_ticket_gain_handler_event(struct WINBINDD_CCACHE_ENTRY *entry,
+						struct timeval t)
+{
+	entry->refresh_time = 0;
+	entry->event = event_add_timed(winbind_event_context(), entry,
+					t,
+					"krb5_ticket_gain_handler",
+					krb5_ticket_gain_handler,
+					entry);
+}
+
+
 /****************************************************************
  Do the work of refreshing the ticket.
 ****************************************************************/
@@ -85,6 +160,7 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
 #ifdef HAVE_KRB5
 	int ret;
 	time_t new_start;
+	time_t expire_time = 0;
 	struct WINBINDD_MEMORY_CREDS *cred_ptr = entry->cred_ptr;
 #endif
 
@@ -97,44 +173,80 @@ static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
 #ifdef HAVE_KRB5
 
 	/* Kinit again if we have the user password and we can't renew the old
-	 * tgt anymore */
-
-	if ((entry->renew_until < time(NULL)) && cred_ptr && cred_ptr->pass) {
-
-		set_effective_uid(entry->uid);
-
-		ret = kerberos_kinit_password_ext(entry->principal_name,
-						  cred_ptr->pass,
-						  0, /* hm, can we do time correction here ? */
-						  &entry->refresh_time,
-						  &entry->renew_until,
-						  entry->ccname,
-						  False, /* no PAC required anymore */
-						  True,
-						  WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
-						  NULL);
-		gain_root_privilege();
-
-		if (ret) {
-			DEBUG(3,("krb5_ticket_refresh_handler: "
-				"could not re-kinit: %s\n",
-				error_message(ret)));
-			TALLOC_FREE(entry->event);
-			return;
-		}
-
-		DEBUG(10,("krb5_ticket_refresh_handler: successful re-kinit "
-			"for: %s in ccache: %s\n",
-			entry->principal_name, entry->ccname));
+	 * tgt anymore 
+	 * NB
+	 * This happens when machine are put to sleep for a very long time. */
+
+	if (entry->renew_until < time(NULL)) {
+rekinit:
+		if (cred_ptr && cred_ptr->pass) {
+
+			set_effective_uid(entry->uid);
+
+			ret = kerberos_kinit_password_ext(entry->principal_name,
+							  cred_ptr->pass,
+							  0, /* hm, can we do time correction here ? */
+							  &entry->refresh_time,
+							  &entry->renew_until,
+							  entry->ccname,
+							  False, /* no PAC required anymore */
+							  True,
+							  WINBINDD_PAM_AUTH_KRB5_RENEW_TIME,
+							  NULL);
+			gain_root_privilege();


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list