[SCM] Samba Shared Repository - branch master updated

Simo Sorce idra at samba.org
Wed Aug 18 05:47:30 MDT 2010


The branch, master has been updated
       via  71dfa62... s3-ads: cleanup ads_keytab_list()
       via  64d8300... s3-ads: cleanup ads_keytab_create_default()
       via  3a99123... s3-ads: cleanup ads_keytab_add_entry()
       via  d6d1ed8... s3-ads: Split, simplify and cleanup keytab functions
      from  b9353c6... s3: Fix serverid_register_msg_flags

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 71dfa62b61380396785c7856c38f45c77c966ff0
Author: Simo Sorce <idra at samba.org>
Date:   Wed Aug 18 06:46:53 2010 -0400

    s3-ads: cleanup ads_keytab_list()

commit 64d8300a56eb0891389a5a2afc5e4902c2d909a2
Author: Simo Sorce <idra at samba.org>
Date:   Wed Aug 18 06:09:27 2010 -0400

    s3-ads: cleanup ads_keytab_create_default()

commit 3a9912370dc36500d207aeb9d1ae58834526b6c3
Author: Simo Sorce <idra at samba.org>
Date:   Wed Aug 18 04:33:32 2010 -0400

    s3-ads: cleanup ads_keytab_add_entry()

commit d6d1ed8bdfb290ac6e1fa4264f2b84d0e4790d98
Author: Simo Sorce <idra at samba.org>
Date:   Wed Aug 18 04:16:41 2010 -0400

    s3-ads: Split, simplify and cleanup keytab functions
    
    add helper function for both smb_krb5_kt_add_entry_ext() and
    ads_keytab_flush()

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

Summary of changes:
 source3/libads/kerberos_keytab.c |  756 ++++++++++++++++++++------------------
 1 files changed, 404 insertions(+), 352 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index 386ce83..d2215ec 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -35,130 +35,184 @@
 /**********************************************************************
 **********************************************************************/
 
