diff options
Diffstat (limited to 'sys/rpc/rpcsec_gss')
-rw-r--r-- | sys/rpc/rpcsec_gss/rpcsec_gss.c | 50 | ||||
-rw-r--r-- | sys/rpc/rpcsec_gss/rpcsec_gss_int.h | 6 | ||||
-rw-r--r-- | sys/rpc/rpcsec_gss/svc_rpcsec_gss.c | 122 |
3 files changed, 136 insertions, 42 deletions
diff --git a/sys/rpc/rpcsec_gss/rpcsec_gss.c b/sys/rpc/rpcsec_gss/rpcsec_gss.c index 983dd251f81f..89d1c56f7cc2 100644 --- a/sys/rpc/rpcsec_gss/rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/rpcsec_gss.c @@ -746,6 +746,7 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) 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()"); @@ -852,6 +853,14 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) 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_HEIMDALV1; + } + /* GSS context establishment loop. */ memset(&recv_token, 0, sizeof(recv_token)); memset(&gr, 0, sizeof(gr)); @@ -862,19 +871,34 @@ rpc_gss_init(AUTH *auth, rpc_gss_options_ret_t *options_ret) 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 b/sys/rpc/rpcsec_gss/rpcsec_gss_int.h index 3d643af8c498..ba200ee3aeb7 100644 --- a/sys/rpc/rpcsec_gss/rpcsec_gss_int.h +++ b/sys/rpc/rpcsec_gss/rpcsec_gss_int.h @@ -73,6 +73,12 @@ struct rpc_gss_init_res { /* Maximum sequence number value. */ #define MAXSEQ 0x80000000 +enum krb_imp { + KRBIMP_UNKNOWN, + KRBIMP_HEIMDALV1, + KRBIMP_MIT +}; + /* Prototypes. */ __BEGIN_DECLS diff --git a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c index 51077c71822c..35c904560836 100644 --- a/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c +++ b/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c @@ -925,9 +925,29 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, 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_HEIMDALV1; + 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, */ 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 @@ svc_rpc_gss_accept_sec_context(struct svc_rpc_gss_client *client, * 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); |