[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Jul 17 02:42:05 UTC 2015


The branch, master has been updated
       via  6aa0ae5 torture: include config.h before any glibc headers
       via  42468bc fssd: include config.h before any glibc headers
       via  102a450 source3/lib: include config.h before any glibc headers
       via  689d4a5 lib/util: include config.h before any glibc headers
       via  5768ca6 tdbrestore: include config.h before any glibc headers
       via  c404793 libads: disable dns_lookup_realm in auto-generated krb5.conf files
       via  d2cbb5f selftest: Do not lookup the realm with Kerberos
       via  c5d91e0 s4-torture: Make the backupkey test as a noop with MIT Kerberos.
       via  547af4c s4-waf: Reformat torture_rpc
       via  c9a8fff s4-auth: Always pass down the salt principal
       via  74ca775 s4-auth: Use kerberos util functions in srv_keytab
       via  6ba4d2d s4-auth: Add smb_krb5_remove_obsolete_keytab_entries()
       via  398b287 s4-auth: Add smb_krb5_create_principals_array()
       via  cd71f93 s4-samdb: Correctly cast data pointer
      from  fec300b vfs: Consolidate failure paths in vfswrap_init_asys_ctx

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


- Log -----------------------------------------------------------------
commit 6aa0ae50e286e99d2fd85d1f92302a318f066fa3
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Sun Jul 12 09:38:01 2015 +0300

    torture: include config.h before any glibc headers
    
    config.h may have some flags which affect glibc behavior, e.g.
    _FILE_OFFSET_BITS=64. To make sure these flags have the desired
    effect, config.h must be included before any glibc header files.
    
    Also remove inclusion of some system files, relying on
    replace/system/*.h instead.
    
    This commit does not fix a specific known bug. It changes the code to
    comply with coding conventions.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan Metzmacher" <metze at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Fri Jul 17 04:41:14 CEST 2015 on sn-devel-104

commit 42468bcb4018b36914b849991f46913bcfb063dd
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Sun Jul 12 09:36:46 2015 +0300

    fssd: include config.h before any glibc headers
    
    config.h may have some flags which affect glibc behavior, e.g.
    _FILE_OFFSET_BITS=64. To make sure these flags have the desired
    effect, config.h must be included before any glibc header files.
    
    This commit does not fix a specific known bug. It changes the code to
    comply with coding conventions.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan Metzmacher" <metze at samba.org>

commit 102a4503b3b5127c394e4155760dd80a7d1aa04c
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Sun Jul 12 09:31:52 2015 +0300

    source3/lib: include config.h before any glibc headers
    
    config.h may have some flags which affect glibc behavior, e.g.
    _FILE_OFFSET_BITS=64. To make sure these flags have the desired
    effect, config.h must be included before any glibc header files.
    
    This commit does not fix a specific known bug. It changes the code to
    comply with coding conventions.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan Metzmacher" <metze at samba.org>

commit 689d4a5796f185cbec407fd2dc8204b12f76f753
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Sun Jul 12 09:30:36 2015 +0300

    lib/util: include config.h before any glibc headers
    
    config.h may have some flags which affect glibc behavior, e.g.
    _FILE_OFFSET_BITS=64. To make sure these flags have the desired
    effect, config.h must be included before any glibc header files.
    
    This commit does not fix a specific known bug. It changes the code to
    comply with coding conventions.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan Metzmacher" <metze at samba.org>

commit 5768ca652360e24262200a30a45e137d85cfa245
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Sun Jul 12 09:29:13 2015 +0300

    tdbrestore: include config.h before any glibc headers
    
    config.h may have some flags which affect glibc behavior, e.g.
    _FILE_OFFSET_BITS=64. To make sure these flags have the desired
    effect, config.h must be included before any glibc header files.
    
    This commit does not fix a specific known bug. It changes the code to
    comply with coding conventions.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan Metzmacher" <metze at samba.org>

commit c404793a38507d52160fea4e3ef8d73f20593820
Author: Uri Simchoni <urisimchoni at gmail.com>
Date:   Thu Jul 2 20:15:43 2015 +0300

    libads: disable dns_lookup_realm in auto-generated krb5.conf files
    
    This patch sets dns_lookup_realm=false in samba-generated krb5.conf.
    
    Disabling dns_lookup_realm in krb5.conf is the recommended practice for
    Kerberos usage in Active Directory environment. dns_lookup_realm is enabled
    by default, at least in Heimdal.
    
    When used by samba, Kerberos libraries operate based on either the system
    krb5.conf, or a private krb5.conf generated specifically for the domain by
    samba code. In the former case, it's the responsibility of the administrator
    to set dns_lookup_realm=false. In the latter case, it's the responsibility
    of samba - which is what this patch does.
    
    In many usage scenarios the value of this variable is of no consequence
    since samba knows the realm in which it is operating, and knows how to
    generate service principal names. However, there are some scenarios
    in which samba calls kerberos_get_principal_from_service_hostname(),
    and here samba consults the Kerberos libraries and this parameter comes
    into play. One primary example is cli_full_connection() function.
    
    Not setting dns_lookup_realm leads to a series of DNS TXT record lookups.
    This can be observed by running "net ads join -k -U <user>".
    
    In AD environments, the TXT queries  typically fail quickly, but test setups
    or misconfigured DNS may lead to large timeouts (for example, if the domain
    is dept.example.com but there's no parent example.com domain and no DNS
    zones for example.com). At the very least we want to avoid those lookups
    because they are hardly documented and lead to confusion.
    
    Signed-off-by: Uri Simchoni <urisimchoni at gmail.com>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit d2cbb5f65facf6b1fbb369cc7e4a5cd8abb86573
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Jul 9 10:11:22 2015 +0200

    selftest: Do not lookup the realm with Kerberos
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c5d91e0e0f750329d3e99c8bd9345aea5a475d94
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Mar 9 20:37:45 2015 +0100

    s4-torture: Make the backupkey test as a noop with MIT Kerberos.
    
    The test is planned but will be skipped in the MIT case this way. We
    need to rewrite the test using a proper cryto/tls library.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 547af4c3c7ffbae3f828251b12fa5193c49cfb1b
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Jul 8 17:03:18 2015 +0200

    s4-waf: Reformat torture_rpc
    
    This makes it easier to read and see what changed in patches.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c9a8fff52519bb57040bf34b730263f191a6a88f
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Apr 23 19:18:32 2015 +0200

    s4-auth: Always pass down the salt principal
    
    We should always pass down the saltPrincipal to smb_krb5_update_keytab()
    function.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 74ca7753e50aeed9069d9d6700cf408254635ba0
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Apr 17 15:54:03 2015 +0200

    s4-auth: Use kerberos util functions in srv_keytab
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6ba4d2d04e8ea5818c306ed1b3fa3b4b8130b629
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Apr 17 15:53:41 2015 +0200

    s4-auth: Add smb_krb5_remove_obsolete_keytab_entries()
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 398b2877127ac46f4c2ea9a6c4ef3112e1a44f5f
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Apr 17 15:53:06 2015 +0200

    s4-auth: Add smb_krb5_create_principals_array()
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cd71f9338acbf4f27e611a47ded58c5934b3f79c
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Apr 16 13:00:54 2015 +0200

    s4-samdb: Correctly cast data pointer
    
    This fixes a signedness warning.
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 auth/credentials/credentials_krb5.c            | 110 +++++++-
 lib/tdb/tools/tdbrestore.c                     |   2 +-
 lib/util/debug.c                               |   2 +-
 lib/util/idtree.c                              |   2 +-
 selftest/target/Samba.pm                       |   2 +-
 source3/lib/messages_dgm_ref.c                 |   2 +-
 source3/libads/kerberos.c                      |   3 +-
 source3/rpc_server/fss/srv_fss_state.c         |   2 +-
 source4/auth/kerberos/kerberos_util.c          | 243 ++++++++++++++++
 source4/auth/kerberos/srv_keytab.c             | 371 ++++---------------------
 source4/dsdb/samdb/ldb_modules/password_hash.c |   2 +-
 source4/torture/local/fsrvp_state.c            |   4 +-
 source4/torture/local/verif_trailer.c          |   4 +-
 source4/torture/rpc/backupkey.c                |  28 +-
 source4/torture/rpc/rpc.c                      |   2 -
 source4/torture/wscript_build                  | 118 +++++++-
 16 files changed, 548 insertions(+), 349 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 286bede..6d0ef6f 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -731,6 +731,83 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
 	return ret;
 }
 
+static int smb_krb5_create_salt_principal(TALLOC_CTX *mem_ctx,
+					  const char *samAccountName,
+					  const char *realm,
+					  const char **salt_principal,
+					  const char **error_string)
+{
+	char *machine_username;
+	bool is_machine_account = false;
+	char *upper_realm;
+	TALLOC_CTX *tmp_ctx;
+	int rc = -1;
+
+	if (samAccountName == NULL) {
+		*error_string = "Cannot determine salt principal, no "
+				"saltPrincipal or samAccountName specified";
+		return rc;
+	}
+
+	if (realm == NULL) {
+		*error_string = "Cannot make principal without a realm";
+		return rc;
+	}
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		*error_string = "Cannot allocate talloc context";
+		return rc;
+	}
+
+	upper_realm = strupper_talloc(tmp_ctx, realm);
+	if (upper_realm == NULL) {
+		*error_string = "Cannot allocate to upper case realm";
+		goto out;
+	}
+
+	machine_username = strlower_talloc(tmp_ctx, samAccountName);
+	if (!machine_username) {
+		*error_string = "Cannot duplicate samAccountName";
+		goto out;
+	}
+
+	if (machine_username[strlen(machine_username) - 1] == '$') {
+		machine_username[strlen(machine_username) - 1] = '\0';
+		is_machine_account = true;
+	}
+
+	if (is_machine_account) {
+		char *lower_realm;
+
+		lower_realm = strlower_talloc(tmp_ctx, realm);
+		if (lower_realm == NULL) {
+			*error_string = "Cannot allocate to lower case realm";
+			goto out;
+		}
+
+		*salt_principal = talloc_asprintf(mem_ctx,
+						  "host/%s.%s@%s",
+						  machine_username,
+						  lower_realm,
+						  upper_realm);
+	} else {
+		*salt_principal = talloc_asprintf(mem_ctx,
+						  "%s@%s",
+						  machine_username,
+						  upper_realm);
+	}
+	if (*salt_principal == NULL) {
+		*error_string = "Cannot create salt principal";
+		goto out;
+	}
+
+	rc = 0;
+out:
+	talloc_free(tmp_ctx);
+	return rc;
+}
+
 /* Get the keytab (actually, a container containing the krb5_keytab)
  * attached to this context.  If this hasn't been done or set before,
  * it will be generated from the password.
@@ -745,6 +822,10 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 	const char *keytab_name;
 	krb5_keytab keytab;
 	TALLOC_CTX *mem_ctx;
+	const char *username = cli_credentials_get_username(cred);
+	const char *realm = cli_credentials_get_realm(cred);
+	const char *error_string;
+	const char *salt_principal;
 
 	if (cred->keytab_obtained >= (MAX(cred->principal_obtained, 
 					  cred->username_obtained))) {
@@ -767,13 +848,30 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
 		return ENOMEM;
 	}
 
+	/*
+	 * FIXME: Currently there is no better way than to create the correct
+	 * salt principal by checking if the username ends with a '$'. It would
+	 * be better if it is part of the credentials.
+	 */
+	ret = smb_krb5_create_salt_principal(mem_ctx,
+					     username,
+					     realm,
+					     &salt_principal,
+					     &error_string);
+	if (ret) {
+		talloc_free(mem_ctx);
+		return ret;
+	}
+
 	ret = smb_krb5_create_memory_keytab(mem_ctx,
-					smb_krb5_context->krb5_context,
-					cli_credentials_get_password(cred),
-					cli_credentials_get_username(cred),
-					cli_credentials_get_realm(cred),
-					cli_credentials_get_kvno(cred),
-					&keytab, &keytab_name);
+					    smb_krb5_context->krb5_context,
+					    cli_credentials_get_password(cred),
+					    username,
+					    realm,
+					    salt_principal,
+					    cli_credentials_get_kvno(cred),
+					    &keytab,
+					    &keytab_name);
 	if (ret) {
 		talloc_free(mem_ctx);
 		return ret;
diff --git a/lib/tdb/tools/tdbrestore.c b/lib/tdb/tools/tdbrestore.c
index f65b36f..81c986c 100644
--- a/lib/tdb/tools/tdbrestore.c
+++ b/lib/tdb/tools/tdbrestore.c
@@ -17,8 +17,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <assert.h>
 #include "replace.h"
+#include <assert.h>
 #include "system/locale.h"
 #include "system/time.h"
 #include "system/filesys.h"
diff --git a/lib/util/debug.c b/lib/util/debug.c
index 726c682..f2a445b 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -19,8 +19,8 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <talloc.h>
 #include "replace.h"
+#include <talloc.h>
 #include "system/filesys.h"
 #include "system/syslog.h"
 #include "system/locale.h"
diff --git a/lib/util/idtree.c b/lib/util/idtree.c
index 0056c09..2104c74 100644
--- a/lib/util/idtree.c
+++ b/lib/util/idtree.c
@@ -32,8 +32,8 @@
  * @file
  */
 
-#include <talloc.h>
 #include "replace.h"
+#include <talloc.h>
 #include "debug.h"
 #include "idtree.h"
 
diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm
index e128fd3..9937203 100644
--- a/selftest/target/Samba.pm
+++ b/selftest/target/Samba.pm
@@ -89,7 +89,7 @@ sub mk_krb5_conf($$)
 
 [libdefaults]
  default_realm = $ctx->{realm}
- dns_lookup_realm = true
+ dns_lookup_realm = false
  dns_lookup_kdc = true
  ticket_lifetime = 24h
  forwardable = yes
diff --git a/source3/lib/messages_dgm_ref.c b/source3/lib/messages_dgm_ref.c
index b4511e0..0a6cbf7 100644
--- a/source3/lib/messages_dgm_ref.c
+++ b/source3/lib/messages_dgm_ref.c
@@ -17,8 +17,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <talloc.h>
 #include "replace.h"
+#include <talloc.h>
 #include "messages_dgm.h"
 #include "messages_dgm_ref.h"
 #include "lib/util/debug.h"
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 1c2d8a2..e4bad74 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -879,7 +879,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
 					"[libdefaults]\n\tdefault_realm = %s\n"
 					"\tdefault_tgs_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
 					"\tdefault_tkt_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
-					"\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n\n"
+					"\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
+					"\tdns_lookup_realm = false\n\n"
 					"[realms]\n\t%s = {\n"
 					"%s\t}\n",
 					realm_upper, aes_enctypes, aes_enctypes, aes_enctypes,
diff --git a/source3/rpc_server/fss/srv_fss_state.c b/source3/rpc_server/fss/srv_fss_state.c
index 97fd0cb..97604f3 100644
--- a/source3/rpc_server/fss/srv_fss_state.c
+++ b/source3/rpc_server/fss/srv_fss_state.c
@@ -17,8 +17,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <fcntl.h>
 #include "source3/include/includes.h"
+#include <fcntl.h>
 #include "source3/include/util_tdb.h"
 #include "lib/dbwrap/dbwrap.h"
 #include "lib/dbwrap/dbwrap_open.h"
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index c2e48fd..b7f5ab0 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -134,6 +134,92 @@ static krb5_error_code impersonate_principal_from_credentials(
 			smb_krb5_context, princ, error_string);
 }
 
