[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Sat Apr 10 05:43:15 MDT 2010


The branch, master has been updated
       via  7726773... s4:dsdb Don't use the permissive modify control on schemaInfo updates
       via  5ebeab3... s4:dsdb Don't return operational attributes on special DNs
       via  6ef167c... s4:rootdse Implement "tokenGroups" in the rootDSE
       via  944dc2c... s4:dsdb Improve error message in extended_dn_in
       via  78dd377... s4:ldif_handlers tokenGroups are SIDs
       via  4b27cc0... s4:rpc_server Fix segfault in modified SamLogon handling
       via  bc66599... s4:provision Don't make the 'slaptest' call produce errors
       via  0340826... s4:rpc_server Add all SIDs into the netlogon SamLogon reply
       via  4074739... s4:schema Try to fix OpenLDAP backend after schema reload support.
       via  c8cb17a... s4:heimdal Create a new PAC when impersonating a user with S4U2Self
       via  f2b63d5... s4:kdc Add functions to hdb-samba4 for the new s4u2self callback.
       via  1d59abc... s4:heimdal Add hooks to check with the DB before we allow s4u2self
       via  aecaddf... s4:credentials Add the functions needed to do S4U2Self with cli_credentials
       via  18f0e24... s4:credentials talloc_free() any previous salt_principal
      from  5beaef7... s4:autogen-waf: generate 'Makefile' instead of 'makefile'

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


- Log -----------------------------------------------------------------
commit 77267733edba42f03f89f3777854569bf2333321
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Apr 10 20:39:45 2010 +1000

    s4:dsdb Don't use the permissive modify control on schemaInfo updates
    
    The use of 'replace' is enough to wipe out the old value, whatever it
    is, we don't need to set 'permissive modify' too.
    
    Additionally, this seems to be causing trouble for the OpenLDAP backend
    
    Andrew Bartlett

commit 5ebeab379430104c615fd401abe9a8c7dc3339b8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Apr 9 19:07:12 2010 +1000

    s4:dsdb Don't return operational attributes on special DNs

commit 6ef167c37bcf2842434a51733c351246294842a2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Apr 9 17:22:35 2010 +1000

    s4:rootdse Implement "tokenGroups" in the rootDSE
    
    This returns the currently connected user's full token.  This is very
    useful for debugging, and should be used in ACL tests.
    
    Andrew Bartlett

commit 944dc2cb0ba13799a343f655a353013e4a9d8dd1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Fri Apr 9 17:21:21 2010 +1000

    s4:dsdb Improve error message in extended_dn_in
    
    This error occours when an extended DN cannot be resolved, so it's
    most helpful to print the problematic extended DN.
    
    Andrew Bartlett

commit 78dd3778494600f8047ba2dd0ea8635eb84258f7
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 7 14:03:29 2010 +1000

    s4:ldif_handlers tokenGroups are SIDs

commit 4b27cc0ea6e829c316da1ee87de180ff8de88fc5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 7 10:42:16 2010 +1000

    s4:rpc_server Fix segfault in modified SamLogon handling

commit bc6659936a4719a30d1f289bca7dbe639cb972cf
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 5 19:03:14 2010 +1000

    s4:provision Don't make the 'slaptest' call produce errors
    
    Adding -n 0 also allows us to check the error code too
    
    Andrew Bartlett

commit 03408267720cc1326be06fe1b6871b31ab18c097
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Mar 30 21:23:46 2010 +1100

    s4:rpc_server Add all SIDs into the netlogon SamLogon reply
    
    We were missing the SIDs that are not in the domain.

commit 4074739fe71a27feb950aa35f74bb27dc42c17f2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 29 21:16:18 2010 +1100

    s4:schema Try to fix OpenLDAP backend after schema reload support.
    
    If we can't get @REPLCHANGED, default to a value of 0.
    
    Andrew Bartlett

commit c8cb17a18c8acd831d9197fd4457881bf58250b1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Mar 29 18:13:46 2010 +1100

    s4:heimdal Create a new PAC when impersonating a user with S4U2Self
    
    If we don't do this, the PAC is given for the machine accout, not the
    account being impersonated.
    
    Andrew Bartlett

commit f2b63d58da895d11ed490dddd5df30c777369fad
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Mar 27 23:11:06 2010 +1100

    s4:kdc Add functions to hdb-samba4 for the new s4u2self callback.
    
    For now, this shares the 'if it's the same host' system with the
    constrained delegation code.
    
    Andrew Bartlett

commit 1d59abc724a9ad01fdc61f3e6cfdf41c9f4cb910
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Sat Mar 27 23:09:31 2010 +1100

    s4:heimdal Add hooks to check with the DB before we allow s4u2self
    
    This allows us to resolve multiple forms of a name, allowing for
    example machine$@REALM to get an S4U2Self ticket for
    host/machine at REALM.
    
    Andrew Bartlett

commit aecaddfa1b2a55c9cc91c3644947c3686714ceb5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Mar 3 13:24:52 2010 +1100

    s4:credentials Add the functions needed to do S4U2Self with cli_credentials
    
    A torture test to demonstrate will be added soon.
    
    Andrew Bartlett

commit 18f0e24f5573611c983d2d5d37409fa77b199dd5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Mar 3 11:34:04 2010 +1100

    s4:credentials talloc_free() any previous salt_principal
    
    This isn't used often, but it is generally better not to leak it onto
    what may be a longer-term context.
    
    Andrew Bartlett

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

Summary of changes:
 source4/auth/credentials/credentials.c             |    2 +
 source4/auth/credentials/credentials.h             |    9 ++-
 source4/auth/credentials/credentials_krb5.c        |   39 +++++++
 source4/auth/kerberos/kerberos.c                   |   79 +++++++++++--
 source4/auth/kerberos/kerberos.h                   |   15 ++-
 source4/auth/kerberos/kerberos_util.c              |  117 ++++++++++++++------
 source4/dsdb/samdb/ldb_modules/extended_dn_in.c    |    2 +-
 source4/dsdb/samdb/ldb_modules/operational.c       |    5 +
 source4/dsdb/samdb/ldb_modules/rootdse.c           |   18 +++
 source4/dsdb/samdb/ldb_modules/schema_load.c       |    6 +-
 source4/dsdb/schema/schema_info_attr.c             |    4 +-
 source4/heimdal/kdc/krb5tgs.c                      |   86 +++++++++++++-
 source4/heimdal/lib/hdb/hdb.h                      |    7 +-
 source4/kdc/db-glue.c                              |   12 +-
 source4/kdc/db-glue.h                              |    8 +-
 source4/kdc/hdb-samba4.c                           |   11 +-
 source4/kdc/mit_samba.c                            |    8 +-
 source4/lib/ldb-samba/ldif_handlers.c              |    1 +
 source4/rpc_server/netlogon/dcerpc_netlogon.c      |   85 +++++++++------
 source4/scripting/python/samba/provisionbackend.py |    9 +-
 20 files changed, 402 insertions(+), 121 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index 358ee1b..5f2658d 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -63,6 +63,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 	cred->realm = NULL;
 	cred->principal = NULL;
 	cred->salt_principal = NULL;
+	cred->impersonate_principal = NULL;
+	cred->target_service = NULL;
 
 	cred->bind_dn = NULL;
 
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index 6c077c9..ab4ee2f 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -76,7 +76,9 @@ struct cli_credentials {
 	const char *domain;
 	const char *realm;
 	const char *principal;
-	const char *salt_principal;
+	char *salt_principal;
+	char *impersonate_principal;
+	char *target_service;
 
 	const char *bind_dn;
 
@@ -268,6 +270,11 @@ 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_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_target_service(struct cli_credentials *cred);
 enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
 NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
 				     struct tevent_context *event_ctx,
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index e04b7f5..1e0db3c 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -798,7 +798,46 @@ const char *cli_credentials_get_salt_principal(struct cli_credentials *cred)
 
 _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal) 
 {
+	talloc_free(cred->salt_principal);
 	cred->salt_principal = talloc_strdup(cred, principal);
 }
 
+/* The 'impersonate_principal' is used to allow on Kerberos principal
+ * (and it's associated keytab etc) to impersonate another.  The
+ * ability to do this is controlled by the KDC, but it is generally
+ * permitted to impersonate anyone to yourself.  This allows any
+ * 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)
+{
+	return cred->impersonate_principal;
+}
+
+_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal)
+{
+	talloc_free(cred->impersonate_principal);
+	cred->impersonate_principal = talloc_strdup(cred, principal);
+}
+
+/* when impersonating for S4U2Self we need to set the target principal
+ * to ourself, as otherwise we would need additional rights.
+ * Similarly, we may only be authorized to do general impersonation to
+ * some particular services.
+ *
+ * Likewise, password changes typically require a ticket to kpasswd/realm directly, not via a TGT
+ *
+ * NULL means that tickets will be obtained for the krbtgt service.
+*/
+
+const char *cli_credentials_get_target_service(struct cli_credentials *cred)
+{
+	return cred->target_service;
+}
+
+_PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, const char *target_service)
+{
+	talloc_free(cred->target_service);
+	cred->target_service = talloc_strdup(cred, target_service);
+}
 
