[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed May 18 00:49:02 MDT 2011


The branch, master has been updated
       via  902b1d9 s4:ntvfs/cifs: return NT_STATUS_INTERNAL_ERROR if no credentials are available
       via  a7b8593 s4:kdc: split s4u2self and s4u2proxy checks
       via  5f48c5d s4:kdc: UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION => flags.trusted_for_delegation
       via  053ef0f s4:auth/credentials: S4U2Self should force CRED_MUST_USE_KERBEROS
       via  a41efe6 s4:auth/credentials: pass 'self_service' to cli_credentials_set_impersonate_principal()
       via  c6836c8 s4:gensec_gssapi: avoid delegation if s4u2self/proxy is used
       via  2c46585 HEIMDAL:kdc: check and regenerate the PAC in the s4u2proxy case
       via  3797e46 HEIMDAL:kdc: pass the correct principal name for the resulting service ticket
       via  cc0ff48 HEIMDAL:kdc: let check_PAC() to verify the incoming server and krbtgt cheksums
      from  2873429 Fix bug #8144 - touch /mnt/newfile fails to set timestamp with CIFS client.

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


- Log -----------------------------------------------------------------
commit 902b1d9a19ca8bbc32c3cf1f67efd9cf6627d711
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon May 2 12:51:58 2011 +0200

    s4:ntvfs/cifs: return NT_STATUS_INTERNAL_ERROR if no credentials are available
    
    This is a configuration problem on the server, no invalid parameter
    from the client.
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Wed May 18 08:49:00 CEST 2011 on sn-devel-104

commit a7b8593f9c8f43f7861d2a0bc0e249f17d8ce7f5
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Apr 7 11:16:55 2011 +0200

    s4:kdc: split s4u2self and s4u2proxy checks
    
    metze

commit 5f48c5df513eecaff162e72bfeff39b9390710e7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Apr 7 12:16:16 2011 +0200

    s4:kdc: UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION => flags.trusted_for_delegation
    
    metze

commit 053ef0f605e8e99bf10e784cf383f954a6940d0a
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Apr 28 17:10:03 2011 +0200

    s4:auth/credentials: S4U2Self should force CRED_MUST_USE_KERBEROS
    
    Otherwise we would not impersonate the desired principal.
    This still doesn't work for plaintext auth, but should
    avoid ntlmssp.
    
    metze

commit a41efe6802da4e81a4af72aa231daa00f5012ab8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Apr 22 11:22:50 2011 +0200

    s4:auth/credentials: pass 'self_service' to cli_credentials_set_impersonate_principal()
    
    This also adds a cli_credentials_get_self_service() helper function.
    
    In order to support S4U2Proxy we need to be able to set
    the service principal for the S4U2Self step independent of the
    target principal.
    
    metze

commit c6836c8ede90a97a31c208a0057cffe78ed5a3d9
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 25 15:44:50 2011 +0100

    s4:gensec_gssapi: avoid delegation if s4u2self/proxy is used
    
    metze

commit 2c46585a428eb224755892884af6bcb0d16df463
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Apr 7 14:40:54 2011 +0200

    HEIMDAL:kdc: check and regenerate the PAC in the s4u2proxy case
    
    TODO: we need to add a S4U_DELEGATION_INFO to the PAC later.
    
    metze

commit 3797e465439ec146cde2b041a553c6dcf1eb9683
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 25 12:36:14 2011 +0100

    HEIMDAL:kdc: pass the correct principal name for the resulting service ticket
    
    Depending on S4U2Proxy the principal name for the resulting
    ticket is not the principal of the client ticket.
    
    metze

commit cc0ff48f28d13fd155489e08f75e64ff0e11b1de
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 25 14:57:42 2011 +0100

    HEIMDAL:kdc: let check_PAC() to verify the incoming server and krbtgt cheksums
    
    For a normal TGS-REQ they're both signed with krbtgt key.
    But for S4U2Proxy requests which ask for contrained delegation,
    the keys differ.
    
    metze

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

Summary of changes:
 source4/auth/credentials/credentials.c      |    1 +
 source4/auth/credentials/credentials.h      |    6 +-
 source4/auth/credentials/credentials_krb5.c |   25 +++++-
 source4/auth/gensec/gensec_gssapi.c         |    4 +
 source4/auth/kerberos/kerberos_util.c       |    8 ++-
 source4/heimdal/kdc/krb5tgs.c               |  130 ++++++++++++++++-----------
 source4/kdc/db-glue.c                       |   43 +++++++--
 source4/kdc/db-glue.h                       |   14 ++-
 source4/kdc/hdb-samba4.c                    |   27 +++++--
 source4/kdc/mit_samba.c                     |    8 +-
 source4/ntvfs/cifs/vfs_cifs.c               |    2 +-
 source4/torture/rpc/remote_pac.c            |    7 +-
 12 files changed, 189 insertions(+), 86 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index 015c549..83e9034 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -64,6 +64,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 	cred->principal = NULL;
 	cred->salt_principal = NULL;
 	cred->impersonate_principal = NULL;
+	cred->self_service = NULL;
 	cred->target_service = NULL;
 
 	cred->bind_dn = NULL;
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index 0b0de59..f8fa2f8 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -84,6 +84,7 @@ struct cli_credentials {
 	const char *principal;
 	char *salt_principal;
 	char *impersonate_principal;
+	char *self_service;
 	char *target_service;
 
 	const char *bind_dn;
@@ -277,10 +278,13 @@ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials,
 void cli_credentials_invalidate_ccache(struct cli_credentials *cred, 
 				       enum credentials_obtained obtained);
 void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal);
-void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal);
+void cli_credentials_set_impersonate_principal(struct cli_credentials *cred,
+					       const char *principal,
+					       const char *self_service);
 void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal);
 const char *cli_credentials_get_salt_principal(struct cli_credentials *cred);
 const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred);