-int smb_krb5_kt_add_entry_ext(krb5_context context,
-			      krb5_keytab keytab,
-			      krb5_kvno kvno,
-			      const char *princ_s,
-			      krb5_enctype *enctypes,
-			      krb5_data password,
-			      bool no_salt,
-			      bool keep_old_entries)
+static krb5_error_code seek_and_delete_old_entries(krb5_context context,
+						   krb5_keytab keytab,
+						   krb5_kvno kvno,
+						   const char *princ_s,
+						   krb5_principal princ,
+						   bool flush,
+						   bool keep_old_entries)
 {
-	krb5_error_code ret = 0;
+	krb5_error_code ret;
 	krb5_kt_cursor cursor;
+	krb5_kt_cursor zero_csr;
 	krb5_keytab_entry kt_entry;
-	krb5_principal princ = NULL;
-	int i;
+	krb5_keytab_entry zero_kt_entry;
 	char *ktprinc = NULL;
 
-	ZERO_STRUCT(kt_entry);
 	ZERO_STRUCT(cursor);
-	
-	ret = smb_krb5_parse_name(context, princ_s, &princ);
-	if (ret) {
-		DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_parse_name(%s) failed (%s)\n", princ_s, error_message(ret)));
-		goto out;
-	}
+	ZERO_STRUCT(zero_csr);
+	ZERO_STRUCT(kt_entry);
+	ZERO_STRUCT(zero_kt_entry);
 
-	/* Seek and delete old keytab entries */
 	ret = krb5_kt_start_seq_get(context, keytab, &cursor);
-	if (ret != KRB5_KT_END && ret != ENOENT ) {
-		DEBUG(3,("smb_krb5_kt_add_entry_ext: Will try to delete old keytab entries\n"));
-		while(!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
-			bool compare_name_ok = False;
+	if (ret == KRB5_KT_END && ret == ENOENT ) {
+		/* no entries */
+		return 0;
+	}
+
+	DEBUG(3, (__location__ ": Will try to delete old keytab entries\n"));
+	while (!krb5_kt_next_entry(context, keytab, &kt_entry, &cursor)) {
+		bool name_ok = False;
 
-			ret = smb_krb5_unparse_name(talloc_tos(), context, kt_entry.principal, &ktprinc);
+		if (!flush && (princ_s != NULL)) {
+			ret = smb_krb5_unparse_name(talloc_tos(), context,
+						    kt_entry.principal,
+						    &ktprinc);
 			if (ret) {
-				DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_unparse_name failed (%s)\n",
-					error_message(ret)));
+				DEBUG(1, (__location__
+					  ": smb_krb5_unparse_name failed "
+					  "(%s)\n", error_message(ret)));
 				goto out;
 			}
 
-			/*---------------------------------------------------------------------------
-			 * Save the entries with kvno - 1.   This is what microsoft does
-			 * to allow people with existing sessions that have kvno - 1 to still
-			 * work.   Otherwise, when the password for the machine changes, all
-			 * kerberizied sessions will 'break' until either the client reboots or
-			 * the client's session key expires and they get a new session ticket
-			 * with the new kvno.
-			 */
-
 #ifdef HAVE_KRB5_KT_COMPARE
-			compare_name_ok = (krb5_kt_compare(context, &kt_entry, princ, 0, 0) == True);
+			name_ok = krb5_kt_compare(context, &kt_entry,
+						  princ, 0, 0);
 #else
-			compare_name_ok = (strcmp(ktprinc, princ_s) == 0);
+			name_ok = (strcmp(ktprinc, princ_s) == 0);
 #endif
 
-			if (!compare_name_ok) {
-				DEBUG(10,("smb_krb5_kt_add_entry_ext: ignoring keytab entry principal %s, kvno = %d\n",
-					ktprinc, kt_entry.vno));
+			if (!name_ok) {
+				DEBUG(10, (__location__ ": ignoring keytab "
+					   "entry principal %s, kvno = %d\n",
+					   ktprinc, kt_entry.vno));
+
+				/* Not a match,
+				 * just free this entry and continue. */
+				ret = smb_krb5_kt_free_entry(context,
+							     &kt_entry);
+				ZERO_STRUCT(kt_entry);
+				if (ret) {
+					DEBUG(1, (__location__
+						  ": smb_krb5_kt_free_entry "
+						  "failed (%s)\n",
+						  error_message(ret)));
+					goto out;
+				}
+
+				TALLOC_FREE(ktprinc);
+				continue;
 			}
 
 			TALLOC_FREE(ktprinc);
+		}
 
-			if (compare_name_ok) {
-				if (kt_entry.vno == kvno - 1) {
-					DEBUG(5,("smb_krb5_kt_add_entry_ext: Saving previous (kvno %d) entry for principal: %s.\n",
-						kvno - 1, princ_s));
-				} else if (!keep_old_entries) {
-					DEBUG(5,("smb_krb5_kt_add_entry_ext: Found old entry for principal: %s (kvno %d) - trying to remove it.\n",
-						princ_s, kt_entry.vno));
-					ret = krb5_kt_end_seq_get(context, keytab, &cursor);
-					ZERO_STRUCT(cursor);
-					if (ret) {
-						DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get() failed (%s)\n",
-							error_message(ret)));
-						goto out;
-					}
-					ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
-					if (ret) {
-						DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
-							error_message(ret)));
-						goto out;
-					}
-
-					DEBUG(5,("smb_krb5_kt_add_entry_ext: removed old entry for principal: %s (kvno %d).\n",
-						princ_s, kt_entry.vno));
-
-					ret = krb5_kt_start_seq_get(context, keytab, &cursor);
-					if (ret) {
-						DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_start_seq failed (%s)\n",
-							error_message(ret)));
-						goto out;
-					}
-					ret = smb_krb5_kt_free_entry(context, &kt_entry);
-					ZERO_STRUCT(kt_entry);
-					if (ret) {
-						DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_remove_entry failed (%s)\n",
-							error_message(ret)));
-						goto out;
-					}
-					continue;
-				}
-			}
+		/*------------------------------------------------------------
+		 * Save the entries with kvno - 1. This is what microsoft does
+		 * to allow people with existing sessions that have kvno - 1
+		 * to still work. Otherwise, when the password for the machine
+		 * changes, all kerberizied sessions will 'break' until either
+		 * the client reboots or the client's session key expires and
+		 * they get a new session ticket with the new kvno.
+		 */
+
+		if (!flush && (kt_entry.vno == kvno - 1)) {
+			DEBUG(5, (__location__ ": Saving previous (kvno %d) "
+				  "entry for principal: %s.\n",
+				  kvno - 1, princ_s));
+			continue;
+		}
 