diff --git a/source4/auth/kerberos/kerberos.c b/source4/auth/kerberos/kerberos.c
index d4549ee..4275764 100644
--- a/source4/auth/kerberos/kerberos.c
+++ b/source4/auth/kerberos/kerberos.c
@@ -33,10 +33,15 @@
  
   This version is built to use a keyblock, rather than needing the
   original password.
+
+  The impersonate_principal is the principal if NULL, or the principal to impersonate
+
+  The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self)
 */
  krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 
-				krb5_principal principal, krb5_keyblock *keyblock,
-				time_t *expire_time, time_t *kdc_time)
+					    krb5_principal principal, krb5_keyblock *keyblock,
+					    const char *target_service,
+					    time_t *expire_time, time_t *kdc_time)
 {
 	krb5_error_code code = 0;
 	krb5_creds my_creds;
@@ -49,7 +54,7 @@
 	krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
 
 	if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
-						 0, NULL, options))) {
+						 0, target_service, options))) {
 		return code;
 	}
 	
@@ -82,36 +87,49 @@
 /*
   simulate a kinit, putting the tgt in the given credentials cache. 
   Orignally by remus at snapserver.com
+
+  The impersonate_principal is the principal if NULL, or the principal to impersonate
+
+  The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self)
+
 */
  krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 
 					    krb5_principal principal, const char *password,
