X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d9a64523371fa019c4575bb400cbbc3a50ac9903..eb6b6ca394357805f2bdba989abae309f718b4d8:/bsd/nfs/nfs_gss.c diff --git a/bsd/nfs/nfs_gss.c b/bsd/nfs/nfs_gss.c index 02c121289..71188d12a 100644 --- a/bsd/nfs/nfs_gss.c +++ b/bsd/nfs/nfs_gss.c @@ -2,7 +2,7 @@ * Copyright (c) 2007-2015 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,10 +22,13 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ +#include +#if CONFIG_NFS + /************* * These functions implement RPCSEC_GSS security for the NFS client and server. * The code is specific to the use of Kerberos v5 and the use of DES MAC MD5 @@ -120,60 +123,62 @@ #define NFS_GSS_ISDBG (NFS_DEBUG_FACILITY & NFS_FAC_GSS) -#if NFSSERVER +#if CONFIG_NFS_SERVER u_long nfs_gss_svc_ctx_hash; struct nfs_gss_svc_ctx_hashhead *nfs_gss_svc_ctx_hashtbl; lck_mtx_t *nfs_gss_svc_ctx_mutex; lck_grp_t *nfs_gss_svc_grp; uint32_t nfsrv_gss_context_ttl = GSS_CTX_EXPIRE; #define GSS_SVC_CTX_TTL ((uint64_t)max(2*GSS_CTX_PEND, nfsrv_gss_context_ttl) * NSEC_PER_SEC) -#endif /* NFSSERVER */ +#endif /* CONFIG_NFS_SERVER */ -#if NFSCLIENT +#if CONFIG_NFS_CLIENT lck_grp_t *nfs_gss_clnt_grp; -#endif /* NFSCLIENT */ +#endif /* CONFIG_NFS_CLIENT */ #define KRB5_MAX_MIC_SIZE 128 uint8_t krb5_mech_oid[11] = { 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02 }; static uint8_t xdrpad[] = { 0x00, 0x00, 0x00, 0x00}; -#if NFSCLIENT -static int nfs_gss_clnt_ctx_find(struct nfsreq *); -static int nfs_gss_clnt_ctx_init(struct nfsreq *, struct nfs_gss_clnt_ctx *); -static int nfs_gss_clnt_ctx_init_retry(struct nfsreq *, struct nfs_gss_clnt_ctx *); -static int nfs_gss_clnt_ctx_callserver(struct nfsreq *, struct nfs_gss_clnt_ctx *); -static uint8_t *nfs_gss_clnt_svcname(struct nfsmount *, gssd_nametype *, uint32_t *); -static int nfs_gss_clnt_gssd_upcall(struct nfsreq *, struct nfs_gss_clnt_ctx *, uint32_t); -void nfs_gss_clnt_ctx_neg_cache_reap(struct nfsmount *); -static void nfs_gss_clnt_ctx_clean(struct nfs_gss_clnt_ctx *); -static int nfs_gss_clnt_ctx_copy(struct nfs_gss_clnt_ctx *, struct nfs_gss_clnt_ctx **); -static void nfs_gss_clnt_ctx_destroy(struct nfs_gss_clnt_ctx *); -static void nfs_gss_clnt_log_error(struct nfsreq *, struct nfs_gss_clnt_ctx *, uint32_t, uint32_t); -#endif /* NFSCLIENT */ - -#if NFSSERVER +#if CONFIG_NFS_CLIENT +static int nfs_gss_clnt_ctx_find(struct nfsreq *); +static int nfs_gss_clnt_ctx_init(struct nfsreq *, struct nfs_gss_clnt_ctx *); +static int nfs_gss_clnt_ctx_init_retry(struct nfsreq *, struct nfs_gss_clnt_ctx *); +static int nfs_gss_clnt_ctx_callserver(struct nfsreq *, struct nfs_gss_clnt_ctx *); +static uint8_t *nfs_gss_clnt_svcname(struct nfsmount *, gssd_nametype *, uint32_t *); +static int nfs_gss_clnt_gssd_upcall(struct nfsreq *, struct nfs_gss_clnt_ctx *, uint32_t); +void nfs_gss_clnt_ctx_neg_cache_reap(struct nfsmount *); +static void nfs_gss_clnt_ctx_clean(struct nfs_gss_clnt_ctx *); +static int nfs_gss_clnt_ctx_copy(struct nfs_gss_clnt_ctx *, struct nfs_gss_clnt_ctx **); +static void nfs_gss_clnt_ctx_destroy(struct nfs_gss_clnt_ctx *); +static void nfs_gss_clnt_log_error(struct nfsreq *, struct nfs_gss_clnt_ctx *, uint32_t, uint32_t); +#endif /* CONFIG_NFS_CLIENT */ + +#if CONFIG_NFS_SERVER static struct nfs_gss_svc_ctx *nfs_gss_svc_ctx_find(uint32_t); -static void nfs_gss_svc_ctx_insert(struct nfs_gss_svc_ctx *); -static void nfs_gss_svc_ctx_timer(void *, void *); -static int nfs_gss_svc_gssd_upcall(struct nfs_gss_svc_ctx *); -static int nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *, uint32_t); -#endif /* NFSSERVER */ +static void nfs_gss_svc_ctx_insert(struct nfs_gss_svc_ctx *); +static void nfs_gss_svc_ctx_timer(void *, void *); +static int nfs_gss_svc_gssd_upcall(struct nfs_gss_svc_ctx *); +static int nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *, uint32_t); -static void host_release_special_port(mach_port_t); +/* This is only used by server code */ +static void nfs_gss_nfsm_chain(struct nfsm_chain *, mbuf_t); +#endif /* CONFIG_NFS_SERVER */ + +static void host_release_special_port(mach_port_t); static mach_port_t host_copy_special_port(mach_port_t); -static void nfs_gss_mach_alloc_buffer(u_char *, uint32_t, vm_map_copy_t *); -static int nfs_gss_mach_vmcopyout(vm_map_copy_t, uint32_t, u_char *); +static void nfs_gss_mach_alloc_buffer(u_char *, uint32_t, vm_map_copy_t *); +static int nfs_gss_mach_vmcopyout(vm_map_copy_t, uint32_t, u_char *); -static int nfs_gss_mchain_length(mbuf_t); -static int nfs_gss_append_chain(struct nfsm_chain *, mbuf_t); -static void nfs_gss_nfsm_chain(struct nfsm_chain *, mbuf_t); +static int nfs_gss_mchain_length(mbuf_t); +static int nfs_gss_append_chain(struct nfsm_chain *, mbuf_t); -#if NFSSERVER +#if CONFIG_NFS_SERVER thread_call_t nfs_gss_svc_ctx_timer_call; int nfs_gss_timer_on = 0; uint32_t nfs_gss_ctx_count = 0; const uint32_t nfs_gss_ctx_max = GSS_SVC_MAXCONTEXTS; -#endif /* NFSSERVER */ +#endif /* CONFIG_NFS_SERVER */ /* * Initialization when NFS starts @@ -181,18 +186,18 @@ const uint32_t nfs_gss_ctx_max = GSS_SVC_MAXCONTEXTS; void nfs_gss_init(void) { -#if NFSCLIENT +#if CONFIG_NFS_CLIENT nfs_gss_clnt_grp = lck_grp_alloc_init("rpcsec_gss_clnt", LCK_GRP_ATTR_NULL); -#endif /* NFSCLIENT */ +#endif /* CONFIG_NFS_CLIENT */ -#if NFSSERVER - nfs_gss_svc_grp = lck_grp_alloc_init("rpcsec_gss_svc", LCK_GRP_ATTR_NULL); +#if CONFIG_NFS_SERVER + nfs_gss_svc_grp = lck_grp_alloc_init("rpcsec_gss_svc", LCK_GRP_ATTR_NULL); nfs_gss_svc_ctx_hashtbl = hashinit(SVC_CTX_HASHSZ, M_TEMP, &nfs_gss_svc_ctx_hash); nfs_gss_svc_ctx_mutex = lck_mtx_alloc_init(nfs_gss_svc_grp, LCK_ATTR_NULL); nfs_gss_svc_ctx_timer_call = thread_call_allocate(nfs_gss_svc_ctx_timer, NULL); -#endif /* NFSSERVER */ +#endif /* CONFIG_NFS_SERVER */ } /* @@ -216,20 +221,22 @@ rpc_gss_prepend_32(mbuf_t *mb, uint32_t value) mbuf_t nmb; error = mbuf_get(MBUF_WAITOK, MBUF_TYPE_DATA, &nmb); - if (error) - return (error); + if (error) { + return error; + } mbuf_setnext(nmb, *mb); *mb = nmb; } #endif error = mbuf_prepend(mb, sizeof(uint32_t), MBUF_WAITOK); - if (error) - return (error); + if (error) { + return error; + } data = mbuf_data(*mb); *data = txdr_unsigned(value); - return (0); + return 0; } /* @@ -250,8 +257,9 @@ rpc_gss_data_create(mbuf_t *mbp_head, uint32_t seqnum) uint8_t *data; error = mbuf_get(MBUF_WAITOK, MBUF_TYPE_DATA, &mb); - if (error) - return (error); + if (error) { + return error; + } data = mbuf_data(mb); #if 0 /* Reserve space for prepending */ @@ -259,26 +267,28 @@ rpc_gss_data_create(mbuf_t *mbp_head, uint32_t seqnum) len = (len & ~0x3) - NFSX_UNSIGNED; printf("%s: data = %p, len = %d\n", __func__, data, (int)len); error = mbuf_setdata(mb, data + len, 0); - if (error || mbuf_trailingspace(mb)) + if (error || mbuf_trailingspace(mb)) { printf("%s: data = %p trailingspace = %d error = %d\n", __func__, mbuf_data(mb), (int)mbuf_trailingspace(mb), error); + } #endif /* Reserve 16 words for prepending */ - error = mbuf_setdata(mb, data + 16*sizeof(uint32_t), 0); + error = mbuf_setdata(mb, data + 16 * sizeof(uint32_t), 0); nfsm_chain_init(nmcp, mb); nfsm_chain_add_32(error, nmcp, seqnum); nfsm_chain_build_done(error, nmcp); - if (error) - return (EINVAL); + if (error) { + return EINVAL; + } mbuf_setnext(nmcp->nmc_mcur, *mbp_head); *mbp_head = nmcp->nmc_mhead; - return (0); + return 0; } /* * Create an rpc_gss_integ_data_t given an argument or result in mb_head. * On successful return mb_head will point to the rpc_gss_integ_data_t of length len. - * Note mb_head will now point to a 4 byte sequence number. len does not include + * Note mb_head will now point to a 4 byte sequence number. len does not include * any extra xdr padding. * Returns 0 on success, else an errno_t */ @@ -294,11 +304,13 @@ rpc_gss_integ_data_create(gss_ctx_id_t ctx, mbuf_t *mb_head, uint32_t seqnum, ui /* Length of the argument or result */ length = nfs_gss_mchain_length(*mb_head); - if (len) + if (len) { *len = length; + } error = rpc_gss_data_create(mb_head, seqnum); - if (error) - return (error); + if (error) { + return error; + } /* * length is the length of the rpc_gss_data @@ -307,12 +319,13 @@ rpc_gss_integ_data_create(gss_ctx_id_t ctx, mbuf_t *mb_head, uint32_t seqnum, ui major = gss_krb5_get_mic_mbuf(&error, ctx, 0, *mb_head, 0, length, &mic); if (major != GSS_S_COMPLETE) { printf("gss_krb5_get_mic_mbuf failed %d\n", error); - return (error); + return error; } error = rpc_gss_prepend_32(mb_head, length); - if (error) - return (error); + if (error) { + return error; + } nfsm_chain_dissect_init(error, &nmc, *mb_head); /* Append GSS mic token by advancing rpc_gss_data_t length + NFSX_UNSIGNED (size of the length field) */ @@ -326,7 +339,7 @@ rpc_gss_integ_data_create(gss_ctx_id_t ctx, mbuf_t *mb_head, uint32_t seqnum, ui // printmbuf("rpc_gss_integ_data_create done", *mb_head, 0, 0); assert(nmc.nmc_mhead == *mb_head); - return (error); + return error; } /* @@ -345,24 +358,28 @@ rpc_gss_priv_data_create(gss_ctx_id_t ctx, mbuf_t *mb_head, uint32_t seqnum, uin uint32_t length; error = rpc_gss_data_create(mb_head, seqnum); - if (error) - return (error); + if (error) { + return error; + } length = nfs_gss_mchain_length(*mb_head); major = gss_krb5_wrap_mbuf(&error, ctx, 1, 0, mb_head, 0, length, NULL); - if (major != GSS_S_COMPLETE) - return (error); + if (major != GSS_S_COMPLETE) { + return error; + } length = nfs_gss_mchain_length(*mb_head); - if (len) + if (len) { *len = length; + } pad = nfsm_pad(length); /* Prepend the opaque length of rep rpc_gss_priv_data */ error = rpc_gss_prepend_32(mb_head, length); - if (error) - return (error); + if (error) { + return error; + } if (pad) { nfsm_chain_dissect_init(error, &nmc, *mb_head); /* Advance the opauque size of length and length data */ @@ -372,10 +389,10 @@ rpc_gss_priv_data_create(gss_ctx_id_t ctx, mbuf_t *mb_head, uint32_t seqnum, uin nfsm_chain_build_done(error, &nmc); } - return (error); + return error; } -#if NFSCLIENT +#if CONFIG_NFS_CLIENT /* * Restore the argument or result from an rpc_gss_integ_data mbuf chain @@ -399,27 +416,29 @@ rpc_gss_integ_data_restore(gss_ctx_id_t ctx __unused, mbuf_t *mb_head, size_t le /* should only be one, ... but */ for (; mb; mb = next) { next = mbuf_next(mb); - if (mbuf_len(mb) == 0) + if (mbuf_len(mb) == 0) { mbuf_free(mb); - else + } else { break; + } } *mb_head = mb; for (; mb && len; mb = mbuf_next(mb)) { tail = mb; - if (mbuf_len(mb) <= len) + if (mbuf_len(mb) <= len) { len -= mbuf_len(mb); - else - return (EBADRPC); + } else { + return EBADRPC; + } } /* drop the mic */ if (tail) { - mbuf_setnext(tail, NULL); - mbuf_freem(mb); + mbuf_setnext(tail, NULL); + mbuf_freem(mb); } - return (0); + return 0; } /* @@ -445,12 +464,13 @@ rpc_gss_priv_data_restore(gss_ctx_id_t ctx, mbuf_t *mb_head, size_t len) if (plen) { mbuf_t tail = NULL; - for(length = 0; length < len && mb; mb = mbuf_next(mb)) { + for (length = 0; length < len && mb; mb = mbuf_next(mb)) { tail = mb; length += mbuf_len(mb); } - if ((length != len) || (mb == NULL) || (tail == NULL)) - return (EBADRPC); + if ((length != len) || (mb == NULL) || (tail == NULL)) { + return EBADRPC; + } mbuf_freem(mb); mbuf_setnext(tail, NULL); @@ -459,7 +479,7 @@ rpc_gss_priv_data_restore(gss_ctx_id_t ctx, mbuf_t *mb_head, size_t len) major = gss_krb5_unwrap_mbuf(&error, ctx, mb_head, 0, len, NULL, &qop); if (major != GSS_S_COMPLETE) { printf("gss_krb5_unwrap_mbuf failed. major = %d minor = %d\n", (int)major, error); - return (error); + return error; } mb = *mb_head; @@ -470,14 +490,15 @@ rpc_gss_priv_data_restore(gss_ctx_id_t ctx, mbuf_t *mb_head, size_t len) /* Chop of any empty mbufs */ for (mb = *mb_head; mb; mb = next) { next = mbuf_next(mb); - if (mbuf_len(mb) == 0) + if (mbuf_len(mb) == 0) { mbuf_free(mb); - else + } else { break; + } } *mb_head = mb; - return (0); + return 0; } /* @@ -503,7 +524,7 @@ uid_t nfs_cred_getasid2uid(kauth_cred_t cred) { uid_t result = SAFE_CAST_INTTYPE(uid_t, kauth_cred_getasid(cred)); - return (result); + return result; } /* @@ -519,9 +540,9 @@ nfs_gss_clnt_ctx_dump(struct nfsmount *nmp) TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) { lck_mtx_lock(cp->gss_clnt_mtx); printf("context %d/%d: refcnt = %d, flags = %x\n", - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getauid(cp->gss_clnt_cred), - cp->gss_clnt_refcnt, cp->gss_clnt_flags); + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getauid(cp->gss_clnt_cred), + cp->gss_clnt_refcnt, cp->gss_clnt_flags); lck_mtx_unlock(cp->gss_clnt_mtx); } NFS_GSS_DBG("Exit\n"); @@ -535,12 +556,13 @@ nfs_gss_clnt_ctx_name(struct nfsmount *nmp, struct nfs_gss_clnt_ctx *cp, char *b int nlen; const char *server = ""; - if (nmp && nmp->nm_mountp) + if (nmp && nmp->nm_mountp) { server = vfs_statfs(nmp->nm_mountp)->f_mntfromname; + } if (cp == NULL) { snprintf(buf, len, "[%s] NULL context", server); - return (buf); + return buf; } if (cp->gss_clnt_principal && !cp->gss_clnt_display) { @@ -550,33 +572,35 @@ nfs_gss_clnt_ctx_name(struct nfsmount *nmp, struct nfs_gss_clnt_ctx *cp, char *b np = cp->gss_clnt_display; nlen = np ? strlen(cp->gss_clnt_display) : 0; } - if (nlen) + if (nlen) { snprintf(buf, len, "[%s] %.*s %d/%d %s", server, nlen, np, - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getuid(cp->gss_clnt_cred), - cp->gss_clnt_principal ? "" : "[from default cred] "); - else + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getuid(cp->gss_clnt_cred), + cp->gss_clnt_principal ? "" : "[from default cred] "); + } else { snprintf(buf, len, "[%s] using default %d/%d ", server, - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getuid(cp->gss_clnt_cred)); - return (buf); + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getuid(cp->gss_clnt_cred)); + } + return buf; } #define NFS_CTXBUFSZ 80 #define NFS_GSS_CTX(req, cp) nfs_gss_clnt_ctx_name((req)->r_nmp, cp ? cp : (req)->r_gss_ctx, CTXBUF, sizeof(CTXBUF)) -#define NFS_GSS_CLNT_CTX_DUMP(nmp) \ - do { \ - if (NFS_GSS_ISDBG && (NFS_DEBUG_FLAGS & 0x2)) \ - nfs_gss_clnt_ctx_dump((nmp)); \ +#define NFS_GSS_CLNT_CTX_DUMP(nmp) \ + do { \ + if (NFS_GSS_ISDBG && (NFS_DEBUG_FLAGS & 0x2)) \ + nfs_gss_clnt_ctx_dump((nmp)); \ } while (0) static int nfs_gss_clnt_ctx_cred_match(kauth_cred_t cred1, kauth_cred_t cred2) { - if (kauth_cred_getasid(cred1) == kauth_cred_getasid(cred2)) - return (1); - return (0); + if (kauth_cred_getasid(cred1) == kauth_cred_getasid(cred2)) { + return 1; + } + return 0; } /* @@ -598,8 +622,9 @@ nfs_gss_clnt_mnt_ref(struct nfsmount *nmp) vnode_t rvp; if (nmp == NULL || - !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) + !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) { return; + } error = VFS_ROOT(nmp->nm_mountp, &rvp, NULL); if (!error) { @@ -619,8 +644,9 @@ nfs_gss_clnt_mnt_rele(struct nfsmount *nmp) vnode_t rvp; if (nmp == NULL || - !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) + !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) { return; + } error = VFS_ROOT(nmp->nm_mountp, &rvp, NULL); if (!error) { @@ -641,7 +667,7 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t struct timeval now; char CTXBUF[NFS_CTXBUFSZ]; - bzero(&treq, sizeof (struct nfsreq)); + bzero(&treq, sizeof(struct nfsreq)); treq.r_nmp = nmp; microuptime(&now); @@ -650,8 +676,8 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t lck_mtx_lock(cp->gss_clnt_mtx); if (cp->gss_clnt_flags & GSS_CTX_DESTROY) { NFS_GSS_DBG("Found destroyed context %s refcnt = %d continuing\n", - NFS_GSS_CTX(req, cp), - cp->gss_clnt_refcnt); + NFS_GSS_CTX(req, cp), + cp->gss_clnt_refcnt); lck_mtx_unlock(cp->gss_clnt_mtx); continue; } @@ -671,9 +697,9 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t cp->gss_clnt_refcnt++; lck_mtx_unlock(cp->gss_clnt_mtx); NFS_GSS_DBG("Marking %s for deletion because %s does not match\n", - NFS_GSS_CTX(req, cp), principal); + NFS_GSS_CTX(req, cp), principal); NFS_GSS_DBG("len = (%d,%d), nt = (%d,%d)\n", cp->gss_clnt_prinlen, plen, - cp->gss_clnt_prinnt, nt); + cp->gss_clnt_prinnt, nt); treq.r_gss_ctx = cp; cp = NULL; break; @@ -687,10 +713,10 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t */ if (cp->gss_clnt_nctime + GSS_NEG_CACHE_TO >= now.tv_sec || cp->gss_clnt_nctime == 0) { NFS_GSS_DBG("Context %s (refcnt = %d) not expired returning EAUTH nctime = %ld now = %ld\n", - NFS_GSS_CTX(req, cp), cp->gss_clnt_refcnt, cp->gss_clnt_nctime, now.tv_sec); + NFS_GSS_CTX(req, cp), cp->gss_clnt_refcnt, cp->gss_clnt_nctime, now.tv_sec); lck_mtx_unlock(cp->gss_clnt_mtx); lck_mtx_unlock(&nmp->nm_lock); - return (NFSERR_EAUTH); + return NFSERR_EAUTH; } if (cp->gss_clnt_refcnt) { struct nfs_gss_clnt_ctx *ncp; @@ -701,18 +727,19 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t */ cp->gss_clnt_flags |= GSS_CTX_DESTROY; NFS_GSS_DBG("Context %s has expired but we still have %d references\n", - NFS_GSS_CTX(req, cp), cp->gss_clnt_refcnt); + NFS_GSS_CTX(req, cp), cp->gss_clnt_refcnt); error = nfs_gss_clnt_ctx_copy(cp, &ncp); lck_mtx_unlock(cp->gss_clnt_mtx); if (error) { lck_mtx_unlock(&nmp->nm_lock); - return (error); + return error; } cp = ncp; break; } else { - if (cp->gss_clnt_nctime) + if (cp->gss_clnt_nctime) { nmp->nm_ncentries--; + } lck_mtx_unlock(cp->gss_clnt_mtx); TAILQ_REMOVE(&nmp->nm_gsscl, cp, gss_clnt_entries); break; @@ -723,7 +750,7 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t req->r_gss_ctx = cp; lck_mtx_unlock(cp->gss_clnt_mtx); lck_mtx_unlock(&nmp->nm_lock); - return (0); + return 0; } lck_mtx_unlock(cp->gss_clnt_mtx); } @@ -737,36 +764,36 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t * in case one is set up for it. */ TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) { - if (!(cp->gss_clnt_flags & (GSS_CTX_INVAL|GSS_CTX_DESTROY))) { + if (!(cp->gss_clnt_flags & (GSS_CTX_INVAL | GSS_CTX_DESTROY))) { nfs_gss_clnt_ctx_ref(req, cp); lck_mtx_unlock(&nmp->nm_lock); NFS_GSS_DBG("Root stole context %s\n", NFS_GSS_CTX(req, NULL)); - return (0); + return 0; } } } NFS_GSS_DBG("Context %s%sfound in Neg Cache @ %ld\n", - NFS_GSS_CTX(req, cp), - cp == NULL ? " not " : "", - cp == NULL ? 0L : cp->gss_clnt_nctime); + NFS_GSS_CTX(req, cp), + cp == NULL ? " not " : "", + cp == NULL ? 0L : cp->gss_clnt_nctime); /* * Not found - create a new context */ if (cp == NULL) { - MALLOC(cp, struct nfs_gss_clnt_ctx *, sizeof(*cp), M_TEMP, M_WAITOK|M_ZERO); + MALLOC(cp, struct nfs_gss_clnt_ctx *, sizeof(*cp), M_TEMP, M_WAITOK | M_ZERO); if (cp == NULL) { lck_mtx_unlock(&nmp->nm_lock); - return (ENOMEM); + return ENOMEM; } cp->gss_clnt_cred = req->r_cred; kauth_cred_ref(cp->gss_clnt_cred); cp->gss_clnt_mtx = lck_mtx_alloc_init(nfs_gss_clnt_grp, LCK_ATTR_NULL); cp->gss_clnt_ptime = now.tv_sec - GSS_PRINT_DELAY; if (principal) { - MALLOC(cp->gss_clnt_principal, uint8_t *, plen+1, M_TEMP, M_WAITOK|M_ZERO); + MALLOC(cp->gss_clnt_principal, uint8_t *, plen + 1, M_TEMP, M_WAITOK | M_ZERO); memcpy(cp->gss_clnt_principal, principal, plen); cp->gss_clnt_prinlen = plen; cp->gss_clnt_prinnt = nt; @@ -806,13 +833,13 @@ nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t /* Remove any old matching contex that had a different principal */ nfs_gss_clnt_ctx_unref(&treq); - return (error); + return error; } static int nfs_gss_clnt_ctx_find(struct nfsreq *req) { - return (nfs_gss_clnt_ctx_find_principal(req, NULL, 0, 0)); + return nfs_gss_clnt_ctx_find_principal(req, NULL, 0, 0); } /* @@ -833,7 +860,7 @@ nfs_gss_clnt_cred_put(struct nfsreq *req, struct nfsm_chain *nmc, mbuf_t args) struct gss_seq *gsp; gss_buffer_desc mic; - slpflag = (PZERO-1); + slpflag = (PZERO - 1); if (req->r_nmp) { slpflag |= (NMFLAG(req->r_nmp, INTR) && req->r_thread && !(req->r_flags & R_NOINTR)) ? PCATCH : 0; recordmark = (req->r_nmp->nm_sotype == SOCK_STREAM); @@ -847,8 +874,9 @@ retry: * be created. */ error = nfs_gss_clnt_ctx_find(req); - if (error) - return (error); + if (error) { + return error; + } } cp = req->r_gss_ctx; @@ -863,8 +891,9 @@ retry: cp->gss_clnt_flags |= GSS_NEEDCTX; msleep(cp, cp->gss_clnt_mtx, slpflag | PDROP, "ctxwait", NULL); slpflag &= ~PCATCH; - if ((error = nfs_sigintr(req->r_nmp, req, req->r_thread, 0))) - return (error); + if ((error = nfs_sigintr(req->r_nmp, req, req->r_thread, 0))) { + return error; + } nfs_gss_clnt_ctx_unref(req); goto retry; } @@ -879,13 +908,13 @@ retry: * to proceed. */ lck_mtx_lock(cp->gss_clnt_mtx); - while (win_getbit(cp->gss_clnt_seqbits, - ((cp->gss_clnt_seqnum - cp->gss_clnt_seqwin) + 1) % cp->gss_clnt_seqwin)) { + while (win_getbit(cp->gss_clnt_seqbits, + ((cp->gss_clnt_seqnum - cp->gss_clnt_seqwin) + 1) % cp->gss_clnt_seqwin)) { cp->gss_clnt_flags |= GSS_NEEDSEQ; msleep(cp, cp->gss_clnt_mtx, slpflag | PDROP, "seqwin", NULL); slpflag &= ~PCATCH; if ((error = nfs_sigintr(req->r_nmp, req, req->r_thread, 0))) { - return (error); + return error; } lck_mtx_lock(cp->gss_clnt_mtx); if (cp->gss_clnt_flags & GSS_CTX_INVAL) { @@ -899,9 +928,10 @@ retry: win_setbit(cp->gss_clnt_seqbits, seqnum % cp->gss_clnt_seqwin); lck_mtx_unlock(cp->gss_clnt_mtx); - MALLOC(gsp, struct gss_seq *, sizeof(*gsp), M_TEMP, M_WAITOK|M_ZERO); - if (gsp == NULL) - return (ENOMEM); + MALLOC(gsp, struct gss_seq *, sizeof(*gsp), M_TEMP, M_WAITOK | M_ZERO); + if (gsp == NULL) { + return ENOMEM; + } gsp->gss_seqnum = seqnum; SLIST_INSERT_HEAD(&req->r_gss_seqlist, gsp, gss_seqnext); } @@ -915,27 +945,30 @@ retry: nfsm_chain_add_32(error, nmc, cp->gss_clnt_service); nfsm_chain_add_32(error, nmc, cp->gss_clnt_handle_len); if (cp->gss_clnt_handle_len > 0) { - if (cp->gss_clnt_handle == NULL) - return (EBADRPC); + if (cp->gss_clnt_handle == NULL) { + return EBADRPC; + } nfsm_chain_add_opaque(error, nmc, cp->gss_clnt_handle, cp->gss_clnt_handle_len); } - if (error) - return(error); + if (error) { + return error; + } /* * Now add the verifier */ if (cp->gss_clnt_proc == RPCSEC_GSS_INIT || - cp->gss_clnt_proc == RPCSEC_GSS_CONTINUE_INIT) { + cp->gss_clnt_proc == RPCSEC_GSS_CONTINUE_INIT) { /* * If the context is still being created * then use a null verifier. */ - nfsm_chain_add_32(error, nmc, RPCAUTH_NULL); // flavor - nfsm_chain_add_32(error, nmc, 0); // length + nfsm_chain_add_32(error, nmc, RPCAUTH_NULL); // flavor + nfsm_chain_add_32(error, nmc, 0); // length nfsm_chain_build_done(error, nmc); - if (!error) + if (!error) { nfs_gss_append_chain(nmc, args); - return (error); + } + return error; } offset = recordmark ? NFSX_UNSIGNED : 0; // record mark @@ -943,17 +976,18 @@ retry: major = gss_krb5_get_mic_mbuf((uint32_t *)&error, cp->gss_clnt_ctx_id, 0, nmc->nmc_mhead, offset, 0, &mic); if (major != GSS_S_COMPLETE) { - printf ("gss_krb5_get_mic_buf failed %d\n", error); - return (error); + printf("gss_krb5_get_mic_buf failed %d\n", error); + return error; } - nfsm_chain_add_32(error, nmc, RPCSEC_GSS); // flavor - nfsm_chain_add_32(error, nmc, mic.length); // length + nfsm_chain_add_32(error, nmc, RPCSEC_GSS); // flavor + nfsm_chain_add_32(error, nmc, mic.length); // length nfsm_chain_add_opaque(error, nmc, mic.value, mic.length); (void)gss_release_buffer(NULL, &mic); nfsm_chain_build_done(error, nmc); - if (error) - return (error); + if (error) { + return error; + } /* * Now we may have to compute integrity or encrypt the call args @@ -961,8 +995,9 @@ retry: */ switch (cp->gss_clnt_service) { case RPCSEC_GSS_SVC_NONE: - if (args) + if (args) { nfs_gss_append_chain(nmc, args); + } break; case RPCSEC_GSS_SVC_INTEGRITY: /* @@ -972,11 +1007,13 @@ retry: /* Note the mbufs that were used in r_mrest are being encapsulated in the rpc_gss_integ_data_t */ assert(req->r_mrest == args); nfsm_chain_finish_mbuf(error, nmc); - if (error) - return (error); + if (error) { + return error; + } error = rpc_gss_integ_data_create(cp->gss_clnt_ctx_id, &args, seqnum, &req->r_gss_arglen); - if (error) + if (error) { break; + } req->r_mrest = args; req->r_gss_argoff = nfsm_chain_offset(nmc); nfs_gss_append_chain(nmc, args); @@ -989,20 +1026,22 @@ retry: /* Note the mbufs that were used in r_mrest are being encapsulated in the rpc_gss_priv_data_t */ assert(req->r_mrest == args); nfsm_chain_finish_mbuf(error, nmc); - if (error) - return (error); + if (error) { + return error; + } error = rpc_gss_priv_data_create(cp->gss_clnt_ctx_id, &args, seqnum, &req->r_gss_arglen); - if (error) + if (error) { break; + } req->r_mrest = args; req->r_gss_argoff = nfsm_chain_offset(nmc); nfs_gss_append_chain(nmc, args); break; default: - return (EINVAL); + return EINVAL; } - return (error); + return error; } /* @@ -1035,8 +1074,9 @@ nfs_gss_clnt_verf_get( reslen = 0; *accepted_statusp = 0; - if (cp == NULL) - return (NFSERR_EAUTH); + if (cp == NULL) { + return NFSERR_EAUTH; + } /* * If it's not an RPCSEC_GSS verifier, then it has to * be a null verifier that resulted from either @@ -1045,14 +1085,17 @@ nfs_gss_clnt_verf_get( * context that resulted from a fallback to sec=sys. */ if (verftype != RPCSEC_GSS) { - if (verftype != RPCAUTH_NULL) - return (NFSERR_EAUTH); - if (cp->gss_clnt_flags & GSS_CTX_COMPLETE) - return (NFSERR_EAUTH); - if (verflen > 0) + if (verftype != RPCAUTH_NULL) { + return NFSERR_EAUTH; + } + if (cp->gss_clnt_flags & GSS_CTX_COMPLETE) { + return NFSERR_EAUTH; + } + if (verflen > 0) { nfsm_chain_adv(error, nmc, nfsm_rndup(verflen)); + } nfsm_chain_get_32(error, nmc, *accepted_statusp); - return (error); + return error; } /* @@ -1066,19 +1109,22 @@ nfs_gss_clnt_verf_get( * the context is complete. */ if (!(cp->gss_clnt_flags & GSS_CTX_COMPLETE)) { - if (verflen > KRB5_MAX_MIC_SIZE) - return (EBADRPC); - MALLOC(cp->gss_clnt_verf, u_char *, verflen, M_TEMP, M_WAITOK|M_ZERO); - if (cp->gss_clnt_verf == NULL) - return (ENOMEM); + if (verflen > KRB5_MAX_MIC_SIZE) { + return EBADRPC; + } + MALLOC(cp->gss_clnt_verf, u_char *, verflen, M_TEMP, M_WAITOK | M_ZERO); + if (cp->gss_clnt_verf == NULL) { + return ENOMEM; + } cp->gss_clnt_verflen = verflen; nfsm_chain_get_opaque(error, nmc, verflen, cp->gss_clnt_verf); nfsm_chain_get_32(error, nmc, *accepted_statusp); - return (error); + return error; } - if (verflen > KRB5_MAX_MIC_SIZE) - return (EBADRPC); + if (verflen > KRB5_MAX_MIC_SIZE) { + return EBADRPC; + } cksum.length = verflen; MALLOC(cksum.value, void *, verflen, M_TEMP, M_WAITOK); @@ -1103,19 +1149,22 @@ nfs_gss_clnt_verf_get( seqnum_buf.length = sizeof(network_seqnum); seqnum_buf.value = &network_seqnum; major = gss_krb5_verify_mic(NULL, cp->gss_clnt_ctx_id, &seqnum_buf, &cksum, NULL); - if (major == GSS_S_COMPLETE) + if (major == GSS_S_COMPLETE) { break; + } } FREE(cksum.value, M_TEMP); - if (gsp == NULL) - return (NFSERR_EAUTH); + if (gsp == NULL) { + return NFSERR_EAUTH; + } /* * Get the RPC accepted status */ nfsm_chain_get_32(error, nmc, *accepted_statusp); - if (*accepted_statusp != RPC_SUCCESS) - return (0); + if (*accepted_statusp != RPC_SUCCESS) { + return 0; + } /* * Now we may have to check integrity or decrypt the results @@ -1136,7 +1185,7 @@ nfs_gss_clnt_verf_get( * - checksum of seqnum + results */ - nfsm_chain_get_32(error, nmc, reslen); // length of results + nfsm_chain_get_32(error, nmc, reslen); // length of results if (reslen > NFS_MAXPACKET) { error = EBADRPC; goto nfsmout; @@ -1144,8 +1193,8 @@ nfs_gss_clnt_verf_get( /* Advance and fetch the mic */ nmc_tmp = *nmc; - nfsm_chain_adv(error, &nmc_tmp, reslen); // skip over the results - nfsm_chain_get_32(error, &nmc_tmp, cksum.length); + nfsm_chain_adv(error, &nmc_tmp, reslen); // skip over the results + nfsm_chain_get_32(error, &nmc_tmp, cksum.length); if (cksum.length > KRB5_MAX_MIC_SIZE) { error = EBADRPC; goto nfsmout; @@ -1175,8 +1224,9 @@ nfs_gss_clnt_verf_get( } #if 0 SLIST_FOREACH(gsp, &req->r_gss_seqlist, gss_seqnext) { - if (seqnum == gsp->gss_seqnum) + if (seqnum == gsp->gss_seqnum) { break; + } } if (gsp == NULL) { error = EBADRPC; @@ -1193,7 +1243,7 @@ nfs_gss_clnt_verf_get( * - wrap token */ prev_mbuf = nmc->nmc_mcur; - nfsm_chain_get_32(error, nmc, reslen); // length of results + nfsm_chain_get_32(error, nmc, reslen); // length of results if (reslen == 0 || reslen > NFS_MAXPACKET) { error = EBADRPC; goto nfsmout; @@ -1205,8 +1255,9 @@ nfs_gss_clnt_verf_get( /* split out the wrap token */ ressize = reslen; error = gss_normalize_mbuf(nmc->nmc_mcur, offset, &ressize, &results_mbuf, &pad_mbuf, 0); - if (error) + if (error) { goto nfsmout; + } if (pad_mbuf) { assert(nfsm_pad(reslen) == mbuf_len(pad_mbuf)); @@ -1237,8 +1288,9 @@ nfs_gss_clnt_verf_get( } #if 0 SLIST_FOREACH(gsp, &req->r_gss_seqlist, gss_seqnext) { - if (seqnum == gsp->gss_seqnum) + if (seqnum == gsp->gss_seqnum) { break; + } } if (gsp == NULL) { error = EBADRPC; @@ -1248,7 +1300,7 @@ nfs_gss_clnt_verf_get( break; } nfsmout: - return (error); + return error; } /* @@ -1271,30 +1323,35 @@ nfs_gss_clnt_args_restore(struct nfsreq *req) struct nfsm_chain mchain, *nmc = &mchain; int error = 0, merr; - if (cp == NULL) - return (NFSERR_EAUTH); + if (cp == NULL) { + return NFSERR_EAUTH; + } - if ((cp->gss_clnt_flags & GSS_CTX_COMPLETE) == 0) - return (ENEEDAUTH); + if ((cp->gss_clnt_flags & GSS_CTX_COMPLETE) == 0) { + return ENEEDAUTH; + } /* Nothing to restore for SVC_NONE */ - if (cp->gss_clnt_service == RPCSEC_GSS_SVC_NONE) - return (0); + if (cp->gss_clnt_service == RPCSEC_GSS_SVC_NONE) { + return 0; + } - nfsm_chain_dissect_init(error, nmc, req->r_mhead); // start at RPC header - nfsm_chain_adv(error, nmc, req->r_gss_argoff); // advance to args - if (error) - return (error); + nfsm_chain_dissect_init(error, nmc, req->r_mhead); // start at RPC header + nfsm_chain_adv(error, nmc, req->r_gss_argoff); // advance to args + if (error) { + return error; + } - if (cp->gss_clnt_service == RPCSEC_GSS_SVC_INTEGRITY) + if (cp->gss_clnt_service == RPCSEC_GSS_SVC_INTEGRITY) { error = rpc_gss_integ_data_restore(cp->gss_clnt_ctx_id, &req->r_mrest, req->r_gss_arglen); - else + } else { error = rpc_gss_priv_data_restore(cp->gss_clnt_ctx_id, &req->r_mrest, req->r_gss_arglen); + } merr = mbuf_setnext(nmc->nmc_mcur, req->r_mrest); /* Should always succeed */ - assert (merr == 0); + assert(merr == 0); - return (error ? error : merr); + return error ? error : merr; } /* @@ -1332,9 +1389,9 @@ nfs_gss_clnt_ctx_init(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) cp->gss_clnt_proc = RPCSEC_GSS_INIT; cp->gss_clnt_service = - req->r_auth == RPCAUTH_KRB5 ? RPCSEC_GSS_SVC_NONE : - req->r_auth == RPCAUTH_KRB5I ? RPCSEC_GSS_SVC_INTEGRITY : - req->r_auth == RPCAUTH_KRB5P ? RPCSEC_GSS_SVC_PRIVACY : 0; + req->r_auth == RPCAUTH_KRB5 ? RPCSEC_GSS_SVC_NONE : + req->r_auth == RPCAUTH_KRB5I ? RPCSEC_GSS_SVC_INTEGRITY : + req->r_auth == RPCAUTH_KRB5P ? RPCSEC_GSS_SVC_PRIVACY : 0; /* * Now loop around alternating gss_init_sec_context and @@ -1345,14 +1402,16 @@ nfs_gss_clnt_ctx_init(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) retry: /* Upcall to the gss_init_sec_context in the gssd */ error = nfs_gss_clnt_gssd_upcall(req, cp, retrycnt); - if (error) + if (error) { goto nfsmout; + } if (cp->gss_clnt_major == GSS_S_COMPLETE) { client_complete = 1; NFS_GSS_DBG("Client complete\n"); - if (server_complete) + if (server_complete) { break; + } } else if (cp->gss_clnt_major != GSS_S_CONTINUE_NEEDED) { /* * We may have gotten here because the accept sec context @@ -1375,7 +1434,7 @@ retry: if (error) { if (error == ENEEDAUTH && (cp->gss_clnt_proc == RPCSEC_GSS_INIT || - cp->gss_clnt_proc == RPCSEC_GSS_CONTINUE_INIT)) { + cp->gss_clnt_proc == RPCSEC_GSS_CONTINUE_INIT)) { /* * We got here because the server had a problem * trying to establish a context and sent that there @@ -1395,8 +1454,9 @@ retry: if (cp->gss_clnt_major == GSS_S_COMPLETE) { NFS_GSS_DBG("Server complete\n"); server_complete = 1; - if (client_complete) + if (client_complete) { break; + } } else if (cp->gss_clnt_major == GSS_S_CONTINUE_NEEDED) { cp->gss_clnt_proc = RPCSEC_GSS_CONTINUE_INIT; } else { @@ -1416,7 +1476,7 @@ retry: cp->gss_clnt_proc = RPCSEC_GSS_DATA; network_seqnum = htonl(cp->gss_clnt_seqwin); - window.length = sizeof (cp->gss_clnt_seqwin); + window.length = sizeof(cp->gss_clnt_seqwin); window.value = &network_seqnum; cksum.value = cp->gss_clnt_verf; cksum.length = cp->gss_clnt_verflen; @@ -1443,9 +1503,10 @@ retry: * are pending within the sequence number window. */ MALLOC(cp->gss_clnt_seqbits, uint32_t *, - nfsm_rndup((cp->gss_clnt_seqwin + 7) / 8), M_TEMP, M_WAITOK|M_ZERO); - if (cp->gss_clnt_seqbits == NULL) + nfsm_rndup((cp->gss_clnt_seqwin + 7) / 8), M_TEMP, M_WAITOK | M_ZERO); + if (cp->gss_clnt_seqbits == NULL) { error = NFSERR_EAUTH; + } nfsmout: /* @@ -1455,7 +1516,7 @@ nfsmout: */ if (error == ENEEDAUTH) { NFS_GSS_DBG("Returning ENEEDAUTH\n"); - return (error); + return error; } /* @@ -1464,8 +1525,9 @@ nfsmout: * drops to zero. */ lck_mtx_lock(cp->gss_clnt_mtx); - if (error) + if (error) { cp->gss_clnt_flags |= GSS_CTX_INVAL; + } /* * Wake any threads waiting to use the context @@ -1478,7 +1540,7 @@ nfsmout: lck_mtx_unlock(cp->gss_clnt_mtx); NFS_GSS_DBG("Returning error = %d\n", error); - return (error); + return error; } /* @@ -1514,8 +1576,9 @@ nfs_gss_clnt_ctx_init_retry(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) tsleep(NULL, PSOCK | slpflag, "nfs_gss_clnt_ctx_init_retry", hz); slpflag = 0; error = nfs_sigintr(req->r_nmp, req, current_thread(), 0); - if (error) + if (error) { goto bad; + } microuptime(&now); } @@ -1526,12 +1589,14 @@ nfs_gss_clnt_ctx_init_retry(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) goto bad; } timeo *= 2; - if (timeo > 60) + if (timeo > 60) { timeo = 60; + } } - if (error == 0) - return 0; // success + if (error == 0) { + return 0; // success + } bad: /* * Give up on this context @@ -1547,7 +1612,7 @@ bad: cp->gss_clnt_flags &= ~GSS_NEEDCTX; wakeup(cp); } - lck_mtx_unlock(cp->gss_clnt_mtx); + lck_mtx_unlock(cp->gss_clnt_mtx); return error; } @@ -1566,30 +1631,35 @@ nfs_gss_clnt_ctx_callserver(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) uint32_t major = cp->gss_clnt_major, minor = cp->gss_clnt_minor; int sz; - if (nfs_mount_gone(req->r_nmp)) - return (ENXIO); + if (nfs_mount_gone(req->r_nmp)) { + return ENXIO; + } nfsm_chain_null(&nmreq); nfsm_chain_null(&nmrep); sz = NFSX_UNSIGNED + nfsm_rndup(cp->gss_clnt_tokenlen); nfsm_chain_build_alloc_init(error, &nmreq, sz); nfsm_chain_add_32(error, &nmreq, cp->gss_clnt_tokenlen); - if (cp->gss_clnt_tokenlen > 0) + if (cp->gss_clnt_tokenlen > 0) { nfsm_chain_add_opaque(error, &nmreq, cp->gss_clnt_token, cp->gss_clnt_tokenlen); + } nfsm_chain_build_done(error, &nmreq); - if (error) + if (error) { goto nfsmout; + } /* Call the server */ - error = nfs_request_gss(req->r_nmp->nm_mountp, &nmreq, req->r_thread, req->r_cred, - (req->r_flags & R_OPTMASK), cp, &nmrep, &status); + error = nfs_request_gss(req->r_nmp->nm_mountp, &nmreq, req->r_thread, req->r_cred, + (req->r_flags & R_OPTMASK), cp, &nmrep, &status); if (cp->gss_clnt_token != NULL) { FREE(cp->gss_clnt_token, M_TEMP); cp->gss_clnt_token = NULL; } - if (!error) + if (!error) { error = status; - if (error) + } + if (error) { goto nfsmout; + } /* Get the server's reply */ @@ -1612,8 +1682,9 @@ nfs_gss_clnt_ctx_callserver(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) nfsm_chain_get_32(error, &nmrep, cp->gss_clnt_minor); nfsm_chain_get_32(error, &nmrep, cp->gss_clnt_seqwin); nfsm_chain_get_32(error, &nmrep, cp->gss_clnt_tokenlen); - if (error) + if (error) { goto nfsmout; + } if (cp->gss_clnt_tokenlen > 0 && cp->gss_clnt_tokenlen < GSS_MAX_TOKEN_LEN) { MALLOC(cp->gss_clnt_token, u_char *, cp->gss_clnt_tokenlen, M_TEMP, M_WAITOK); if (cp->gss_clnt_token == NULL) { @@ -1630,17 +1701,15 @@ nfs_gss_clnt_ctx_callserver(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp) */ if (cp->gss_clnt_major != GSS_S_COMPLETE && cp->gss_clnt_major != GSS_S_CONTINUE_NEEDED) { - printf("nfs_gss_clnt_ctx_callserver: gss_clnt_major = %d\n", cp->gss_clnt_major); nfs_gss_clnt_log_error(req, cp, major, minor); - } nfsmout: nfsm_chain_cleanup(&nmreq); nfsm_chain_cleanup(&nmrep); - return (error); + return error; } /* @@ -1661,18 +1730,20 @@ nfs_gss_clnt_svcname(struct nfsmount *nmp, gssd_nametype *nt, uint32_t *len) char *svcname, *d, *server; int lindx, sindx; - if (nfs_mount_gone(nmp)) - return (NULL); + if (nfs_mount_gone(nmp)) { + return NULL; + } if (nmp->nm_sprinc) { *len = strlen(nmp->nm_sprinc) + 1; MALLOC(svcname, char *, *len, M_TEMP, M_WAITOK); *nt = GSSD_HOSTBASED; - if (svcname == NULL) - return (NULL); + if (svcname == NULL) { + return NULL; + } strlcpy(svcname, nmp->nm_sprinc, *len); - return ((uint8_t *)svcname); + return (uint8_t *)svcname; } *nt = GSSD_HOSTBASED; @@ -1688,7 +1759,7 @@ nfs_gss_clnt_svcname(struct nfsmount *nmp, gssd_nametype *nt, uint32_t *len) d = strchr(server, ':'); *len = (uint32_t)(d ? (d - server) : strlen(server)); } - + *len += 5; /* "nfs@" plus null */ MALLOC(svcname, char *, *len, M_TEMP, M_WAITOK); strlcpy(svcname, "nfs", *len); @@ -1696,7 +1767,7 @@ nfs_gss_clnt_svcname(struct nfsmount *nmp, gssd_nametype *nt, uint32_t *len) strlcat(svcname, server, *len); NFS_GSS_DBG("nfs svcname = %s\n", svcname); - return ((uint8_t *)svcname); + return (uint8_t *)svcname; } /* @@ -1717,30 +1788,32 @@ nfs_gss_clnt_get_upcall_port(kauth_cred_t credp) kr = host_get_gssd_port(host_priv_self(), &gssd_host_port); if (kr != KERN_SUCCESS) { printf("nfs_gss_get_upcall_port: can't get gssd port, status %x (%d)\n", kr, kr); - return (IPC_PORT_NULL); + return IPC_PORT_NULL; } if (!IPC_PORT_VALID(gssd_host_port)) { printf("nfs_gss_get_upcall_port: gssd port not valid\n"); - return (IPC_PORT_NULL); + return IPC_PORT_NULL; } asid = kauth_cred_getasid(credp); uid = kauth_cred_getauid(credp); - if (uid == AU_DEFAUDITID) + if (uid == AU_DEFAUDITID) { uid = kauth_cred_getuid(credp); + } kr = mach_gss_lookup(gssd_host_port, uid, asid, &uc_port); - if (kr != KERN_SUCCESS) + if (kr != KERN_SUCCESS) { printf("nfs_gss_clnt_get_upcall_port: mach_gssd_lookup failed: status %x (%d)\n", kr, kr); + } host_release_special_port(gssd_host_port); - return (uc_port); + return uc_port; } static void nfs_gss_clnt_log_error(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32_t major, uint32_t minor) { -#define GETMAJERROR(x) (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) +#define GETMAJERROR(x) (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK) struct nfsmount *nmp = req->r_nmp; char who[] = "client"; uint32_t gss_error = GETMAJERROR(cp->gss_clnt_major); @@ -1751,23 +1824,25 @@ nfs_gss_clnt_log_error(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32_t if (req->r_thread) { proc = (proc_t)get_bsdthreadtask_info(req->r_thread); - if (proc != NULL && (proc->p_fd == NULL || (proc->p_lflag & P_LVFORK))) + if (proc != NULL && (proc->p_fd == NULL || (proc->p_lflag & P_LVFORK))) { proc = NULL; + } if (proc) { - if (*proc->p_comm) + if (*proc->p_comm) { procn = proc->p_comm; + } pid = proc->p_pid; } } else { procn = "kernproc"; pid = 0; } - + microuptime(&now); if ((cp->gss_clnt_major != major || cp->gss_clnt_minor != minor || - cp->gss_clnt_ptime + GSS_PRINT_DELAY < now.tv_sec) && + cp->gss_clnt_ptime + GSS_PRINT_DELAY < now.tv_sec) && (nmp->nm_state & NFSSTA_MOUNTED)) { - /* + /* * Will let gssd do some logging in hopes that it can translate * the minor code. */ @@ -1786,21 +1861,21 @@ nfs_gss_clnt_log_error(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32_t *%%% It would be really nice to get the terminal from the proc or auditinfo_addr struct and print that here. */ printf("NFS: gssd auth failure by %s on audit session %d uid %d proc %s/%d for mount %s. Error: major = %d minor = %d\n", - cp->gss_clnt_display ? cp->gss_clnt_display : who, kauth_cred_getasid(req->r_cred), kauth_cred_getuid(req->r_cred), - procn, pid, vfs_statfs(nmp->nm_mountp)->f_mntfromname, gss_error, (int32_t)cp->gss_clnt_minor); + cp->gss_clnt_display ? cp->gss_clnt_display : who, kauth_cred_getasid(req->r_cred), kauth_cred_getuid(req->r_cred), + procn, pid, vfs_statfs(nmp->nm_mountp)->f_mntfromname, gss_error, (int32_t)cp->gss_clnt_minor); cp->gss_clnt_ptime = now.tv_sec; switch (gss_error) { case 7: printf("NFS: gssd does not have credentials for session %d/%d, (kinit)?\n", - kauth_cred_getasid(req->r_cred), kauth_cred_getauid(req->r_cred)); + kauth_cred_getasid(req->r_cred), kauth_cred_getauid(req->r_cred)); break; case 11: printf("NFS: gssd has expired credentals for session %d/%d, (kinit)?\n", - kauth_cred_getasid(req->r_cred), kauth_cred_getauid(req->r_cred)); + kauth_cred_getasid(req->r_cred), kauth_cred_getauid(req->r_cred)); break; } } else { NFS_GSS_DBG("NFS: gssd auth failure by %s on audit session %d uid %d proc %s/%d for mount %s. Error: major = %d minor = %d\n", - cp->gss_clnt_display ? cp->gss_clnt_display : who, kauth_cred_getasid(req->r_cred), kauth_cred_getuid(req->r_cred), - procn, pid, vfs_statfs(nmp->nm_mountp)->f_mntfromname, gss_error, (int32_t)cp->gss_clnt_minor); + cp->gss_clnt_display ? cp->gss_clnt_display : who, kauth_cred_getasid(req->r_cred), kauth_cred_getuid(req->r_cred), + procn, pid, vfs_statfs(nmp->nm_mountp)->f_mntfromname, gss_error, (int32_t)cp->gss_clnt_minor); } } @@ -1835,12 +1910,14 @@ nfs_gss_clnt_gssd_upcall(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32 uint32_t selected = (uint32_t)-1; struct nfs_etype etype; - if (nmp == NULL || vfs_isforce(nmp->nm_mountp) || (nmp->nm_state & (NFSSTA_FORCE | NFSSTA_DEAD))) - return (ENXIO); + if (nmp == NULL || vfs_isforce(nmp->nm_mountp) || (nmp->nm_state & (NFSSTA_FORCE | NFSSTA_DEAD))) { + return ENXIO; + } if (cp->gss_clnt_gssd_flags & GSSD_RESTART) { - if (cp->gss_clnt_token) + if (cp->gss_clnt_token) { FREE(cp->gss_clnt_token, M_TEMP); + } cp->gss_clnt_token = NULL; cp->gss_clnt_tokenlen = 0; cp->gss_clnt_proc = RPCSEC_GSS_INIT; @@ -1853,8 +1930,9 @@ nfs_gss_clnt_gssd_upcall(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32 } NFS_GSS_DBG("Retrycnt = %d nm_etype.count = %d\n", retrycnt, nmp->nm_etype.count); - if (retrycnt >= nmp->nm_etype.count) - return (EACCES); + if (retrycnt >= nmp->nm_etype.count) { + return EACCES; + } /* Copy the mount etypes to an order set of etypes to try */ etype = nmp->nm_etype; @@ -1866,15 +1944,18 @@ nfs_gss_clnt_gssd_upcall(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32 */ if (etype.selected < etype.count) { etype.etypes[0] = nmp->nm_etype.etypes[etype.selected]; - for (uint32_t i = 0; i < etype.selected; i++) - etype.etypes[i+1] = nmp->nm_etype.etypes[i]; - for (uint32_t i = etype.selected + 1; i < etype.count; i++) + for (uint32_t i = 0; i < etype.selected; i++) { + etype.etypes[i + 1] = nmp->nm_etype.etypes[i]; + } + for (uint32_t i = etype.selected + 1; i < etype.count; i++) { etype.etypes[i] = nmp->nm_etype.etypes[i]; + } } /* Remove the ones we've already have tried */ - for (uint32_t i = retrycnt; i < etype.count; i++) + for (uint32_t i = retrycnt; i < etype.count; i++) { etype.etypes[i - retrycnt] = etype.etypes[i]; + } etype.count = etype.count - retrycnt; NFS_GSS_DBG("etype count = %d preferred etype = %d\n", etype.count, etype.etypes[0]); @@ -1897,8 +1978,7 @@ nfs_gss_clnt_gssd_upcall(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32 plen = (uint32_t)strlen(nmp->nm_principal); principal = (uint8_t *)nmp->nm_principal; cp->gss_clnt_prinnt = nt = GSSD_USER; - } - else if (nmp->nm_realm) { + } else if (nmp->nm_realm) { plen = (uint32_t)strlen(nmp->nm_realm); principal = (uint8_t *)nmp->nm_realm; nt = GSSD_USER; @@ -1906,16 +1986,20 @@ nfs_gss_clnt_gssd_upcall(struct nfsreq *req, struct nfs_gss_clnt_ctx *cp, uint32 if (!IPC_PORT_VALID(cp->gss_clnt_mport)) { cp->gss_clnt_mport = nfs_gss_clnt_get_upcall_port(req->r_cred); - if (cp->gss_clnt_mport == IPC_PORT_NULL) + if (cp->gss_clnt_mport == IPC_PORT_NULL) { goto out; + } } - if (plen) + if (plen) { nfs_gss_mach_alloc_buffer(principal, plen, &pname); - if (cp->gss_clnt_svcnamlen) + } + if (cp->gss_clnt_svcnamlen) { nfs_gss_mach_alloc_buffer(cp->gss_clnt_svcname, cp->gss_clnt_svcnamlen, &svcname); - if (cp->gss_clnt_tokenlen) + } + if (cp->gss_clnt_tokenlen) { nfs_gss_mach_alloc_buffer(cp->gss_clnt_token, cp->gss_clnt_tokenlen, &itoken); + } /* Always want to export the lucid context */ cp->gss_clnt_gssd_flags |= GSSD_LUCID_CONTEXT; @@ -1936,7 +2020,7 @@ retry: &cp->gss_clnt_context, &cp->gss_clnt_cred_handle, &ret_flags, - &octx, (mach_msg_type_number_t *) &lucidlen, + &octx, (mach_msg_type_number_t *) &lucidlen, &otoken, &otokenlen, cp->gss_clnt_display ? NULL : display_name, &cp->gss_clnt_major, @@ -1953,14 +2037,17 @@ retry: if (kr != KERN_SUCCESS) { printf("nfs_gss_clnt_gssd_upcall: mach_gss_init_sec_context failed: %x (%d)\n", kr, kr); if (kr == MIG_SERVER_DIED && cp->gss_clnt_cred_handle == 0 && - retry_cnt++ < NFS_GSS_MACH_MAX_RETRIES && - !vfs_isforce(nmp->nm_mountp) && (nmp->nm_state & (NFSSTA_FORCE | NFSSTA_DEAD)) == 0) { - if (plen) + retry_cnt++ < NFS_GSS_MACH_MAX_RETRIES && + !vfs_isforce(nmp->nm_mountp) && (nmp->nm_state & (NFSSTA_FORCE | NFSSTA_DEAD)) == 0) { + if (plen) { nfs_gss_mach_alloc_buffer(principal, plen, &pname); - if (cp->gss_clnt_svcnamlen) + } + if (cp->gss_clnt_svcnamlen) { nfs_gss_mach_alloc_buffer(cp->gss_clnt_svcname, cp->gss_clnt_svcnamlen, &svcname); - if (cp->gss_clnt_tokenlen > 0) + } + if (cp->gss_clnt_tokenlen > 0) { nfs_gss_mach_alloc_buffer(cp->gss_clnt_token, cp->gss_clnt_tokenlen, &itoken); + } goto retry; } @@ -1974,9 +2061,10 @@ retry: if (dlen < MAX_DISPLAY_STR) { MALLOC(cp->gss_clnt_display, char *, dlen, M_TEMP, M_WAITOK); - if (cp->gss_clnt_display == NULL) + if (cp->gss_clnt_display == NULL) { goto skip; - bcopy(display_name, cp->gss_clnt_display, dlen); + } + bcopy(display_name, cp->gss_clnt_display, dlen); } else { goto skip; } @@ -2013,8 +2101,9 @@ skip: goto out; } - if (cp->gss_clnt_ctx_id) + if (cp->gss_clnt_ctx_id) { gss_krb5_destroy_context(cp->gss_clnt_ctx_id); + } cp->gss_clnt_ctx_id = gss_krb5_make_context(lucid_ctx_buffer, lucidlen); if (cp->gss_clnt_ctx_id == NULL) { printf("Failed to make context from lucid_ctx_buffer\n"); @@ -2029,8 +2118,9 @@ skip: } /* Free context token used as input */ - if (cp->gss_clnt_token) + if (cp->gss_clnt_token) { FREE(cp->gss_clnt_token, M_TEMP); + } cp->gss_clnt_token = NULL; cp->gss_clnt_tokenlen = 0; @@ -2040,14 +2130,14 @@ skip: if (cp->gss_clnt_token == NULL) { printf("nfs_gss_clnt_gssd_upcall: could not allocate %d bytes\n", otokenlen); vm_map_copy_discard((vm_map_copy_t) otoken); - return (ENOMEM); + return ENOMEM; } error = nfs_gss_mach_vmcopyout((vm_map_copy_t) otoken, otokenlen, cp->gss_clnt_token); if (error) { printf("Could not copyout gss token\n"); FREE(cp->gss_clnt_token, M_TEMP); cp->gss_clnt_token = NULL; - return (NFSERR_EAUTH); + return NFSERR_EAUTH; } cp->gss_clnt_tokenlen = otokenlen; } @@ -2057,11 +2147,12 @@ skip: NFS_GSS_DBG("etype selected = %d\n", nmp->nm_etype.etypes[selected]); } NFS_GSS_DBG("Up call succeeded major = %d\n", cp->gss_clnt_major); - return (0); + return 0; out: - if (cp->gss_clnt_token) + if (cp->gss_clnt_token) { FREE(cp->gss_clnt_token, M_TEMP); + } cp->gss_clnt_token = NULL; cp->gss_clnt_tokenlen = 0; /* Server's handle isn't valid. Don't reuse */ @@ -2070,9 +2161,9 @@ out: FREE(cp->gss_clnt_handle, M_TEMP); cp->gss_clnt_handle = NULL; } - + NFS_GSS_DBG("Up call returned NFSERR_EAUTH"); - return (NFSERR_EAUTH); + return NFSERR_EAUTH; } /* @@ -2096,8 +2187,9 @@ nfs_gss_clnt_rpcdone(struct nfsreq *req) struct gss_seq *gsp, *ngsp; int i = 0; - if (cp == NULL || !(cp->gss_clnt_flags & GSS_CTX_COMPLETE)) - return; // no context - don't bother + if (cp == NULL || !(cp->gss_clnt_flags & GSS_CTX_COMPLETE)) { + return; // no context - don't bother + } /* * Reset the bit for this request in the * sequence number window to indicate it's done. @@ -2105,9 +2197,10 @@ nfs_gss_clnt_rpcdone(struct nfsreq *req) */ lck_mtx_lock(cp->gss_clnt_mtx); gsp = SLIST_FIRST(&req->r_gss_seqlist); - if (gsp && gsp->gss_seqnum > (cp->gss_clnt_seqnum - cp->gss_clnt_seqwin)) + if (gsp && gsp->gss_seqnum > (cp->gss_clnt_seqnum - cp->gss_clnt_seqwin)) { win_resetbit(cp->gss_clnt_seqbits, - gsp->gss_seqnum % cp->gss_clnt_seqwin); + gsp->gss_seqnum % cp->gss_clnt_seqwin); + } /* * Limit the seqnum list to GSS_CLNT_SEQLISTMAX entries @@ -2160,14 +2253,16 @@ nfs_gss_clnt_ctx_unref(struct nfsreq *req) struct timeval now; char CTXBUF[NFS_CTXBUFSZ]; - if (cp == NULL) + if (cp == NULL) { return; + } req->r_gss_ctx = NULL; lck_mtx_lock(cp->gss_clnt_mtx); - if (--cp->gss_clnt_refcnt < 0) + if (--cp->gss_clnt_refcnt < 0) { panic("Over release of gss context!\n"); + } if (cp->gss_clnt_refcnt == 0) { if ((cp->gss_clnt_flags & GSS_CTX_INVAL) && @@ -2177,10 +2272,12 @@ nfs_gss_clnt_ctx_unref(struct nfsreq *req) } if (cp->gss_clnt_flags & GSS_CTX_DESTROY) { destroy = 1; - if (cp->gss_clnt_flags & GSS_CTX_STICKY) + if (cp->gss_clnt_flags & GSS_CTX_STICKY) { nfs_gss_clnt_mnt_rele(nmp); - if (cp->gss_clnt_nctime) + } + if (cp->gss_clnt_nctime) { on_neg_cache = 1; + } } } if (!destroy && cp->gss_clnt_nctime == 0 && @@ -2236,14 +2333,17 @@ nfs_gss_clnt_ctx_neg_cache_reap(struct nfsmount *nmp) /* Don't reap STICKY contexts */ if ((cp->gss_clnt_flags & GSS_CTX_STICKY) || - !(cp->gss_clnt_flags & GSS_CTX_INVAL)) + !(cp->gss_clnt_flags & GSS_CTX_INVAL)) { continue; + } /* Keep up to GSS_MAX_NEG_CACHE_ENTRIES */ - if (nmp->nm_ncentries <= GSS_MAX_NEG_CACHE_ENTRIES) + if (nmp->nm_ncentries <= GSS_MAX_NEG_CACHE_ENTRIES) { break; + } /* Contexts too young */ - if (cp->gss_clnt_nctime + GSS_NEG_CACHE_TO >= now.tv_sec) + if (cp->gss_clnt_nctime + GSS_NEG_CACHE_TO >= now.tv_sec) { continue; + } /* Not referenced, remove it. */ lck_mtx_lock(cp->gss_clnt_mtx); if (cp->gss_clnt_refcnt == 0) { @@ -2336,10 +2436,11 @@ nfs_gss_clnt_ctx_copy(struct nfs_gss_clnt_ctx *scp, struct nfs_gss_clnt_ctx **dc struct nfs_gss_clnt_ctx *dcp; *dcpp = (struct nfs_gss_clnt_ctx *)NULL; - MALLOC(dcp, struct nfs_gss_clnt_ctx *, sizeof (struct nfs_gss_clnt_ctx), M_TEMP, M_WAITOK); - if (dcp == NULL) - return (ENOMEM); - bzero(dcp, sizeof (struct nfs_gss_clnt_ctx)); + MALLOC(dcp, struct nfs_gss_clnt_ctx *, sizeof(struct nfs_gss_clnt_ctx), M_TEMP, M_WAITOK); + if (dcp == NULL) { + return ENOMEM; + } + bzero(dcp, sizeof(struct nfs_gss_clnt_ctx)); dcp->gss_clnt_mtx = lck_mtx_alloc_init(nfs_gss_clnt_grp, LCK_ATTR_NULL); dcp->gss_clnt_cred = scp->gss_clnt_cred; kauth_cred_ref(dcp->gss_clnt_cred); @@ -2349,7 +2450,7 @@ nfs_gss_clnt_ctx_copy(struct nfs_gss_clnt_ctx *scp, struct nfs_gss_clnt_ctx **dc MALLOC(dcp->gss_clnt_principal, uint8_t *, dcp->gss_clnt_prinlen, M_TEMP, M_WAITOK | M_ZERO); if (dcp->gss_clnt_principal == NULL) { FREE(dcp, M_TEMP); - return (ENOMEM); + return ENOMEM; } bcopy(scp->gss_clnt_principal, dcp->gss_clnt_principal, dcp->gss_clnt_prinlen); } @@ -2364,7 +2465,7 @@ nfs_gss_clnt_ctx_copy(struct nfs_gss_clnt_ctx *scp, struct nfs_gss_clnt_ctx **dc *dcpp = dcp; - return (0); + return 0; } /* @@ -2374,8 +2475,8 @@ static void nfs_gss_clnt_ctx_destroy(struct nfs_gss_clnt_ctx *cp) { NFS_GSS_DBG("Destroying context %d/%d\n", - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getauid(cp->gss_clnt_cred)); + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getauid(cp->gss_clnt_cred)); host_release_special_port(cp->gss_clnt_mport); cp->gss_clnt_mport = IPC_PORT_NULL; @@ -2384,8 +2485,9 @@ nfs_gss_clnt_ctx_destroy(struct nfs_gss_clnt_ctx *cp) lck_mtx_destroy(cp->gss_clnt_mtx, nfs_gss_clnt_grp); cp->gss_clnt_mtx = (lck_mtx_t *)NULL; } - if (IS_VALID_CRED(cp->gss_clnt_cred)) + if (IS_VALID_CRED(cp->gss_clnt_cred)) { kauth_cred_unref(&cp->gss_clnt_cred); + } cp->gss_clnt_entries.tqe_next = NFSNOLIST; cp->gss_clnt_entries.tqe_prev = NFSNOLIST; if (cp->gss_clnt_principal) { @@ -2420,18 +2522,20 @@ nfs_gss_clnt_ctx_renew(struct nfsreq *req) int error = 0; char CTXBUF[NFS_CTXBUFSZ]; - if (cp == NULL) - return (0); + if (cp == NULL) { + return 0; + } - if (req->r_nmp == NULL) - return (ENXIO); + if (req->r_nmp == NULL) { + return ENXIO; + } nmp = req->r_nmp; lck_mtx_lock(cp->gss_clnt_mtx); if (cp->gss_clnt_flags & GSS_CTX_INVAL) { lck_mtx_unlock(cp->gss_clnt_mtx); nfs_gss_clnt_ctx_unref(req); - return (0); // already being renewed + return 0; // already being renewed } cp->gss_clnt_flags |= (GSS_CTX_INVAL | GSS_CTX_DESTROY); @@ -2442,19 +2546,22 @@ nfs_gss_clnt_ctx_renew(struct nfsreq *req) } lck_mtx_unlock(cp->gss_clnt_mtx); - if (cp->gss_clnt_proc == RPCSEC_GSS_DESTROY) - return (EACCES); /* Destroying a context is best effort. Don't renew. */ + if (cp->gss_clnt_proc == RPCSEC_GSS_DESTROY) { + return EACCES; /* Destroying a context is best effort. Don't renew. */ + } /* * If we're setting up a context let nfs_gss_clnt_ctx_init know this is not working * and to try some other etype. */ - if (cp->gss_clnt_proc != RPCSEC_GSS_DATA) - return (ENEEDAUTH); + if (cp->gss_clnt_proc != RPCSEC_GSS_DATA) { + return ENEEDAUTH; + } error = nfs_gss_clnt_ctx_copy(cp, &ncp); NFS_GSS_DBG("Renewing context %s\n", NFS_GSS_CTX(req, ncp)); nfs_gss_clnt_ctx_unref(req); - if (error) - return (error); + if (error) { + return error; + } lck_mtx_lock(&nmp->nm_lock); /* @@ -2467,10 +2574,11 @@ nfs_gss_clnt_ctx_renew(struct nfsreq *req) lck_mtx_unlock(&nmp->nm_lock); error = nfs_gss_clnt_ctx_init_retry(req, ncp); // Initialize new context - if (error) + if (error) { nfs_gss_clnt_ctx_unref(req); + } - return (error); + return error; } @@ -2487,12 +2595,13 @@ nfs_gss_clnt_ctx_unmount(struct nfsmount *nmp) struct nfsreq req; req.r_nmp = nmp; - if (!nmp) + if (!nmp) { return; + } lck_mtx_lock(&nmp->nm_lock); - while((cp = TAILQ_FIRST(&nmp->nm_gsscl))) { + while ((cp = TAILQ_FIRST(&nmp->nm_gsscl))) { TAILQ_REMOVE(&nmp->nm_gsscl, cp, gss_clnt_entries); cp->gss_clnt_entries.tqe_next = NFSNOLIST; lck_mtx_lock(cp->gss_clnt_mtx); @@ -2518,9 +2627,10 @@ nfs_gss_clnt_ctx_unmount(struct nfsmount *nmp) nfsm_chain_null(&nmrep); nfsm_chain_build_alloc_init(error, &nmreq, 0); nfsm_chain_build_done(error, &nmreq); - if (!error) + if (!error) { nfs_request_gss(nmp->nm_mountp, &nmreq, - current_thread(), cp->gss_clnt_cred, 0, cp, &nmrep, &status); + current_thread(), cp->gss_clnt_cred, 0, cp, &nmrep, &status); + } nfsm_chain_cleanup(&nmreq); nfsm_chain_cleanup(&nmrep); } @@ -2560,9 +2670,9 @@ nfs_gss_clnt_ctx_remove(struct nfsmount *nmp, kauth_cred_t cred) if (nfs_gss_clnt_ctx_cred_match(cp->gss_clnt_cred, cred)) { if (cp->gss_clnt_flags & GSS_CTX_DESTROY) { NFS_GSS_DBG("Found destroyed context %d/%d. refcnt = %d continuing\n", - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getauid(cp->gss_clnt_cred), - cp->gss_clnt_refcnt); + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getauid(cp->gss_clnt_cred), + cp->gss_clnt_refcnt); lck_mtx_unlock(cp->gss_clnt_mtx); continue; } @@ -2576,19 +2686,19 @@ nfs_gss_clnt_ctx_remove(struct nfsmount *nmp, kauth_cred_t cred) * refcount is zero. */ NFS_GSS_DBG("Removed context %d/%d refcnt = %d\n", - kauth_cred_getasid(cp->gss_clnt_cred), - kauth_cred_getuid(cp->gss_clnt_cred), - cp->gss_clnt_refcnt); + kauth_cred_getasid(cp->gss_clnt_cred), + kauth_cred_getuid(cp->gss_clnt_cred), + cp->gss_clnt_refcnt); nfs_gss_clnt_ctx_unref(&req); - return (0); + return 0; } lck_mtx_unlock(cp->gss_clnt_mtx); } lck_mtx_unlock(&nmp->nm_lock); - + NFS_GSS_DBG("Returning ENOENT\n"); - return (ENOENT); + return ENOENT; } /* @@ -2596,8 +2706,7 @@ nfs_gss_clnt_ctx_remove(struct nfsmount *nmp, kauth_cred_t cred) */ int nfs_gss_clnt_ctx_set_principal(struct nfsmount *nmp, vfs_context_t ctx, - uint8_t *principal, uint32_t princlen, uint32_t nametype) - + uint8_t *principal, uint32_t princlen, uint32_t nametype) { struct nfsreq req; int error; @@ -2618,13 +2727,14 @@ nfs_gss_clnt_ctx_set_principal(struct nfsmount *nmp, vfs_context_t ctx, * neagative cache and if and when the user has credentials for the principal * we should be good to go in that we will select those credentials for this principal. */ - if (error == EACCES || error == EAUTH || error == ENEEDAUTH) + if (error == EACCES || error == EAUTH || error == ENEEDAUTH) { error = 0; + } /* We're done with this request */ nfs_gss_clnt_ctx_unref(&req); - return (error); + return error; } /* @@ -2632,7 +2742,7 @@ nfs_gss_clnt_ctx_set_principal(struct nfsmount *nmp, vfs_context_t ctx, */ int nfs_gss_clnt_ctx_get_principal(struct nfsmount *nmp, vfs_context_t ctx, - struct user_nfs_gss_principal *p) + struct user_nfs_gss_principal *p) { struct nfsreq req; int error = 0; @@ -2653,8 +2763,8 @@ nfs_gss_clnt_ctx_get_principal(struct nfsmount *nmp, vfs_context_t ctx, lck_mtx_lock(cp->gss_clnt_mtx); if (cp->gss_clnt_flags & GSS_CTX_DESTROY) { NFS_GSS_DBG("Found destroyed context %s refcnt = %d continuing\n", - NFS_GSS_CTX(&req, cp), - cp->gss_clnt_refcnt); + NFS_GSS_CTX(&req, cp), + cp->gss_clnt_refcnt); lck_mtx_unlock(cp->gss_clnt_mtx); continue; } @@ -2671,13 +2781,14 @@ out: lck_mtx_unlock(&nmp->nm_lock); p->flags |= NFS_IOC_NO_CRED_FLAG; /* No credentials, valid or invalid on this mount */ NFS_GSS_DBG("No context found for session %d by uid %d\n", - kauth_cred_getasid(cred), kauth_cred_getuid(cred)); - return (0); + kauth_cred_getasid(cred), kauth_cred_getuid(cred)); + return 0; } /* Indicate if the cred is INVALID */ - if (cp->gss_clnt_flags & GSS_CTX_INVAL) + if (cp->gss_clnt_flags & GSS_CTX_INVAL) { p->flags |= NFS_IOC_INVALID_CRED_FLAG; + } /* We have set a principal on the mount */ if (cp->gss_clnt_principal) { @@ -2708,16 +2819,16 @@ out: req.r_gss_ctx = cp; NFS_GSS_DBG("Found context %s\n", NFS_GSS_CTX(&req, NULL)); nfs_gss_clnt_ctx_unref(&req); - return (error); + return error; } -#endif /* NFSCLIENT */ +#endif /* CONFIG_NFS_CLIENT */ /************* * * Server functions */ -#if NFSSERVER +#if CONFIG_NFS_SERVER /* * Find a server context based on a handle value received @@ -2730,9 +2841,10 @@ nfs_gss_svc_ctx_find(uint32_t handle) struct nfs_gss_svc_ctx *cp; uint64_t timenow; - if (handle == 0) - return (NULL); - + if (handle == 0) { + return NULL; + } + head = &nfs_gss_svc_ctx_hashtbl[SVC_CTX_HASH(handle)]; /* * Don't return a context that is going to expire in GSS_CTX_PEND seconds @@ -2744,14 +2856,14 @@ nfs_gss_svc_ctx_find(uint32_t handle) LIST_FOREACH(cp, head, gss_svc_entries) { if (cp->gss_svc_handle == handle) { if (timenow > cp->gss_svc_incarnation + GSS_SVC_CTX_TTL) { - /* + /* * Context has or is about to expire. Don't use. * We'll return null and the client will have to create * a new context. */ cp->gss_svc_handle = 0; /* - * Make sure though that we stay around for GSS_CTX_PEND seconds + * Make sure though that we stay around for GSS_CTX_PEND seconds * for other threads that might be using the context. */ cp->gss_svc_incarnation = timenow; @@ -2759,16 +2871,16 @@ nfs_gss_svc_ctx_find(uint32_t handle) cp = NULL; break; } - lck_mtx_lock(cp->gss_svc_mtx); + lck_mtx_lock(cp->gss_svc_mtx); cp->gss_svc_refcnt++; - lck_mtx_unlock(cp->gss_svc_mtx); + lck_mtx_unlock(cp->gss_svc_mtx); break; } } lck_mtx_unlock(nfs_gss_svc_ctx_mutex); - return (cp); + return cp; } /* @@ -2780,7 +2892,7 @@ nfs_gss_svc_ctx_insert(struct nfs_gss_svc_ctx *cp) { struct nfs_gss_svc_ctx_hashhead *head; struct nfs_gss_svc_ctx *p; - + lck_mtx_lock(nfs_gss_svc_ctx_mutex); /* @@ -2790,15 +2902,17 @@ nfs_gss_svc_ctx_insert(struct nfs_gss_svc_ctx *cp) */ retry: cp->gss_svc_handle = random(); - if (cp->gss_svc_handle == 0) + if (cp->gss_svc_handle == 0) { goto retry; + } head = &nfs_gss_svc_ctx_hashtbl[SVC_CTX_HASH(cp->gss_svc_handle)]; LIST_FOREACH(p, head, gss_svc_entries) - if (p->gss_svc_handle == cp->gss_svc_handle) - goto retry; + if (p->gss_svc_handle == cp->gss_svc_handle) { + goto retry; + } clock_interval_to_deadline(GSS_CTX_PEND, NSEC_PER_SEC, - &cp->gss_svc_incarnation); + &cp->gss_svc_incarnation); LIST_INSERT_HEAD(head, cp, gss_svc_entries); nfs_gss_ctx_count++; @@ -2806,7 +2920,7 @@ retry: nfs_gss_timer_on = 1; nfs_interval_timer_start(nfs_gss_svc_ctx_timer_call, - min(GSS_TIMER_PERIOD, max(GSS_CTX_TTL_MIN, nfsrv_gss_context_ttl)) * MSECS_PER_SEC); + min(GSS_TIMER_PERIOD, max(GSS_CTX_TTL_MIN, nfsrv_gss_context_ttl)) * MSECS_PER_SEC); } lck_mtx_unlock(nfs_gss_svc_ctx_mutex); @@ -2840,16 +2954,17 @@ nfs_gss_svc_ctx_timer(__unused void *param1, __unused void *param2) */ LIST_FOREACH_SAFE(cp, &nfs_gss_svc_ctx_hashtbl[i], gss_svc_entries, next) { contexts++; - if (timenow > cp->gss_svc_incarnation + - (cp->gss_svc_handle ? GSS_SVC_CTX_TTL : 0) - && cp->gss_svc_refcnt == 0) { + if (timenow > cp->gss_svc_incarnation + + (cp->gss_svc_handle ? GSS_SVC_CTX_TTL : 0) + && cp->gss_svc_refcnt == 0) { /* * A stale context - remove it */ LIST_REMOVE(cp, gss_svc_entries); NFS_GSS_DBG("Removing contex for %d\n", cp->gss_svc_uid); - if (cp->gss_svc_seqbits) + if (cp->gss_svc_seqbits) { FREE(cp->gss_svc_seqbits, M_TEMP); + } lck_mtx_destroy(cp->gss_svc_mtx, nfs_gss_svc_grp); FREE(cp, M_TEMP); contexts--; @@ -2864,9 +2979,10 @@ nfs_gss_svc_ctx_timer(__unused void *param1, __unused void *param2) * set up another callout to check on them later. */ nfs_gss_timer_on = nfs_gss_ctx_count > 0; - if (nfs_gss_timer_on) + if (nfs_gss_timer_on) { nfs_interval_timer_start(nfs_gss_svc_ctx_timer_call, - min(GSS_TIMER_PERIOD, max(GSS_CTX_TTL_MIN, nfsrv_gss_context_ttl)) * MSECS_PER_SEC); + min(GSS_TIMER_PERIOD, max(GSS_CTX_TTL_MIN, nfsrv_gss_context_ttl)) * MSECS_PER_SEC); + } lck_mtx_unlock(nfs_gss_svc_ctx_mutex); } @@ -2909,8 +3025,9 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) nfsm_chain_get_32(error, nmc, seqnum); nfsm_chain_get_32(error, nmc, service); nfsm_chain_get_32(error, nmc, handle_len); - if (error) + if (error) { goto nfsmout; + } /* * Make sure context setup/destroy is being done with a nullproc @@ -2930,10 +3047,10 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) goto nfsmout; } - nd->nd_sec = - service == RPCSEC_GSS_SVC_NONE ? RPCAUTH_KRB5 : - service == RPCSEC_GSS_SVC_INTEGRITY ? RPCAUTH_KRB5I : - service == RPCSEC_GSS_SVC_PRIVACY ? RPCAUTH_KRB5P : 0; + nd->nd_sec = + service == RPCSEC_GSS_SVC_NONE ? RPCAUTH_KRB5 : + service == RPCSEC_GSS_SVC_INTEGRITY ? RPCAUTH_KRB5I : + service == RPCSEC_GSS_SVC_PRIVACY ? RPCAUTH_KRB5P : 0; if (proc == RPCSEC_GSS_INIT) { /* @@ -2947,7 +3064,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) /* * Set up a new context */ - MALLOC(cp, struct nfs_gss_svc_ctx *, sizeof(*cp), M_TEMP, M_WAITOK|M_ZERO); + MALLOC(cp, struct nfs_gss_svc_ctx *, sizeof(*cp), M_TEMP, M_WAITOK | M_ZERO); if (cp == NULL) { error = ENOMEM; goto nfsmout; @@ -2963,8 +3080,9 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) goto nfsmout; } nfsm_chain_get_32(error, nmc, handle); - if (error) + if (error) { goto nfsmout; + } cp = nfs_gss_svc_ctx_find(handle); if (cp == NULL) { error = NFSERR_AUTHERR | RPCSEC_GSS_CTXPROBLEM; @@ -2989,7 +3107,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) /* * Sequence number is bad */ - error = EINVAL; // drop the request + error = EINVAL; // drop the request goto nfsmout; } @@ -3004,16 +3122,18 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) header_len = nfsm_chain_offset(nmc); nfsm_chain_get_32(error, nmc, flavor); nfsm_chain_get_32(error, nmc, cksum.length); - if (error) + if (error) { goto nfsmout; - if (flavor != RPCSEC_GSS || cksum.length > KRB5_MAX_MIC_SIZE) + } + if (flavor != RPCSEC_GSS || cksum.length > KRB5_MAX_MIC_SIZE) { error = NFSERR_AUTHERR | AUTH_BADVERF; - else { + } else { MALLOC(cksum.value, void *, cksum.length, M_TEMP, M_WAITOK); nfsm_chain_get_opaque(error, nmc, cksum.length, cksum.value); } - if (error) + if (error) { goto nfsmout; + } /* Now verify the client's call header checksum */ major = gss_krb5_verify_mic_mbuf((uint32_t *)&error, cp->gss_svc_ctx_id, nmc->nmc_mhead, 0, header_len, &cksum, NULL); @@ -3032,7 +3152,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) bzero(&temp_pcred, sizeof(temp_pcred)); temp_pcred.cr_uid = cp->gss_svc_uid; bcopy(cp->gss_svc_gids, temp_pcred.cr_groups, - sizeof(gid_t) * cp->gss_svc_ngroups); + sizeof(gid_t) * cp->gss_svc_ngroups); temp_pcred.cr_ngroups = cp->gss_svc_ngroups; nd->nd_cr = posix_cred_create(&temp_pcred); @@ -3060,7 +3180,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) * - length of checksum token * - checksum of seqnum + call args */ - nfsm_chain_get_32(error, nmc, arglen); // length of args + nfsm_chain_get_32(error, nmc, arglen); // length of args if (arglen > NFS_MAXPACKET) { error = EBADRPC; goto nfsmout; @@ -3070,8 +3190,9 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) nfsm_chain_adv(error, &nmc_tmp, arglen); nfsm_chain_get_32(error, &nmc_tmp, cksum.length); cksum.value = NULL; - if (cksum.length > 0 && cksum.length < GSS_MAX_MIC_LEN) + if (cksum.length > 0 && cksum.length < GSS_MAX_MIC_LEN) { MALLOC(cksum.value, void *, cksum.length, M_TEMP, M_WAITOK); + } if (cksum.value == NULL) { error = EBADRPC; @@ -3083,7 +3204,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) start = nfsm_chain_offset(nmc); major = gss_krb5_verify_mic_mbuf((uint32_t *)&error, cp->gss_svc_ctx_id, - nmc->nmc_mhead, start, arglen, &cksum, NULL); + nmc->nmc_mhead, start, arglen, &cksum, NULL); FREE(cksum.value, M_TEMP); if (major != GSS_S_COMPLETE) { printf("Server args: gss_krb5_verify_mic_mbuf failed %d\n", error); @@ -3098,7 +3219,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) */ nfsm_chain_get_32(error, nmc, seqnum); if (seqnum != nd->nd_gss_seqnum) { - error = EBADRPC; // returns as GARBAGEARGS + error = EBADRPC; // returns as GARBAGEARGS goto nfsmout; } break; @@ -3110,7 +3231,7 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) * - wrap token (37-40 bytes) */ prev_mbuf = nmc->nmc_mcur; - nfsm_chain_get_32(error, nmc, arglen); // length of args + nfsm_chain_get_32(error, nmc, arglen); // length of args if (arglen > NFS_MAXPACKET) { error = EBADRPC; goto nfsmout; @@ -3122,8 +3243,9 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) /* split out the wrap token */ argsize = arglen; error = gss_normalize_mbuf(nmc->nmc_mcur, start, &argsize, &reply_mbuf, &pad_mbuf, 0); - if (error) + if (error) { goto nfsmout; + } assert(argsize == arglen); if (pad_mbuf) { @@ -3160,10 +3282,10 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) nfsm_chain_get_32(error, nmc, seqnum); if (seqnum != nd->nd_gss_seqnum) { printf("%s: Sequence number mismatch seqnum = %d nd->nd_gss_seqnum = %d\n", - __func__, seqnum, nd->nd_gss_seqnum); + __func__, seqnum, nd->nd_gss_seqnum); printmbuf("reply_mbuf", nmc->nmc_mhead, 0, 0); printf("reply_mbuf %p nmc_head %p\n", reply_mbuf, nmc->nmc_mhead); - error = EBADRPC; // returns as GARBAGEARGS + error = EBADRPC; // returns as GARBAGEARGS goto nfsmout; } break; @@ -3176,8 +3298,9 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) */ nfsm_chain_get_32(error, nmc, flavor); nfsm_chain_get_32(error, nmc, verflen); - if (error || flavor != RPCAUTH_NULL || verflen > 0) + if (error || flavor != RPCAUTH_NULL || verflen > 0) { error = NFSERR_AUTHERR | RPCSEC_GSS_CREDPROBLEM; + } if (error) { if (proc == RPCSEC_GSS_INIT) { lck_mtx_destroy(cp->gss_svc_mtx, nfs_gss_svc_grp); @@ -3191,9 +3314,10 @@ nfs_gss_svc_cred_get(struct nfsrv_descript *nd, struct nfsm_chain *nmc) nd->nd_gss_context = cp; return 0; nfsmout: - if (cp) + if (cp) { nfs_gss_svc_ctx_deref(cp); - return (error); + } + return error; } /* @@ -3219,7 +3343,7 @@ nfs_gss_svc_verf_put(struct nfsrv_descript *nd, struct nfsm_chain *nmc) */ nfsm_chain_add_32(error, nmc, RPCAUTH_NULL); nfsm_chain_add_32(error, nmc, 0); - return (error); + return error; } /* @@ -3230,15 +3354,17 @@ nfs_gss_svc_verf_put(struct nfsrv_descript *nd, struct nfsm_chain *nmc) */ seqbuf.length = NFSX_UNSIGNED; if (cp->gss_svc_proc == RPCSEC_GSS_INIT || - cp->gss_svc_proc == RPCSEC_GSS_CONTINUE_INIT) + cp->gss_svc_proc == RPCSEC_GSS_CONTINUE_INIT) { network_seqnum = htonl(cp->gss_svc_seqwin); - else + } else { network_seqnum = htonl(nd->nd_gss_seqnum); + } seqbuf.value = &network_seqnum; major = gss_krb5_get_mic((uint32_t *)&error, cp->gss_svc_ctx_id, 0, &seqbuf, &cksum); - if (major != GSS_S_COMPLETE) - return (error); + if (major != GSS_S_COMPLETE) { + return error; + } /* * Now wrap it in a token and add @@ -3249,7 +3375,7 @@ nfs_gss_svc_verf_put(struct nfsrv_descript *nd, struct nfsm_chain *nmc) nfsm_chain_add_opaque(error, nmc, cksum.value, cksum.length); gss_release_buffer(NULL, &cksum); - return (error); + return error; } /* @@ -3267,8 +3393,9 @@ nfs_gss_svc_prepare_reply(struct nfsrv_descript *nd, struct nfsm_chain *nmc) int error = 0; if (cp->gss_svc_proc == RPCSEC_GSS_INIT || - cp->gss_svc_proc == RPCSEC_GSS_CONTINUE_INIT) - return (0); + cp->gss_svc_proc == RPCSEC_GSS_CONTINUE_INIT) { + return 0; + } switch (nd->nd_sec) { case RPCAUTH_KRB5: @@ -3276,12 +3403,12 @@ nfs_gss_svc_prepare_reply(struct nfsrv_descript *nd, struct nfsm_chain *nmc) break; case RPCAUTH_KRB5I: case RPCAUTH_KRB5P: - nd->nd_gss_mb = nmc->nmc_mcur; // record current mbuf - nfsm_chain_finish_mbuf(error, nmc); // split the chain here + nd->nd_gss_mb = nmc->nmc_mcur; // record current mbuf + nfsm_chain_finish_mbuf(error, nmc); // split the chain here break; } - return (error); + return error; } /* @@ -3305,15 +3432,17 @@ nfs_gss_svc_protect_reply(struct nfsrv_descript *nd, mbuf_t mrep __unused) * together. */ - mb = nd->nd_gss_mb; // the mbuf where we split - results = mbuf_next(mb); // first mbuf in the results - error = mbuf_setnext(mb, NULL); // disconnect the chains - if (error) - return (error); - nfs_gss_nfsm_chain(nmc_res, mb); // set up the prepend chain + mb = nd->nd_gss_mb; // the mbuf where we split + results = mbuf_next(mb); // first mbuf in the results + error = mbuf_setnext(mb, NULL); // disconnect the chains + if (error) { + return error; + } + nfs_gss_nfsm_chain(nmc_res, mb); // set up the prepend chain nfsm_chain_build_done(error, nmc_res); - if (error) - return (error); + if (error) { + return error; + } if (nd->nd_sec == RPCAUTH_KRB5I) { error = rpc_gss_integ_data_create(cp->gss_svc_ctx_id, &results, nd->nd_gss_seqnum, &reslen); @@ -3321,10 +3450,10 @@ nfs_gss_svc_protect_reply(struct nfsrv_descript *nd, mbuf_t mrep __unused) /* RPCAUTH_KRB5P */ error = rpc_gss_priv_data_create(cp->gss_svc_ctx_id, &results, nd->nd_gss_seqnum, &reslen); } - nfs_gss_append_chain(nmc_res, results); // Append the results mbufs + nfs_gss_append_chain(nmc_res, results); // Append the results mbufs nfsm_chain_build_done(error, nmc_res); - return (error); + return error; } /* @@ -3355,14 +3484,15 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * switch (cp->gss_svc_proc) { case RPCSEC_GSS_INIT: nfs_gss_svc_ctx_insert(cp); - /* FALLTHRU */ + /* FALLTHRU */ case RPCSEC_GSS_CONTINUE_INIT: /* Get the token from the request */ nfsm_chain_get_32(error, nmreq, cp->gss_svc_tokenlen); cp->gss_svc_token = NULL; - if (cp->gss_svc_tokenlen > 0 && cp->gss_svc_tokenlen < GSS_MAX_TOKEN_LEN) + if (cp->gss_svc_tokenlen > 0 && cp->gss_svc_tokenlen < GSS_MAX_TOKEN_LEN) { MALLOC(cp->gss_svc_token, u_char *, cp->gss_svc_tokenlen, M_TEMP, M_WAITOK); + } if (cp->gss_svc_token == NULL) { autherr = RPCSEC_GSS_CREDPROBLEM; break; @@ -3373,8 +3503,9 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * error = nfs_gss_svc_gssd_upcall(cp); if (error) { autherr = RPCSEC_GSS_CREDPROBLEM; - if (error == NFSERR_EAUTH) + if (error == NFSERR_EAUTH) { error = 0; + } break; } @@ -3382,8 +3513,9 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * * If the context isn't complete, pass the new token * back to the client for another round. */ - if (cp->gss_svc_major != GSS_S_COMPLETE) + if (cp->gss_svc_major != GSS_S_COMPLETE) { break; + } /* * Now the server context is complete. @@ -3393,7 +3525,7 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * cp->gss_svc_seqwin = GSS_SVC_SEQWINDOW; MALLOC(cp->gss_svc_seqbits, uint32_t *, - nfsm_rndup((cp->gss_svc_seqwin + 7) / 8), M_TEMP, M_WAITOK|M_ZERO); + nfsm_rndup((cp->gss_svc_seqwin + 7) / 8), M_TEMP, M_WAITOK | M_ZERO); if (cp->gss_svc_seqbits == NULL) { autherr = RPCSEC_GSS_CREDPROBLEM; break; @@ -3413,10 +3545,10 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * */ cp = nfs_gss_svc_ctx_find(cp->gss_svc_handle); if (cp != NULL) { - cp->gss_svc_handle = 0; // so it can't be found + cp->gss_svc_handle = 0; // so it can't be found lck_mtx_lock(cp->gss_svc_mtx); clock_interval_to_deadline(GSS_CTX_PEND, NSEC_PER_SEC, - &cp->gss_svc_incarnation); + &cp->gss_svc_incarnation); lck_mtx_unlock(cp->gss_svc_mtx); } break; @@ -3427,23 +3559,25 @@ nfs_gss_svc_ctx_init(struct nfsrv_descript *nd, struct nfsrv_sock *slp, mbuf_t * /* Now build the reply */ - if (nd->nd_repstat == 0) + if (nd->nd_repstat == 0) { nd->nd_repstat = autherr ? (NFSERR_AUTHERR | autherr) : NFSERR_RETVOID; + } sz = 7 * NFSX_UNSIGNED + nfsm_rndup(cp->gss_svc_tokenlen); // size of results error = nfsrv_rephead(nd, slp, &nmrep, sz); *mrepp = nmrep.nmc_mhead; - if (error || autherr) + if (error || autherr) { goto nfsmout; + } if (cp->gss_svc_proc == RPCSEC_GSS_INIT || cp->gss_svc_proc == RPCSEC_GSS_CONTINUE_INIT) { nfsm_chain_add_32(error, &nmrep, sizeof(cp->gss_svc_handle)); nfsm_chain_add_32(error, &nmrep, cp->gss_svc_handle); - + nfsm_chain_add_32(error, &nmrep, cp->gss_svc_major); nfsm_chain_add_32(error, &nmrep, cp->gss_svc_minor); nfsm_chain_add_32(error, &nmrep, cp->gss_svc_seqwin); - + nfsm_chain_add_32(error, &nmrep, cp->gss_svc_tokenlen); if (cp->gss_svc_token != NULL) { nfsm_chain_add_opaque(error, &nmrep, cp->gss_svc_token, cp->gss_svc_tokenlen); @@ -3456,10 +3590,12 @@ nfsmout: if (autherr != 0) { nd->nd_gss_context = NULL; LIST_REMOVE(cp, gss_svc_entries); - if (cp->gss_svc_seqbits != NULL) + if (cp->gss_svc_seqbits != NULL) { FREE(cp->gss_svc_seqbits, M_TEMP); - if (cp->gss_svc_token != NULL) + } + if (cp->gss_svc_token != NULL) { FREE(cp->gss_svc_token, M_TEMP); + } lck_mtx_destroy(cp->gss_svc_mtx, nfs_gss_svc_grp); FREE(cp, M_TEMP); } @@ -3469,7 +3605,7 @@ nfsmout: nfsm_chain_cleanup(&nmrep); *mrepp = NULL; } - return (error); + return error; } /* @@ -3504,8 +3640,9 @@ nfs_gss_svc_gssd_upcall(struct nfs_gss_svc_ctx *cp) goto out; } - if (cp->gss_svc_tokenlen > 0) + if (cp->gss_svc_tokenlen > 0) { nfs_gss_mach_alloc_buffer(cp->gss_svc_token, cp->gss_svc_tokenlen, &itoken); + } retry: printf("Calling mach_gss_accept_sec_context\n"); @@ -3526,12 +3663,13 @@ retry: &cp->gss_svc_minor); printf("mach_gss_accept_sec_context returned %d\n", kr); - if (kr != KERN_SUCCESS) { + if (kr != KERN_SUCCESS) { printf("nfs_gss_svc_gssd_upcall failed: %x (%d)\n", kr, kr); if (kr == MIG_SERVER_DIED && cp->gss_svc_context == 0 && - retry_cnt++ < NFS_GSS_MACH_MAX_RETRIES) { - if (cp->gss_svc_tokenlen > 0) + retry_cnt++ < NFS_GSS_MACH_MAX_RETRIES) { + if (cp->gss_svc_tokenlen > 0) { nfs_gss_mach_alloc_buffer(cp->gss_svc_token, cp->gss_svc_tokenlen, &itoken); + } goto retry; } host_release_special_port(mp); @@ -3554,8 +3692,9 @@ retry: FREE(lucid_ctx_buffer, M_TEMP); goto out; } - if (cp->gss_svc_ctx_id) + if (cp->gss_svc_ctx_id) { gss_krb5_destroy_context(cp->gss_svc_ctx_id); + } cp->gss_svc_ctx_id = gss_krb5_make_context(lucid_ctx_buffer, lucidlen); if (cp->gss_svc_ctx_id == NULL) { printf("Failed to make context from lucid_ctx_buffer\n"); @@ -3564,36 +3703,37 @@ retry: } /* Free context token used as input */ - if (cp->gss_svc_token) + if (cp->gss_svc_token) { FREE(cp->gss_svc_token, M_TEMP); + } cp->gss_svc_token = NULL; cp->gss_svc_tokenlen = 0; - + if (otokenlen > 0) { /* Set context token to gss output token */ MALLOC(cp->gss_svc_token, u_char *, otokenlen, M_TEMP, M_WAITOK); if (cp->gss_svc_token == NULL) { printf("nfs_gss_svc_gssd_upcall: could not allocate %d bytes\n", otokenlen); vm_map_copy_discard((vm_map_copy_t) otoken); - return (ENOMEM); + return ENOMEM; } error = nfs_gss_mach_vmcopyout((vm_map_copy_t) otoken, otokenlen, cp->gss_svc_token); if (error) { FREE(cp->gss_svc_token, M_TEMP); cp->gss_svc_token = NULL; - return (NFSERR_EAUTH); + return NFSERR_EAUTH; } cp->gss_svc_tokenlen = otokenlen; } - return (0); + return 0; out: FREE(cp->gss_svc_token, M_TEMP); cp->gss_svc_tokenlen = 0; cp->gss_svc_token = NULL; - return (NFSERR_EAUTH); + return NFSERR_EAUTH; } /* @@ -3620,15 +3760,17 @@ nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *cp, uint32_t seq) * move the window up, and set the bit. */ if (seq > cp->gss_svc_seqmax) { - if (seq - cp->gss_svc_seqmax > win) + if (seq - cp->gss_svc_seqmax > win) { bzero(bits, nfsm_rndup((win + 7) / 8)); - else - for (i = cp->gss_svc_seqmax + 1; i < seq; i++) + } else { + for (i = cp->gss_svc_seqmax + 1; i < seq; i++) { win_resetbit(bits, i % win); + } + } win_setbit(bits, seq % win); cp->gss_svc_seqmax = seq; lck_mtx_unlock(cp->gss_svc_mtx); - return (1); + return 1; } /* @@ -3636,7 +3778,7 @@ nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *cp, uint32_t seq) */ if (seq <= cp->gss_svc_seqmax - win) { lck_mtx_unlock(cp->gss_svc_mtx); - return (0); + return 0; } /* @@ -3644,11 +3786,11 @@ nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *cp, uint32_t seq) */ if (win_getbit(bits, seq % win)) { lck_mtx_unlock(cp->gss_svc_mtx); - return (0); + return 0; } win_setbit(bits, seq % win); lck_mtx_unlock(cp->gss_svc_mtx); - return (1); + return 1; } /* @@ -3661,12 +3803,13 @@ nfs_gss_svc_seqnum_valid(struct nfs_gss_svc_ctx *cp, uint32_t seq) void nfs_gss_svc_ctx_deref(struct nfs_gss_svc_ctx *cp) { - lck_mtx_lock(cp->gss_svc_mtx); - if (cp->gss_svc_refcnt > 0) + lck_mtx_lock(cp->gss_svc_mtx); + if (cp->gss_svc_refcnt > 0) { cp->gss_svc_refcnt--; - else + } else { printf("nfs_gss_ctx_deref: zero refcount\n"); - lck_mtx_unlock(cp->gss_svc_mtx); + } + lck_mtx_unlock(cp->gss_svc_mtx); } /* @@ -3678,7 +3821,7 @@ nfs_gss_svc_cleanup(void) struct nfs_gss_svc_ctx_hashhead *head; struct nfs_gss_svc_ctx *cp, *ncp; int i; - + lck_mtx_lock(nfs_gss_svc_ctx_mutex); /* @@ -3691,8 +3834,9 @@ nfs_gss_svc_cleanup(void) head = &nfs_gss_svc_ctx_hashtbl[i]; LIST_FOREACH_SAFE(cp, head, gss_svc_entries, ncp) { LIST_REMOVE(cp, gss_svc_entries); - if (cp->gss_svc_seqbits) + if (cp->gss_svc_seqbits) { FREE(cp->gss_svc_seqbits, M_TEMP); + } lck_mtx_destroy(cp->gss_svc_mtx, nfs_gss_svc_grp); FREE(cp, M_TEMP); } @@ -3701,7 +3845,7 @@ nfs_gss_svc_cleanup(void) lck_mtx_unlock(nfs_gss_svc_ctx_mutex); } -#endif /* NFSSERVER */ +#endif /* CONFIG_NFS_SERVER */ /************* @@ -3711,7 +3855,7 @@ nfs_gss_svc_cleanup(void) /* * Release a host special port that was obtained by host_get_special_port * or one of its macros (host_get_gssd_port in this case). - * This really should be in a public kpi. + * This really should be in a public kpi. */ /* This should be in a public header if this routine is not */ @@ -3721,14 +3865,15 @@ extern ipc_port_t ipc_port_copy_send(ipc_port_t); static void host_release_special_port(mach_port_t mp) { - if (IPC_PORT_VALID(mp)) + if (IPC_PORT_VALID(mp)) { ipc_port_release_send(mp); + } } static mach_port_t host_copy_special_port(mach_port_t mp) { - return (ipc_port_copy_send(mp)); + return ipc_port_copy_send(mp); } /* @@ -3750,11 +3895,18 @@ nfs_gss_mach_alloc_buffer(u_char *buf, uint32_t buflen, vm_map_copy_t *addr) vm_size_t tbuflen; *addr = NULL; - if (buf == NULL || buflen == 0) + if (buf == NULL || buflen == 0) { return; + } tbuflen = vm_map_round_page(buflen, - vm_map_page_mask(ipc_kernel_map)); + vm_map_page_mask(ipc_kernel_map)); + + if (tbuflen < buflen) { + printf("nfs_gss_mach_alloc_buffer: vm_map_round_page failed\n"); + return; + } + kr = vm_allocate_kernel(ipc_kernel_map, &kmem_buf, tbuflen, VM_FLAGS_ANYWHERE, VM_KERN_MEMORY_FILE); if (kr != 0) { printf("nfs_gss_mach_alloc_buffer: vm_allocate failed\n"); @@ -3762,33 +3914,33 @@ nfs_gss_mach_alloc_buffer(u_char *buf, uint32_t buflen, vm_map_copy_t *addr) } kr = vm_map_wire_kernel(ipc_kernel_map, - vm_map_trunc_page(kmem_buf, - vm_map_page_mask(ipc_kernel_map)), - vm_map_round_page(kmem_buf + tbuflen, - vm_map_page_mask(ipc_kernel_map)), - VM_PROT_READ|VM_PROT_WRITE, VM_KERN_MEMORY_FILE, FALSE); + vm_map_trunc_page(kmem_buf, + vm_map_page_mask(ipc_kernel_map)), + vm_map_round_page(kmem_buf + tbuflen, + vm_map_page_mask(ipc_kernel_map)), + VM_PROT_READ | VM_PROT_WRITE, VM_KERN_MEMORY_FILE, FALSE); if (kr != 0) { printf("nfs_gss_mach_alloc_buffer: vm_map_wire failed\n"); return; } - + bcopy(buf, (void *) kmem_buf, buflen); // Shouldn't need to bzero below since vm_allocate returns zeroed pages // bzero(kmem_buf + buflen, tbuflen - buflen); - + kr = vm_map_unwire(ipc_kernel_map, - vm_map_trunc_page(kmem_buf, - vm_map_page_mask(ipc_kernel_map)), - vm_map_round_page(kmem_buf + tbuflen, - vm_map_page_mask(ipc_kernel_map)), - FALSE); + vm_map_trunc_page(kmem_buf, + vm_map_page_mask(ipc_kernel_map)), + vm_map_round_page(kmem_buf + tbuflen, + vm_map_page_mask(ipc_kernel_map)), + FALSE); if (kr != 0) { printf("nfs_gss_mach_alloc_buffer: vm_map_unwire failed\n"); return; } kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t) kmem_buf, - (vm_map_size_t) buflen, TRUE, addr); + (vm_map_size_t) buflen, TRUE, addr); if (kr != 0) { printf("nfs_gss_mach_alloc_buffer: vm_map_copyin failed\n"); return; @@ -3809,14 +3961,15 @@ nfs_gss_mach_vmcopyout(vm_map_copy_t in, uint32_t len, u_char *out) int error; error = vm_map_copyout(ipc_kernel_map, &map_data, in); - if (error) - return (error); + if (error) { + return error; + } data = CAST_DOWN(vm_offset_t, map_data); bcopy((void *) data, out, len); vm_deallocate(ipc_kernel_map, data, len); - return (0); + return 0; } /* @@ -3828,10 +3981,11 @@ nfs_gss_mchain_length(mbuf_t mhead) mbuf_t mb; int len = 0; - for (mb = mhead; mb; mb = mbuf_next(mb)) + for (mb = mhead; mb; mb = mbuf_next(mb)) { len += mbuf_len(mb); + } - return (len); + return len; } /* @@ -3845,21 +3999,24 @@ nfs_gss_append_chain(struct nfsm_chain *nmc, mbuf_t mc) /* Connect the mbuf chains */ error = mbuf_setnext(nmc->nmc_mcur, mc); - if (error) - return (error); + if (error) { + return error; + } /* Find the last mbuf in the chain */ tail = NULL; - for (mb = mc; mb; mb = mbuf_next(mb)) + for (mb = mc; mb; mb = mbuf_next(mb)) { tail = mb; + } nmc->nmc_mcur = tail; nmc->nmc_ptr = (caddr_t) mbuf_data(tail) + mbuf_len(tail); nmc->nmc_left = mbuf_trailingspace(tail); - return (0); + return 0; } +#if CONFIG_NFS_SERVER /* Only used by CONFIG_NFS_SERVER */ /* * Convert an mbuf chain to an NFS mbuf chain */ @@ -3870,8 +4027,9 @@ nfs_gss_nfsm_chain(struct nfsm_chain *nmc, mbuf_t mc) /* Find the last mbuf in the chain */ tail = NULL; - for (mb = mc; mb; mb = mbuf_next(mb)) + for (mb = mc; mb; mb = mbuf_next(mb)) { tail = mb; + } nmc->nmc_mhead = mc; nmc->nmc_mcur = tail; @@ -3879,7 +4037,7 @@ nfs_gss_nfsm_chain(struct nfsm_chain *nmc, mbuf_t mc) nmc->nmc_left = mbuf_trailingspace(tail); nmc->nmc_flags = 0; } - +#endif /* CONFIG_NFS_SERVER */ #if 0 @@ -3891,16 +4049,20 @@ hexdump(const char *msg, void *data, size_t len) { size_t i, j; u_char *d = data; - char *p, disbuf[3*DISPLAYLEN+1]; - + char *p, disbuf[3 * DISPLAYLEN + 1]; + printf("NFS DEBUG %s len=%d:\n", msg, (uint32_t)len); - if (len > MAXDISPLAYLEN) + if (len > MAXDISPLAYLEN) { len = MAXDISPLAYLEN; + } for (i = 0; i < len; i += DISPLAYLEN) { - for (p = disbuf, j = 0; (j + i) < len && j < DISPLAYLEN; j++, p += 3) + for (p = disbuf, j = 0; (j + i) < len && j < DISPLAYLEN; j++, p += 3) { snprintf(p, 4, "%02x ", d[i + j]); + } printf("\t%s\n", disbuf); } } #endif + +#endif /* CONFIG_NFS */