/*
- * Copyright (c) 2007-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2020 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
* 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,
* 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 <nfs/nfs_conf.h>
+#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
#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;
+static LCK_GRP_DECLARE(nfs_gss_svc_grp, "rpcsec_gss_svc");
+static LCK_MTX_DECLARE(nfs_gss_svc_ctx_mutex, &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
-lck_grp_t *nfs_gss_clnt_grp;
-#endif /* NFSCLIENT */
+#if CONFIG_NFS_CLIENT
+LCK_GRP_DECLARE(nfs_gss_clnt_grp, "rpcsec_gss_clnt");
+#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 *, size_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 *, size_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
void
nfs_gss_init(void)
{
-#if NFSCLIENT
- nfs_gss_clnt_grp = lck_grp_alloc_init("rpcsec_gss_clnt", LCK_GRP_ATTR_NULL);
-#endif /* NFSCLIENT */
-
-#if NFSSERVER
- nfs_gss_svc_grp = lck_grp_alloc_init("rpcsec_gss_svc", LCK_GRP_ATTR_NULL);
-
+#if CONFIG_NFS_SERVER
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 */
}
/*
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;
}
/*
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 */
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
*/
/* 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
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) */
// printmbuf("rpc_gss_integ_data_create done", *mb_head, 0, 0);
assert(nmc.nmc_mhead == *mb_head);
- return (error);
+ return error;
}
/*
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 */
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
/* 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;
}
/*
{
uint32_t major, error;
mbuf_t mb = *mb_head, next;
- uint32_t plen;
- size_t length;
+ size_t plen, length;
gss_qop_t qop = GSS_C_QOP_REVERSE;
/* Chop of the opaque length */
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);
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;
/* 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;
}
/*
nfs_cred_getasid2uid(kauth_cred_t cred)
{
uid_t result = SAFE_CAST_INTTYPE(uid_t, kauth_cred_getasid(cred));
- return (result);
+ return result;
}
/*
lck_mtx_lock(&nmp->nm_lock);
NFS_GSS_DBG("Enter\n");
TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) {
- lck_mtx_lock(cp->gss_clnt_mtx);
+ 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);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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");
lck_mtx_unlock(&nmp->nm_lock);
nfs_gss_clnt_ctx_name(struct nfsmount *nmp, struct nfs_gss_clnt_ctx *cp, char *buf, int len)
{
char *np;
- int nlen;
+ size_t 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) {
np = cp->gss_clnt_display;
nlen = np ? strlen(cp->gss_clnt_display) : 0;
}
- 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
+ if (nlen) {
+ snprintf(buf, len, "[%s] %.*s %d/%d %s", server, nlen > INT_MAX ? INT_MAX : (int)nlen, np,
+ 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;
}
/*
* so that defaults can be set by service identities.
*/
-static void
+static int
nfs_gss_clnt_mnt_ref(struct nfsmount *nmp)
{
int error;
vnode_t rvp;
if (nmp == NULL ||
- !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED))
- return;
+ !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) {
+ return EINVAL;
+ }
error = VFS_ROOT(nmp->nm_mountp, &rvp, NULL);
if (!error) {
- vnode_ref(rvp);
+ error = vnode_ref(rvp);
vnode_put(rvp);
}
+
+ return error;
}
/*
- * Unbusy the mout. See above comment,
+ * Unbusy the mount. See above comment,
*/
-static void
+static int
nfs_gss_clnt_mnt_rele(struct nfsmount *nmp)
{
int error;
vnode_t rvp;
if (nmp == NULL ||
- !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED))
- return;
+ !(vfs_flags(nmp->nm_mountp) & MNT_AUTOMOUNTED)) {
+ return EINVAL;
+ }
error = VFS_ROOT(nmp->nm_mountp, &rvp, NULL);
if (!error) {
vnode_rele(rvp);
vnode_put(rvp);
}
+
+ return error;
}
int nfs_root_steals_ctx = 0;
static int
-nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, uint32_t plen, uint32_t nt)
+nfs_gss_clnt_ctx_find_principal(struct nfsreq *req, uint8_t *principal, size_t plen, uint32_t nt)
{
struct nfsmount *nmp = req->r_nmp;
- struct nfs_gss_clnt_ctx *cp;
- struct nfsreq treq;
+ struct nfs_gss_clnt_ctx *cp, *tcp;
+ struct nfsreq *treq;
int error = 0;
struct timeval now;
char CTXBUF[NFS_CTXBUFSZ];
- bzero(&treq, sizeof (struct nfsreq));
- treq.r_nmp = nmp;
+ treq = zalloc_flags(nfs_req_zone, Z_WAITOK | Z_ZERO);
+ treq->r_nmp = nmp;
microuptime(&now);
lck_mtx_lock(&nmp->nm_lock);
- TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) {
- lck_mtx_lock(cp->gss_clnt_mtx);
+ TAILQ_FOREACH_SAFE(cp, &nmp->nm_gsscl, gss_clnt_entries, tcp) {
+ 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);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ NFS_GSS_CTX(req, cp),
+ cp->gss_clnt_refcnt);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
continue;
}
if (nfs_gss_clnt_ctx_cred_match(cp->gss_clnt_cred, req->r_cred)) {
bcmp(cp->gss_clnt_principal, principal, plen) != 0) {
cp->gss_clnt_flags |= (GSS_CTX_INVAL | GSS_CTX_DESTROY);
cp->gss_clnt_refcnt++;
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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_DBG("len = (%d,%d), nt = (%d,%d)\n", cp->gss_clnt_prinlen, plen,
- cp->gss_clnt_prinnt, nt);
- treq.r_gss_ctx = cp;
+ NFS_GSS_CTX(req, cp), principal);
+ NFS_GSS_DBG("len = (%zu,%zu), nt = (%d,%d)\n", cp->gss_clnt_prinlen, plen,
+ cp->gss_clnt_prinnt, nt);
+ treq->r_gss_ctx = cp;
cp = NULL;
break;
}
*/
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);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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);
+ NFS_ZFREE(nfs_req_zone, treq);
+ return NFSERR_EAUTH;
}
if (cp->gss_clnt_refcnt) {
struct nfs_gss_clnt_ctx *ncp;
*/
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);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
if (error) {
lck_mtx_unlock(&nmp->nm_lock);
- return (error);
+ NFS_ZFREE(nfs_req_zone, treq);
+ 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);
+ }
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
TAILQ_REMOVE(&nmp->nm_gsscl, cp, gss_clnt_entries);
break;
}
/* Found a valid context to return */
cp->gss_clnt_refcnt++;
req->r_gss_ctx = cp;
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
lck_mtx_unlock(&nmp->nm_lock);
- return (0);
+ NFS_ZFREE(nfs_req_zone, treq);
+ return 0;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
}
if (!cp && nfs_root_steals_ctx && principal == NULL && kauth_cred_getuid(req->r_cred) == 0) {
* 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);
+ NFS_ZFREE(nfs_req_zone, treq);
+ 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);
+ NFS_ZFREE(nfs_req_zone, treq);
+ 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);
+ lck_mtx_init(&cp->gss_clnt_mtx, &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;
cp->gss_clnt_flags |= GSS_CTX_STICKY;
- nfs_gss_clnt_mnt_ref(nmp);
+ if (!nfs_gss_clnt_mnt_ref(nmp)) {
+ cp->gss_clnt_flags |= GSS_CTX_USECOUNT;
+ }
}
} else {
+ uint32_t oldflags = cp->gss_clnt_flags;
nfs_gss_clnt_ctx_clean(cp);
if (principal) {
/*
* match and we will fall through here.
*/
cp->gss_clnt_flags |= GSS_CTX_STICKY;
+
+ /*
+ * We are preserving old flags if it set, and we take a ref if not set.
+ * Also, because of the short circuit we will not take extra refs here.
+ */
+ if ((oldflags & GSS_CTX_USECOUNT) || !nfs_gss_clnt_mnt_ref(nmp)) {
+ cp->gss_clnt_flags |= GSS_CTX_USECOUNT;
+ }
}
}
}
/* Remove any old matching contex that had a different principal */
- nfs_gss_clnt_ctx_unref(&treq);
-
- return (error);
+ nfs_gss_clnt_ctx_unref(treq);
+ NFS_ZFREE(nfs_req_zone, treq);
+ 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);
}
/*
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);
* be created.
*/
error = nfs_gss_clnt_ctx_find(req);
- if (error)
- return (error);
+ if (error) {
+ return error;
+ }
}
cp = req->r_gss_ctx;
* doing the context setup. Wait until the context thread
* is null.
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_thread && cp->gss_clnt_thread != current_thread()) {
cp->gss_clnt_flags |= GSS_NEEDCTX;
- msleep(cp, cp->gss_clnt_mtx, slpflag | PDROP, "ctxwait", NULL);
+ 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;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_flags & GSS_CTX_COMPLETE) {
/*
* we allocate a new sequence number and allow this request
* 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)) {
+ 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)) {
cp->gss_clnt_flags |= GSS_NEEDSEQ;
- msleep(cp, cp->gss_clnt_mtx, slpflag | PDROP, "seqwin", NULL);
+ 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);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_flags & GSS_CTX_INVAL) {
/* Renewed while while we were waiting */
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
nfs_gss_clnt_ctx_unref(req);
goto retry;
}
}
seqnum = ++cp->gss_clnt_seqnum;
win_setbit(cp->gss_clnt_seqbits, seqnum % cp->gss_clnt_seqwin);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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);
}
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
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
*/
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:
/*
/* 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);
/* 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;
}
/*
struct nfs_gss_clnt_ctx *cp = req->r_gss_ctx;
struct nfsm_chain nmc_tmp;
struct gss_seq *gsp;
- uint32_t reslen, offset;
+ uint32_t reslen;
int error = 0;
mbuf_t results_mbuf, prev_mbuf, pad_mbuf;
- size_t ressize;
+ size_t ressize, offset;
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
* 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;
}
/*
* 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);
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
* - 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;
/* 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;
}
#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;
* - 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;
/* 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));
}
#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;
break;
}
nfsmout:
- return (error);
+ return error;
}
/*
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;
}
/*
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
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
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
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 {
/*
* The context is apparently established successfully
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
cp->gss_clnt_flags |= GSS_CTX_COMPLETE;
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
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;
* 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:
/*
*/
if (error == ENEEDAUTH) {
NFS_GSS_DBG("Returning ENEEDAUTH\n");
- return (error);
+ return error;
}
/*
* It will be removed when the reference count
* drops to zero.
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
- if (error)
+ lck_mtx_lock(&cp->gss_clnt_mtx);
+ if (error) {
cp->gss_clnt_flags |= GSS_CTX_INVAL;
+ }
/*
* Wake any threads waiting to use the context
cp->gss_clnt_flags &= ~GSS_NEEDCTX;
wakeup(cp);
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
NFS_GSS_DBG("Returning error = %d\n", error);
- return (error);
+ return error;
}
/*
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);
}
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
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
cp->gss_clnt_flags |= GSS_CTX_INVAL;
/*
cp->gss_clnt_flags &= ~GSS_NEEDCTX;
wakeup(cp);
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
return error;
}
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 */
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) {
*/
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;
}
/*
*/
static uint8_t *
-nfs_gss_clnt_svcname(struct nfsmount *nmp, gssd_nametype *nt, uint32_t *len)
+nfs_gss_clnt_svcname(struct nfsmount *nmp, gssd_nametype *nt, size_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;
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);
strlcat(svcname, server, *len);
NFS_GSS_DBG("nfs svcname = %s\n", svcname);
- return ((uint8_t *)svcname);
+ return (uint8_t *)svcname;
}
/*
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);
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.
*/
*%%% 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);
}
}
mach_msg_type_number_t otokenlen;
int error = 0;
uint8_t *principal = NULL;
- uint32_t plen = 0;
+ size_t plen = 0;
int32_t nt = GSSD_STRING_NAME;
vm_map_copy_t pname = NULL;
vm_map_copy_t svcname = NULL;
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;
}
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;
*/
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]);
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;
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;
&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,
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;
}
}
if (cp->gss_clnt_display == NULL && *display_name != '\0') {
- int dlen = strnlen(display_name, MAX_DISPLAY_STR) + 1; /* Add extra byte to include '\0' */
+ size_t dlen = strnlen(display_name, MAX_DISPLAY_STR) + 1; /* Add extra byte to include '\0' */
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;
}
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");
}
/* 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;
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;
}
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 */
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;
}
/*
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.
* We do this even if the request timed out.
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
+ 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
cp->gss_clnt_flags &= ~GSS_NEEDSEQ;
wakeup(cp);
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
}
/*
{
req->r_gss_ctx = cp;
- lck_mtx_lock(cp->gss_clnt_mtx);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
cp->gss_clnt_refcnt++;
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
}
/*
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)
+ lck_mtx_lock(&cp->gss_clnt_mtx);
+ 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) &&
}
if (cp->gss_clnt_flags & GSS_CTX_DESTROY) {
destroy = 1;
- if (cp->gss_clnt_flags & GSS_CTX_STICKY)
- nfs_gss_clnt_mnt_rele(nmp);
- if (cp->gss_clnt_nctime)
+ if ((cp->gss_clnt_flags & GSS_CTX_USECOUNT) && !nfs_gss_clnt_mnt_rele(nmp)) {
+ cp->gss_clnt_flags &= ~GSS_CTX_USECOUNT;
+ }
+ if (cp->gss_clnt_nctime) {
on_neg_cache = 1;
+ }
}
}
if (!destroy && cp->gss_clnt_nctime == 0 &&
cp->gss_clnt_nctime = now.tv_sec;
neg_cache = 1;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
if (destroy) {
NFS_GSS_DBG("Destroying context %s\n", NFS_GSS_CTX(req, cp));
if (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);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_refcnt == 0) {
cp->gss_clnt_flags |= GSS_CTX_DESTROY;
destroy = 1;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
if (destroy) {
TAILQ_REMOVE(&nmp->nm_gsscl, cp, gss_clnt_entries);
nmp->nm_ncentries++;
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));
- dcp->gss_clnt_mtx = lck_mtx_alloc_init(nfs_gss_clnt_grp, LCK_ATTR_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));
+ lck_mtx_init(&dcp->gss_clnt_mtx, &nfs_gss_clnt_grp, LCK_ATTR_NULL);
dcp->gss_clnt_cred = scp->gss_clnt_cred;
kauth_cred_ref(dcp->gss_clnt_cred);
dcp->gss_clnt_prinlen = scp->gss_clnt_prinlen;
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);
}
*dcpp = dcp;
- return (0);
+ return 0;
}
/*
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;
- if (cp->gss_clnt_mtx) {
- 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))
+ lck_mtx_destroy(&cp->gss_clnt_mtx, &nfs_gss_clnt_grp);
+
+ 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) {
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);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_flags & GSS_CTX_INVAL) {
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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);
cp->gss_clnt_flags &= ~GSS_NEEDSEQ;
wakeup(cp);
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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);
/*
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;
}
struct nfs_gss_clnt_ctx *cp;
struct nfsm_chain nmreq, nmrep;
int error, status;
- struct nfsreq req;
- req.r_nmp = nmp;
+ struct nfsreq *req;
- if (!nmp)
+ if (!nmp) {
return;
+ }
-
+ req = zalloc(nfs_req_zone);
+ req->r_nmp = nmp;
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);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
if (cp->gss_clnt_flags & GSS_CTX_DESTROY) {
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
continue;
}
cp->gss_clnt_refcnt++;
- lck_mtx_unlock(cp->gss_clnt_mtx);
- req.r_gss_ctx = cp;
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
+ req->r_gss_ctx = cp;
lck_mtx_unlock(&nmp->nm_lock);
/*
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);
}
* the reference to remove it if its
* refcount is zero.
*/
- lck_mtx_lock(cp->gss_clnt_mtx);
+ lck_mtx_lock(&cp->gss_clnt_mtx);
cp->gss_clnt_flags |= (GSS_CTX_INVAL | GSS_CTX_DESTROY);
- lck_mtx_unlock(cp->gss_clnt_mtx);
- nfs_gss_clnt_ctx_unref(&req);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
+ nfs_gss_clnt_ctx_unref(req);
lck_mtx_lock(&nmp->nm_lock);
}
lck_mtx_unlock(&nmp->nm_lock);
assert(TAILQ_EMPTY(&nmp->nm_gsscl));
+ NFS_ZFREE(nfs_req_zone, req);
}
int
nfs_gss_clnt_ctx_remove(struct nfsmount *nmp, kauth_cred_t cred)
{
- struct nfs_gss_clnt_ctx *cp;
- struct nfsreq req;
+ struct nfs_gss_clnt_ctx *cp, *tcp;
+ struct nfsreq *req;
- req.r_nmp = nmp;
+ req = zalloc(nfs_req_zone);
+ req->r_nmp = nmp;
NFS_GSS_DBG("Enter\n");
NFS_GSS_CLNT_CTX_DUMP(nmp);
lck_mtx_lock(&nmp->nm_lock);
- TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) {
- lck_mtx_lock(cp->gss_clnt_mtx);
+ TAILQ_FOREACH_SAFE(cp, &nmp->nm_gsscl, gss_clnt_entries, tcp) {
+ lck_mtx_lock(&cp->gss_clnt_mtx);
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);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ 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;
}
cp->gss_clnt_refcnt++;
cp->gss_clnt_flags |= (GSS_CTX_INVAL | GSS_CTX_DESTROY);
- lck_mtx_unlock(cp->gss_clnt_mtx);
- req.r_gss_ctx = cp;
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
+ req->r_gss_ctx = cp;
lck_mtx_unlock(&nmp->nm_lock);
/*
* Drop the reference to remove it if its
* 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);
- nfs_gss_clnt_ctx_unref(&req);
- return (0);
+ kauth_cred_getasid(cp->gss_clnt_cred),
+ kauth_cred_getuid(cp->gss_clnt_cred),
+ cp->gss_clnt_refcnt);
+ nfs_gss_clnt_ctx_unref(req);
+ NFS_ZFREE(nfs_req_zone, req);
+ return 0;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
}
lck_mtx_unlock(&nmp->nm_lock);
-
+
+ NFS_ZFREE(nfs_req_zone, req);
NFS_GSS_DBG("Returning ENOENT\n");
- return (ENOENT);
+ return ENOENT;
}
/*
*/
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, size_t princlen, uint32_t nametype)
{
- struct nfsreq req;
+ struct nfsreq *req;
int error;
NFS_GSS_DBG("Enter:\n");
- bzero(&req, sizeof(struct nfsreq));
- req.r_nmp = nmp;
- req.r_gss_ctx = NULL;
- req.r_auth = nmp->nm_auth;
- req.r_thread = vfs_context_thread(ctx);
- req.r_cred = vfs_context_ucred(ctx);
+ req = zalloc_flags(nfs_req_zone, Z_WAITOK | Z_ZERO);
+ req->r_nmp = nmp;
+ req->r_auth = nmp->nm_auth;
+ req->r_thread = vfs_context_thread(ctx);
+ req->r_cred = vfs_context_ucred(ctx);
- error = nfs_gss_clnt_ctx_find_principal(&req, principal, princlen, nametype);
+ error = nfs_gss_clnt_ctx_find_principal(req, principal, princlen, nametype);
NFS_GSS_DBG("nfs_gss_clnt_ctx_find_principal returned %d\n", error);
/*
* We don't care about auth errors. Those would indicate that the context is in the
* 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);
+ nfs_gss_clnt_ctx_unref(req);
+ NFS_ZFREE(nfs_req_zone, req);
+ return error;
}
/*
*/
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;
+ struct nfsreq *req;
int error = 0;
struct nfs_gss_clnt_ctx *cp;
kauth_cred_t cred = vfs_context_ucred(ctx);
p->princlen = 0;
p->flags = 0;
- req.r_nmp = nmp;
+ req = zalloc_flags(nfs_req_zone, Z_WAITOK);
+ req->r_nmp = nmp;
lck_mtx_lock(&nmp->nm_lock);
TAILQ_FOREACH(cp, &nmp->nm_gsscl, gss_clnt_entries) {
- lck_mtx_lock(cp->gss_clnt_mtx);
+ 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);
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ NFS_GSS_CTX(req, cp),
+ cp->gss_clnt_refcnt);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
continue;
}
if (nfs_gss_clnt_ctx_cred_match(cp->gss_clnt_cred, cred)) {
cp->gss_clnt_refcnt++;
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
goto out;
}
- lck_mtx_unlock(cp->gss_clnt_mtx);
+ lck_mtx_unlock(&cp->gss_clnt_mtx);
}
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));
+ NFS_ZFREE(nfs_req_zone, req);
+ 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) {
lck_mtx_unlock(&nmp->nm_lock);
- 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);
+ req->r_gss_ctx = cp;
+ NFS_GSS_DBG("Found context %s\n", NFS_GSS_CTX(req, NULL));
+ nfs_gss_clnt_ctx_unref(req);
+ NFS_ZFREE(nfs_req_zone, req);
+ 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
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
*/
clock_interval_to_deadline(GSS_CTX_PEND, NSEC_PER_SEC, &timenow);
- lck_mtx_lock(nfs_gss_svc_ctx_mutex);
+ lck_mtx_lock(&nfs_gss_svc_ctx_mutex);
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;
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);
+ lck_mtx_unlock(&nfs_gss_svc_ctx_mutex);
- return (cp);
+ return cp;
}
/*
{
struct nfs_gss_svc_ctx_hashhead *head;
struct nfs_gss_svc_ctx *p;
-
- lck_mtx_lock(nfs_gss_svc_ctx_mutex);
+
+ lck_mtx_lock(&nfs_gss_svc_ctx_mutex);
/*
* Give the client a random handle so that if we reboot
*/
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++;
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);
+ lck_mtx_unlock(&nfs_gss_svc_ctx_mutex);
}
/*
int contexts = 0;
int i;
- lck_mtx_lock(nfs_gss_svc_ctx_mutex);
+ lck_mtx_lock(&nfs_gss_svc_ctx_mutex);
clock_get_uptime(&timenow);
NFS_GSS_DBG("is running\n");
*/
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);
+ }
+ lck_mtx_destroy(&cp->gss_svc_mtx, &nfs_gss_svc_grp);
FREE(cp, M_TEMP);
contexts--;
}
* 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);
+ lck_mtx_unlock(&nfs_gss_svc_ctx_mutex);
}
/*
uint32_t handle, handle_len;
uint32_t major;
struct nfs_gss_svc_ctx *cp = NULL;
- uint32_t flavor = 0, header_len;
+ uint32_t flavor = 0;
int error = 0;
- uint32_t arglen, start;
- size_t argsize;
+ uint32_t arglen;
+ size_t argsize, start, header_len;
gss_buffer_desc cksum;
struct nfsm_chain nmc_tmp;
mbuf_t reply_mbuf, prev_mbuf, pad_mbuf;
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
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) {
/*
/*
* 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;
}
- cp->gss_svc_mtx = lck_mtx_alloc_init(nfs_gss_svc_grp, LCK_ATTR_NULL);
+ lck_mtx_init(&cp->gss_svc_mtx, &nfs_gss_svc_grp, LCK_ATTR_NULL);
cp->gss_svc_refcnt = 1;
} else {
/*
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;
/*
* Sequence number is bad
*/
- error = EINVAL; // drop the request
+ error = EINVAL; // drop the request
goto nfsmout;
}
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);
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);
- temp_pcred.cr_ngroups = cp->gss_svc_ngroups;
+ sizeof(gid_t) * cp->gss_svc_ngroups);
+ temp_pcred.cr_ngroups = (short)cp->gss_svc_ngroups;
nd->nd_cr = posix_cred_create(&temp_pcred);
if (nd->nd_cr == NULL) {
* - 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;
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;
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);
*/
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;
* - 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;
/* 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) {
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;
*/
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);
+ lck_mtx_destroy(&cp->gss_svc_mtx, &nfs_gss_svc_grp);
FREE(cp, M_TEMP);
cp = NULL;
}
nd->nd_gss_context = cp;
return 0;
nfsmout:
- if (cp)
+ if (cp) {
nfs_gss_svc_ctx_deref(cp);
- return (error);
+ }
+ return error;
}
/*
*/
nfsm_chain_add_32(error, nmc, RPCAUTH_NULL);
nfsm_chain_add_32(error, nmc, 0);
- return (error);
+ return error;
}
/*
*/
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
nfsm_chain_add_opaque(error, nmc, cksum.value, cksum.length);
gss_release_buffer(NULL, &cksum);
- return (error);
+ return error;
}
/*
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:
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;
}
/*
* 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);
/* 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;
}
/*
switch (cp->gss_svc_proc) {
case RPCSEC_GSS_INIT:
nfs_gss_svc_ctx_insert(cp);
- /* FALLTHRU */
+ OS_FALLTHROUGH;
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;
error = nfs_gss_svc_gssd_upcall(cp);
if (error) {
autherr = RPCSEC_GSS_CREDPROBLEM;
- if (error == NFSERR_EAUTH)
+ if (error == NFSERR_EAUTH) {
error = 0;
+ }
break;
}
* 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.
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;
*/
cp = nfs_gss_svc_ctx_find(cp->gss_svc_handle);
if (cp != NULL) {
- cp->gss_svc_handle = 0; // so it can't be found
- lck_mtx_lock(cp->gss_svc_mtx);
+ 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);
- lck_mtx_unlock(cp->gss_svc_mtx);
+ &cp->gss_svc_incarnation);
+ lck_mtx_unlock(&cp->gss_svc_mtx);
}
break;
default:
/* 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);
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);
+ }
+ lck_mtx_destroy(&cp->gss_svc_mtx, &nfs_gss_svc_grp);
FREE(cp, M_TEMP);
}
nfsm_chain_cleanup(&nmrep);
*mrepp = NULL;
}
- return (error);
+ return error;
}
/*
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");
&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);
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");
}
/* 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;
}
/*
uint32_t win = cp->gss_svc_seqwin;
uint32_t i;
- lck_mtx_lock(cp->gss_svc_mtx);
+ lck_mtx_lock(&cp->gss_svc_mtx);
/*
* If greater than the window upper bound,
* 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);
+ lck_mtx_unlock(&cp->gss_svc_mtx);
+ return 1;
}
/*
* Invalid if below the lower bound of the window
*/
if (seq <= cp->gss_svc_seqmax - win) {
- lck_mtx_unlock(cp->gss_svc_mtx);
- return (0);
+ lck_mtx_unlock(&cp->gss_svc_mtx);
+ return 0;
}
/*
* In the window, invalid if the bit is already set
*/
if (win_getbit(bits, seq % win)) {
- lck_mtx_unlock(cp->gss_svc_mtx);
- return (0);
+ lck_mtx_unlock(&cp->gss_svc_mtx);
+ return 0;
}
win_setbit(bits, seq % win);
- lck_mtx_unlock(cp->gss_svc_mtx);
- return (1);
+ lck_mtx_unlock(&cp->gss_svc_mtx);
+ return 1;
}
/*
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);
}
/*
struct nfs_gss_svc_ctx_hashhead *head;
struct nfs_gss_svc_ctx *cp, *ncp;
int i;
-
- lck_mtx_lock(nfs_gss_svc_ctx_mutex);
+
+ lck_mtx_lock(&nfs_gss_svc_ctx_mutex);
/*
* Run through all the buckets
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);
+ }
+ lck_mtx_destroy(&cp->gss_svc_mtx, &nfs_gss_svc_grp);
FREE(cp, M_TEMP);
}
}
- lck_mtx_unlock(nfs_gss_svc_ctx_mutex);
+ lck_mtx_unlock(&nfs_gss_svc_ctx_mutex);
}
-#endif /* NFSSERVER */
+#endif /* CONFIG_NFS_SERVER */
/*************
/*
* 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 */
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);
}
/*
* complete.
*/
static void
-nfs_gss_mach_alloc_buffer(u_char *buf, uint32_t buflen, vm_map_copy_t *addr)
+nfs_gss_mach_alloc_buffer(u_char *buf, size_t buflen, vm_map_copy_t *addr)
{
kern_return_t kr;
vm_offset_t kmem_buf;
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");
}
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;
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;
}
/*
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;
}
/*
/* 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
*/
/* 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;
nmc->nmc_left = mbuf_trailingspace(tail);
nmc->nmc_flags = 0;
}
-
+#endif /* CONFIG_NFS_SERVER */
#if 0
{
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 */