+					    krb5_principal impersonate_principal, const char *target_service,
 					    time_t *expire_time, time_t *kdc_time)
 {
 	krb5_error_code code = 0;
 	krb5_creds my_creds;
-	krb5_get_init_creds_opt *options;
+	krb5_creds *impersonate_creds;
+	krb5_get_init_creds_opt *init_options;
+	krb5_get_creds_opt options;
 
-	if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
+	if ((code = krb5_get_init_creds_opt_alloc(ctx, &init_options))) {
 		return code;
 	}
 
-	krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
+	krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, init_options);
 
+	/* If we are not impersonating, then get this ticket for the
+	 * target service, otherwise a krbtgt, and get the next ticket
+	 * for the target */
 	if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, 
-						 NULL, 
-						 NULL, 0, NULL, options))) {
-		krb5_get_init_creds_opt_free(ctx, options);
+						 NULL, NULL,
+						 0,
+						 impersonate_principal ? NULL : target_service,
+						 init_options))) {
+		krb5_get_init_creds_opt_free(ctx, init_options);
 		return code;
 	}
-	
+
 	if ((code = krb5_cc_initialize(ctx, cc, principal))) {
-		krb5_get_init_creds_opt_free(ctx, options);
+		krb5_get_init_creds_opt_free(ctx, init_options);
 		krb5_free_cred_contents(ctx, &my_creds);
 		return code;
 	}
 	
 	if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
-		krb5_get_init_creds_opt_free(ctx, options);
+		krb5_get_init_creds_opt_free(ctx, init_options);
 		krb5_free_cred_contents(ctx, &my_creds);
 		return code;
 	}
@@ -124,9 +142,44 @@
 		*kdc_time = (time_t) my_creds.times.starttime;
 	}
 
-	krb5_get_init_creds_opt_free(ctx, options);
+	krb5_get_init_creds_opt_free(ctx, init_options);
 	krb5_free_cred_contents(ctx, &my_creds);
 	
+	if (code == 0 && impersonate_principal) {
+		krb5_principal target_princ;
+		if ((code = krb5_get_creds_opt_alloc(ctx, &options))) {
+			return code;
+		}
+
+		if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) {
+			krb5_get_creds_opt_free(ctx, options);
+			return code;
+		}
+
+		if ((code = krb5_parse_name(ctx, target_service, &target_princ))) {
+			krb5_get_creds_opt_free(ctx, options);
+			return code;
+		}
+
+		if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) {
+			krb5_get_creds_opt_free(ctx, options);
+			krb5_free_principal(ctx, target_princ);
+			return code;
+		}
+
+		if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) {
+			krb5_free_principal(ctx, target_princ);
+			krb5_get_creds_opt_free(ctx, options);
+			return code;
+		}
+
+		krb5_free_principal(ctx, target_princ);
+
+		code = krb5_cc_store_cred(ctx, cc, impersonate_creds);
+		krb5_get_creds_opt_free(ctx, options);
+		krb5_free_creds(ctx, impersonate_creds);
+	}
+
 	return 0;
 }
 
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index 498da0f..992b509 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -88,11 +88,13 @@ krb5_error_code ads_krb5_mk_req(krb5_context context,
 				krb5_ccache ccache, 
 				krb5_data *outbuf);
 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