+const char *cli_credentials_get_self_service(struct cli_credentials *cred);
 const char *cli_credentials_get_target_service(struct cli_credentials *cred);
 enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
 enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds);
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index d3925a0..bfba167 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -788,19 +788,36 @@ _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, c
  * member of the domain to get the groups of a user.  This is also
  * known as S4U2Self */
 
-const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred)
+_PUBLIC_ const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred)
 {
 	return cred->impersonate_principal;
 }
 
-_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal)
+/*
+ * The 'self_service' is the service principal that
+ * represents the same object (by its objectSid)
+ * as the client principal (typically our machine account).
+ * When trying to impersonate 'impersonate_principal' with
+ * S4U2Self.
+ */
+_PUBLIC_ const char *cli_credentials_get_self_service(struct cli_credentials *cred)
+{
+	return cred->self_service;
+}
+
+_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred,
+							const char *principal,
+							const char *self_service)
 {
 	talloc_free(cred->impersonate_principal);
 	cred->impersonate_principal = talloc_strdup(cred, principal);
+	talloc_free(cred->self_service);
+	cred->self_service = talloc_strdup(cred, self_service);
+	cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS);
 }
 
-/* when impersonating for S4U2Self we need to set the target principal
- * to ourself, as otherwise we would need additional rights.
+/*
+ * when impersonating for S4U2proxy we need to set the target principal.
  * Similarly, we may only be authorized to do general impersonation to
  * some particular services.
  *
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 4bdd7f8..47f4774 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -302,6 +302,10 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
 
 	gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
 
+	if (cli_credentials_get_impersonate_principal(creds)) {
+		gensec_gssapi_state->want_flags &= ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG);
+	}
+
 	gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
 	if (gensec_gssapi_state->target_principal) {
 		name_type = GSS_C_NULL_OID;
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index 45b0b07..f05016b 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -338,7 +338,9 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
 				 const char **error_string)
 {
 	krb5_error_code ret;
-	const char *password, *target_service;
+	const char *password;
+	const char *self_service;
+	const char *target_service;
 	time_t kdc_time = 0;
 	krb5_principal princ;
 	krb5_principal impersonate_principal;
@@ -363,6 +365,7 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
 		return ret;
 	}
 
+	self_service = cli_credentials_get_self_service(credentials);
 	target_service = cli_credentials_get_target_service(credentials);
 
 	password = cli_credentials_get_password(credentials);
@@ -403,7 +406,8 @@ krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
 		if (password) {
 			ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, 
 							 princ, password,
-							 impersonate_principal, target_service,
+							 impersonate_principal,
+							 self_service,
 							 krb_options,
 							 NULL, &kdc_time);
 		} else if (impersonate_principal) {
diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c
index 037934f..66170cb 100644
--- a/source4/heimdal/kdc/krb5tgs.c
+++ b/source4/heimdal/kdc/krb5tgs.c
@@ -282,8 +282,9 @@ check_PAC(krb5_context context,
 	  hdb_entry_ex *client,
 	  hdb_entry_ex *server,
 	  hdb_entry_ex *krbtgt,
-	  const EncryptionKey *server_key,
+	  const EncryptionKey *server_check_key,
 	  const EncryptionKey *krbtgt_check_key,
+	  const EncryptionKey *server_sign_key,
 	  const EncryptionKey *krbtgt_sign_key,
 	  EncTicketPart *tkt,
 	  krb5_data *rspac,
@@ -328,7 +329,7 @@ check_PAC(krb5_context context,
 
 		ret = krb5_pac_verify(context, pac, tkt->authtime,
 				      client_principal,
-				      krbtgt_check_key, NULL);
+				      server_check_key, krbtgt_check_key);
 		if (ret) {
 		    krb5_pac_free(context, pac);
 		    return ret;
@@ -351,7 +352,7 @@ check_PAC(krb5_context context,
 		    *signedpath = 1;
 		    ret = _krb5_pac_sign(context, pac, tkt->authtime,
 					 client_principal,
-					 server_key, krbtgt_sign_key, rspac);
+					 server_sign_key, krbtgt_sign_key, rspac);
 		}
 		krb5_pac_free(context, pac);
 		
@@ -1464,10 +1465,9 @@ tgs_build_reply(krb5_context context,
 		const struct sockaddr *from_addr)
 {
     krb5_error_code ret;
-    krb5_principal cp = NULL, sp = NULL;
-    krb5_principal client_principal = NULL;
+    krb5_principal cp = NULL, sp = NULL, tp = NULL;
     krb5_principal krbtgt_principal = NULL;
-    char *spn = NULL, *cpn = NULL;
+    char *spn = NULL, *cpn = NULL, *tpn = NULL;
     hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
     HDB *clientdb, *s4u2self_impersonated_clientdb;
     krb5_realm ref_realm = NULL;
@@ -1719,16 +1719,16 @@ server_lookup:
     krb5_free_principal(context, krbtgt_principal);
     if (ret) {
 	krb5_error_code ret2;
-	char *tpn, *tpn2;
-	ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
-	ret2 = krb5_unparse_name(context, krbtgt->entry.principal, &tpn2);
+	char *ktpn, *ktpn2;
+	ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
+	ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
 	kdc_log(context, config, 0,
 		"Request with wrong krbtgt: %s, %s not found in our database",
-		(ret == 0) ? tpn : "<unknown>", (ret2 == 0) ? tpn2 : "<unknown>");
+		(ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
 	if(ret == 0)
-	    free(tpn);
+	    free(ktpn);
 	if(ret2 == 0)
-	    free(tpn2);
+	    free(ktpn2);
 	ret = KRB5KRB_AP_ERR_NOT_US;
 	goto out;
     }
@@ -1740,13 +1740,13 @@ server_lookup:
      * this) before the strcmp() */
     if (strcmp(krb5_principal_get_realm(context, server->entry.principal),
 	       krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) {
-	char *tpn;
-	ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &tpn);
+	char *ktpn;
+	ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn);
 	kdc_log(context, config, 0,
 		"Request with wrong krbtgt: %s",
-		(ret == 0) ? tpn : "<unknown>");
+		(ret == 0) ? ktpn : "<unknown>");
 	if(ret == 0)