-			/* Not a match, just free this entry and continue. */
-			ret = smb_krb5_kt_free_entry(context, &kt_entry);
-			ZERO_STRUCT(kt_entry);
-			if (ret) {
-				DEBUG(1,("smb_krb5_kt_add_entry_ext: smb_krb5_kt_free_entry failed (%s)\n", error_message(ret)));
-				goto out;
-			}
+		if (keep_old_entries) {
+			DEBUG(5, (__location__ ": Saving old (kvno %d) "
+				  "entry for principal: %s.\n",
+				  kvno, princ_s));
+			continue;
 		}
 
+		DEBUG(5, (__location__ ": Found old entry for principal: %s "
+			  "(kvno %d) - trying to remove it.\n",
+			  princ_s, kt_entry.vno));
+
 		ret = krb5_kt_end_seq_get(context, keytab, &cursor);
 		ZERO_STRUCT(cursor);
 		if (ret) {
-			DEBUG(1,("smb_krb5_kt_add_entry_ext: krb5_kt_end_seq_get failed (%s)\n",error_message(ret)));
+			DEBUG(1, (__location__ ": krb5_kt_end_seq_get() "
+				  "failed (%s)\n", error_message(ret)));
+			goto out;
+		}
+		ret = krb5_kt_remove_entry(context, keytab, &kt_entry);
+		if (ret) {
+			DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
+				  "failed (%s)\n", error_message(ret)));
+			goto out;
+		}
+
+		DEBUG(5, (__location__ ": removed old entry for principal: "
+			  "%s (kvno %d).\n", princ_s, kt_entry.vno));
+
+		ret = krb5_kt_start_seq_get(context, keytab, &cursor);
+		if (ret) {
+			DEBUG(1, (__location__ ": krb5_kt_start_seq() failed "
+				  "(%s)\n", error_message(ret)));
+			goto out;
+		}
+		ret = smb_krb5_kt_free_entry(context, &kt_entry);
+		ZERO_STRUCT(kt_entry);
+		if (ret) {
+			DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
+				  "failed (%s)\n", error_message(ret)));
 			goto out;
 		}
 	}
 
