summaryrefslogtreecommitdiff
path: root/source4/heimdal/lib/gssapi
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-12-01 05:20:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:46:56 -0500
commit9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7 (patch)
tree8ef389a528fdc2caca79f279c086b4f8bea7afeb /source4/heimdal/lib/gssapi
parent22f1de0998ee34be4c032b16e4a6d30c9f8e6b85 (diff)
downloadsamba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.tar.gz
samba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.tar.bz2
samba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.zip
r11995: A big kerberos-related update.
This merges Samba4 up to current lorikeet-heimdal, which includes a replacement for some Samba-specific hacks. In particular, the credentials system now supplies GSS client and server credentials. These are imported into GSS with gss_krb5_import_creds(). Unfortunetly this can't take an MEMORY keytab, so we now create a FILE based keytab as provision and join time. Because the keytab is now created in advance, we don't spend .4s at negprot doing sha1 s2k calls. Also, because the keytab is read in real time, any change in the server key will be correctly picked up by the the krb5 code. To mark entries in the secrets which should be exported to a keytab, there is a new kerberosSecret objectClass. The new routine cli_credentials_update_all_keytabs() searches for these, and updates the keytabs. This is called in the provision.js via the ejs wrapper credentials_update_all_keytabs(). We can now (in theory) use a system-provided /etc/krb5.keytab, if krb5Keytab: FILE:/etc/krb5.keytab is added to the secrets.ldb record. By default the attribute privateKeytab: secrets.keytab is set, pointing to allow the whole private directory to be moved without breaking the internal links. (This used to be commit 6b75573df49c6210e1b9d71e108a9490976bd41d)
Diffstat (limited to 'source4/heimdal/lib/gssapi')
-rw-r--r--source4/heimdal/lib/gssapi/accept_sec_context.c106
-rw-r--r--source4/heimdal/lib/gssapi/acquire_cred.c50
-rw-r--r--source4/heimdal/lib/gssapi/arcfour.c8
-rw-r--r--source4/heimdal/lib/gssapi/copy_ccache.c123
-rw-r--r--source4/heimdal/lib/gssapi/gssapi.h21
-rw-r--r--source4/heimdal/lib/gssapi/gssapi_locl.h2
-rw-r--r--source4/heimdal/lib/gssapi/init_sec_context.c2
-rw-r--r--source4/heimdal/lib/gssapi/release_cred.c2
8 files changed, 134 insertions, 180 deletions
diff --git a/source4/heimdal/lib/gssapi/accept_sec_context.c b/source4/heimdal/lib/gssapi/accept_sec_context.c
index 5d43cdcb43..9ca60a6cdd 100644
--- a/source4/heimdal/lib/gssapi/accept_sec_context.c
+++ b/source4/heimdal/lib/gssapi/accept_sec_context.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: accept_sec_context.c,v 1.53 2005/05/29 15:12:41 lha Exp $");
+RCSID("$Id: accept_sec_context.c,v 1.55 2005/11/25 15:57:35 lha Exp $");
HEIMDAL_MUTEX gssapi_keytab_mutex = HEIMDAL_MUTEX_INITIALIZER;
krb5_keytab gssapi_krb5_keytab;
@@ -125,66 +125,24 @@ gsskrb5_accept_delegated_token
krb5_principal principal = (*context_handle)->source;
krb5_ccache ccache = NULL;
krb5_error_code kret;
- int32_t ac_flags, ret;
- gss_cred_id_t handle = NULL;
+ int32_t ac_flags, ret = GSS_S_COMPLETE;
- if (delegated_cred_handle == NULL) {
- /* XXX Create a new delegated_cred_handle? */
-
- ret = 0;
+ *minor_status = 0;
+ /* XXX Create a new delegated_cred_handle? */
+ if (delegated_cred_handle == NULL)
kret = krb5_cc_default (gssapi_krb5_context, &ccache);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- } else {
-
- *delegated_cred_handle = NULL;
-
- handle = calloc(1, sizeof(*handle));
- if (handle == NULL) {
- ret = GSS_S_FAILURE;
- *minor_status = ENOMEM;
- krb5_set_error_string(gssapi_krb5_context, "out of memory");
- gssapi_krb5_set_error_string();
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- if ((ret = gss_duplicate_name(minor_status, principal,
- &handle->principal)) != 0) {
- *flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
- }
- kret = krb5_cc_gen_new (gssapi_krb5_context,
- &krb5_mcc_ops,
- &handle->ccache);
- if (kret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
- }
- ccache = handle->ccache;
-
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
- if (ret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
- if (ret) {
- *flags &= ~GSS_C_DELEG_FLAG;
- goto end_fwd;
- }
+ else
+ kret = krb5_cc_gen_new (gssapi_krb5_context, &krb5_mcc_ops, &ccache);
+ if (kret) {
+ *flags &= ~GSS_C_DELEG_FLAG;
+ goto out;
}
kret = krb5_cc_initialize(gssapi_krb5_context, ccache, principal);
if (kret) {
*flags &= ~GSS_C_DELEG_FLAG;
- ret = 0;
- goto end_fwd;
+ goto out;
}
krb5_auth_con_removeflags(gssapi_krb5_context,
@@ -204,29 +162,29 @@ gsskrb5_accept_delegated_token
*flags &= ~GSS_C_DELEG_FLAG;
ret = GSS_S_FAILURE;
*minor_status = kret;
- goto end_fwd;
+ goto out;
}
- end_fwd:
- /* if there was some kind of failure, clean up internal structures */
- if ((*flags & GSS_C_DELEG_FLAG) == 0) {
- if (handle) {
- if (handle->principal)
- gss_release_name(minor_status, &handle->principal);
- if (handle->mechanisms)
- gss_release_oid_set(NULL, &handle->mechanisms);
- if (handle->ccache)
- krb5_cc_destroy(gssapi_krb5_context, handle->ccache);
- free(handle);
- handle = NULL;
- }
+
+ if (delegated_cred_handle) {
+ ret = gss_krb5_import_cred(minor_status,
+ ccache,
+ NULL,
+ NULL,
+ delegated_cred_handle);
+ if (ret != GSS_S_COMPLETE)
+ goto out;
+
+ (*delegated_cred_handle)->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
+ ccache = NULL;
}
- if (delegated_cred_handle == NULL) {
- if (ccache)
+
+out:
+ if (ccache) {
+ if (delegated_cred_handle == NULL)
krb5_cc_close(gssapi_krb5_context, ccache);
+ else
+ krb5_cc_destroy(gssapi_krb5_context, ccache);
}
- if (handle)
- *delegated_cred_handle = handle;
-
return ret;
}
@@ -1054,7 +1012,7 @@ spnego_accept_sec_context
if(len > data.length - taglen)
return ASN1_OVERRUN;
- ret = decode_NegTokenInit((const char *)data.data + taglen, len,
+ ret = decode_NegTokenInit((const unsigned char *)data.data + taglen, len,
&ni, &ni_len);
if (ret)
return GSS_S_DEFECTIVE_TOKEN;
@@ -1065,7 +1023,7 @@ spnego_accept_sec_context
}
for (i = 0; !found && i < ni.mechTypes->len; ++i) {
- char mechbuf[17];
+ unsigned char mechbuf[17];
size_t mech_len;
ret = der_put_oid (mechbuf + sizeof(mechbuf) - 1,
diff --git a/source4/heimdal/lib/gssapi/acquire_cred.c b/source4/heimdal/lib/gssapi/acquire_cred.c
index d67b400920..44dbef3c48 100644
--- a/source4/heimdal/lib/gssapi/acquire_cred.c
+++ b/source4/heimdal/lib/gssapi/acquire_cred.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: acquire_cred.c,v 1.24 2005/10/26 11:25:16 lha Exp $");
+RCSID("$Id: acquire_cred.c,v 1.25 2005/11/02 08:56:25 lha Exp $");
OM_uint32
_gssapi_krb5_ccache_lifetime(OM_uint32 *minor_status,
@@ -106,7 +106,6 @@ get_keytab(krb5_context context, krb5_keytab *keytab)
static OM_uint32 acquire_initiator_cred
(OM_uint32 * minor_status,
krb5_context context,
- krb5_keytab keytab,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -122,7 +121,7 @@ static OM_uint32 acquire_initiator_cred
krb5_get_init_creds_opt *opt;
krb5_ccache ccache;
krb5_error_code kret;
- krb5_boolean made_keytab = FALSE;
+ krb5_keytab keytab;
ccache = NULL;
def_princ = NULL;
@@ -214,7 +213,7 @@ end:
krb5_free_cred_contents(context, &cred);
if (def_princ != NULL)
krb5_free_principal(context, def_princ);
- if (made_keytab)
+ if (keytab != NULL)
krb5_kt_close(context, keytab);
if (ret != GSS_S_COMPLETE) {
if (ccache != NULL)
@@ -230,7 +229,6 @@ end:
static OM_uint32 acquire_acceptor_cred
(OM_uint32 * minor_status,
krb5_context context,
- krb5_keytab keytab,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
gss_cred_usage_t cred_usage,
@@ -244,21 +242,14 @@ static OM_uint32 acquire_acceptor_cred
kret = 0;
ret = GSS_S_FAILURE;
- if (keytab == NULL) {
- kret = get_keytab(context, &handle->keytab);
- if (kret)
- goto end;
- handle->made_keytab = TRUE;
- } else {
- handle->keytab = keytab;
- handle->made_keytab = FALSE;
- }
+ kret = get_keytab(context, &handle->keytab);
+ if (kret)
+ goto end;
ret = GSS_S_COMPLETE;
end:
if (ret != GSS_S_COMPLETE) {
- if (handle->made_keytab)
- krb5_kt_close(context, handle->keytab);
+ krb5_kt_close(context, handle->keytab);
if (kret != 0) {
*minor_status = kret;
gssapi_krb5_set_error_string ();
@@ -267,9 +258,8 @@ end:
return (ret);
}
-OM_uint32 gsskrb5_acquire_cred
+OM_uint32 gss_acquire_cred
(OM_uint32 * minor_status,
- struct krb5_keytab_data *keytab,
const gss_name_t desired_name,
OM_uint32 time_req,
const gss_OID_set desired_mechs,
@@ -328,7 +318,6 @@ OM_uint32 gsskrb5_acquire_cred
}
if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
ret = acquire_initiator_cred(minor_status, gssapi_krb5_context,
- keytab,
desired_name, time_req,
desired_mechs, cred_usage,
handle, actual_mechs, time_rec);
@@ -341,7 +330,7 @@ OM_uint32 gsskrb5_acquire_cred
}
if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
ret = acquire_acceptor_cred(minor_status, gssapi_krb5_context,
- keytab, time_req,
+ time_req,
desired_mechs, cred_usage,
handle, actual_mechs, time_rec);
if (ret != GSS_S_COMPLETE) {
@@ -381,24 +370,3 @@ OM_uint32 gsskrb5_acquire_cred
return (GSS_S_COMPLETE);
}
-OM_uint32 gss_acquire_cred
- (OM_uint32 * minor_status,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- const gss_OID_set desired_mechs,
- gss_cred_usage_t cred_usage,
- gss_cred_id_t * output_cred_handle,
- gss_OID_set * actual_mechs,
- OM_uint32 * time_rec
- )
-{
- return gsskrb5_acquire_cred(minor_status,
- NULL,
- desired_name,
- time_req,
- desired_mechs,
- cred_usage,
- output_cred_handle,
- actual_mechs,
- time_rec);
-}
diff --git a/source4/heimdal/lib/gssapi/arcfour.c b/source4/heimdal/lib/gssapi/arcfour.c
index 52bb2ecf1b..01c6c75ecc 100644
--- a/source4/heimdal/lib/gssapi/arcfour.c
+++ b/source4/heimdal/lib/gssapi/arcfour.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 - 2004 Kungliga Tekniska Högskolan
+ * Copyright (c) 2003 - 2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: arcfour.c,v 1.17 2005/05/06 07:13:32 lha Exp $");
+RCSID("$Id: arcfour.c,v 1.18 2005/11/01 06:55:55 lha Exp $");
/*
* Implements draft-brezak-win2k-krb-rc4-hmac-04.txt
@@ -105,7 +105,7 @@ arcfour_mic_key(krb5_context context, krb5_keyblock *key,
static krb5_error_code
arcfour_mic_cksum(krb5_keyblock *key, unsigned usage,
u_char *sgn_cksum, size_t sgn_cksum_sz,
- const char *v1, size_t l1,
+ const u_char *v1, size_t l1,
const void *v2, size_t l2,
const void *v3, size_t l3)
{
@@ -256,7 +256,7 @@ _gssapi_verify_mic_arcfour(OM_uint32 * minor_status,
p = token_buffer->value;
omret = gssapi_krb5_verify_header (&p,
token_buffer->length,
- type,
+ (u_char *)type,
GSS_KRB5_MECHANISM);
if (omret)
return omret;
diff --git a/source4/heimdal/lib/gssapi/copy_ccache.c b/source4/heimdal/lib/gssapi/copy_ccache.c
index 0f2f155870..782b701e44 100644
--- a/source4/heimdal/lib/gssapi/copy_ccache.c
+++ b/source4/heimdal/lib/gssapi/copy_ccache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
+ * Copyright (c) 2000 - 2001, 2003 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: copy_ccache.c,v 1.9 2005/10/31 16:02:08 lha Exp $");
+RCSID("$Id: copy_ccache.c,v 1.13 2005/11/28 23:05:44 lha Exp $");
OM_uint32
gss_krb5_copy_ccache(OM_uint32 *minor_status,
@@ -63,9 +63,11 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status,
OM_uint32
-gss_krb5_import_ccache(OM_uint32 *minor_status,
- krb5_ccache in,
- gss_cred_id_t *cred)
+gss_krb5_import_cred(OM_uint32 *minor_status,
+ krb5_ccache id,
+ krb5_principal keytab_principal,
+ krb5_keytab keytab,
+ gss_cred_id_t *cred)
{
krb5_error_code kret;
gss_cred_id_t handle;
@@ -83,57 +85,94 @@ gss_krb5_import_ccache(OM_uint32 *minor_status,
}
HEIMDAL_MUTEX_init(&handle->cred_id_mutex);
- handle->usage = GSS_C_INITIATE;
+ handle->usage = 0;
- kret = krb5_cc_get_principal(gssapi_krb5_context, in, &handle->principal);
- if (kret) {
- free(handle);
- gssapi_krb5_set_error_string ();
- *minor_status = kret;
- return GSS_S_FAILURE;
- }
+ if (id) {
+ char *str;
- ret = _gssapi_krb5_ccache_lifetime(minor_status,
- in,
- handle->principal,
- &handle->lifetime);
- if (ret != GSS_S_COMPLETE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
- free(handle);
- return ret;
- }
+ handle->usage |= GSS_C_INITIATE;
- ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
- if (ret == GSS_S_COMPLETE)
- ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
- &handle->mechanisms);
- if (ret != GSS_S_COMPLETE) {
- krb5_free_principal(gssapi_krb5_context, handle->principal);
- free(handle);
- *minor_status = kret;
- return GSS_S_FAILURE;
+ kret = krb5_cc_get_principal(gssapi_krb5_context, id,
+ &handle->principal);
+ if (kret) {
+ free(handle);
+ gssapi_krb5_set_error_string ();
+ *minor_status = kret;
+ return GSS_S_FAILURE;
+ }
+
+ if (keytab_principal) {
+ krb5_boolean match;
+
+ match = krb5_principal_compare(gssapi_krb5_context,
+ handle->principal,
+ keytab_principal);
+ if (match == FALSE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ gssapi_krb5_clear_status ();
+ *minor_status = EINVAL;
+ return GSS_S_FAILURE;
+ }
+ }
+
+ ret = _gssapi_krb5_ccache_lifetime(minor_status,
+ id,
+ handle->principal,
+ &handle->lifetime);
+ if (ret != GSS_S_COMPLETE) {
+ krb5_free_principal(gssapi_krb5_context, handle->principal);
+ free(handle);
+ return ret;
+ }
+
+
+ kret = krb5_cc_get_full_name(gssapi_krb5_context, id, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ free(str);
+ if (kret)
+ goto out;
}
- {
- const char *type, *name;
+
+ if (keytab) {
char *str;
- type = krb5_cc_get_type(gssapi_krb5_context, in);
- name = krb5_cc_get_name(gssapi_krb5_context, in);
-
- if (asprintf(&str, "%s:%s", type, name) == -1) {
- krb5_set_error_string(gssapi_krb5_context,
- "malloc - out of memory");
- kret = ENOMEM;
- goto out;
+ handle->usage |= GSS_C_ACCEPT;
+
+ if (keytab_principal && handle->principal == NULL) {
+ kret = krb5_copy_principal(gssapi_krb5_context,
+ keytab_principal,
+ &handle->principal);
+ if (kret)
+ goto out;
}
- kret = krb5_cc_resolve(gssapi_krb5_context, str, &handle->ccache);
+ kret = krb5_kt_get_full_name(gssapi_krb5_context, keytab, &str);
+ if (kret)
+ goto out;
+
+ kret = krb5_kt_resolve(gssapi_krb5_context, str, &handle->keytab);
free(str);
if (kret)
goto out;
}
+
+ if (id || keytab) {
+ ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
+ if (ret == GSS_S_COMPLETE)
+ ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
+ &handle->mechanisms);
+ if (ret != GSS_S_COMPLETE) {
+ kret = *minor_status;
+ goto out;
+ }
+ }
+
*minor_status = 0;
*cred = handle;
return GSS_S_COMPLETE;
diff --git a/source4/heimdal/lib/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi.h
index 64a31d1eee..20700dc826 100644
--- a/source4/heimdal/lib/gssapi/gssapi.h
+++ b/source4/heimdal/lib/gssapi/gssapi.h
@@ -775,18 +775,6 @@ OM_uint32 gss_unseal
* kerberos mechanism specific functions
*/
-OM_uint32 gsskrb5_acquire_cred
- (OM_uint32 * minor_status,
- struct krb5_keytab_data *keytab,
- const gss_name_t desired_name,
- OM_uint32 time_req,
- const gss_OID_set desired_mechs,
- gss_cred_usage_t cred_usage,
- gss_cred_id_t * output_cred_handle,
- gss_OID_set * actual_mechs,
- OM_uint32 * time_rec
- );
-
OM_uint32
gss_krb5_ccache_name(OM_uint32 * /*minor_status*/,
const char * /*name */,
@@ -805,10 +793,11 @@ OM_uint32 gss_krb5_copy_service_keyblock
gss_ctx_id_t context_handle,
struct EncryptionKey **out);
-OM_uint32
-gss_krb5_import_ccache(OM_uint32 */*minor*/,
- struct krb5_ccache_data * /*in*/,
- gss_cred_id_t */*out*/);
+OM_uint32 gss_krb5_import_cred(OM_uint32 *minor_status,
+ struct krb5_ccache_data * /* id */,
+ struct Principal * /* keytab_principal */,
+ struct krb5_keytab_data * /* keytab */,
+ gss_cred_id_t */* cred */);
OM_uint32 gss_krb5_get_tkt_flags
(OM_uint32 */*minor*/,
diff --git a/source4/heimdal/lib/gssapi/gssapi_locl.h b/source4/heimdal/lib/gssapi/gssapi_locl.h
index ae291d15a9..b9bea7db2e 100644
--- a/source4/heimdal/lib/gssapi/gssapi_locl.h
+++ b/source4/heimdal/lib/gssapi/gssapi_locl.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: gssapi_locl.h,v 1.42 2005/10/26 11:23:48 lha Exp $ */
+/* $Id: gssapi_locl.h,v 1.43 2005/11/02 08:51:17 lha Exp $ */
#ifndef GSSAPI_LOCL_H
#define GSSAPI_LOCL_H
diff --git a/source4/heimdal/lib/gssapi/init_sec_context.c b/source4/heimdal/lib/gssapi/init_sec_context.c
index e7e8f5153e..61c020b800 100644
--- a/source4/heimdal/lib/gssapi/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/init_sec_context.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: init_sec_context.c,v 1.60 2005/10/12 07:25:18 lha Exp $");
+RCSID("$Id: init_sec_context.c,v 1.61 2005/11/02 11:52:49 lha Exp $");
/*
* copy the addresses from `input_chan_bindings' (if any) to
diff --git a/source4/heimdal/lib/gssapi/release_cred.c b/source4/heimdal/lib/gssapi/release_cred.c
index ddd80c144b..cca3dfe379 100644
--- a/source4/heimdal/lib/gssapi/release_cred.c
+++ b/source4/heimdal/lib/gssapi/release_cred.c
@@ -33,7 +33,7 @@
#include "gssapi_locl.h"
-RCSID("$Id: release_cred.c,v 1.10 2003/10/07 00:51:46 lha Exp $");
+RCSID("$Id: release_cred.c,v 1.11 2005/11/02 08:57:35 lha Exp $");
OM_uint32 gss_release_cred
(OM_uint32 * minor_status,