Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149210967
D51731.1789682432.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
24 KB
Referenced Files
None
Subscribers
None
D51731.1789682432.diff
View Options
diff --git a/sys/kgssapi/gss_accept_sec_context.c.sav b/sys/kgssapi/gss_accept_sec_context.c
--- a/sys/kgssapi/gss_accept_sec_context.c.sav
+++ b/sys/kgssapi/gss_accept_sec_context.c
@@ -41,6 +41,11 @@
#include "gssd.h"
#include "kgss_if.h"
+/*
+ * This function should only be called when the gssd
+ * daemon running on the system is an old one that
+ * does not use gss_krb5_export_lucid_sec_context().
+ */
OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_cred_id_t acceptor_cred_handle,
@@ -138,7 +143,145 @@
* etc.) to the kernel implementation.
*/
if (res.major_status == GSS_S_COMPLETE)
- res.major_status = kgss_transfer_context(ctx);
+ res.major_status = kgss_transfer_context(ctx, NULL);
return (res.major_status);
}
+
+/*
+ * This function should be called when the gssd daemon is
+ * one that uses gss_krb5_export_lucid_sec_context().
+ * There is a lot of code common with
+ * gss_accept_sec_context(). However, the structures used
+ * are not the same and future changes may be needed for
+ * this one. As such, I have not factored out the common
+ * code.
+ * gss_supports_lucid() may be used to check to see if the
+ * gssd daemon uses gss_krb5_export_lucid_sec_context().
+ */
+OM_uint32 gss_accept_sec_context_lucid_v1(OM_uint32 *minor_status,
+ gss_ctx_id_t *context_handle,
+ const gss_cred_id_t acceptor_cred_handle,
+ const gss_buffer_t input_token,
+ const gss_channel_bindings_t input_chan_bindings,
+ gss_name_t *src_name,
+ gss_OID *mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 *ret_flags,
+ OM_uint32 *time_rec,
+ gss_cred_id_t *delegated_cred_handle,
+ gss_buffer_t exported_name,
+ uid_t *uidp,
+ gid_t *gidp,
+ int *numgroups,
+ gid_t *groups)
+{
+ struct accept_sec_context_lucid_v1_res res;
+ struct accept_sec_context_lucid_v1_args args;
+ enum clnt_stat stat;
+ gss_ctx_id_t ctx = *context_handle;
+ gss_name_t name;
+ gss_cred_id_t cred;
+ CLIENT *cl;
+
+ cl = kgss_gssd_client();
+ if (cl == NULL) {
+ *minor_status = 0;
+ return (GSS_S_FAILURE);
+ }
+
+ if (ctx)
+ args.ctx = ctx->handle;
+ else
+ args.ctx = 0;
+ if (acceptor_cred_handle)
+ args.cred = acceptor_cred_handle->handle;
+ else
+ args.cred = 0;
+ args.input_token = *input_token;
+ args.input_chan_bindings = input_chan_bindings;
+
+ bzero(&res, sizeof(res));
+ stat = gssd_accept_sec_context_lucid_v1_1(&args, &res, cl);
+ CLNT_RELEASE(cl);
+ if (stat != RPC_SUCCESS) {
+ *minor_status = stat;
+ return (GSS_S_FAILURE);
+ }
+
+ if (res.major_status != GSS_S_COMPLETE
+ && res.major_status != GSS_S_CONTINUE_NEEDED) {
+ *minor_status = res.minor_status;
+ xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);
+ return (res.major_status);
+ }
+
+ *minor_status = res.minor_status;
+
+ if (!ctx) {
+ ctx = kgss_create_context(res.mech_type);
+ if (!ctx) {
+ xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);
+ *minor_status = 0;
+ return (GSS_S_BAD_MECH);
+ }
+ }
+ *context_handle = ctx;
+
+ ctx->handle = res.ctx;
+ name = malloc(sizeof(struct _gss_name_t), M_GSSAPI, M_WAITOK);
+ name->handle = res.src_name;
+ if (src_name) {
+ *src_name = name;
+ } else {
+ OM_uint32 junk;
+ gss_release_name(&junk, &name);
+ }
+ if (mech_type)
+ *mech_type = KGSS_MECH_TYPE(ctx);
+ kgss_copy_buffer(&res.output_token, output_token);
+ if (ret_flags)
+ *ret_flags = res.ret_flags;
+ if (time_rec)
+ *time_rec = res.time_rec;
+ cred = malloc(sizeof(struct _gss_cred_id_t), M_GSSAPI, M_WAITOK);
+ cred->handle = res.delegated_cred_handle;
+ if (delegated_cred_handle) {
+ *delegated_cred_handle = cred;
+ } else {
+ OM_uint32 junk;
+ gss_release_cred(&junk, &cred);
+ }
+
+ /*
+ * If the context establishment is complete, export it from
+ * userland and hand the result (which includes key material
+ * etc.) to the kernel implementation.
+ */
+ if (res.major_status == GSS_S_COMPLETE) {
+ int i, n;
+
+ /* First, get the unix credentials. */
+ *uidp = res.uid;
+ *gidp = res.gid;
+ n = res.gidlist.gidlist_len;
+ if (n > *numgroups)
+ n = *numgroups;
+ for (i = 0; i < n; i++)
+ groups[i] = res.gidlist.gidlist_val[i];
+ *numgroups = n;
+
+ /* Next, get the exported_name. */
+ kgss_copy_buffer(&res.exported_name, exported_name);
+
+ /* Now, handle the lucid credential setup. */
+ res.major_status = kgss_transfer_context(ctx, &res.lucid);
+ if (res.major_status != GSS_S_COMPLETE)
+ printf("gss_accept_sec_context_lucid_v1: "
+ "transfer failed\n");
+ }
+
+ xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);
+
+ return (res.major_status);
+}
diff --git a/sys/kgssapi/gss_impl.c.sav b/sys/kgssapi/gss_impl.c
--- a/sys/kgssapi/gss_impl.c.sav
+++ b/sys/kgssapi/gss_impl.c
@@ -192,12 +192,18 @@
}
OM_uint32
-kgss_transfer_context(gss_ctx_id_t ctx)
+kgss_transfer_context(gss_ctx_id_t ctx, void *lctx)
{
struct export_sec_context_res res;
struct export_sec_context_args args;
enum clnt_stat stat;
OM_uint32 maj_stat;
+
+ if (lctx != NULL) {
+ maj_stat = KGSS_IMPORT(ctx, MIT_V1, lctx);
+ ctx->handle = 0;
+ return (maj_stat);
+ }
KGSS_CURVNET_SET_QUIET(KGSS_TD_TO_VNET(curthread));
if (!KGSS_VNET(kgss_gssd_handle)) {
diff --git a/sys/kgssapi/gss_init_sec_context.c.sav b/sys/kgssapi/gss_init_sec_context.c
--- a/sys/kgssapi/gss_init_sec_context.c.sav
+++ b/sys/kgssapi/gss_init_sec_context.c
@@ -42,6 +42,11 @@
#include "gssd.h"
#include "kgss_if.h"
+/*
+ * This function should only be called when the gssd
+ * daemon running on the system is an old one that
+ * does not use gss_krb5_export_lucid_sec_context().
+ */
OM_uint32
gss_init_sec_context(OM_uint32 * minor_status,
const gss_cred_id_t initiator_cred_handle,
@@ -133,7 +138,145 @@
* etc.) to the kernel implementation.
*/
if (res.major_status == GSS_S_COMPLETE)
- res.major_status = kgss_transfer_context(ctx);
+ res.major_status = kgss_transfer_context(ctx, NULL);
return (res.major_status);
}
+
+OM_uint32
+gss_supports_lucid(uint32_t *minor_status, uint32_t *vers)
+{
+ struct supports_lucid_res res;
+ enum clnt_stat stat;
+ CLIENT *cl;
+
+ *minor_status = 0;
+
+ cl = kgss_gssd_client();
+ if (cl == NULL)
+ return (GSS_S_FAILURE);
+
+ bzero(&res, sizeof(res));
+ stat = gssd_supports_lucid_1(NULL, &res, cl);
+ CLNT_RELEASE(cl);
+ if (stat != RPC_SUCCESS) {
+ *minor_status = stat;
+ return (GSS_S_FAILURE);
+ }
+
+ if (vers)
+ *vers = res.vers;
+
+ return (res.major_status);
+}
+
+/*
+ * This function should be called when the gssd daemon is
+ * one that uses gss_krb5_export_lucid_sec_context().
+ * There is a lot of code common with
+ * gss_init_sec_context(). However, the structures used
+ * are not the same and future changes may be needed for
+ * this one. As such, I have not factored out the common
+ * code.
+ * gss_supports_lucid() may be used to check to see if the
+ * gssd daemon uses gss_krb5_export_lucid_sec_context().
+ */
+OM_uint32
+gss_init_sec_context_lucid_v1(OM_uint32 * minor_status,
+ const gss_cred_id_t initiator_cred_handle,
+ gss_ctx_id_t * context_handle,
+ const gss_name_t target_name,
+ const gss_OID input_mech_type,
+ OM_uint32 req_flags,
+ OM_uint32 time_req,
+ const gss_channel_bindings_t input_chan_bindings,
+ const gss_buffer_t input_token,
+ gss_OID * actual_mech_type,
+ gss_buffer_t output_token,
+ OM_uint32 * ret_flags,
+ OM_uint32 * time_rec)
+{
+ struct init_sec_context_lucid_v1_res res;
+ struct init_sec_context_lucid_v1_args args;
+ enum clnt_stat stat;
+ gss_ctx_id_t ctx = *context_handle;
+ CLIENT *cl;
+
+ *minor_status = 0;
+
+ cl = kgss_gssd_client();
+ if (cl == NULL)
+ return (GSS_S_FAILURE);
+
+ args.uid = curthread->td_ucred->cr_uid;
+ if (initiator_cred_handle)
+ args.cred = initiator_cred_handle->handle;
+ else
+ args.cred = 0;
+ if (ctx)
+ args.ctx = ctx->handle;
+ else
+ args.ctx = 0;
+ args.name = target_name->handle;
+ args.mech_type = input_mech_type;
+ args.req_flags = req_flags;
+ args.time_req = time_req;
+ args.input_chan_bindings = input_chan_bindings;
+ if (input_token)
+ args.input_token = *input_token;
+ else {
+ args.input_token.length = 0;
+ args.input_token.value = NULL;
+ }
+
+ bzero(&res, sizeof(res));
+ stat = gssd_init_sec_context_lucid_v1_1(&args, &res, cl);
+ CLNT_RELEASE(cl);
+ if (stat != RPC_SUCCESS) {
+ *minor_status = stat;
+ return (GSS_S_FAILURE);
+ }
+
+ if (res.major_status != GSS_S_COMPLETE
+ && res.major_status != GSS_S_CONTINUE_NEEDED) {
+ *minor_status = res.minor_status;
+ xdr_free((xdrproc_t) xdr_init_sec_context_lucid_v1_res, &res);
+ return (res.major_status);
+ }
+
+ *minor_status = res.minor_status;
+
+ if (!ctx) {
+ ctx = kgss_create_context(res.actual_mech_type);
+ if (!ctx) {
+ xdr_free((xdrproc_t) xdr_init_sec_context_lucid_v1_res, &res);
+ *minor_status = 0;
+ return (GSS_S_BAD_MECH);
+ }
+ }
+ *context_handle = ctx;
+ ctx->handle = res.ctx;
+ if (actual_mech_type)
+ *actual_mech_type = KGSS_MECH_TYPE(ctx);
+ kgss_copy_buffer(&res.output_token, output_token);
+ if (ret_flags)
+ *ret_flags = res.ret_flags;
+ if (time_rec)
+ *time_rec = res.time_rec;
+
+ /*
+ * If the context establishment is complete, export it from
+ * userland and hand the result (which includes key material
+ * etc.) to the kernel implementation.
+ */
+ if (res.major_status == GSS_S_COMPLETE) {
+ res.major_status = kgss_transfer_context(ctx, &res.lucid);
+ if (res.major_status != GSS_S_COMPLETE)
+ printf("gss_init_sec_context_lucid_v1: "
+ "transfer failed\n");
+ }
+
+ xdr_free((xdrproc_t) xdr_init_sec_context_lucid_v1_res, &res);
+
+ return (res.major_status);
+}
diff --git a/sys/kgssapi/gssapi.h.sav b/sys/kgssapi/gssapi.h
--- a/sys/kgssapi/gssapi.h.sav
+++ b/sys/kgssapi/gssapi.h
@@ -420,6 +420,28 @@
gss_buffer_t, /* output_token */
OM_uint32 *, /* ret_flags */
OM_uint32 * /* time_rec */
+ );
+
+OM_uint32 gss_init_sec_context_lucid_v1
+ (OM_uint32 *, /* minor_status */
+ const gss_cred_id_t, /* initiator_cred_handle */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_name_t, /* target_name */
+ const gss_OID, /* mech_type */
+ OM_uint32, /* req_flags */
+ OM_uint32, /* time_req */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ const gss_buffer_t, /* input_token */
+ gss_OID *, /* actual_mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 * /* time_rec */
+ );
+
+OM_uint32 gss_supports_lucid
+ (OM_uint32 *, /* minor_status */
+ OM_uint32 * /* vers */
);
OM_uint32 gss_accept_sec_context
@@ -437,6 +459,26 @@
gss_cred_id_t * /* delegated_cred_handle */
);
+OM_uint32 gss_accept_sec_context_lucid_v1
+ (OM_uint32 *, /* minor_status */
+ gss_ctx_id_t *, /* context_handle */
+ const gss_cred_id_t, /* acceptor_cred_handle */
+ const gss_buffer_t, /* input_token_buffer */
+ const gss_channel_bindings_t,
+ /* input_chan_bindings */
+ gss_name_t *, /* src_name */
+ gss_OID *, /* mech_type */
+ gss_buffer_t, /* output_token */
+ OM_uint32 *, /* ret_flags */
+ OM_uint32 *, /* time_rec */
+ gss_cred_id_t *, /* delegated_cred_handle */
+ gss_buffer_t, /* exported_name */
+ uid_t *, /* Unix cred */
+ gid_t *,
+ int *, /* Number of groups */
+ gid_t * /* groups list */
+ );
+
OM_uint32 gss_delete_sec_context
(OM_uint32 *, /* minor_status */
gss_ctx_id_t *, /* context_handle */
diff --git a/sys/kgssapi/gssapi_impl.h.sav b/sys/kgssapi/gssapi_impl.h
--- a/sys/kgssapi/gssapi_impl.h.sav
+++ b/sys/kgssapi/gssapi_impl.h
@@ -78,5 +78,5 @@
extern const char *kgss_find_mech_by_oid(const gss_OID oid);
extern gss_ctx_id_t kgss_create_context(gss_OID mech_type);
extern void kgss_delete_context(gss_ctx_id_t ctx, gss_buffer_t output_token);
-extern OM_uint32 kgss_transfer_context(gss_ctx_id_t ctx);
+extern OM_uint32 kgss_transfer_context(gss_ctx_id_t ctx, void *lctx);
extern void kgss_copy_buffer(const gss_buffer_t from, gss_buffer_t to);
diff --git a/sys/kgssapi/gssd.x.sav b/sys/kgssapi/gssd.x
--- a/sys/kgssapi/gssd.x.sav
+++ b/sys/kgssapi/gssd.x
@@ -48,6 +48,21 @@
typedef uint64_t gssd_cred_id_t;
typedef uint64_t gssd_name_t;
+struct kgss_lucid_desc {
+ uint32_t initiate;
+ uint32_t endtime;
+ uint64_t send_seq;
+ uint64_t recv_seq;
+ uint32_t protocol;
+ uint32_t rfc_sign;
+ uint32_t rfc_seal;
+ uint32_t have_subkey;
+ uint32_t ctx_type;
+ gss_buffer_desc ctx_key;
+ uint32_t subkey_type;
+ gss_buffer_desc subkey_key;
+};
+
struct init_sec_context_res {
uint32_t major_status;
uint32_t minor_status;
@@ -70,6 +85,29 @@
gss_buffer_desc input_token;
};
+struct init_sec_context_lucid_v1_res {
+ uint32_t major_status;
+ uint32_t minor_status;
+ gssd_ctx_id_t ctx;
+ gss_OID actual_mech_type;
+ gss_buffer_desc output_token;
+ uint32_t ret_flags;
+ uint32_t time_rec;
+ kgss_lucid_desc lucid;
+};
+
+struct init_sec_context_lucid_v1_args {
+ uint32_t uid;
+ gssd_cred_id_t cred;
+ gssd_ctx_id_t ctx;
+ gssd_name_t name;
+ gss_OID mech_type;
+ uint32_t req_flags;
+ uint32_t time_req;
+ gss_channel_bindings_t input_chan_bindings;
+ gss_buffer_desc input_token;
+};
+
struct accept_sec_context_res {
uint32_t major_status;
uint32_t minor_status;
@@ -89,6 +127,30 @@
gss_channel_bindings_t input_chan_bindings;
};
+struct accept_sec_context_lucid_v1_res {
+ uint32_t major_status;
+ uint32_t minor_status;
+ gssd_ctx_id_t ctx;
+ gssd_name_t src_name;
+ gss_OID mech_type;
+ gss_buffer_desc output_token;
+ uint32_t ret_flags;
+ uint32_t time_rec;
+ gssd_cred_id_t delegated_cred_handle;
+ kgss_lucid_desc lucid;
+ gss_buffer_desc exported_name;
+ uint32_t uid;
+ uint32_t gid;
+ uint32_t gidlist<>;
+};
+
+struct accept_sec_context_lucid_v1_args {
+ gssd_ctx_id_t ctx;
+ gssd_cred_id_t cred;
+ gss_buffer_desc input_token;
+ gss_channel_bindings_t input_chan_bindings;
+};
+
struct delete_sec_context_res {
uint32_t major_status;
uint32_t minor_status;
@@ -101,7 +163,8 @@
enum sec_context_format {
KGSS_HEIMDAL_0_6,
- KGSS_HEIMDAL_1_1
+ KGSS_HEIMDAL_1_1,
+ MIT_V1
};
struct export_sec_context_res {
@@ -229,6 +292,11 @@
char ip_addr<NI_MAXHOST>;
};
+struct supports_lucid_res {
+ uint32_t major_status;
+ uint32_t vers;
+};
+
program GSSD {
version GSSDVERS {
void GSSD_NULL(void) = 0;
@@ -274,5 +342,14 @@
ip_to_dns_res
GSSD_IP_TO_DNS(ip_to_dns_args) = 14;
+
+ init_sec_context_lucid_v1_res
+ GSSD_INIT_SEC_CONTEXT_LUCID_V1(init_sec_context_lucid_v1_args) = 15;
+
+ accept_sec_context_lucid_v1_res
+ GSSD_ACCEPT_SEC_CONTEXT_LUCID_V1(accept_sec_context_lucid_v1_args) = 16;
+
+ supports_lucid_res
+ GSSD_SUPPORTS_LUCID(void) = 17;
} = 1;
} = 0x40677373;
diff --git a/sys/kgssapi/krb5/krb5_mech.c.sav b/sys/kgssapi/krb5/krb5_mech.c
--- a/sys/kgssapi/krb5/krb5_mech.c.sav
+++ b/sys/kgssapi/krb5/krb5_mech.c
@@ -215,6 +215,18 @@
*to = from;
else
*to = NULL;
+}
+
+static void
+copy_lucid_key(gss_buffer_desc *from, uint32_t type, struct krb5_keyblock *to)
+{
+
+ to->kk_type = type;
+ to->kk_key.kd_length = from->length;
+ if (from->length > 0) {
+ to->kk_key.kd_data = malloc(from->length, M_GSSAPI, M_WAITOK);
+ memcpy(to->kk_key.kd_data, from->value, from->length);
+ }
}
/*
@@ -399,6 +411,70 @@
struct krb5_context *kc = (struct krb5_context *)ctx;
mtx_init(&kc->kc_lock, "krb5 gss lock", NULL, MTX_DEF);
+}
+
+static OM_uint32
+krb5_lucid_import(gss_ctx_id_t ctx,
+ enum sec_context_format format,
+ const gss_buffer_t context_token)
+{
+ struct krb5_context *kc = (struct krb5_context *)ctx;
+ kgss_lucid_desc *lctx = (kgss_lucid_desc *)context_token;
+ OM_uint32 res;
+
+ kc->kc_more_flags = 0;
+ if (lctx->protocol == 0) {
+ kc->kc_cksumtype = lctx->rfc_sign;
+ kc->kc_keytype = lctx->rfc_seal;
+ copy_lucid_key(&lctx->ctx_key, lctx->ctx_type,
+ &kc->kc_keyblock);
+ } else if (lctx->protocol == 1) {
+ if (lctx->have_subkey != 0) {
+ if (lctx->initiate != 0)
+ copy_lucid_key(&lctx->subkey_key,
+ lctx->subkey_type,
+ &kc->kc_remote_subkey);
+ else
+ copy_lucid_key(&lctx->subkey_key,
+ lctx->subkey_type,
+ &kc->kc_local_subkey);
+ kc->kc_cksumtype = lctx->subkey_type;
+ kc->kc_keytype = lctx->subkey_type;
+ kc->kc_more_flags |= ACCEPTOR_SUBKEY;
+ } else {
+ if (lctx->initiate != 0)
+ copy_lucid_key(&lctx->ctx_key,
+ lctx->ctx_type,
+ &kc->kc_remote_subkey);
+ else
+ copy_lucid_key(&lctx->ctx_key,
+ lctx->ctx_type,
+ &kc->kc_local_subkey);
+ kc->kc_cksumtype = lctx->ctx_type;
+ kc->kc_keytype = lctx->ctx_type;
+ }
+ } else {
+ return (GSS_S_DEFECTIVE_TOKEN);
+ }
+ kc->kc_local_seqnumber = lctx->send_seq;
+ kc->kc_remote_seqnumber = lctx->recv_seq;
+ if (lctx->initiate != 0)
+ kc->kc_more_flags |= LOCAL;
+ kc->kc_lifetime = lctx->endtime;
+ kc->kc_msg_order.km_flags = 0;
+
+ res = get_keys(kc);
+ if (GSS_ERROR(res))
+ return (res);
+
+ /*
+ * We don't need these anymore.
+ */
+ delete_keyblock(&kc->kc_keyblock);
+ delete_keyblock(&kc->kc_local_subkey);
+ delete_keyblock(&kc->kc_remote_subkey);
+
+ return (GSS_S_COMPLETE);
}
static OM_uint32
@@ -413,6 +489,10 @@
uint32_t flags;
int i;
+ /* For MIT, just call krb5_lucid_import(). */
+ if (format == MIT_V1)
+ return (krb5_lucid_import(ctx, format, context_token));
+
/*
* We support heimdal 0.6 and heimdal 1.1
*/
diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss.c.sav b/sys/rpc/rpcsec_gss/rpcsec_gss.c
--- a/sys/rpc/rpcsec_gss/rpcsec_gss.c.sav
+++ b/sys/rpc/rpcsec_gss/rpcsec_gss.c
@@ -746,6 +746,7 @@
struct rpc_callextra ext;
gss_OID mech_oid;
gss_OID_set mechlist;
+ static enum krb_imp my_krb_imp = KRBIMP_UNKNOWN;
rpc_gss_log_debug("in rpc_gss_refresh()");
@@ -850,6 +851,14 @@
options_ret->major_status = maj_stat;
options_ret->minor_status = min_stat;
goto out;
+ }
+
+ if (my_krb_imp == KRBIMP_UNKNOWN) {
+ maj_stat = gss_supports_lucid(&min_stat, NULL);
+ if (maj_stat == GSS_S_COMPLETE)
+ my_krb_imp = KRBIMP_MIT;
+ else
+ my_krb_imp = KRBIMP_HESIOD1;
}
/* GSS context establishment loop. */
@@ -862,19 +871,34 @@
for (;;) {
crsave = td->td_ucred;
td->td_ucred = gd->gd_ucred;
- maj_stat = gss_init_sec_context(&min_stat,
- gd->gd_options.my_cred,
- &gd->gd_ctx,
- name,
- gd->gd_mech,
- gd->gd_options.req_flags,
- gd->gd_options.time_req,
- gd->gd_options.input_channel_bindings,
- recv_tokenp,
- &gd->gd_mech, /* used mech */
- &send_token,
- &options_ret->ret_flags,
- &options_ret->time_req);
+ if (my_krb_imp == KRBIMP_MIT)
+ maj_stat = gss_init_sec_context_lucid_v1(&min_stat,
+ gd->gd_options.my_cred,
+ &gd->gd_ctx,
+ name,
+ gd->gd_mech,
+ gd->gd_options.req_flags,
+ gd->gd_options.time_req,
+ gd->gd_options.input_channel_bindings,
+ recv_tokenp,
+ &gd->gd_mech, /* used mech */
+ &send_token,
+ &options_ret->ret_flags,
+ &options_ret->time_req);
+ else
+ maj_stat = gss_init_sec_context(&min_stat,
+ gd->gd_options.my_cred,
+ &gd->gd_ctx,
+ name,
+ gd->gd_mech,
+ gd->gd_options.req_flags,
+ gd->gd_options.time_req,
+ gd->gd_options.input_channel_bindings,
+ recv_tokenp,
+ &gd->gd_mech, /* used mech */
+ &send_token,
+ &options_ret->ret_flags,
+ &options_ret->time_req);
td->td_ucred = crsave;
/*
diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss_int.h.sav b/sys/rpc/rpcsec_gss/rpcsec_gss_int.h
--- a/sys/rpc/rpcsec_gss/rpcsec_gss_int.h.sav
+++ b/sys/rpc/rpcsec_gss/rpcsec_gss_int.h
@@ -73,6 +73,12 @@
/* Maximum sequence number value. */
#define MAXSEQ 0x80000000
+enum krb_imp {
+ KRBIMP_UNKNOWN,
+ KRBIMP_HESIOD1,
+ KRBIMP_MIT
+};
+
/* Prototypes. */
__BEGIN_DECLS
diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.sav b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
--- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c.sav
+++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c
@@ -925,9 +925,29 @@
OM_uint32 maj_stat = 0, min_stat = 0, ret_flags;
OM_uint32 cred_lifetime;
struct svc_rpc_gss_svc_name *sname;
+ gss_buffer_desc export_name;
+ rpc_gss_ucred_t *uc = &client->cl_ucred;
+ int numgroups;
+ static enum krb_imp my_krb_imp = KRBIMP_UNKNOWN;
rpc_gss_log_debug("in svc_rpc_gss_accept_context()");
+ if (my_krb_imp == KRBIMP_UNKNOWN) {
+ maj_stat = gss_supports_lucid(&min_stat, NULL);
+ if (maj_stat == GSS_S_COMPLETE)
+ my_krb_imp = KRBIMP_MIT;
+ else
+ my_krb_imp = KRBIMP_HESIOD1;
+ min_stat = 0;
+ }
+
+ if (my_krb_imp == KRBIMP_MIT) {
+ uc->uid = 65534;
+ uc->gid = 65534;
+ uc->gidlist = client->cl_gid_storage;
+ numgroups = NGROUPS;
+ }
+
/* Deserialize arguments. */
memset(&recv_tok, 0, sizeof(recv_tok));
@@ -949,18 +969,38 @@
if (sname->sn_program == rqst->rq_prog
&& sname->sn_version == rqst->rq_vers) {
retry:
- gr->gr_major = gss_accept_sec_context(
- &gr->gr_minor,
- &client->cl_ctx,
- sname->sn_cred,
- &recv_tok,
- GSS_C_NO_CHANNEL_BINDINGS,
- &client->cl_cname,
- &mech,
- &gr->gr_token,
- &ret_flags,
- &cred_lifetime,
- &client->cl_creds);
+ if (my_krb_imp == KRBIMP_MIT)
+ gr->gr_major =
+ gss_accept_sec_context_lucid_v1(
+ &gr->gr_minor,
+ &client->cl_ctx,
+ sname->sn_cred,
+ &recv_tok,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client->cl_cname,
+ &mech,
+ &gr->gr_token,
+ &ret_flags,
+ &cred_lifetime,
+ &client->cl_creds,
+ &export_name,
+ &uc->uid,
+ &uc->gid,
+ &numgroups,
+ &uc->gidlist[0]);
+ else
+ gr->gr_major = gss_accept_sec_context(
+ &gr->gr_minor,
+ &client->cl_ctx,
+ sname->sn_cred,
+ &recv_tok,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client->cl_cname,
+ &mech,
+ &gr->gr_token,
+ &ret_flags,
+ &cred_lifetime,
+ &client->cl_creds);
if (gr->gr_major ==
GSS_S_CREDENTIALS_EXPIRED) {
/*
@@ -982,18 +1022,37 @@
return (FALSE);
}
} else {
- gr->gr_major = gss_accept_sec_context(
- &gr->gr_minor,
- &client->cl_ctx,
- client->cl_sname->sn_cred,
- &recv_tok,
- GSS_C_NO_CHANNEL_BINDINGS,
- &client->cl_cname,
- &mech,
- &gr->gr_token,
- &ret_flags,
- &cred_lifetime,
- NULL);
+ if (my_krb_imp == KRBIMP_MIT)
+ gr->gr_major = gss_accept_sec_context_lucid_v1(
+ &gr->gr_minor,
+ &client->cl_ctx,
+ client->cl_sname->sn_cred,
+ &recv_tok,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client->cl_cname,
+ &mech,
+ &gr->gr_token,
+ &ret_flags,
+ &cred_lifetime,
+ NULL,
+ &export_name,
+ &uc->uid,
+ &uc->gid,
+ &numgroups,
+ &uc->gidlist[0]);
+ else
+ gr->gr_major = gss_accept_sec_context(
+ &gr->gr_minor,
+ &client->cl_ctx,
+ client->cl_sname->sn_cred,
+ &recv_tok,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &client->cl_cname,
+ &mech,
+ &gr->gr_token,
+ &ret_flags,
+ &cred_lifetime,
+ NULL);
}
sx_xunlock(&svc_rpc_gss_lock);
@@ -1009,8 +1068,12 @@
rpc_gss_log_status("accept_sec_context", client->cl_mech,
gr->gr_major, gr->gr_minor);
client->cl_state = CLIENT_STALE;
+ if (my_krb_imp == KRBIMP_MIT)
+ uc->gidlen = 0;
return (TRUE);
}
+ if (my_krb_imp == KRBIMP_MIT)
+ uc->gidlen = numgroups;
gr->gr_handle.value = &client->cl_id;
gr->gr_handle.length = sizeof(client->cl_id);
@@ -1022,8 +1085,6 @@
client->cl_done_callback = FALSE;
if (gr->gr_major == GSS_S_COMPLETE) {
- gss_buffer_desc export_name;
-
/*
* Change client expiration time to be near when the
* client creds expire (or 24 hours if we can't figure
@@ -1046,8 +1107,10 @@
*/
client->cl_rawcred.version = RPCSEC_GSS_VERSION;
rpc_gss_oid_to_mech(mech, &client->cl_rawcred.mechanism);
- maj_stat = gss_export_name(&min_stat, client->cl_cname,
- &export_name);
+ maj_stat = GSS_S_COMPLETE;
+ if (my_krb_imp != KRBIMP_MIT)
+ maj_stat = gss_export_name(&min_stat, client->cl_cname,
+ &export_name);
if (maj_stat != GSS_S_COMPLETE) {
rpc_gss_log_status("gss_export_name", client->cl_mech,
maj_stat, min_stat);
@@ -1068,7 +1131,8 @@
* Use gss_pname_to_uid to map to unix creds. For
* kerberos5, this uses krb5_aname_to_localname.
*/
- svc_rpc_gss_build_ucred(client, client->cl_cname);
+ if (my_krb_imp != KRBIMP_MIT)
+ svc_rpc_gss_build_ucred(client, client->cl_cname);
svc_rpc_gss_set_flavor(client);
gss_release_name(&min_stat, &client->cl_cname);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 17, 10:00 PM (6 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29739621
Default Alt Text
D51731.1789682432.diff (24 KB)
Attached To
Mode
D51731: kgssapi: Fix the kgssapi so that it can use MIT Kerberos
Attached
Detach File
Event Timeline
Log In to Comment