-	/* Ensure we don't double free. */
+out:
+	if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
+		smb_krb5_kt_free_entry(context, &kt_entry);
+	}
+	if (keytab) {
+		if (memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) {
+			krb5_kt_end_seq_get(context, keytab, &cursor);
+		}
+	}
+
+	return ret;
+}
+
+int smb_krb5_kt_add_entry_ext(krb5_context context,
+			      krb5_keytab keytab,
+			      krb5_kvno kvno,
+			      const char *princ_s,
+			      krb5_enctype *enctypes,
+			      krb5_data password,
+			      bool no_salt,
+			      bool keep_old_entries)
+{
+	krb5_error_code ret;
+	krb5_keytab_entry kt_entry;
+	krb5_principal princ = NULL;
+	int i;
+
 	ZERO_STRUCT(kt_entry);
-	ZERO_STRUCT(cursor);
 
-	/* If we get here, we have deleted all the old entries with kvno's not equal to the current kvno-1. */
+	ret = smb_krb5_parse_name(context, princ_s, &princ);
+	if (ret) {
+		DEBUG(1, (__location__ ": smb_krb5_parse_name(%s) "
+			  "failed (%s)\n", princ_s, error_message(ret)));
+		goto out;
+	}
+
+	/* Seek and delete old keytab entries */
+	ret = seek_and_delete_old_entries(context, keytab, kvno,
+					  princ_s, princ, false,
+					  keep_old_entries);
+	if (ret) {
+		goto out;
+	}
+
+	/* If we get here, we have deleted all the old entries with kvno's
+	 * not equal to the current kvno-1. */
 
 	/* Now add keytab entries for all encryption types */
 	for (i = 0; enctypes[i]; i++) {
@@ -166,45 +220,33 @@ int smb_krb5_kt_add_entry_ext(krb5_context context,
 
 		keyp = KRB5_KT_KEY(&kt_entry);
 
-		if (create_kerberos_key_from_string(context, princ, &password, keyp, enctypes[i], no_salt)) {
+		if (create_kerberos_key_from_string(context, princ,
+						    &password, keyp,
+						    enctypes[i], no_salt)) {
 			continue;
 		}
 
 		kt_entry.principal = princ;
 		kt_entry.vno       = kvno;
 
-		DEBUG(3,("smb_krb5_kt_add_entry_ext: adding keytab entry for (%s) with encryption type (%d) and version (%d)\n",
-			princ_s, enctypes[i], kt_entry.vno));
+		DEBUG(3, (__location__ ": adding keytab entry for (%s) with "
+			  "encryption type (%d) and version (%d)\n",
+			  princ_s, enctypes[i], kt_entry.vno));
 		ret = krb5_kt_add_entry(context, keytab, &kt_entry);
 		krb5_free_keyblock_contents(context, keyp);
 		ZERO_STRUCT(kt_entry);
 		if (ret) {
-			DEBUG(1,("smb_krb5_kt_add_entry_ext: adding entry to keytab failed (%s)\n", error_message(ret)));
+			DEBUG(1, (__location__ ": adding entry to keytab "
+				  "failed (%s)\n", error_message(ret)));
 			goto out;
 		}
 	}
 
-
 out:
-	{
-		krb5_keytab_entry zero_kt_entry;
-		ZERO_STRUCT(zero_kt_entry);
-		if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
-			smb_krb5_kt_free_entry(context, &kt_entry);
-		}
-	}
 	if (princ) {
 		krb5_free_principal(context, princ);
 	}
-	
-	{
-		krb5_kt_cursor zero_csr;
-		ZERO_STRUCT(zero_csr);
-		if ((memcmp(&cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
-			krb5_kt_end_seq_get(context, keytab, &cursor);	
-		}
-	}
-	
+
 	return (int)ret;
 }
 
@@ -236,38 +278,44 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
 	krb5_keytab keytab = NULL;
 	krb5_data password;
 	krb5_kvno kvno;
-        krb5_enctype enctypes[4] = { ENCTYPE_DES_CBC_CRC, 
-				     ENCTYPE_DES_CBC_MD5, 
-				     ENCTYPE_ARCFOUR_HMAC, 
-				     0 };
-	char *princ_s = NULL, *short_princ_s = NULL;
+        krb5_enctype enctypes[4] = {
+		ENCTYPE_DES_CBC_CRC,
+		ENCTYPE_DES_CBC_MD5,
+		ENCTYPE_ARCFOUR_HMAC,
+		0
+	};
+	char *princ_s = NULL;
+	char *short_princ_s = NULL;
 	char *password_s = NULL;
 	char *my_fqdn;
-	TALLOC_CTX *ctx = NULL;
+	TALLOC_CTX *tmpctx = NULL;
 	char *machine_name;
+	ADS_STATUS aderr;
 
 	initialize_krb5_error_table();
 	ret = krb5_init_context(&context);
 	if (ret) {
-		DEBUG(1,("ads_keytab_add_entry: could not krb5_init_context: %s\n",error_message(ret)));
+		DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
+			  error_message(ret)));
 		return -1;
 	}
 
 	ret = smb_krb5_open_keytab(context, NULL, True, &keytab);
 	if (ret) {
-		DEBUG(1,("ads_keytab_add_entry: smb_krb5_open_keytab failed (%s)\n", error_message(ret)));
+		DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
+			  error_message(ret)));
 		goto out;
 	}
 
 	/* retrieve the password */
 	if (!secrets_init()) {
-		DEBUG(1,("ads_keytab_add_entry: secrets_init failed\n"));
+		DEBUG(1, (__location__ ": secrets_init failed\n"));
 		ret = -1;
 		goto out;
 	}
 	password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
 	if (!password_s) {
-		DEBUG(1,("ads_keytab_add_entry: failed to fetch machine password\n"));
+		DEBUG(1, (__location__ ": failed to fetch machine password\n"));
 		ret = -1;
 		goto out;
 	}
@@ -276,38 +324,44 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
 	password.length = strlen(password_s);
 
 	/* we need the dNSHostName value here */
