Skip to content

Commit

Permalink
Fix the kgssapi so that it can be loaded as a module. Currently
Browse files Browse the repository at this point in the history
the NFS subsystems use five of the rpcsec_gss/kgssapi entry points,
but since it was not obvious which others might be useful, all
nineteen were included. Basically the nineteen entry points are
set in a structure called rpc_gss_entries and inline functions
defined in sys/rpc/rpcsec_gss.h check for the entry points being
non-NULL and then call them. A default value is returned otherwise.
Requested by rwatson.

Reviewed by:	jhb
MFC after:	2 weeks
  • Loading branch information
Rick Macklem authored and Rick Macklem committed Jun 19, 2011
1 parent f982db4 commit 7e7fd7d
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 69 deletions.
14 changes: 4 additions & 10 deletions sys/fs/nfs/nfs_commonkrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,7 @@ newnfs_disconnect(struct nfssockreq *nrp)
client = nrp->nr_client;
nrp->nr_client = NULL;
mtx_unlock(&nrp->nr_mtx);
#ifdef KGSSAPI
rpc_gss_secpurge(client);
#endif
rpc_gss_secpurge_call(client);
CLNT_CLOSE(client);
CLNT_RELEASE(client);
} else {
Expand All @@ -337,21 +335,18 @@ static AUTH *
nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal,
char *srv_principal, gss_OID mech_oid, struct ucred *cred)
{
#ifdef KGSSAPI
rpc_gss_service_t svc;
AUTH *auth;
#ifdef notyet
rpc_gss_options_req_t req_options;
#endif
#endif

switch (secflavour) {
#ifdef KGSSAPI
case RPCSEC_GSS_KRB5:
case RPCSEC_GSS_KRB5I:
case RPCSEC_GSS_KRB5P:
if (!mech_oid) {
if (!rpc_gss_mech_to_oid("kerberosv5", &mech_oid))
if (!rpc_gss_mech_to_oid_call("kerberosv5", &mech_oid))
return (NULL);
}
if (secflavour == RPCSEC_GSS_KRB5)
Expand All @@ -367,7 +362,7 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal,
req_options.input_channel_bindings = NULL;
req_options.enc_type = nfs_keytab_enctype;

auth = rpc_gss_secfind(nrp->nr_client, cred,
auth = rpc_gss_secfind_call(nrp->nr_client, cred,
clnt_principal, srv_principal, mech_oid, svc,
&req_options);
#else
Expand All @@ -377,15 +372,14 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal,
* principals. As such, that case cannot yet be handled.
*/
if (clnt_principal == NULL)
auth = rpc_gss_secfind(nrp->nr_client, cred,
auth = rpc_gss_secfind_call(nrp->nr_client, cred,
srv_principal, mech_oid, svc);
else
auth = NULL;
#endif
if (auth != NULL)
return (auth);
/* fallthrough */
#endif /* KGSSAPI */
case AUTH_SYS:
default:
return (authunix_create(cred));
Expand Down
12 changes: 2 additions & 10 deletions sys/fs/nfsclient/nfs_clkrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,9 @@ nfscbd_addsock(struct file *fp)
int
nfscbd_nfsd(struct thread *td, struct nfsd_nfscbd_args *args)
{
#ifdef KGSSAPI
char principal[128];
int error;
#endif

#ifdef KGSSAPI
if (args != NULL) {
error = copyinstr(args->principal, principal,
sizeof(principal), NULL);
Expand All @@ -229,7 +226,6 @@ nfscbd_nfsd(struct thread *td, struct nfsd_nfscbd_args *args)
} else {
principal[0] = '\0';
}
#endif

/*
* Only the first nfsd actually does any work. The RPC code
Expand All @@ -244,20 +240,16 @@ nfscbd_nfsd(struct thread *td, struct nfsd_nfscbd_args *args)

NFSD_UNLOCK();

#ifdef KGSSAPI
if (principal[0] != '\0')
rpc_gss_set_svc_name(principal, "kerberosv5",
rpc_gss_set_svc_name_call(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_CALLBCKPROG, NFSV4_CBVERS);
#endif

nfscbd_pool->sp_minthreads = 4;
nfscbd_pool->sp_maxthreads = 4;

svc_run(nfscbd_pool);

#ifdef KGSSAPI
rpc_gss_clear_svc_name(NFS_CALLBCKPROG, NFSV4_CBVERS);
#endif
rpc_gss_clear_svc_name_call(NFS_CALLBCKPROG, NFSV4_CBVERS);

NFSD_LOCK();
nfs_numnfscbd--;
Expand Down
37 changes: 12 additions & 25 deletions sys/fs/nfsserver/nfs_nfsdkrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,18 +386,14 @@ nfsrvd_addsock(struct file *fp)
int
nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
{
#ifdef KGSSAPI
char principal[MAXHOSTNAMELEN + 5];
int error;
bool_t ret2, ret3, ret4;
#endif

#ifdef KGSSAPI
error = copyinstr(args->principal, principal, sizeof (principal),
NULL);
if (error)
return (error);
#endif

/*
* Only the first nfsd actually does any work. The RPC code
Expand All @@ -412,38 +408,29 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args)

NFSD_UNLOCK();

#ifdef KGSSAPI
/* An empty string implies AUTH_SYS only. */
if (principal[0] != '\0') {
ret2 = rpc_gss_set_svc_name(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
ret3 = rpc_gss_set_svc_name(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
ret4 = rpc_gss_set_svc_name(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_PROG, NFS_VER4);

if (!ret2 || !ret3 || !ret4) {
NFSD_LOCK();
newnfs_numnfsd--;
nfsrvd_init(1);
NFSD_UNLOCK();
return (EAUTH);
}
ret2 = rpc_gss_set_svc_name_call(principal,
"kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
ret3 = rpc_gss_set_svc_name_call(principal,
"kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
ret4 = rpc_gss_set_svc_name_call(principal,
"kerberosv5", GSS_C_INDEFINITE, NFS_PROG, NFS_VER4);

if (!ret2 || !ret3 || !ret4)
printf("nfsd: can't register svc name\n");
}
#endif

nfsrvd_pool->sp_minthreads = args->minthreads;
nfsrvd_pool->sp_maxthreads = args->maxthreads;

svc_run(nfsrvd_pool);

#ifdef KGSSAPI
if (principal[0] != '\0') {
rpc_gss_clear_svc_name(NFS_PROG, NFS_VER2);
rpc_gss_clear_svc_name(NFS_PROG, NFS_VER3);
rpc_gss_clear_svc_name(NFS_PROG, NFS_VER4);
rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2);
rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3);
rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER4);
}
#endif

NFSD_LOCK();
newnfs_numnfsd--;
Expand Down
37 changes: 35 additions & 2 deletions sys/kgssapi/gss_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <kgssapi/gssapi_impl.h>
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#include <rpc/rpcsec_gss.h>

#include "gssd.h"
#include "kgss_if.h"
Expand Down Expand Up @@ -253,8 +254,40 @@ kgss_copy_buffer(const gss_buffer_t from, gss_buffer_t to)
static int
kgssapi_modevent(module_t mod, int type, void *data)
{

return (0);
int error = 0;

switch (type) {
case MOD_LOAD:
rpc_gss_entries.rpc_gss_secfind = rpc_gss_secfind;
rpc_gss_entries.rpc_gss_secpurge = rpc_gss_secpurge;
rpc_gss_entries.rpc_gss_seccreate = rpc_gss_seccreate;
rpc_gss_entries.rpc_gss_set_defaults = rpc_gss_set_defaults;
rpc_gss_entries.rpc_gss_max_data_length =
rpc_gss_max_data_length;
rpc_gss_entries.rpc_gss_get_error = rpc_gss_get_error;
rpc_gss_entries.rpc_gss_mech_to_oid = rpc_gss_mech_to_oid;
rpc_gss_entries.rpc_gss_oid_to_mech = rpc_gss_oid_to_mech;
rpc_gss_entries.rpc_gss_qop_to_num = rpc_gss_qop_to_num;
rpc_gss_entries.rpc_gss_get_mechanisms = rpc_gss_get_mechanisms;
rpc_gss_entries.rpc_gss_get_versions = rpc_gss_get_versions;
rpc_gss_entries.rpc_gss_is_installed = rpc_gss_is_installed;
rpc_gss_entries.rpc_gss_set_svc_name = rpc_gss_set_svc_name;
rpc_gss_entries.rpc_gss_clear_svc_name = rpc_gss_clear_svc_name;
rpc_gss_entries.rpc_gss_getcred = rpc_gss_getcred;
rpc_gss_entries.rpc_gss_set_callback = rpc_gss_set_callback;
rpc_gss_entries.rpc_gss_clear_callback = rpc_gss_clear_callback;
rpc_gss_entries.rpc_gss_get_principal_name =
rpc_gss_get_principal_name;
rpc_gss_entries.rpc_gss_svc_max_data_length =
rpc_gss_svc_max_data_length;
break;
case MOD_UNLOAD:
/* Unloading of the kgssapi module isn't supported. */
/* FALLTHROUGH */
default:
error = EOPNOTSUPP;
};
return (error);
}
static moduledata_t kgssapi_mod = {
"kgssapi",
Expand Down
2 changes: 2 additions & 0 deletions sys/modules/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ SUBDIR= ${_3dfx} \
jme \
joy \
kbdmux \
kgssapi \
kgssapi_krb5 \
khelp \
krpc \
ksyms \
Expand Down
3 changes: 2 additions & 1 deletion sys/modules/kgssapi_krb5/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ SRCS= krb5_mech.c \
kcrypto_des.c \
kcrypto_des3.c \
kcrypto_aes.c \
kcrypto_arcfour.c
kcrypto_arcfour.c \
opt_inet6.h

SRCS+= kgss_if.h gssd.h
MFILES= kgssapi/kgss_if.m
Expand Down
12 changes: 3 additions & 9 deletions sys/nfsclient/nfs_krpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,7 @@ nfs_disconnect(struct nfsmount *nmp)
client = nmp->nm_client;
nmp->nm_client = NULL;
mtx_unlock(&nmp->nm_mtx);
#ifdef KGSSAPI
rpc_gss_secpurge(client);
#endif
rpc_gss_secpurge_call(client);
CLNT_CLOSE(client);
CLNT_RELEASE(client);
} else
Expand All @@ -325,18 +323,15 @@ nfs_safedisconnect(struct nfsmount *nmp)
static AUTH *
nfs_getauth(struct nfsmount *nmp, struct ucred *cred)
{
#ifdef KGSSAPI
rpc_gss_service_t svc;
AUTH *auth;
#endif

switch (nmp->nm_secflavor) {
#ifdef KGSSAPI
case RPCSEC_GSS_KRB5:
case RPCSEC_GSS_KRB5I:
case RPCSEC_GSS_KRB5P:
if (!nmp->nm_mech_oid)
if (!rpc_gss_mech_to_oid("kerberosv5",
if (!rpc_gss_mech_to_oid_call("kerberosv5",
&nmp->nm_mech_oid))
return (NULL);
if (nmp->nm_secflavor == RPCSEC_GSS_KRB5)
Expand All @@ -345,12 +340,11 @@ nfs_getauth(struct nfsmount *nmp, struct ucred *cred)
svc = rpc_gss_svc_integrity;
else
svc = rpc_gss_svc_privacy;
auth = rpc_gss_secfind(nmp->nm_client, cred,
auth = rpc_gss_secfind_call(nmp->nm_client, cred,
nmp->nm_principal, nmp->nm_mech_oid, svc);
if (auth)
return (auth);
/* fallthrough */
#endif
case AUTH_SYS:
default:
return (authunix_create(cred));
Expand Down
16 changes: 4 additions & 12 deletions sys/nfsserver/nfs_srvkrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,9 @@ nfssvc_addsock(struct file *fp, struct thread *td)
static int
nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
{
#ifdef KGSSAPI
char principal[128];
int error;
#endif

#ifdef KGSSAPI
if (args) {
error = copyinstr(args->principal, principal,
sizeof(principal), NULL);
Expand All @@ -434,7 +431,6 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
getcredhostname(td->td_ucred, principal + 4,
sizeof(principal) - 4);
}
#endif

/*
* Only the first nfsd actually does any work. The RPC code
Expand All @@ -449,12 +445,10 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)

NFSD_UNLOCK();

#ifdef KGSSAPI
rpc_gss_set_svc_name(principal, "kerberosv5",
rpc_gss_set_svc_name_call(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
rpc_gss_set_svc_name(principal, "kerberosv5",
rpc_gss_set_svc_name_call(principal, "kerberosv5",
GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
#endif

if (args) {
nfsrv_pool->sp_minthreads = args->minthreads;
Expand All @@ -466,10 +460,8 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)

svc_run(nfsrv_pool);

#ifdef KGSSAPI
rpc_gss_clear_svc_name(NFS_PROG, NFS_VER2);
rpc_gss_clear_svc_name(NFS_PROG, NFS_VER3);
#endif
rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2);
rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3);

NFSD_LOCK();
nfsrv_numnfsd--;
Expand Down
4 changes: 4 additions & 0 deletions sys/rpc/rpc_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");

#include <rpc/rpc.h>
#include <rpc/nettype.h>
#include <rpc/rpcsec_gss.h>

#include <rpc/rpc_com.h>

Expand All @@ -69,6 +70,9 @@ extern u_long sb_max_adj; /* not defined in socketvar.h */
#define strrchr rindex
#endif

/* Provide an entry point hook for the rpcsec_gss module. */
struct rpc_gss_entries rpc_gss_entries;

struct handle {
NCONF_HANDLE *nhandle;
int nflag; /* Whether NETPATH or NETCONFIG */
Expand Down
Loading

0 comments on commit 7e7fd7d

Please sign in to comment.