-int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 
-			       krb5_principal principal, const char *password, 
-			       time_t *expire_time, time_t *kdc_time);
-int kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 
+krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
+					   krb5_principal principal, const char *password,
+					   krb5_principal impersonate_principal, const char *target_service,
+					   time_t *expire_time, time_t *kdc_time);
+krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
 			       krb5_principal principal, krb5_keyblock *keyblock,
+			       const char *target_service,
 			       time_t *expire_time, time_t *kdc_time);
 krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
 							krb5_principal host_princ,
@@ -107,6 +109,11 @@ char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TAL
 				 struct smb_krb5_context *smb_krb5_context,
 				 krb5_ccache ccache,
 				 const char **error_string);
+krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx,
+						       struct cli_credentials *credentials,
+						       struct smb_krb5_context *smb_krb5_context,
+						       krb5_principal *princ,
+						       const char **error_string);
 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 
 					   struct cli_credentials *credentials, 
 					   struct smb_krb5_context *smb_krb5_context,
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index 494f36d..44d97b7 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -40,6 +40,42 @@ static krb5_error_code free_principal(struct principal_container *pc)
 	return 0;
 }
 
+
+static krb5_error_code parse_principal(TALLOC_CTX *parent_ctx,
+				       const char *princ_string,
+				       struct smb_krb5_context *smb_krb5_context,
+				       krb5_principal *princ,
+				       const char **error_string)
+{
+	int ret;
+	struct principal_container *mem_ctx;
+	if (princ_string == NULL) {
+		 *princ = NULL;
+		 return 0;
+	}
+
+	ret = krb5_parse_name(smb_krb5_context->krb5_context,
+			      princ_string, princ);
+
+	if (ret) {
+		(*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
+		return ret;
+	}
+
+	mem_ctx = talloc(parent_ctx, struct principal_container);
+	if (!mem_ctx) {
+		(*error_string) = error_message(ENOMEM);
+		return ENOMEM;
+	}
+
+	/* This song-and-dance effectivly puts the principal
+	 * into talloc, so we can't loose it. */
+	mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
+	mem_ctx->principal = *princ;
+	talloc_set_destructor(mem_ctx, free_principal);
+	return 0;
+}
+
 static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, 
 						       struct cli_credentials *machine_account, 
 						       struct smb_krb5_context *smb_krb5_context,
@@ -50,6 +86,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 	char *salt_body;
 	char *lower_realm;
 	const char *salt_principal;
+	const char *error_string;
 	struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
 	if (!mem_ctx) {
 		return ENOMEM;
@@ -57,7 +94,7 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 
 	salt_principal = cli_credentials_get_salt_principal(machine_account);
 	if (salt_principal) {
-		ret = krb5_parse_name(smb_krb5_context->krb5_context, salt_principal, salt_princ); 
+		ret = parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, &error_string);
 	} else {
 		machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account));
 		
@@ -85,15 +122,15 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 		ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ, 
 					  cli_credentials_get_realm(machine_account), 
 					  "host", salt_body, NULL);
+		if (ret == 0) {
+			/* This song-and-dance effectivly puts the principal
+			 * into talloc, so we can't loose it. */
+			mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
+			mem_ctx->principal = *salt_princ;
+			talloc_set_destructor(mem_ctx, free_principal);
+		}
 	} 
 
-	if (ret == 0) {
-		/* This song-and-dance effectivly puts the principal
-		 * into talloc, so we can't loose it. */
-		mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
-		mem_ctx->principal = *salt_princ;
-		talloc_set_destructor(mem_ctx, free_principal);
-	}
 	return ret;
 }
 
@@ -110,36 +147,36 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 {
 	krb5_error_code ret;
 	const char *princ_string;
-	struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
+	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
 	if (!mem_ctx) {
 		(*error_string) = error_message(ENOMEM);
 		return ENOMEM;
 	}
-	
 	princ_string = cli_credentials_get_principal(credentials, mem_ctx);
-
-	/* A NULL here has meaning, as the gssapi server case will
-	 * then use the principal from the client */
 	if (!princ_string) {
-		talloc_free(mem_ctx);
-		princ = NULL;
-		return 0;
+		(*error_string) = error_message(ENOMEM);
+		return ENOMEM;
 	}
 
-	ret = krb5_parse_name(smb_krb5_context->krb5_context,
-			      princ_string, princ);
+	ret = parse_principal(parent_ctx, princ_string,
+			      smb_krb5_context, princ, error_string);
+	talloc_free(mem_ctx);
+	return ret;
+}
 