+krb5_error_code smb_krb5_create_principals_array(TALLOC_CTX *mem_ctx,
+						 krb5_context context,
+						 const char *account_name,
+						 const char *realm,
+						 uint32_t num_spns,
+						 const char *spns[],
+						 uint32_t *pnum_principals,
+						 krb5_principal **pprincipals,
+						 const char **error_string)
+{
+	krb5_error_code code;
+	TALLOC_CTX *tmp_ctx;
+	uint32_t num_principals = 0;
+	krb5_principal *principals;
+	uint32_t i;
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		*error_string = "Cannot allocate tmp_ctx";
+		return ENOMEM;
+	}
+
+	if (realm == NULL) {
+		*error_string = "Cannot create principal without a realm";
+		code = EINVAL;
+		goto done;
+	}
+
+	if (account_name == NULL && (num_spns == 0 || spns == NULL)) {
+		*error_string = "Cannot create principal without an account or SPN";
+		code = EINVAL;
+		goto done;
+	}
+
+	if (account_name != NULL && account_name[0] != '\0') {
+		num_principals++;
+	}
+	num_principals += num_spns;
+
+	principals = talloc_zero_array(tmp_ctx,
+				       krb5_principal,
+				       num_principals);
+	if (principals == NULL) {
+		*error_string = "Cannot allocate principals";
+		code = ENOMEM;
+		goto done;
+	}
+
+	for (i = 0; i < num_spns; i++) {
+		code = krb5_parse_name(context, spns[i], &(principals[i]));
+		if (code != 0) {
+			*error_string = smb_get_krb5_error_message(context,
+								   code,
+								   mem_ctx);
+			goto done;
+		}
+	}
+
+	if (account_name != NULL && account_name[0] != '\0') {
+		code = smb_krb5_make_principal(context,
+					       &(principals[i]),
+					       realm,
+					       account_name,
+					       NULL);
+		if (code != 0) {
+			*error_string = smb_get_krb5_error_message(context,
+								   code,
+								   mem_ctx);
+			goto done;
+		}
+	}
+
+	if (pnum_principals != NULL) {
+		*pnum_principals = num_principals;
+
+		if (pprincipals != NULL) {
+			*pprincipals = talloc_steal(mem_ctx, principals);
+		}
+	}
+
+	code = 0;
+done:
+	talloc_free(tmp_ctx);
+	return code;
+}
+
 /**
  * Return a freshly allocated ccache (destroyed by destructor on child
  * of parent_ctx), for a given set of client credentials 
@@ -385,3 +471,160 @@ krb5_error_code smb_krb5_get_keytab_container(TALLOC_CTX *mem_ctx,
 
 	return 0;
 }
+
+/*
+ * Walk the keytab, looking for entries of this principal name,
+ * with KVNO other than current kvno -1.
+ *
+ * These entries are now stale,
+ * we only keep the current and previous entries around.
+ *
+ * Inspired by the code in Samba3 for 'use kerberos keytab'.
+ */
+krb5_error_code smb_krb5_remove_obsolete_keytab_entries(TALLOC_CTX *mem_ctx,
+							krb5_context context,
+							krb5_keytab keytab,
+							uint32_t num_principals,
+							krb5_principal *principals,
+							krb5_kvno kvno,
+							bool *found_previous,
+							const char **error_string)
+{
+	TALLOC_CTX *tmp_ctx;
+	krb5_error_code code;
+	krb5_kt_cursor cursor;
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		*error_string = "Cannot allocate tmp_ctx";
+		return ENOMEM;
+	}
+
+	*found_previous = true;
+
+	code = krb5_kt_start_seq_get(context, keytab, &cursor);
+	switch (code) {
+	case 0:
+		break;
+#ifdef HEIM_ERR_OPNOTSUPP
+	case HEIM_ERR_OPNOTSUPP:
+#endif
+	case ENOENT:
+	case KRB5_KT_END:
+		/* no point enumerating if there isn't anything here */
+		code = 0;
+		goto done;
+	default:
+		*error_string = talloc_asprintf(mem_ctx,
+						"failed to open keytab for read of old entries: %s\n",
+						smb_get_krb5_error_message(context, code, mem_ctx));
+		goto done;
+	}
+
+	do {
+		krb5_keytab_entry entry;
+		bool matched = false;
+		uint32_t i;
+
+		code = krb5_kt_next_entry(context, keytab, &entry, &cursor);
+		if (code) {
+			break;
+		}
+
+		for (i = 0; i < num_principals; i++) {
+			krb5_boolean ok;
+
+			ok = smb_krb5_kt_compare(context,
+						&entry,
+						principals[i],
+						0,
+						0);
+			if (ok) {
+				matched = true;
+				break;
+			}
+		}
+
+		if (!matched) {
+			/*
+			 * Free the entry, it wasn't the one we were looking
+			 * for anyway
+			 */
+			krb5_kt_free_entry(context, &entry);
+			/* Make sure we do not double free */
+			ZERO_STRUCT(entry);
+			continue;
+		}
+
+		/* Delete it, if it is not kvno - 1 */
+		if (entry.vno != (kvno - 1)) {
+			krb5_error_code rc;
+
+			/* Release the enumeration.  We are going to
+			 * have to start this from the top again,
+			 * because deletes during enumeration may not
+			 * always be consistent.
+			 *
+			 * Also, the enumeration locks a FILE: keytab
+			 */
+			krb5_kt_end_seq_get(context, keytab, &cursor);
+
+			code = krb5_kt_remove_entry(context, keytab, &entry);
+			krb5_kt_free_entry(context, &entry);
+
+			/* Make sure we do not double free */
+			ZERO_STRUCT(entry);
+
+			/* Deleted: Restart from the top */
+			rc = krb5_kt_start_seq_get(context, keytab, &cursor);
+			if (rc != 0) {
+				krb5_kt_free_entry(context, &entry);
+
+				/* Make sure we do not double free */
+				ZERO_STRUCT(entry);
+
+				DEBUG(1, ("failed to restart enumeration of keytab: %s\n",
+					  smb_get_krb5_error_message(context,
+								     code,
+								     tmp_ctx)));
+
+				talloc_free(tmp_ctx);
+				return rc;
+			}
+
+			if (code != 0) {
+				break;
+			}
+
+		} else {
+			*found_previous = true;
+		}
+
+		/* Free the entry, we don't need it any more */
+		krb5_kt_free_entry(context, &entry);
+		/* Make sure we do not double free */
+		ZERO_STRUCT(entry);
+	} while (code != 0);
+
+	krb5_kt_end_seq_get(context, keytab, &cursor);
+
+	switch (code) {
+	case 0:
+		break;
+	case ENOENT:
+	case KRB5_KT_END:
+		code = 0;
+		break;
+	default:
+		*error_string = talloc_asprintf(mem_ctx,
+						"failed in deleting old entries for principal: %s\n",
+						smb_get_krb5_error_message(context,
+									   code,
+									   mem_ctx));
+	}
+
+	code = 0;
+done:
+	talloc_free(tmp_ctx);
+	return code;
+}
diff --git a/source4/auth/kerberos/srv_keytab.c b/source4/auth/kerberos/srv_keytab.c
index 754f2c2..ed7b1a3 100644
--- a/source4/auth/kerberos/srv_keytab.c
+++ b/source4/auth/kerberos/srv_keytab.c
@@ -23,171 +23,24 @@
 
 #include "includes.h"
 #include "system/kerberos.h"
+#include "auth/credentials/credentials.h"


-- 
Samba Shared Repository



More information about the samba-cvs mailing list