[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Sep 5 14:19:01 UTC 2018


The branch, master has been updated
       via  aa07400 kdc: Improve code clarity with extra brackets
       via  41473da heimdal: Change KDC to respect HDB server name type if f.canonicalize is set
       via  f7c409c torture krb5.kdc.canon: Correct principal being checked in TEST_AS_REQ_SELF stage
       via  9e1ba90 torture: Confirm that this element of the krb5.kdc test does not pass against Windows
       via  3e5ad20 selftest/samba4.blackbox.export.keytab: Update to use a principal with SPN as UPN
       via  71ba7cb selftest: Add new test to run krb5.kdc.canon against a user with an SPN for a UPN
       via  a6182bd Revert "s4/heimdal: allow SPNs in AS-REQ"
       via  364c13a selftest/samba4.blackbox.export.keytab: Remove stray exit 0 and so run cleanup
       via  630cc6e torture: Add tests to prove that kinit to an SPN is not allowed (unless it is also a UPN)
      from  8de348e third_party: Import exact files from waf-2.0.8/waflib

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


- Log -----------------------------------------------------------------
commit aa07400f733effc4d42c6d81b6eeb9af8394b38b
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 3 12:50:39 2018 +1200

    kdc: Improve code clarity with extra brackets
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Sep  5 16:17:59 CEST 2018 on sn-devel-144

commit 41473daf09efbc4aed7ab0961ef536f15fca84f6
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 3 12:49:40 2018 +1200

    heimdal: Change KDC to respect HDB server name type if f.canonicalize is set
    
    This changes behaviour flagged as being for Java 1.6.  My hope is that this does not
    set f.canonicalize
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit f7c409c4c833615abbe0291e700b0a9fad55dd13
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 3 10:41:10 2018 +1200

    torture krb5.kdc.canon: Correct principal being checked in TEST_AS_REQ_SELF stage
    
    We have already checked the client principal.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 9e1ba904d00cc71d5a14c8ec830052cb091302f5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Aug 27 15:01:41 2018 +1200

    torture: Confirm that this element of the krb5.kdc test does not pass against Windows
    
    This should be fixed, but in the meantime add clue to avoid regressions on
    bug 11539.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 3e5ad20260f8366f1b1bc954f0199b7fd812bec7
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 3 20:26:17 2018 +1200

    selftest/samba4.blackbox.export.keytab: Update to use a principal with SPN as UPN
    
    The ability the kinit with an SPN (not also being a UPN) has gone away as
    windows doesn't offer this functionality.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 71ba7cb9b1a5896e6fcdcd6d607339c40d335027
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Aug 27 15:00:12 2018 +1200

    selftest: Add new test to run krb5.kdc.canon against a user with an SPN for a UPN
    
    The failures in this test compared with Windows Server 1709 are added to
    knownfail.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit a6182bd9512e6c78cfd2127790419418ab776be9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Nov 30 16:30:49 2017 +1300

    Revert "s4/heimdal: allow SPNs in AS-REQ"
    
    This reverts commit 20dc68050df7b1b0c9d06f8251183a0a6283fcaf.
    
    Tests (the krb5.kdc testsuite) show this behaviour is incorrect.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 364c13ac3d2d1cd05d0f5f375697807c8585f844
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Sep 3 16:38:20 2018 +1200

    selftest/samba4.blackbox.export.keytab: Remove stray exit 0 and so run cleanup
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

commit 630cc6e6268cfed08b9f21cd77181f82f36ea44b
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Nov 16 14:01:56 2017 +1300

    torture: Add tests to prove that kinit to an SPN is not allowed (unless it is also a UPN)
    
    The krb5.kdc.canon testsuite has been updated to pass against Windows
    Server 1709 in four modes:
    
    * A normal user
    * A user with a UPN
    * A user with an SPN (machine account)
    * A user with an SPN as the UPN
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>

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

Summary of changes:
 selftest/selftest.pl                             |   1 +
 selftest/target/Samba4.pm                        |  23 ++
 source4/heimdal/kdc/kerberos5.c                  |  13 +-
 source4/kdc/db-glue.c                            |   2 +-
 source4/selftest/tests.py                        |   6 +
 source4/torture/krb5/kdc-canon-heimdal.c         | 350 ++++++++++++++++++++---
 source4/torture/krb5/kdc-heimdal.c               |   9 +
 testprogs/blackbox/test_export_keytab_heimdal.sh |  15 +-
 testprogs/blackbox/test_export_keytab_mit.sh     |   2 -
 9 files changed, 369 insertions(+), 52 deletions(-)


Changeset truncated at 500 lines:

diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index 7eb5f74..3ee266c 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -815,6 +815,7 @@ sub get_running_env($)
 my @exported_envvars = (
 	# domain stuff
 	"DOMAIN",
+	"DNSNAME",
 	"REALM",
 	"DOMSID",
 
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index fb4fcc6..68038fb 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -747,6 +747,7 @@ nogroup:x:65534:nobody
 		DOMAIN => $ctx->{domain},
 		USERNAME => $ctx->{username},
 		REALM => $ctx->{realm},
+		DNSNAME => $ctx->{dnsname},
 		SAMSID => $ctx->{samsid},
 		PASSWORD => $ctx->{password},
 		LDAPDIR => $ctx->{ldapdir},
@@ -870,6 +871,28 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
 	$samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
 	$samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
 	$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
+	    . " user create --configfile=$ctx->{smb_conf} testupnspn $ctx->{password}";
+	unless (system($samba_tool_cmd) == 0) {
+		warn("Unable to add testupnspn user: \n$samba_tool_cmd\n");
+		return undef;
+	}
+
+	my $user_dn = "cn=testupnspn,cn=users,$base_dn";
+	open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
+	print LDIF "dn: $user_dn
+changetype: modify
+replace: userPrincipalName
+userPrincipalName: http/testupnspn.$ctx->{dnsname}\@$ctx->{realm}
+replace: servicePrincipalName
+servicePrincipalName: http/testupnspn.$ctx->{dnsname}
+-
+";
+	close(LDIF);
+
+	$samba_tool_cmd = "";
+	$samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+	$samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+	$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
 	    . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
 	unless (system($samba_tool_cmd) == 0) {
 		warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n");
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 12187dd..27d38ad 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -762,9 +762,9 @@ kdc_check_flags(krb5_context context,
 	    return KRB5KDC_ERR_POLICY;
 	}
 
-	if (!is_as_req && !client->flags.client){
+	if(!client->flags.client){
 	    kdc_log(context, config, 0,
-		    "Principal may only act as client in AS-REQ -- %s", client_name);
+		    "Principal may not act as client -- %s", client_name);
 	    return KRB5KDC_ERR_POLICY;
 	}
 
@@ -1056,7 +1056,7 @@ _kdc_as_rep(krb5_context context,
      */
 
     ret = _kdc_db_fetch(context, config, client_princ,
-			HDB_F_GET_ANY | flags, NULL,
+			HDB_F_GET_CLIENT | flags, NULL,
 			&clientdb, &client);
     if(ret == HDB_ERR_NOT_FOUND_HERE) {
 	kdc_log(context, config, 5, "client %s does not have secrets at this KDC, need to proxy", client_name);
@@ -1486,10 +1486,13 @@ _kdc_as_rep(krb5_context context,
     _krb5_principal2principalname(&rep.ticket.sname,
 				  server->entry.principal);
     /* java 1.6 expects the name to be the same type, lets allow that
-     * uncomplicated name-types. */
+     * uncomplicated name-types, when f.canonicalize is not set (to
+     * match Windows Server 1709). */
 #define CNT(sp,t) (((sp)->sname->name_type) == KRB5_NT_##t)
-    if (CNT(b, UNKNOWN) || CNT(b, PRINCIPAL) || CNT(b, SRV_INST) || CNT(b, SRV_HST) || CNT(b, SRV_XHST))
+    if (!f.canonicalize
+	&& (CNT(b, UNKNOWN) || CNT(b, PRINCIPAL) || CNT(b, SRV_INST) || CNT(b, SRV_HST) || CNT(b, SRV_XHST))) {
 	rep.ticket.sname.name_type = b->sname->name_type;
+    }
 #undef CNT
 
     et.flags.initial = 1;
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index bb428e4..acd24ec 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -914,7 +914,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
 			krb5_clear_error_message(context);
 			goto out;
 		}
-	} else if (flags & SDB_F_CANON && flags & SDB_F_FOR_AS_REQ) {
+	} else if ((flags & SDB_F_CANON) && (flags & SDB_F_FOR_AS_REQ)) {
 		/*
 		 * SDB_F_CANON maps from the canonicalize flag in the
 		 * packet, and has a different meaning between AS-REQ
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index cb78dd0..8c3547d 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -1080,6 +1080,12 @@ plansmbtorture4testsuite('krb5.kdc', "rodc", ['ncacn_np:$SERVER_IP', "-k", "yes"
 env = "promoted_dc"
 plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER_IP', "-k", "yes", '-U$USERNAME%$PASSWORD', '--workgroup=$DOMAIN', '--realm=$REALM'],
                          "samba4.krb5.kdc with specified account")
+plansmbtorture4testsuite('krb5.kdc', env, ['ncacn_np:$SERVER_IP', "-k", "yes", '-Utestupnspn%$PASSWORD', '--workgroup=$DOMAIN', '--realm=$REALM',
+                                           '--option=torture:expect_machine_account=true',
+                                           '--option=torture:krb5-upn=http/testupnspn.$DNSNAME@$REALM',
+                                           '--option=torture:krb5-hostname=testupnspn.$DNSNAME',
+                                           '--option=torture:krb5-service=http'],
+                         "samba4.krb5.kdc with account having identical UPN and SPN")
 
 
 for env in ["rodc", "promoted_dc", "fl2000dc", "fl2008r2dc"]:
diff --git a/source4/torture/krb5/kdc-canon-heimdal.c b/source4/torture/krb5/kdc-canon-heimdal.c
index 5b782a2..30eca87 100644
--- a/source4/torture/krb5/kdc-canon-heimdal.c
+++ b/source4/torture/krb5/kdc-canon-heimdal.c
@@ -43,7 +43,8 @@
 #define TEST_UPN              0x0000040
 #define TEST_S4U2SELF         0x0000080
 #define TEST_REMOVEDOLLAR     0x0000100
-#define TEST_ALL              0x00001FF
+#define TEST_AS_REQ_SPN       0x0000200
+#define TEST_ALL              0x00003FF
 
 struct test_data {
 	const char *test_name;
@@ -62,6 +63,8 @@ struct test_data {
 	bool other_upn_suffix;
 	bool s4u2self;
 	bool removedollar;
+	bool as_req_spn;
+	bool spn_is_upn;
 	const char *krb5_service;
 	const char *krb5_hostname;
 };
@@ -238,7 +241,8 @@ static bool torture_krb5_pre_send_as_req_test(struct torture_krb5_context *test_
 	torture_assert_int_equal(test_context->tctx, used, send_buf->length, "length mismatch");
 	torture_assert_int_equal(test_context->tctx, test_context->as_req.pvno,
 				 5, "Got wrong as_req->pvno");
-	if (test_context->test_data->canonicalize || test_context->test_data->enterprise) {
+	if (test_context->test_data->canonicalize
+	    || test_context->test_data->enterprise) {
 		torture_assert(test_context->tctx,
 			       test_context->as_req.req_body.kdc_options.canonicalize,
 			       "krb5 libs did not set canonicalize!");
@@ -249,7 +253,23 @@ static bool torture_krb5_pre_send_as_req_test(struct torture_krb5_context *test_
 					 "krb5 libs unexpectedly set canonicalize!");
 	}
 
-	if (test_context->test_data->enterprise) {
+	if (test_context->test_data->as_req_spn) {
+		if (test_context->test_data->upn) {
+			torture_assert_int_equal(test_context->tctx,
+						 test_context->as_req.req_body.cname->name_type,
+						 KRB5_NT_PRINCIPAL,
+						 "krb5 libs unexpectedly "
+						 "did not set principal "
+						 "as NT_SRV_HST!");
+		} else {
+			torture_assert_int_equal(test_context->tctx,
+						 test_context->as_req.req_body.cname->name_type,
+						 KRB5_NT_SRV_HST,
+						 "krb5 libs unexpectedly "
+						 "did not set principal "
+						 "as NT_SRV_HST!");
+		}
+	} else if (test_context->test_data->enterprise) {
 		torture_assert_int_equal(test_context->tctx,
 					 test_context->as_req.req_body.cname->name_type,
 					 KRB5_NT_ENTERPRISE_PRINCIPAL,
@@ -351,6 +371,11 @@ static bool torture_krb5_post_recv_as_req_test(struct torture_krb5_context *test
 						 error.error_code,
 						 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN - KRB5KDC_ERR_NONE,
 						 "Got wrong error.error_code");
+		} else if (test_context->test_data->as_req_spn && !test_context->test_data->spn_is_upn) {
+			torture_assert_int_equal(test_context->tctx,
+						 error.error_code,
+						 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN - KRB5KDC_ERR_NONE,
+						 "Got wrong error.error_code");
 		} else {
 			torture_assert_int_equal(test_context->tctx,
 						 error.error_code,
@@ -580,6 +605,14 @@ static bool torture_krb5_pre_send_tgs_req_canon_test(struct torture_krb5_context
 					 test_context->tgs_req.req_body.realm, test_context->test_data->real_realm,
 				 "Mismatch in realm between request and expected request");
 
+	} else if (test_context->test_data->as_req_spn) {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.sname->name_type, KRB5_NT_SRV_HST,
+					 "Mismatch in name type between request and expected request, expected  KRB5_NT_SRV_HST");
+		torture_assert_str_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.realm, test_context->test_data->real_realm,
+				 "Mismatch in realm between request and expected request");
+
 	} else if (test_context->test_data->canonicalize) {
 		torture_assert_int_equal(test_context->tctx,
 					 test_context->tgs_req.req_body.sname->name_type, KRB5_NT_PRINCIPAL,
@@ -704,7 +737,22 @@ static bool torture_krb5_pre_send_self_trust_tgs_req_test(struct torture_krb5_co
 				 0, "decode_TGS_REQ for TEST_SELF_TRUST_TGS_REQ test failed");
 	torture_assert_int_equal(test_context->tctx, used, send_buf->length, "length mismatch");
 	torture_assert_int_equal(test_context->tctx, test_context->tgs_req.pvno, 5, "Got wrong as_req->pvno");
-	torture_assert_int_equal(test_context->tctx, test_context->tgs_req.req_body.kdc_options.canonicalize, false, "krb5 libs unexpectedly set canonicalize!");
+
+	if (test_context->test_data->enterprise
+	    || (test_context->test_data->spn_is_upn && test_context->test_data->upn)) {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.kdc_options.canonicalize,
+					 true,
+					 "krb5 libs unexpectedly"
+					 " did not set canonicalize!");
+	} else {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.kdc_options.canonicalize,
+					 false,
+					 "krb5 libs unexpectedly"
+					 " set canonicalize!");
+	}
+	
 
 	if (test_context->test_data->canonicalize) {
 		torture_assert_str_equal(test_context->tctx,
@@ -829,11 +877,23 @@ static bool torture_krb5_pre_send_tgs_req_test(struct torture_krb5_context *test
 	torture_assert_int_equal(test_context->tctx, used, send_buf->length, "length mismatch");
 	torture_assert_int_equal(test_context->tctx, test_context->tgs_req.pvno, 5,
 				 "Got wrong as_req->pvno");
-	torture_assert_int_equal(test_context->tctx,
-				 test_context->tgs_req.req_body.kdc_options.canonicalize,
-				 false,
-				 "krb5 libs unexpectedly set canonicalize!");
 
+	if (test_context->test_data->enterprise
+	    && test_context->test_data->s4u2self == false
+	    && test_context->test_data->spn_is_upn) {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.kdc_options.canonicalize,
+					 true,
+					 "krb5 libs unexpectedly"
+					 " did not set canonicalize!");
+	} else {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.kdc_options.canonicalize,
+					 false,
+					 "krb5 libs unexpectedly"
+					 " set canonicalize!");
+	}
+	
 	if (test_context->test_data->enterprise) {
 		torture_assert_int_equal(test_context->tctx,
 					 test_context->tgs_req.req_body.sname->name_type,
@@ -844,6 +904,28 @@ static bool torture_krb5_pre_send_tgs_req_test(struct torture_krb5_context *test
 					 test_context->test_data->real_realm,
 					 "Mismatch in realm between request and expected request");
 
+	} else if (test_context->test_data->spn_is_upn && test_context->test_data->upn && test_context->test_data->canonicalize) {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.sname->name_type,
+					 KRB5_NT_PRINCIPAL,
+					 "Mismatch in name type between request and expected request, expected  KRB5_NT_PRINCIPAL");
+		torture_assert_str_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.realm,
+					 test_context->test_data->real_realm,
+					 "Mismatch in realm between request and expected request");
+
+	} else if (test_context->test_data->spn_is_upn
+		   && test_context->test_data->as_req_spn
+		   && test_context->test_data->canonicalize == false) {
+		torture_assert_int_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.sname->name_type,
+					 KRB5_NT_SRV_HST,
+					 "Mismatch in name type between request and expected request, expected  KRB5_NT_SRV_HST");
+		torture_assert_str_equal(test_context->tctx,
+					 test_context->tgs_req.req_body.realm,
+					 test_context->test_data->realm,
+					 "Mismatch in realm between request and expected request");
+
 	} else {
 		torture_assert_int_equal(test_context->tctx,
 					 test_context->tgs_req.req_body.sname->name_type,
@@ -1191,7 +1273,12 @@ static bool torture_krb5_post_recv_as_req_self_test(struct torture_krb5_context
 					 error.pvno, 5,
 					 "Got wrong error.pvno");
 		if ((torture_setting_bool(test_context->tctx, "expect_machine_account", false)
-		     && (test_context->test_data->upn == false))) {
+		     && ((test_context->test_data->upn == false)
+			 || (test_context->test_data->as_req_spn &&
+			     test_context->test_data->spn_is_upn)
+			 || (test_context->test_data->enterprise == false &&
+			     test_context->test_data->upn &&
+			    test_context->test_data->spn_is_upn)))) {
 			torture_assert_int_equal(test_context->tctx,
 						 error.error_code,
 						 KRB5KRB_ERR_RESPONSE_TOO_BIG - KRB5KDC_ERR_NONE,
@@ -1415,10 +1502,10 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 	krb5_principal principal;
 	krb5_principal krbtgt_other;
 	krb5_principal expected_principal;
-	char *principal_string;
+	const char *principal_string = NULL;
 	char *krbtgt_other_string;
 	int principal_flags;
-	char *expected_principal_string;
+	const char *expected_principal_string = NULL;
 	char *expected_unparse_principal_string;
 	int expected_principal_flags;
 	char *got_principal_string;
@@ -1436,6 +1523,8 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 	krb5_data in_data, enc_ticket;
 	krb5_get_creds_opt opt;
 
+	const char *spn = NULL;
+	const char *spn_real_realm = NULL;
 	const char *upn = torture_setting_string(tctx, "krb5-upn", "");
 	test_data->krb5_service = torture_setting_string(tctx, "krb5-service", "host");
 	test_data->krb5_hostname = torture_setting_string(tctx, "krb5-hostname", "");
@@ -1448,6 +1537,14 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 		torture_skip(tctx, "This test needs a UPN specified as --option=torture:krb5-upn=user at example.com to run");
 	}
 
+	/*
+	 * If we have not passed a SPN on the command line,
+	 * then skip the SPN tests.
+	 */
+	if (test_data->as_req_spn && test_data->krb5_hostname[0] == '\0') {
+		torture_skip(tctx, "This test needs a hostname specified as --option=torture:krb5-hostname=hostname.example.com and optinally --option=torture:krb5-service=service (defaults to host) to run");
+	}
+
 	if (test_data->removedollar &&
 	    !torture_setting_bool(tctx, "run_removedollar_test", false))
 	{
@@ -1520,8 +1617,34 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 		*p = '\0';
 	}
 
-	principal_string = talloc_asprintf(test_data, "%s@%s", test_data->username, test_data->realm);
+	spn = talloc_asprintf(test_data, "%s/%s@%s",
+			      test_data->krb5_service,
+			      test_data->krb5_hostname,
+			      test_data->realm);
+
+	spn_real_realm = talloc_asprintf(test_data, "%s/%s@%s",
+					 test_data->krb5_service,
+					 test_data->krb5_hostname,
+					 test_data->real_realm);
+
+	if (test_data->as_req_spn) {
+		if (test_data->enterprise) {
+			torture_skip(tctx,
+				     "This test combination "
+				     "is skipped intentionally");
+		}
+		principal_string = spn;
+	} else {
+		principal_string = talloc_asprintf(test_data,
+						   "%s@%s",
+						   test_data->username,
+						   test_data->realm);
+		
+	}
 
+	test_data->spn_is_upn
+		= (strcasecmp(upn, spn) == 0);
+				
 	/*
 	 * If we are set to canonicalize, we get back the fixed UPPER
 	 * case realm, and the real username (ie matching LDAP
@@ -1533,13 +1656,17 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 	 * Finally, if we are not set to canonicalize, we get back the
 	 * fixed UPPER case realm, but the as-sent username
 	 */
-	if (test_data->canonicalize) {
+	if (test_data->as_req_spn && !test_data->spn_is_upn) {
+		expected_principal_string = spn;
+	} else if (test_data->canonicalize) {
 		expected_principal_string = talloc_asprintf(test_data,
 							    "%s@%s",
 							    test_data->real_username,
 							    test_data->real_realm);
 	} else if (test_data->enterprise) {
 		expected_principal_string = principal_string;
+	} else if (test_data->as_req_spn && test_data->spn_is_upn) {
+		expected_principal_string = spn_real_realm;
 	} else {
 		expected_principal_string = talloc_asprintf(test_data,
 							    "%s@%s",
@@ -1574,7 +1701,25 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 						       expected_principal_flags,
 						       &expected_principal),
 				 0, "krb5_parse_name_flags failed");
-
+	
+	if (test_data->as_req_spn) {
+		if (test_data->upn) {
+			krb5_principal_set_type(k5_context,
+						principal,
+						KRB5_NT_PRINCIPAL);
+			krb5_principal_set_type(k5_context,
+						expected_principal,
+						KRB5_NT_PRINCIPAL);
+		} else {
+			krb5_principal_set_type(k5_context,
+						principal,
+						KRB5_NT_SRV_HST);
+			krb5_principal_set_type(k5_context,
+						expected_principal,
+						KRB5_NT_SRV_HST);
+		}
+	}
+	
 	torture_assert_int_equal(tctx,
 				 krb5_unparse_name(k5_context,
 						   expected_principal,
@@ -1617,6 +1762,14 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 					 "Got wrong error_code from krb5_get_init_creds_password");
 		/* We can't proceed with more checks */
 		return true;
+	} else if (test_context->test_data->as_req_spn
+		   && !test_context->test_data->spn_is_upn) {
+		torture_assert_int_equal(tctx, k5ret,
+					 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN,
+					 "Got wrong error_code from "
+					 "krb5_get_init_creds_password");
+		/* We can't proceed with more checks */
+		return true;
 	} else {
 		assertion_message = talloc_asprintf(tctx,
 						    "krb5_get_init_creds_password for %s failed: %s",
@@ -1639,6 +1792,12 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 								 my_creds.client),
 					 KRB5_NT_ENTERPRISE_PRINCIPAL,
 					 "smb_krb5_init_context gave incorrect client->name.name_type");
+	} else if (test_data->canonicalize == false && test_data->as_req_spn) {
+		torture_assert_int_equal(tctx,
+					 krb5_principal_get_type(k5_context,
+								 my_creds.client),
+					 KRB5_NT_SRV_HST,
+					 "smb_krb5_init_context gave incorrect client->name.name_type");
 	} else {
 		torture_assert_int_equal(tctx,
 					 krb5_principal_get_type(k5_context,
@@ -1844,7 +2003,9 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 		 * servicePrincipalName) can expect this test to succeed
 		 */
 		if (torture_setting_bool(tctx, "expect_machine_account", false)
-		    && (test_data->enterprise || test_data->upn == false)) {
+		    && (test_data->enterprise
+			|| test_data->spn_is_upn
+			|| test_data->upn == false)) {
 			torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
 			torture_assert_int_equal(tctx, krb5_cc_store_cred(k5_context,
 									  ccache, server_creds),
@@ -1882,6 +2043,7 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 	 */
 	if (test_context->test_data->canonicalize == false
 	    || test_context->test_data->enterprise
+	    || (test_context->test_data->spn_is_upn && test_context->test_data->upn)
 	    || (test_context->test_data->upper_realm
 		&& test_context->test_data->netbios_realm == false)) {
 		test_context->test_stage = TEST_TGS_REQ;
@@ -1909,16 +2071,77 @@ static bool torture_krb5_as_req_canon(struct torture_context *tctx, const void *
 	 * Only machine accounts (strictly, accounts with a
 	 * servicePrincipalName) can expect this test to succeed
 	 */
-	if (torture_setting_bool(tctx, "expect_machine_account", false) && (test_data->enterprise || test_data->upn == false)) {
+	if (torture_setting_bool(tctx, "expect_machine_account", false)
+	    && (test_data->enterprise ||
+		(test_context->test_data->as_req_spn 
+		 || test_context->test_data->spn_is_upn)
+		|| test_data->upn == false)) {
 		DATA_BLOB client_to_server;
 		torture_assert_int_equal(tctx, k5ret, 0, assertion_message);
 		client_to_server = data_blob_const(enc_ticket.data, enc_ticket.length);
-		torture_assert(tctx,
-			       test_accept_ticket(tctx,
-					popt_get_cmdline_credentials(),
-						  expected_unparse_principal_string,
-						  client_to_server),
-			       "test_accept_ticket failed - failed to accept the ticket we just created");
+
+		/* This is very weird */
+		if (test_data->canonicalize == false
+		    && test_context->test_data->as_req_spn
+		    && test_context->test_data->spn_is_upn
+		    && test_context->test_data->s4u2self) {
+			
+			torture_assert(tctx,
+				       test_accept_ticket(tctx,
+							  popt_get_cmdline_credentials(),
+							  spn_real_realm,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list