-	if (ret) {
-		(*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
-		return ret;
-	}
+/* Obtain the principal set on this context.  Requires a
+ * smb_krb5_context because we are doing krb5 principal parsing with
+ * the library routines.  The returned princ is placed in the talloc
+ * system by means of a destructor (do *not* free). */
 
-	/* This song-and-dance effectivly puts the principal
-	 * into talloc, so we can't loose it. */
-	mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
-	mem_ctx->principal = *princ;
-	talloc_set_destructor(mem_ctx, free_principal);
-	return 0;
+ krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx,
+							struct cli_credentials *credentials,
+							struct smb_krb5_context *smb_krb5_context,
+							krb5_principal *princ,
+							const char **error_string)
+{
+	return parse_principal(parent_ctx, cli_credentials_get_impersonate_principal(credentials),
+			       smb_krb5_context, princ, error_string);
 }
 
 /**
@@ -154,9 +191,10 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 				 const char **error_string)
 {
 	krb5_error_code ret;
-	const char *password;
+	const char *password, *target_service;
 	time_t kdc_time = 0;
 	krb5_principal princ;
+	krb5_principal impersonate_principal;
 	int tries;
 	TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
 
@@ -171,14 +209,26 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 		return ret;
 	}
 
+	ret = impersonate_principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &impersonate_principal, error_string);
+	if (ret) {
+		talloc_free(mem_ctx);
+		return ret;
+	}
+
+	target_service = cli_credentials_get_target_service(credentials);
+
 	password = cli_credentials_get_password(credentials);
 
 	tries = 2;
 	while (tries--) {
 		if (password) {
 			ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, 
-							 princ, 
-							 password, NULL, &kdc_time);
+							 princ, password,
+							 impersonate_principal, target_service,
+							 NULL, &kdc_time);
+		} else if (impersonate_principal) {
+			(*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock.  A password must be specified in the credentials";
+			return EINVAL;
 		} else {
 			/* No password available, try to use a keyblock instead */
 			
@@ -197,8 +247,9 @@ static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
 			
 			if (ret == 0) {
 				ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, ccache, 
-								 princ,
-								 &keyblock, NULL, &kdc_time);
+								 princ, &keyblock,
+								 target_service,
+								 NULL, &kdc_time);
 				krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &keyblock);
 			}
 		}
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c
index 3393116..e040ee1 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_in.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_in.c
@@ -156,7 +156,7 @@ static int extended_base_callback(struct ldb_request *req, struct ldb_reply *are
 
 		if (!ac->basedn) {
 			const char *str = talloc_asprintf(req, "Base-DN '%s' not found",
-							  ldb_dn_get_linearized(ac->req->op.search.base));
+							  ldb_dn_get_extended_linearized(req, ac->req->op.search.base, 1));
 			ldb_set_errstring(ldb_module_get_ctx(ac->module), str);
 			return ldb_module_done(ac->req, NULL, NULL,
 					       LDB_ERR_NO_SUCH_OBJECT);
diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c
index 9fc0d1a..94fe411 100644
--- a/source4/dsdb/samdb/ldb_modules/operational.c
+++ b/source4/dsdb/samdb/ldb_modules/operational.c
@@ -497,6 +497,11 @@ static int operational_search(struct ldb_module *module, struct ldb_request *req
 	unsigned int i, a;
 	int ret;
 
+	/* There are no operational attributes on special DNs */
+	if (ldb_dn_is_special(req->op.search.base)) {
+		return ldb_next_request(module, req);
+	}
+
 	ldb = ldb_module_get_ctx(module);
 
 	ac = talloc(req, struct operational_context);
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 808552f..e99fcaa 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -29,6 +29,7 @@
 #include "dsdb/samdb/ldb_modules/util.h"
 #include "libcli/security/security.h"
 #include "librpc/ndr/libndr.h"
+#include "auth/auth.h"
 
 struct private_data {
 	unsigned int num_controls;
@@ -381,6 +382,23 @@ static int rootdse_add_dynamic(struct ldb_module *module, struct ldb_message *ms


-- 
Samba Shared Repository


More information about the samba-cvs mailing list