mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
credentials: Create a smb_gss_krb5_copy_ccache() function
This sets the default principal on the copied ccache if it hasn't been set yet. Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
72fe43f218
commit
f981e2c980
@ -63,6 +63,130 @@ static int free_dccache(struct ccache_container *ccc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t smb_gss_krb5_copy_ccache(uint32_t *min_stat,
|
||||
gss_cred_id_t cred,
|
||||
struct ccache_container *ccc)
|
||||
{
|
||||
#ifndef SAMBA4_USES_HEIMDAL /* MIT 1.10 */
|
||||
krb5_context context = ccc->smb_krb5_context->krb5_context;
|
||||
krb5_ccache dummy_ccache = NULL;
|
||||
krb5_creds creds = {0};
|
||||
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);
|
||||
if (code != 0) {
|
||||
*min_stat = code;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not need set a default principal on the temporary dummy
|
||||
* ccache, as we do consume it at all in this function.
|
||||
*/
|
||||
maj_stat = gss_krb5_copy_ccache(min_stat, cred, dummy_ccache);
|
||||
if (maj_stat != 0) {
|
||||
krb5_cc_close(context, dummy_ccache);
|
||||
return maj_stat;
|
||||
}
|
||||
|
||||
code = krb5_cc_start_seq_get(context, dummy_ccache, &cursor);
|
||||
if (code != 0) {
|
||||
krb5_cc_close(context, dummy_ccache);
|
||||
*min_stat = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
code = krb5_cc_next_cred(context,
|
||||
dummy_ccache,
|
||||
&cursor,
|
||||
&creds);
|
||||
if (code != 0) {
|
||||
krb5_cc_close(context, dummy_ccache);
|
||||
*min_stat = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
do {
|
||||
if (creds.ticket_flags & TKT_FLG_PRE_AUTH) {
|
||||
krb5_data *tgs;
|
||||
|
||||
tgs = krb5_princ_component(context,
|
||||
creds.server,
|
||||
0);
|
||||
if (tgs != NULL && tgs->length >= 1) {
|
||||
int cmp;
|
||||
|
||||
cmp = memcmp(tgs->data,
|
||||
KRB5_TGS_NAME,
|
||||
tgs->length);
|
||||
if (cmp == 0 && creds.client != NULL) {
|
||||
princ = creds.client;
|
||||
code = KRB5_CC_END;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
|
||||
code = krb5_cc_next_cred(context,
|
||||
dummy_ccache,
|
||||
&cursor,
|
||||
&creds);
|
||||
} while (code == 0);
|
||||
|
||||
if (code == KRB5_CC_END) {
|
||||
krb5_cc_end_seq_get(context, dummy_ccache, &cursor);
|
||||
code = 0;
|
||||
}
|
||||
krb5_cc_close(context, dummy_ccache);
|
||||
|
||||
if (code != 0 || princ == NULL) {
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
*min_stat = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the default principal for the cache we copy
|
||||
* into. This is needed to be able that other calls
|
||||
* can read it with e.g. gss_acquire_cred() or
|
||||
* krb5_cc_get_principal().
|
||||
*/
|
||||
code = krb5_cc_initialize(context, ccc->ccache, princ);
|
||||
if (code != 0) {
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
*min_stat = EINVAL;
|
||||
return GSS_S_FAILURE;
|
||||
}
|
||||
krb5_free_cred_contents(context, &creds);
|
||||
|
||||
#endif /* SAMBA4_USES_HEIMDAL */
|
||||
|
||||
return gss_krb5_copy_ccache(min_stat,
|
||||
cred,
|
||||
ccc->ccache);
|
||||
}
|
||||
|
||||
_PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
|
||||
struct loadparm_context *lp_ctx,
|
||||
struct smb_krb5_context **smb_krb5_context)
|
||||
@ -712,8 +836,8 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
{
|
||||
int ret;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
struct ccache_container *ccc;
|
||||
struct gssapi_creds_container *gcc;
|
||||
struct ccache_container *ccc = NULL;
|
||||
struct gssapi_creds_container *gcc = NULL;
|
||||
if (cred->client_gss_creds_obtained > obtained) {
|
||||
return 0;
|
||||
}
|
||||
@ -729,8 +853,9 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
|
||||
return ret;
|
||||
}
|
||||
|
||||
maj_stat = gss_krb5_copy_ccache(&min_stat,
|
||||
gssapi_cred, ccc->ccache);
|
||||
maj_stat = smb_gss_krb5_copy_ccache(&min_stat,
|
||||
gssapi_cred,
|
||||
ccc);
|
||||
if (maj_stat) {
|
||||
if (min_stat) {
|
||||
ret = min_stat;
|
||||
|
Loading…
Reference in New Issue
Block a user