-	
-	if ( (ctx = talloc_init("ads_keytab_add_entry")) == NULL ) {
-		DEBUG(0,("ads_keytab_add_entry: talloc() failed!\n"));
+	tmpctx = talloc_init(__location__);
+	if (!tmpctx) {
+		DEBUG(0, (__location__ ": talloc_init() failed!\n"));
 		ret = -1;
 		goto out;
 	}
-	
-	if ( (my_fqdn = ads_get_dnshostname( ads, ctx, global_myname())) == NULL ) {
-		DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's dns name in AD!\n"));
+
+	my_fqdn = ads_get_dnshostname(ads, tmpctx, global_myname());
+	if (!my_fqdn) {
+		DEBUG(0, (__location__ ": unable to determine machine "
+			  "account's dns name in AD!\n"));
 		ret = -1;
-		goto out;	
+		goto out;
 	}
-	
-	if ( (machine_name = ads_get_samaccountname( ads, ctx, global_myname())) == NULL ) {
-		DEBUG(0,("ads_keytab_add_entry: unable to determine machine account's short name in AD!\n"));
+
+	machine_name = ads_get_samaccountname(ads, tmpctx, global_myname());
+	if (!machine_name) {
+		DEBUG(0, (__location__ ": unable to determine machine "
+			  "account's short name in AD!\n"));
 		ret = -1;
-		goto out;	
+		goto out;
 	}
 	/*strip the trailing '$' */
 	machine_name[strlen(machine_name)-1] = '\0';
-		
-	/* Construct our principal */
 
+	/* Construct our principal */
 	if (strchr_m(srvPrinc, '@')) {
 		/* It's a fully-named principal. */
-		if (asprintf(&princ_s, "%s", srvPrinc) == -1) {
+		princ_s = talloc_asprintf(tmpctx, "%s", srvPrinc);
+		if (!princ_s) {
 			ret = -1;
 			goto out;
 		}
 	} else if (srvPrinc[strlen(srvPrinc)-1] == '$') {
 		/* It's the machine account, as used by smbclient clients. */
-		if (asprintf(&princ_s, "%s@%s", srvPrinc, lp_realm()) == -1) {
+		princ_s = talloc_asprintf(tmpctx, "%s@%s",
+					  srvPrinc, lp_realm());
+		if (!princ_s) {
 			ret = -1;
 			goto out;
 		}
@@ -315,61 +369,72 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc)
 		/* It's a normal service principal.  Add the SPN now so that we
 		 * can obtain credentials for it and double-check the salt value
 		 * used to generate the service's keys. */
-		 
-		if (asprintf(&princ_s, "%s/%s@%s", srvPrinc, my_fqdn, lp_realm()) == -1) {
+
+		princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
+					  srvPrinc, my_fqdn, lp_realm());
+		if (!princ_s) {
 			ret = -1;
 			goto out;
 		}
-		if (asprintf(&short_princ_s, "%s/%s@%s", srvPrinc, machine_name, lp_realm()) == -1) {
+		short_princ_s = talloc_asprintf(tmpctx, "%s/%s@%s",
+						srvPrinc, machine_name,
+						lp_realm());
+		if (!princ_s) {
 			ret = -1;
 			goto out;
 		}
-		
-		/* According to http://support.microsoft.com/kb/326985/en-us, 
-		   certain principal names are automatically mapped to the host/...
-		   principal in the AD account.  So only create these in the 
-		   keytab, not in AD.  --jerry */
-		   
-		if ( !strequal( srvPrinc, "cifs" ) && !strequal(srvPrinc, "host" ) ) {
-			DEBUG(3,("ads_keytab_add_entry: Attempting to add/update '%s'\n", princ_s));
-			
-			if (!ADS_ERR_OK(ads_add_service_principal_name(ads, global_myname(), my_fqdn, srvPrinc))) {
-				DEBUG(1,("ads_keytab_add_entry: ads_add_service_principal_name failed.\n"));
+
+		/* According to http://support.microsoft.com/kb/326985/en-us,
+		   certain principal names are automatically mapped to the
+		   host/... principal in the AD account.
+		   So only create these in the keytab, not in AD.  --jerry */
+
+		if (!strequal(srvPrinc, "cifs") &&
+		    !strequal(srvPrinc, "host")) {
+			DEBUG(3, (__location__ ": Attempting to add/update "
+				  "'%s'\n", princ_s));
+
+			aderr = ads_add_service_principal_name(ads,
+					global_myname(), my_fqdn, srvPrinc);
+			if (!ADS_ERR_OK(aderr)) {
+				DEBUG(1, (__location__ ": failed to "
+					 "ads_add_service_principal_name.\n"));
 				goto out;
 			}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list