-	    free(tpn);
+	    free(ktpn);
 	ret = KRB5KRB_AP_ERR_NOT_US;
     }
 
@@ -1789,7 +1789,9 @@ server_lookup:
     }
 
     ret = check_PAC(context, config, cp,
-		    client, server, krbtgt, ekey, &tkey_check->key, &tkey_sign->key,
+		    client, server, krbtgt,
+		    &tkey_check->key, &tkey_check->key,
+		    ekey, &tkey_sign->key,
 		    tgt, &rspac, &signedpath);
     if (ret) {
 	const char *msg = krb5_get_error_message(context, ret);
@@ -1821,7 +1823,9 @@ server_lookup:
      * Process request
      */
 
-    client_principal = cp;
+    /* by default the tgt principal matches the client principal */
+    tp = cp;
+    tpn = cpn;
 
     if (client) {
 	const PA_DATA *sdata;
@@ -1832,7 +1836,6 @@ server_lookup:
 	    krb5_crypto crypto;
 	    krb5_data datack;
 	    PA_S4U2Self self;
-	    char *selfcpn = NULL;
 	    const char *str;
 
 	    ret = decode_PA_S4U2Self(sdata->padata_value.data,
@@ -1875,14 +1878,14 @@ server_lookup:
 	    }
 
 	    ret = _krb5_principalname2krb5_principal(context,
-						     &client_principal,
+						     &tp,
 						     self.name,
 						     self.realm);
 	    free_PA_S4U2Self(&self);
 	    if (ret)
 		goto out;
 
-	    ret = krb5_unparse_name(context, client_principal, &selfcpn);	
+	    ret = krb5_unparse_name(context, tp, &tpn);
 	    if (ret)
 		goto out;
 
@@ -1890,7 +1893,7 @@ server_lookup:
 	    if(rspac.data) {
 		krb5_pac p = NULL;
 		krb5_data_free(&rspac);
-		ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON,
+		ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | HDB_F_CANON,
 				    NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
 		if (ret) {
 		    const char *msg;
@@ -1904,14 +1907,16 @@ server_lookup:
 		    if (ret == HDB_ERR_NOENTRY)
 			ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
 		    msg = krb5_get_error_message(context, ret);
-		    kdc_log(context, config, 1, "S2U4Self principal to impersonate %s not found in database: %s", cpn, msg);
+		    kdc_log(context, config, 1,
+			    "S2U4Self principal to impersonate %s not found in database: %s",
+			    tpn, msg);
 		    krb5_free_error_message(context, msg);
 		    goto out;
 		}
 		ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
 		if (ret) {
 		    kdc_log(context, config, 0, "PAC generation failed for -- %s",
-			    selfcpn);
+			    tpn);
 		    goto out;
 		}
 		if (p != NULL) {
@@ -1922,7 +1927,7 @@ server_lookup:
 		    krb5_pac_free(context, p);
 		    if (ret) {
 			kdc_log(context, config, 0, "PAC signing failed for -- %s",
-				selfcpn);
+				tpn);
 			goto out;
 		    }
 		}
@@ -1937,8 +1942,7 @@ server_lookup:
 		kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
 			"to impersonate to service "
 			"(tried for user %s to service %s)",
-			cpn, selfcpn, spn);
-		free(selfcpn);
+			cpn, tpn, spn);
 		goto out;
 	    }
 
