[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Tue May 7 12:34:01 UTC 2024
The branch, master has been updated
via 87e31f88f28 s3:libsmb: let cli_session_creds_init() keep the value from 'client use kerberos'
via e6c693b7056 s3:winbindd: pass a NULL ccache to kerberos_return_pac() for a MEMORY ccache
via 147565232dc s3:libads: use smb_krb5_cc_new_unique_memory() in kerberos_return_pac()
via 16a5279e291 auth/credentials: use smb_krb5_cc_new_unique_memory() in cli_credentials_new_ccache()
via 176c55efb20 auth/credentials: use smb_krb5_cc_new_unique_memory() in cli_credentials_shallow_ccache()
via 5d385ab691f auth/credentials: use smb_krb5_cc_new_unique_memory() in smb_gss_krb5_copy_ccache()
via 92bebeb58ef auth/credentials: use smb_krb5_cc_new_unique_memory() in krb5_cc_remove_cred_wrap()
via 21b96f010a4 lib/krb5_wrap: make use of smb_krb5_cc_new_unique_memory() in smb_krb5_kinit_s4u2_ccache()
via 48bcc218c98 lib/krb5_wrap: add smb_krb5_cc_new_unique_memory()
via e3f97f35b18 s3:gse: don't call krb5_cc_resolve() as server
via 6ced3c6af22 s3:gse: avoid prompting for a password that we don't use in the end
via ce05fe3b718 s3:gse: make use of gensec_kerberos_possible()
via 4dd2468d5bc s4:gensec_gssapi: make use of gensec_kerberos_possible()
via a3c87bf4404 auth/gensec: add gensec_get_unparsed_target_principal() helper
via 996fd13949b auth/gensec: add gensec_kerberos_possible() helper
via 1275e77933f s3:client: avoid cli_credentials_get_password() to check for a specified password
via b9cf6c8dd4d auth:creds: Add test for cli_credentials_get_username_obtained()
via f9afd24c907 auth/credentials: add cli_credentials_get_username_obtained()
via 7f0aff46825 auth:creds: Add test for cli_credentials_get_password_obtained()
via c14366cce45 auth/credentials: add cli_credentials_get_password_obtained()
via a85f1b6facd lib/cmdline: skip the password prompt if we have a valid krb5 ccache
via c7d3946659f auth/credentials: add cli_credentials_get_ccache_name_obtained()
via 4723d695608 auth:creds: Add test for cli_credentials_get_principal_obtained()
via 1e5546748cd auth/credentials: add cli_credentials_get_principal_obtained()
from 5edd1e7c3ee smbd: Implement FSCTL_DELETE_REPARSE_POINT
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 87e31f88f28210dc6b7033182435f55204098368
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Mar 7 15:31:39 2024 +0100
s3:libsmb: let cli_session_creds_init() keep the value from 'client use kerberos'
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Tue May 7 12:33:29 UTC 2024 on atb-devel-224
commit e6c693b705686a590d2fa8f434ff015d8926a349
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Feb 28 17:28:43 2024 +0100
s3:winbindd: pass a NULL ccache to kerberos_return_pac() for a MEMORY ccache
It means kerberos_return_pac() will use smb_krb5_cc_new_unique_memory().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 147565232dc7cc3127e09268000723c5a3eea62b
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Feb 28 17:27:39 2024 +0100
s3:libads: use smb_krb5_cc_new_unique_memory() in kerberos_return_pac()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 16a5279e2918e7348f1695629bf3fa61c9007424
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 16:38:42 2024 +0100
auth/credentials: use smb_krb5_cc_new_unique_memory() in cli_credentials_new_ccache()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 176c55efb202f1f218c6c4ddf69d2d357488e25f
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 16:21:02 2024 +0100
auth/credentials: use smb_krb5_cc_new_unique_memory() in cli_credentials_shallow_ccache()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 5d385ab691f21bdd4524c41560c7f53653cf179d
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 16:19:58 2024 +0100
auth/credentials: use smb_krb5_cc_new_unique_memory() in smb_gss_krb5_copy_ccache()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 92bebeb58ef5ab91937d29640bf7a3c7929518ca
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 15:49:09 2024 +0100
auth/credentials: use smb_krb5_cc_new_unique_memory() in krb5_cc_remove_cred_wrap()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 21b96f010a4f9472a03aca5f4c1ed5a658530f52
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 15:47:15 2024 +0100
lib/krb5_wrap: make use of smb_krb5_cc_new_unique_memory() in smb_krb5_kinit_s4u2_ccache()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 48bcc218c980e9478e2a3479e889766e6ca7f1dd
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Feb 27 15:42:37 2024 +0100
lib/krb5_wrap: add smb_krb5_cc_new_unique_memory()
This generates a memory credential cache that is
not visible to a (the default) credential cache collection.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit e3f97f35b18f9c11d718223b64de87ce1c08f64c
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 29 16:15:37 2024 +0100
s3:gse: don't call krb5_cc_resolve() as server
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 6ced3c6af22a5e8f7d84e52c769029ea8a265724
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 14 14:23:23 2022 +0200
s3:gse: avoid prompting for a password that we don't use in the end
Currently we rely on a valid default credential cache being available
and don't make use of the password.
In future we'll do a kinit on demand, but that's for another day.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit ce05fe3b718a5d242f31f1acb25f5d7c5a6e4e0a
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 5 15:33:51 2024 +0100
s3:gse: make use of gensec_kerberos_possible()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 4dd2468d5bcd704d8a745f9f3e487e539ae66bbb
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 5 15:33:51 2024 +0100
s4:gensec_gssapi: make use of gensec_kerberos_possible()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit a3c87bf440457c59cdad8883fca142b5f06da587
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 5 15:32:59 2024 +0100
auth/gensec: add gensec_get_unparsed_target_principal() helper
This will be useful for debugging.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 996fd13949b9c4aa842971520a6a6d3059559caa
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Mar 5 14:41:39 2024 +0100
auth/gensec: add gensec_kerberos_possible() helper
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 1275e77933f74b5b8551aa9c5e5f84fbd561de04
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 14 13:49:39 2022 +0200
s3:client: avoid cli_credentials_get_password() to check for a specified password
Using cli_credentials_get_password_obtained() is more lightweight as
it avoids a possible password prompt.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit b9cf6c8dd4d256300df170b1b21a86fe02416018
Author: Andreas Schneider <asn at samba.org>
Date: Tue May 7 07:45:50 2024 +0200
auth:creds: Add test for cli_credentials_get_username_obtained()
Signed-off-by: Andreas Schneider <asn at samba.org>
commit f9afd24c907eaecd65a3b7a1387139472876047d
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Mar 13 17:50:34 2024 +0100
auth/credentials: add cli_credentials_get_username_obtained()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 7f0aff468256415c76bbcd5c7249f909de9f3b91
Author: Andreas Schneider <asn at samba.org>
Date: Tue May 7 07:44:22 2024 +0200
auth:creds: Add test for cli_credentials_get_password_obtained()
Signed-off-by: Andreas Schneider <asn at samba.org>
commit c14366cce45a437584d9050067a34fffb847e134
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 14 13:46:18 2022 +0200
auth/credentials: add cli_credentials_get_password_obtained()
It's often useful to know if a password was already explicitly
specified without triggering the password callback function.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit a85f1b6facd2b641f98dcea9b997a02d8f276882
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 14 13:34:37 2022 +0200
lib/cmdline: skip the password prompt if we have a valid krb5 ccache
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15018
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit c7d3946659ff9ce167f68f3f052fae02a8907869
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Apr 14 13:29:47 2022 +0200
auth/credentials: add cli_credentials_get_ccache_name_obtained()
It's often good to know if a credential structure already has
a valid kerberos credential cache attached, without the side
effect of doing a kinit and prompt for a password.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15018
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
commit 4723d695608e7737176e4f6eb407885a38989fc8
Author: Andreas Schneider <asn at samba.org>
Date: Tue May 7 07:54:46 2024 +0200
auth:creds: Add test for cli_credentials_get_principal_obtained()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15018
Signed-off-by: Andreas Schneider <asn at samba.org>
commit 1e5546748cd22c9e654ed066ab1d27aadec0d3d3
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Mar 13 17:50:56 2024 +0100
auth/credentials: add cli_credentials_get_principal_obtained()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15018
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andreas Schneider <asn at samba.org>
-----------------------------------------------------------------------
Summary of changes:
auth/credentials/credentials.c | 83 +++++++++++++++++++
auth/credentials/credentials.h | 8 ++
auth/credentials/credentials_krb5.c | 160 +++++++++++++++++++++++++-----------
auth/credentials/tests/test_creds.c | 13 ++-
auth/gensec/gensec_internal.h | 4 +
auth/gensec/gensec_util.c | 81 ++++++++++++++++++
lib/cmdline/cmdline.c | 19 +++++
lib/krb5_wrap/krb5_samba.c | 78 +++++++++++++++++-
lib/krb5_wrap/krb5_samba.h | 5 ++
source3/client/client.c | 4 +-
source3/libads/authdata.c | 33 +++++++-
source3/librpc/crypto/gse.c | 76 ++++++++---------
source3/libsmb/cliconnect.c | 8 +-
source3/winbindd/winbindd_pam.c | 47 ++++++-----
source4/auth/gensec/gensec_gssapi.c | 42 +++-------
15 files changed, 511 insertions(+), 150 deletions(-)
Changeset truncated at 500 lines:
diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 6a590483e99..441db6f0e5b 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -176,6 +176,18 @@ _PUBLIC_ uint32_t cli_credentials_get_gensec_features(struct cli_credentials *cr
return creds->gensec_features;
}
+/**
+ * @brief Find out how the username was obtained.
+ *
+ * @param cred A credentials context.
+ *
+ * @return The obtained information for the username.
+ */
+_PUBLIC_ enum credentials_obtained
+cli_credentials_get_username_obtained(struct cli_credentials *cred)
+{
+ return cred->username_obtained;
+}
/**
* Obtain the username for this credentials context.
@@ -268,6 +280,64 @@ _PUBLIC_ const char *cli_credentials_get_bind_dn(struct cli_credentials *cred)
}
+/**
+ * @brief Find out how the principal was obtained.
+ *
+ * @param cred A credentials context.
+ *
+ * @return The obtained information for the principal.
+ */
+_PUBLIC_ enum credentials_obtained
+cli_credentials_get_principal_obtained(struct cli_credentials *cred)
+{
+ if (cred->machine_account_pending) {
+ cli_credentials_set_machine_account(cred,
+ cred->machine_account_pending_lp_ctx);
+ }
+
+ if (cred->principal_obtained < cred->username_obtained
+ || cred->principal_obtained < MAX(cred->domain_obtained, cred->realm_obtained)) {
+ const char *effective_username = NULL;
+ const char *effective_realm = NULL;
+ enum credentials_obtained effective_obtained;
+
+ /*
+ * We don't want to trigger a callbacks in
+ * cli_credentials_get_username()
+ * cli_credentials_get_domain()
+ * nor
+ * cli_credentials_get_realm()
+ */
+
+ effective_username = cred->username;
+ if (effective_username == NULL || strlen(effective_username) == 0) {
+ return cred->username_obtained;
+ }
+
+ if (cred->domain_obtained > cred->realm_obtained) {
+ effective_realm = cred->domain;
+ effective_obtained = MIN(cred->domain_obtained,
+ cred->username_obtained);
+ } else {
+ effective_realm = cred->realm;
+ effective_obtained = MIN(cred->realm_obtained,
+ cred->username_obtained);
+ }
+
+ if (effective_realm == NULL || strlen(effective_realm) == 0) {
+ effective_realm = cred->domain;
+ effective_obtained = MIN(cred->domain_obtained,
+ cred->username_obtained);
+ }
+
+ if (effective_realm != NULL && strlen(effective_realm) != 0) {
+ return effective_obtained;
+ }
+ }
+
+ return cred->principal_obtained;
+}
+
/**
* Obtain the client principal for this credentials context.
* @param cred credentials context
@@ -453,6 +523,19 @@ _PUBLIC_ const char *cli_credentials_get_password(struct cli_credentials *cred)
return cred->password;
}
+/**
+ * @brief Find out how the password was obtained.
+ *
+ * @param cred A credentials context.
+ *
+ * @return The obtained information for the password.
+ */
+_PUBLIC_ enum credentials_obtained
+cli_credentials_get_password_obtained(struct cli_credentials *cred)
+{
+ return cred->password_obtained;
+}
+
/**
* @brief Obtain the password for this credentials context.
*
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 9a9bd513201..386647c7aae 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -91,6 +91,7 @@ struct cli_credentials *cli_credentials_init_server(TALLOC_CTX *mem_ctx,
void cli_credentials_set_anonymous(struct cli_credentials *cred);
bool cli_credentials_wrong_password(struct cli_credentials *cred);
const char *cli_credentials_get_password(struct cli_credentials *cred);
+enum credentials_obtained cli_credentials_get_password_obtained(struct cli_credentials *cred);
const char *cli_credentials_get_password_and_obtained(struct cli_credentials *cred,
enum credentials_obtained *obtained);
void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
@@ -105,6 +106,7 @@ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_
DATA_BLOB *_lm_session_key, DATA_BLOB *_session_key);
const char *cli_credentials_get_realm(struct cli_credentials *cred);
const char *cli_credentials_get_username(struct cli_credentials *cred);
+enum credentials_obtained cli_credentials_get_username_obtained(struct cli_credentials *cred);
const char *cli_credentials_get_username_and_obtained(struct cli_credentials *cred,
enum credentials_obtained *obtained);
int cli_credentials_get_krb5_context(struct cli_credentials *cred,
@@ -120,6 +122,10 @@ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
struct loadparm_context *lp_ctx,
char *ccache_name,
struct ccache_container **ccc, const char **error_string);
+bool cli_credentials_get_ccache_name_obtained(struct cli_credentials *cred,
+ TALLOC_CTX *mem_ctx,
+ char **ccache_name,
+ enum credentials_obtained *obtained);
bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred,
const char *principal,
unsigned int *count);
@@ -280,6 +286,8 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
bool cli_credentials_set_username_callback(struct cli_credentials *cred,
const char *(*username_cb) (struct cli_credentials *));
+enum credentials_obtained cli_credentials_get_principal_obtained(struct cli_credentials *cred);
+
/**
* Obtain the client principal for this credentials context.
* @param cred credentials context
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index dcfa2e4daee..49077db23b3 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -79,25 +79,15 @@ static uint32_t smb_gss_krb5_copy_ccache(uint32_t *min_stat,
krb5_cc_cursor cursor = NULL;
krb5_principal princ = NULL;
krb5_error_code code;
- char *dummy_name;
uint32_t maj_stat = GSS_S_FAILURE;
- dummy_name = talloc_asprintf(ccc,
- "MEMORY:gss_krb5_copy_ccache-%p",
- &ccc->ccache);
- if (dummy_name == NULL) {
- *min_stat = ENOMEM;
- return GSS_S_FAILURE;
- }
-
/*
* Create a dummy ccache, so we can iterate over the credentials
* and find the default principal for the ccache we want to
* copy. The new ccache needs to be initialized with this
* principal.
*/
- code = krb5_cc_resolve(context, dummy_name, &dummy_ccache);
- TALLOC_FREE(dummy_name);
+ code = smb_krb5_cc_new_unique_memory(context, NULL, NULL, &dummy_ccache);
if (code != 0) {
*min_stat = code;
return GSS_S_FAILURE;
@@ -382,29 +372,18 @@ static krb5_error_code krb5_cc_remove_cred_wrap(struct ccache_container *ccc,
krb5_creds cached_creds = {0};
krb5_cc_cursor cursor = NULL;
krb5_error_code code;
- char *dummy_name;
-
- dummy_name = talloc_asprintf(ccc,
- "MEMORY:copy_ccache-%p",
- &ccc->ccache);
- if (dummy_name == NULL) {
- return KRB5_CC_NOMEM;
- }
- code = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context,
- dummy_name,
- &dummy_ccache);
+ code = smb_krb5_cc_new_unique_memory(ccc->smb_krb5_context->krb5_context,
+ NULL, NULL,
+ &dummy_ccache);
if (code != 0) {
DBG_ERR("krb5_cc_resolve failed: %s\n",
smb_get_krb5_error_message(
ccc->smb_krb5_context->krb5_context,
code, ccc));
- TALLOC_FREE(dummy_name);
return code;
}
- TALLOC_FREE(dummy_name);
-
code = krb5_cc_start_seq_get(ccc->smb_krb5_context->krb5_context,
ccc->ccache,
&cursor);
@@ -597,10 +576,11 @@ _PUBLIC_ bool cli_credentials_failed_kerberos_login(struct cli_credentials *cred
static int cli_credentials_new_ccache(struct cli_credentials *cred,
struct loadparm_context *lp_ctx,
- char *ccache_name,
+ char *given_ccache_name,
struct ccache_container **_ccc,
const char **error_string)
{
+ char *ccache_name = given_ccache_name;
bool must_free_cc_name = false;
krb5_error_code ret;
struct ccache_container *ccc = talloc(cred, struct ccache_container);
@@ -623,25 +603,27 @@ static int cli_credentials_new_ccache(struct cli_credentials *cred,
}
if (!ccache_name) {
- must_free_cc_name = true;
-
if (lpcfg_parm_bool(lp_ctx, NULL, "credentials", "krb5_cc_file", false)) {
ccache_name = talloc_asprintf(ccc, "FILE:/tmp/krb5_cc_samba_%u_%p",
(unsigned int)getpid(), ccc);
- } else {
- ccache_name = talloc_asprintf(ccc, "MEMORY:%p",
- ccc);
- }
-
- if (!ccache_name) {
- talloc_free(ccc);
- (*error_string) = strerror(ENOMEM);
- return ENOMEM;
+ if (ccache_name == NULL) {
+ talloc_free(ccc);
+ (*error_string) = strerror(ENOMEM);
+ return ENOMEM;
+ }
+ must_free_cc_name = true;
}
}
- ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name,
- &ccc->ccache);
+ if (ccache_name != NULL) {
+ ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name,
+ &ccc->ccache);
+ } else {
+ ret = smb_krb5_cc_new_unique_memory(ccc->smb_krb5_context->krb5_context,
+ ccc, &ccache_name,
+ &ccc->ccache);
+ must_free_cc_name = true;
+ }
if (ret) {
(*error_string) = talloc_asprintf(cred, "failed to resolve a krb5 ccache (%s): %s\n",
ccache_name,
@@ -758,6 +740,95 @@ _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred,
return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string);
}
+/**
+ * @brief Check if a valid Kerberos credential cache is attached.
+ *
+ * This will not ask for a password nor do a kinit.
+ *
+ * @param cred The credentials context.
+ *
+ * @param mem_ctx A memory context to allocate the ccache_name.
+ *
+ * @param ccache_name A pointer to a string to store the ccache name.
+ *
+ * @param obtained A pointer to store the information how the ccache was
+ * obtained.
+ *
+ * @return True if a credential cache is attached, false if not or an error
+ * occurred.
+ */
+_PUBLIC_ bool cli_credentials_get_ccache_name_obtained(
+ struct cli_credentials *cred,
+ TALLOC_CTX *mem_ctx,
+ char **ccache_name,
+ enum credentials_obtained *obtained)
+{
+ if (ccache_name != NULL) {
+ *ccache_name = NULL;
+ }
+
+ if (obtained != NULL) {
+ *obtained = CRED_UNINITIALISED;
+ }
+
+ if (cred->machine_account_pending) {
+ return false;
+ }
+
+ if (cred->ccache_obtained == CRED_UNINITIALISED) {
+ return false;
+ }
+
+ if (cred->ccache_obtained >= cred->ccache_threshold) {
+ krb5_context k5ctx = cred->ccache->smb_krb5_context->krb5_context;
+ krb5_ccache k5ccache = cred->ccache->ccache;
+ krb5_error_code ret;
+ time_t lifetime = 0;
+
+ ret = smb_krb5_cc_get_lifetime(k5ctx, k5ccache, &lifetime);
+ if (ret == KRB5_CC_END || ret == ENOENT) {
+ return false;
+ }
+ if (ret != 0) {
+ return false;
+ }
+ if (lifetime == 0) {
+ return false;
+ } else if (lifetime < 300) {
+ if (cred->password_obtained >= cred->ccache_obtained) {
+ /*
+ * we have a password to re-kinit
+ * so let the caller try that.
+ */
+ return false;
+ }
+ }
+
+ if (ccache_name != NULL) {
+ char *name = NULL;
+
+ ret = krb5_cc_get_full_name(k5ctx, k5ccache, &name);
+ if (ret != 0) {
+ return false;
+ }
+
+ *ccache_name = talloc_strdup(mem_ctx, name);
+ SAFE_FREE(name);
+ if (*ccache_name == NULL) {
+ return false;
+ }
+ }
+
+ if (obtained != NULL) {
+ *obtained = cred->ccache_obtained;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
/* We have good reason to think the ccache in these credentials is invalid - blow it away */
static void cli_credentials_unconditionally_invalidate_client_gss_creds(struct cli_credentials *cred)
{
@@ -1070,7 +1141,6 @@ static int cli_credentials_shallow_ccache(struct cli_credentials *cred)
const struct ccache_container *old_ccc = NULL;
enum credentials_obtained old_obtained;
struct ccache_container *ccc = NULL;
- char *ccache_name = NULL;
krb5_principal princ;
old_obtained = cred->ccache_obtained;
@@ -1103,10 +1173,10 @@ static int cli_credentials_shallow_ccache(struct cli_credentials *cred)
*ccc = *old_ccc;
ccc->ccache = NULL;
- ccache_name = talloc_asprintf(ccc, "MEMORY:%p", ccc);
-
- ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context,
- ccache_name, &ccc->ccache);
+ ret = smb_krb5_cc_new_unique_memory(ccc->smb_krb5_context->krb5_context,
+ NULL,
+ NULL,
+ &ccc->ccache);
if (ret != 0) {
TALLOC_FREE(ccc);
return ret;
@@ -1114,8 +1184,6 @@ static int cli_credentials_shallow_ccache(struct cli_credentials *cred)
talloc_set_destructor(ccc, free_mccache);
- TALLOC_FREE(ccache_name);
-
ret = smb_krb5_cc_copy_creds(ccc->smb_krb5_context->krb5_context,
old_ccc->ccache, ccc->ccache);
if (ret != 0) {
diff --git a/auth/credentials/tests/test_creds.c b/auth/credentials/tests/test_creds.c
index 2cb2e6d0e34..054b7321ce4 100644
--- a/auth/credentials/tests/test_creds.c
+++ b/auth/credentials/tests/test_creds.c
@@ -166,6 +166,9 @@ static void torture_creds_parse_string(void **state)
{
TALLOC_CTX *mem_ctx = *state;
struct cli_credentials *creds = NULL;
+ enum credentials_obtained princ_obtained = CRED_UNINITIALISED;
+ enum credentials_obtained usr_obtained = CRED_UNINITIALISED;
+ enum credentials_obtained pwd_obtained = CRED_UNINITIALISED;
creds = cli_credentials_init(mem_ctx);
assert_non_null(creds);
@@ -213,13 +216,17 @@ static void torture_creds_parse_string(void **state)
assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
assert_string_equal(creds->username, "wurst at brot.realm");
- assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+ usr_obtained = cli_credentials_get_username_obtained(creds);
+ assert_int_equal(usr_obtained, CRED_SPECIFIED);
assert_string_equal(creds->principal, "wurst at brot.realm");
- assert_int_equal(creds->principal_obtained, CRED_SPECIFIED);
+ princ_obtained = cli_credentials_get_principal_obtained(creds);
+ assert_int_equal(princ_obtained, CRED_SPECIFIED);
assert_string_equal(creds->password, "BROT");
- assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+ pwd_obtained = cli_credentials_get_password_obtained(creds);
+ assert_int_equal(pwd_obtained, CRED_SPECIFIED);
+
}
static void torture_creds_krb5_state(void **state)
diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h
index 4d8eca99881..8454eef32a0 100644
--- a/auth/gensec/gensec_internal.h
+++ b/auth/gensec/gensec_internal.h
@@ -198,4 +198,8 @@ NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security,
NTTIME gensec_child_expire_time(struct gensec_security *gensec_security);
const char *gensec_child_final_auth_type(struct gensec_security *gensec_security);
+char *gensec_get_unparsed_target_principal(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx);
+NTSTATUS gensec_kerberos_possible(struct gensec_security *gensec_security);
+
#endif /* __GENSEC_H__ */
diff --git a/auth/gensec/gensec_util.c b/auth/gensec/gensec_util.c
index b6b4a722f27..0c7688d33d2 100644
--- a/auth/gensec/gensec_util.c
+++ b/auth/gensec/gensec_util.c
@@ -23,10 +23,14 @@
#include "includes.h"
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_internal.h"
+#include "auth/credentials/credentials.h"
#include "auth/common_auth.h"
#include "../lib/util/asn1.h"
#include "param/param.h"
#include "libds/common/roles.h"
+#include "lib/util/util_net.h"
+
+#undef strcasecmp
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH
@@ -336,3 +340,80 @@ const char *gensec_child_final_auth_type(struct gensec_security *gensec_security
return gensec_final_auth_type(gensec_security->child_security);
}
+
+char *gensec_get_unparsed_target_principal(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx)
+{
+ const char *target_principal = gensec_get_target_principal(gensec_security);
+ const char *service = gensec_get_target_service(gensec_security);
+ const char *hostname = gensec_get_target_hostname(gensec_security);
+
+ if (target_principal != NULL) {
+ return talloc_strdup(mem_ctx, target_principal);
+ } else if (service != NULL && hostname != NULL) {
+ return talloc_asprintf(mem_ctx, "%s/%s", service, hostname);
+ } else if (hostname != NULL) {
+ return talloc_strdup(mem_ctx, target_principal);
+ }
+
+ return NULL;
+}
+
+NTSTATUS gensec_kerberos_possible(struct gensec_security *gensec_security)
+{
+ struct cli_credentials *creds = gensec_get_credentials(gensec_security);
+ bool auth_requested = cli_credentials_authentication_requested(creds);
+ enum credentials_use_kerberos krb5_state =
+ cli_credentials_get_kerberos_state(creds);
+ char *user_principal = NULL;
+ const char *client_realm = cli_credentials_get_realm(creds);
+ const char *target_principal = gensec_get_target_principal(gensec_security);
+ const char *hostname = gensec_get_target_hostname(gensec_security);
+
+ if (!auth_requested) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (krb5_state == CRED_USE_KERBEROS_DISABLED) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list