@@ -1954,8 +1958,7 @@ server_lookup:
 		str = "";
 	    }
 	    kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
-		    "service %s %s", cpn, selfcpn, spn, str);
-	    free(selfcpn);
+		    "service %s %s", cpn, tpn, spn, str);
 	}
     }
 
@@ -1971,7 +1974,6 @@ server_lookup:
 	int ad_signedpath = 0;
 	Key *clientkey;
 	Ticket *t;
-	char *str;
 
 	/*
 	 * Require that the KDC have issued the service's krbtgt (not
@@ -2002,11 +2004,23 @@ server_lookup:
 	    goto out;
 	}
 
+	ret = _krb5_principalname2krb5_principal(context,
+						 &tp,
+						 adtkt.cname,
+						 adtkt.crealm);
+	if (ret)
+	    goto out;
+
+	ret = krb5_unparse_name(context, tp, &tpn);
+	if (ret)
+	    goto out;
+
 	/* check that ticket is valid */
 	if (adtkt.flags.forwardable == 0) {
 	    kdc_log(context, config, 0,
 		    "Missing forwardable flag on ticket for "
-		    "constrained delegation from %s to %s ", cpn, spn);
+		    "constrained delegation from %s as %s to %s ",
+		    cpn, tpn, spn);
 	    ret = KRB5KDC_ERR_BADOPTION;
 	    goto out;
 	}
@@ -2015,25 +2029,37 @@ server_lookup:
 					   client, sp);
 	if (ret) {
 	    kdc_log(context, config, 0,
-		    "constrained delegation from %s to %s not allowed",
-		    cpn, spn);
+		    "constrained delegation from %s as %s to %s not allowed",
+		    cpn, tpn, spn);
 	    goto out;
 	}
 
-	ret = _krb5_principalname2krb5_principal(context,
-						 &client_principal,
-						 adtkt.cname,
-						 adtkt.crealm);
-	if (ret)
-	    goto out;
-
-	ret = krb5_unparse_name(context, client_principal, &str);
-	if (ret)
+	ret = verify_flags(context, config, &adtkt, tpn);
+	if (ret) {
 	    goto out;
+	}
 
-	ret = verify_flags(context, config, &adtkt, str);
+	krb5_data_free(&rspac);
+	/*
+	 * generate the PAC for the user.
+	 *
+	 * TODO: pass in t->sname and t->realm and build
+	 * a S4U_DELEGATION_INFO blob to the PAC.
+	 */
+	ret = check_PAC(context, config, tp,
+			client, server, krbtgt,
+			&clientkey->key, &tkey_check->key,
+			ekey, &tkey_sign->key,
+			&adtkt, &rspac, &ad_signedpath);
+	if (ret == 0 && !ad_signedpath)
+	    ret = KRB5KDC_ERR_BADOPTION;
 	if (ret) {
-	    free(str);
+	    const char *msg = krb5_get_error_message(context, ret);
+	    kdc_log(context, config, 0,
+		    "Verify delegated PAC failed to %s for client"
+		    "%s as %s from %s with %s",
+		    spn, cpn, tpn, from, msg);
+	    krb5_free_error_message(context, msg);
 	    goto out;
 	}
 
@@ -2043,7 +2069,7 @@ server_lookup:
 	ret = check_KRB5SignedPath(context,
 				   config,
 				   krbtgt,
-				   cp,
+				   tp,
 				   &adtkt,
 				   NULL,
 				   &ad_signedpath);
@@ -2055,15 +2081,13 @@ server_lookup:
 		    "KRB5SignedPath check from service %s failed "
 		    "for delegation to %s for client %s "
 		    "from %s failed with %s",
-		    spn, str, cpn, from, msg);
+		    spn, tpn, cpn, from, msg);
 	    krb5_free_error_message(context, msg);
-	    free(str);
 	    goto out;
 	}
 
 	kdc_log(context, config, 0, "constrained delegation for %s "
-		"from %s to %s", str, cpn, spn);
-	free(str);
+		"from %s to %s", tpn, cpn, spn);
     }
 
     /*
@@ -2134,7 +2158,7 @@ server_lookup:
     ret = tgs_make_reply(context,
 			 config,
 			 b,
-			 client_principal,
+			 tp,
 			 tgt,
 			 replykey,
 			 rk_is_subkey,
@@ -2156,6 +2180,8 @@ server_lookup:
 			 reply);
 	
 out:
+    if (tpn != cpn)
+	    free(tpn);
     free(spn);
     free(cpn);
 	
@@ -2170,8 +2196,8 @@ out:
     if(s4u2self_impersonated_client)
 	_kdc_free_ent(context, s4u2self_impersonated_client);
 
-    if (client_principal && client_principal != cp)
-	krb5_free_principal(context, client_principal);
+    if (tp && tp != cp)
+	krb5_free_principal(context, tp);
     if (cp)
 	krb5_free_principal(context, cp);
     if (sp)
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index 732e553..72262ac 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -159,6 +159,20 @@ static HDBFlags uf2HDBFlags(krb5_context context, uint32_t userAccountControl, e
 	if (userAccountControl & UF_TRUSTED_FOR_DELEGATION) {
 		flags.ok_as_delegate = 1;
 	}
+	if (userAccountControl & UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION) {
+		/*
+		 * this is confusing...
+		 *
+		 * UF_TRUSTED_FOR_DELEGATION
+		 * => ok_as_delegate
+		 *
+		 * and
+		 *
+		 * UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
+		 * => trusted_for_delegation
+		 */
+		flags.trusted_for_delegation = 1;
+	}
 	if (!(userAccountControl & UF_NOT_DELEGATED)) {
 		flags.forwardable = 1;
 		flags.proxiable = 1;
@@ -1521,14 +1535,12 @@ krb5_error_code samba_kdc_nextkey(krb5_context context,
 /* Check if a given entry may delegate or do s4u2self to this target principal
  *
  * This is currently a very nasty hack - allowing only delegation to itself.
- *
- * This is shared between the constrained delegation and S4U2Self code.
  */
 krb5_error_code
-samba_kdc_check_identical_client_and_server(krb5_context context,
-					    struct samba_kdc_db_context *kdc_db_ctx,
-					    hdb_entry_ex *entry,
-					    krb5_const_principal target_principal)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list