Print this page
NEX-6532 allow specifying individual IP addresses without @ prefix in NFS access lists
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Alex Deiter <alex.deiter@nexenta.com>
NEX-6673 possible NULL pointer dereference in mountd`mount
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Alex Deiter <alex.deiter@nexenta.com>
NEX-4116 mountd: The IP to name translation is usually not needed in nfsauth_access()
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-4603 mountd: Compile warnings cleanup
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-2614 Add non-interactive mode for ypinit
NEX-2394 mountd() door services are sub-optimal in large... (redux)
NEX-1974 Support for more than 16 groups with AUTH_SYS
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-2394 mountd() door services are sub-optimal in large scale deployments
NEX-2526 mountd consumes an inordinate amount of memory
NEX-2502 4.0.3 RC4 Unable to mount NFS shares
Revert "NEX-2394 mountd() door services are sub-optimal in large scale deployments".
This reverts commit c6e1673e3a4b8ba866c77dee7b8f03f858be07d6.
The fix for NEX-2394 worked fine when putting the mountd binary in 4.0.2,
but needs additional work in a 4.0.3 environment
NEX-2394 mountd() door services are sub-optimal in large scale deployments
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Ryuji Masuda <ryuji.masuda@nexenta.com>
Reviewed by: Kirill Davydychev <kirill.davydychev@nexenta.com>
NEX-1128 NFS server: Generic uid and gid remapping for AUTH_SYS
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
OS-141 mountd(1m) needs to be able to set listen backlog
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
OS-134 mountd(1m): Remove limit of FDs in RPC server
Reviewed by: Michael Tsymbalyuk <michael.tsymbalyuk@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
OS-133 mountd: Busy do_logging_queue() eats memory
Reviewed by: Michael Tsymbalyuk <michael.tsymbalyuk@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
OS-131 mountd(1m) leaks nd_hostservlist in do_logging_queue()
Reviewed by: Ilya Usvyatsky <ilya.usvyatsky@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
@@ -19,12 +19,12 @@
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2016 Nexenta Systems, Inc.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
@@ -61,10 +61,11 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <thread.h>
+#include <pthread.h>
#include <assert.h>
#include <priv_utils.h>
#include <nfs/auth.h>
#include <nfs/nfssys.h>
#include <nfs/nfs.h>
@@ -86,10 +87,11 @@
#include <attr.h>
#include "smfcfg.h"
#include <pwd.h>
#include <grp.h>
#include <alloca.h>
+#include <atomic.h>
extern int daemonize_init(void);
extern void daemonize_fini(int);
extern int _nfssys(int, void *);
@@ -127,12 +129,19 @@
extern void nfscmd_func(void *, char *, size_t, door_desc_t *, uint_t);
thread_t nfsauth_thread;
thread_t cmd_thread;
-thread_t logging_thread;
+/*
+ * The following logging and BSM related data structs
+ * are only used when mountd_bsm_audit is TRUE; this
+ * is done by specifying the undocumented -A flag to
+ * mountd(1m).
+ */
+static bool_t mountd_bsm_audit = FALSE;
+
typedef struct logging_data {
char *ld_host;
char *ld_path;
char *ld_rpath;
int ld_status;
@@ -142,29 +151,190 @@
} logging_data;
static logging_data *logging_head = NULL;
static logging_data *logging_tail = NULL;
+#define MOUNTD_STKSZ (16 * 1024) /* 16KB Stacks */
+static uint32_t nm_thrds = 0;
+static uint32_t mx_thrds = 2; /* fallback default: see main() */
+
+static thread_key_t door_key;
+static mutex_t door_lock;
+static int cmd_door = -1;
+static cond_t cdoor_cv;
+static int auth_door = -1;
+static cond_t adoor_cv;
+
+typedef enum {
+ UNKNOWN_FUNC = 0,
+ NFSAUTH_FUNC = 1,
+ NFSCMD_FUNC = 2
+} dr_cmd_t;
+
/*
* Our copy of some system variables obtained using sysconf(3c)
*/
static long ngroups_max; /* _SC_NGROUPS_MAX */
static long pw_size; /* _SC_GETPW_R_SIZE_MAX */
+static char *
+cmd2str(dr_cmd_t t)
+{
+ switch (t) {
+ case NFSAUTH_FUNC:
+ return ("NFSAUTH_FUNC");
+
+ case NFSCMD_FUNC:
+ return ("NFSCMD_FUNC");
+
+ case UNKNOWN_FUNC:
+ default:
+ return ("UNKNOWN_FUNC");
+ }
+}
+
+void *
+mntd_thr_start(void *arg)
+{
+ dr_cmd_t *cp = (dr_cmd_t *)arg;
+ dr_cmd_t cmd = *cp;
+ static void *value;
+ int dfd = 0;
+
+ value = (nm_thrds >= mx_thrds) ? (void *)1 : (void *)0;
+ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+ (void) thr_setspecific(door_key, value);
+
+ switch (cmd) {
+ case NFSAUTH_FUNC:
+ (void) mutex_lock(&door_lock);
+ while (auth_door == -1)
+ cond_wait(&adoor_cv, &door_lock);
+ dfd = auth_door;
+ (void) mutex_unlock(&door_lock);
+ break;
+
+ case NFSCMD_FUNC:
+ (void) mutex_lock(&door_lock);
+ while (cmd_door == -1)
+ cond_wait(&cdoor_cv, &door_lock);
+ dfd = cmd_door;
+ (void) mutex_unlock(&door_lock);
+ break;
+
+ default:
+ syslog(LOG_NOTICE, "mntd_thr_start: %s", cmd2str(cmd));
+ free(cp);
+ thr_exit(NULL);
+ }
+
+ if (door_bind(dfd) < 0) {
+ syslog(LOG_ERR, "Unable to bind door for %s: %m", cmd2str(cmd));
+ exit(20);
+ }
+#ifdef DEBUG
+ syslog(LOG_NOTICE, "%s Door Bound Successfully", cmd2str(cmd));
+#endif
+ free(cp);
+ door_return(NULL, 0, NULL, 0);
+
+ /* NOTREACHED */
+ return (NULL);
+}
+
+/*
+ * Manages stacksize and threadpool
+ */
+static void
+mntd_thr_create(door_info_t *dp)
+{
+ thread_t tid;
+ int num = 0;
+ int rc = 0;
+ size_t stksz = MOUNTD_STKSZ;
+ long flags = THR_DETACHED;
+ void *proc;
+ dr_cmd_t *cp;
+#ifdef DEBUG
+ char func[1024] = {0};
+#endif
+
+ if (dp == NULL) {
+ syslog(LOG_NOTICE, "mntd_thr_create: dp == NULL");
+ return;
+ }
+ proc = (void *)(uintptr_t)dp->di_proc;
+
+ if ((cp = (dr_cmd_t *)malloc(sizeof (dr_cmd_t))) == (dr_cmd_t *)NULL) {
+ syslog(LOG_ERR, "mntd_thr_create: %m");
+ return;
+ }
+
+#ifdef DEBUG
+ (void) addrtosymstr(proc, func, sizeof (func));
+ syslog(LOG_NOTICE, "mntd_thr_create: func = %s", func);
+#endif
+
+ if (proc == (void *)nfsauth_func)
+ *cp = NFSAUTH_FUNC;
+ else if (proc == (void *)nfscmd_func)
+ *cp = NFSCMD_FUNC;
+ else {
+ free(cp);
+ return;
+ }
+
+ if ((num = atomic_inc_32_nv(&nm_thrds)) > mx_thrds) {
+ atomic_dec_32(&nm_thrds);
+ num -= 1;
+#ifdef DEBUG
+ syslog(LOG_ERR,
+ "mntd_thr_create: %d threads already active", num);
+#endif
+ free(cp);
+ return;
+ }
+
+ rc = thr_create(NULL, stksz, mntd_thr_start, (void *)cp, flags, &tid);
+ if (rc != 0) {
+ atomic_dec_32(&nm_thrds);
+ syslog(LOG_ERR, "mntd_thr_create: %m");
+ free(cp);
+ return;
+ }
+#ifdef DEBUG
+ syslog(LOG_NOTICE,
+ "mntd_thr_create: tid %d created (nm_thrds = %d)", tid, nm_thrds);
+#endif
+}
+
+static void
+mntd_thr_destroy(void *arg)
+{
+ atomic_dec_32(&nm_thrds);
+#ifdef DEBUG
+ syslog(LOG_NOTICE, "mntd_thr_destroy: (nm_thrds = %d)", nm_thrds);
+#endif
+}
+
/* ARGSUSED */
static void *
nfsauth_svc(void *arg)
{
- int doorfd = -1;
uint_t darg;
+ uint_t flags = (DOOR_PRIVATE | DOOR_NO_CANCEL | DOOR_REFUSE_DESC);
#ifdef DEBUG
int dfd;
#endif
- if ((doorfd = door_create(nfsauth_func, NULL,
- DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
- syslog(LOG_ERR, "Unable to create door: %m\n");
+ /* register 'nfsauth_func' as the new door service */
+ (void) mutex_lock(&door_lock);
+ auth_door = door_create(nfsauth_func, NULL, flags);
+ (void) mutex_unlock(&door_lock);
+
+ if (auth_door < 0) {
+ syslog(LOG_ERR, "nfsauth_svc: %m");
exit(10);
}
#ifdef DEBUG
/*
@@ -171,11 +341,11 @@
* Create a file system path for the door
*/
if ((dfd = open(MOUNTD_DOOR, O_RDWR|O_CREAT|O_TRUNC,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
syslog(LOG_ERR, "Unable to open %s: %m\n", MOUNTD_DOOR);
- (void) close(doorfd);
+ (void) close(auth_door);
exit(11);
}
/*
* Clean up any stale namespace associations
@@ -183,26 +353,33 @@
(void) fdetach(MOUNTD_DOOR);
/*
* Register in namespace to pass to the kernel to door_ki_open
*/
- if (fattach(doorfd, MOUNTD_DOOR) == -1) {
+ if (fattach(auth_door, MOUNTD_DOOR) == -1) {
syslog(LOG_ERR, "Unable to fattach door: %m\n");
(void) close(dfd);
- (void) close(doorfd);
+ (void) close(auth_door);
exit(12);
}
(void) close(dfd);
#endif
/*
* Must pass the doorfd down to the kernel.
*/
- darg = doorfd;
+ darg = auth_door;
(void) _nfssys(MOUNTD_ARGS, &darg);
/*
+ * Signal thread that kernel has door descriptor
+ */
+ (void) mutex_lock(&door_lock);
+ cond_signal(&adoor_cv);
+ (void) mutex_unlock(&door_lock);
+
+ /*
* Wait for incoming calls
*/
/*CONSTCOND*/
for (;;)
(void) pause();
@@ -215,30 +392,40 @@
/*
* NFS command service thread code for setup and handling of the
* nfs_cmd requests for character set conversion and other future
* events.
*/
-
static void *
cmd_svc(void *arg)
{
- int doorfd = -1;
uint_t darg;
+ uint_t flags = (DOOR_PRIVATE | DOOR_NO_CANCEL | DOOR_REFUSE_DESC);
- if ((doorfd = door_create(nfscmd_func, NULL,
- DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
+ /* register 'nfscmd_func' as the new door service */
+ (void) mutex_lock(&door_lock);
+ cmd_door = door_create(nfscmd_func, NULL, flags);
+ (void) mutex_unlock(&door_lock);
+
+ if (cmd_door < 0) {
syslog(LOG_ERR, "Unable to create cmd door: %m\n");
exit(10);
}
/*
- * Must pass the doorfd down to the kernel.
+ * Must pass the cmd_door down to the kernel.
*/
- darg = doorfd;
+ darg = cmd_door;
(void) _nfssys(NFSCMD_ARGS, &darg);
/*
+ * Signal thread that kernel has door descriptor
+ */
+ (void) mutex_lock(&door_lock);
+ cond_signal(&cdoor_cv);
+ (void) mutex_unlock(&door_lock);
+
+ /*
* Wait for incoming calls
*/
/*CONSTCOND*/
for (;;)
(void) pause();
@@ -249,10 +436,12 @@
}
static void
free_logging_data(logging_data *lq)
{
+ assert(mountd_bsm_audit == TRUE);
+
if (lq != NULL) {
free(lq->ld_host);
free(lq->ld_netid);
if (lq->ld_nb != NULL) {
@@ -270,10 +459,12 @@
static logging_data *
remove_head_of_queue(void)
{
logging_data *lq;
+ assert(mountd_bsm_audit == TRUE);
+
/*
* Pull it off the queue.
*/
lq = logging_head;
if (lq) {
@@ -294,10 +485,12 @@
do_logging_queue(logging_data *lq)
{
int cleared = 0;
char *host;
+ assert(mountd_bsm_audit == TRUE);
+
while (lq) {
struct cln cln;
if (lq->ld_host == NULL) {
DTRACE_PROBE(mountd, name_by_lazy);
@@ -329,10 +522,12 @@
static void *
logging_svc(void *arg)
{
logging_data *lq;
+ assert(mountd_bsm_audit == TRUE);
+
for (;;) {
(void) mutex_lock(&logging_queue_lock);
while (logging_head == NULL) {
(void) cond_wait(&logging_queue_cv,
&logging_queue_lock);
@@ -509,11 +704,11 @@
if (ret != SA_OK) {
syslog(LOG_ERR, "Reading of mountd_port from SMF "
"failed, using default value");
}
- while ((c = getopt(argc, argv, "dvrm:p:")) != EOF) {
+ while ((c = getopt(argc, argv, "dvrm:p:A")) != EOF) {
switch (c) {
case 'd':
debug++;
break;
case 'v':
@@ -529,10 +724,12 @@
argv[0]);
break;
}
max_threads = tmp;
break;
+ case 'A':
+ mountd_bsm_audit = TRUE;
case 'p':
if (convert_int(&tmp, optarg) != 0 || tmp < 1 ||
tmp > UINT16_MAX) {
(void) fprintf(stderr, "%s: invalid port "
"number\n", argv[0]);
@@ -596,12 +793,14 @@
mount_vers_max = mount_vers_min;
}
(void) setlocale(LC_ALL, "");
(void) rwlock_init(&sharetab_lock, USYNC_THREAD, NULL);
(void) mutex_init(&mnttab_lock, USYNC_THREAD, NULL);
+ if (mountd_bsm_audit) {
(void) mutex_init(&logging_queue_lock, USYNC_THREAD, NULL);
(void) cond_init(&logging_queue_cv, USYNC_THREAD, NULL);
+ }
netgroup_init();
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
@@ -639,10 +838,11 @@
default:
/* daemon was already running */
exit(0);
}
+ if (mountd_bsm_audit)
audit_mountd_setup(); /* BSM */
/*
* Get required system variables
*/
@@ -699,14 +899,18 @@
/*
* If max_threads was specified, then set the
* maximum number of threads to the value specified.
*/
- if (max_threads > 0 && !rpc_control(RPC_SVC_THRMAX_SET, &max_threads)) {
+ if (max_threads > 0) {
+ if (!rpc_control(RPC_SVC_THRMAX_SET, &max_threads)) {
fprintf(stderr, "unable to set max_threads\n");
exit(1);
}
+ /* Default to one fourth of all threads */
+ mx_thrds = (uint32_t)(max_threads / 4);
+ }
if (mountd_port < 0 || mountd_port > UINT16_MAX) {
fprintf(stderr, "unable to use specified port\n");
exit(1);
}
@@ -717,10 +921,22 @@
*/
svc_unreg(MOUNTPROG, MOUNTVERS);
svc_unreg(MOUNTPROG, MOUNTVERS_POSIX);
svc_unreg(MOUNTPROG, MOUNTVERS3);
+ (void) mutex_init(&door_lock, USYNC_THREAD, NULL);
+ (void) cond_init(&adoor_cv, USYNC_THREAD, NULL);
+ (void) cond_init(&cdoor_cv, USYNC_THREAD, NULL);
+
+ /* server function to create/optimize door threads */
+ (void) door_server_create(mntd_thr_create);
+ if (thr_keycreate(&door_key, mntd_thr_destroy) != 0) {
+ fprintf(stderr, "thr_keycreate (server thread): %s\n",
+ strerror(errno));
+ exit(3);
+ }
+
/*
* Create the nfsauth thread with same signal disposition
* as the main thread. We need to create a separate thread
* since mountd() will be both an RPC server (for remote
* traffic) _and_ a doors server (for kernel upcalls).
@@ -747,14 +963,17 @@
* audit_mountd_mount logging for mount requests. Use the same
* signal disposition as the main thread. We create
* a separate thread to allow the mount request threads to
* clear as soon as possible.
*/
- if (thr_create(NULL, 0, logging_svc, 0, thr_flags, &logging_thread)) {
- syslog(LOG_ERR, gettext("Failed to create LOGGING svc thread"));
+ if (mountd_bsm_audit) {
+ if (thr_create(NULL, 0, logging_svc, 0, thr_flags, NULL)) {
+ syslog(LOG_ERR,
+ gettext("Failed to create LOGGING svc thread"));
exit(2);
}
+ }
/*
* Enumerate network transports and create service listeners
* as appropriate for each.
*/
@@ -850,12 +1069,10 @@
char *host;
saverrno = errno; /* save error code */
host = cln_gethost(cln);
- if (host == NULL)
- return;
errno = saverrno;
if (errno == 0)
syslog(LOG_ERR, "couldn't send reply to %s", host);
else
@@ -1076,10 +1293,12 @@
char *rpath, int status, int error)
{
logging_data *lq;
struct netbuf *nb;
+ assert(mountd_bsm_audit == TRUE);
+
lq = (logging_data *)calloc(1, sizeof (logging_data));
if (lq == NULL)
goto cleanup;
/*
@@ -1153,11 +1372,10 @@
return (FALSE);
}
#define CLN_CLNAMES (1 << 0)
-#define CLN_HOST (1 << 1)
static void
cln_init_common(struct cln *cln, SVCXPRT *transp, char *netid,
struct netbuf *nbuf)
{
@@ -1168,15 +1386,34 @@
} else {
cln->netid = netid;
cln->nbuf = nbuf;
}
- cln->nconf = NULL;
cln->clnames = NULL;
- cln->host = NULL;
-
cln->flags = 0;
+
+ bzero(cln->host, sizeof (cln->host));
+
+ if (cln->netid != NULL && cln->nbuf != NULL &&
+ (cln->nconf = getnetconfigent(cln->netid)) != NULL) {
+ if (strcmp(cln->nconf->nc_protofmly, NC_INET) == 0) {
+ struct sockaddr_in *sa;
+ /* LINTED pointer alignment */
+ sa = (struct sockaddr_in *)(cln->nbuf->buf);
+ (void) inet_ntop(AF_INET, &sa->sin_addr.s_addr,
+ cln->host, sizeof (cln->host));
+ } else if (strcmp(cln->nconf->nc_protofmly, NC_INET6) == 0) {
+ struct sockaddr_in6 *sa;
+ /* LINTED pointer alignment */
+ sa = (struct sockaddr_in6 *)(cln->nbuf->buf);
+ (void) inet_ntop(AF_INET6, &sa->sin6_addr.s6_addr,
+ cln->host, sizeof (cln->host));
+ }
+ }
+
+ if (strlen(cln->host) == 0)
+ (void) strlcpy(cln->host, "(unknown)", sizeof (cln->host));
}
void
cln_init(struct cln *cln, SVCXPRT *transp)
{
@@ -1195,12 +1432,10 @@
if (cln->nconf != NULL)
freenetconfigent(cln->nconf);
if (cln->clnames != NULL)
netdir_free(cln->clnames, ND_HOSTSERVLIST);
-
- free(cln->host);
}
struct netbuf *
cln_getnbuf(struct cln *cln)
{
@@ -1209,83 +1444,26 @@
struct nd_hostservlist *
cln_getclientsnames(struct cln *cln)
{
if ((cln->flags & CLN_CLNAMES) == 0) {
- /*
- * nconf is not needed if we do not have nbuf (see
- * cln_gethost() too), so we check for nbuf and in a case it is
- * NULL we do not try to get nconf.
- */
- if (cln->netid != NULL && cln->nbuf != NULL) {
- cln->nconf = getnetconfigent(cln->netid);
- if (cln->nconf == NULL)
- syslog(LOG_ERR, "%s: getnetconfigent failed",
- cln->netid);
- }
-
- if (cln->nconf != NULL && cln->nbuf != NULL)
+ if (cln->nconf != NULL && cln->nbuf != NULL) {
(void) __netdir_getbyaddr_nosrv(cln->nconf,
&cln->clnames, cln->nbuf);
-
+ }
cln->flags |= CLN_CLNAMES;
}
return (cln->clnames);
}
-/*
- * Return B_TRUE if the host is already available at no cost
- */
-boolean_t
-cln_havehost(struct cln *cln)
-{
- return ((cln->flags & (CLN_CLNAMES | CLN_HOST)) != 0);
-}
-
char *
cln_gethost(struct cln *cln)
{
if (cln_getclientsnames(cln) != NULL)
return (cln->clnames->h_hostservs[0].h_host);
- if ((cln->flags & CLN_HOST) == 0) {
- if (cln->nconf == NULL || cln->nbuf == NULL) {
- cln->host = strdup("(anon)");
- } else {
- char host[MAXIPADDRLEN];
-
- if (strcmp(cln->nconf->nc_protofmly, NC_INET) == 0) {
- struct sockaddr_in *sa;
-
- /* LINTED pointer alignment */
- sa = (struct sockaddr_in *)(cln->nbuf->buf);
- (void) inet_ntoa_r(sa->sin_addr, host);
-
- cln->host = strdup(host);
- } else if (strcmp(cln->nconf->nc_protofmly,
- NC_INET6) == 0) {
- struct sockaddr_in6 *sa;
-
- /* LINTED pointer alignment */
- sa = (struct sockaddr_in6 *)(cln->nbuf->buf);
- (void) inet_ntop(AF_INET6,
- sa->sin6_addr.s6_addr,
- host, INET6_ADDRSTRLEN);
-
- cln->host = strdup(host);
- } else {
- syslog(LOG_ERR, gettext("Client's address is "
- "neither IPv4 nor IPv6"));
-
- cln->host = strdup("(anon)");
- }
- }
-
- cln->flags |= CLN_HOST;
- }
-
return (cln->host);
}
/*
* Check mount requests, add to mounted list if ok
@@ -1328,21 +1506,12 @@
* get the host name now in case we need to spit out an
* error message.
*/
if (verbose) {
DTRACE_PROBE(mountd, name_by_verbose);
- if ((host = cln_gethost(&cln)) == NULL) {
- /*
- * We failed to get a name for the client, even
- * 'anon', probably because we ran out of memory.
- * In this situation it doesn't make sense to
- * allow the mount to succeed.
- */
- error = EACCES;
- goto reply;
+ host = cln_gethost(&cln);
}
- }
/*
* If the version being used is less than the minimum version,
* the filehandle translation should not be provided to the
* client.
@@ -1543,36 +1712,36 @@
audit_status = mountres3.fhs_status;
break;
}
- if (cln_havehost(&cln))
+ if (host == NULL)
host = cln_gethost(&cln);
if (verbose)
- syslog(LOG_NOTICE, "MOUNT: %s %s %s",
- (host == NULL) ? "unknown host" : host,
+ syslog(LOG_NOTICE, "MOUNT: %s %s %s", host,
error ? "denied" : "mounted", path);
+ if (mountd_bsm_audit) {
/*
* If we can not create a queue entry, go ahead and do it
* in the context of this thread.
*/
enqueued = enqueue_logging_data(host, transp, path, rpath,
audit_status, error);
- if (enqueued == FALSE) {
- if (host == NULL) {
- DTRACE_PROBE(mountd, name_by_in_thread);
- host = cln_gethost(&cln);
- }
+ if (enqueued == FALSE) {
DTRACE_PROBE(mountd, logged_in_thread);
audit_mountd_mount(host, path, audit_status); /* BSM */
- if (!error)
- mntlist_new(host, rpath); /* add entry to mount list */
}
+ }
+ if (enqueued == FALSE && !error) {
+ /* Add entry to mount list */
+ mntlist_new(host, rpath);
+ }
+
if (path != NULL)
svc_freeargs(transp, xdr_dirpath, (caddr_t)&path);
if (sh)
sharefree(sh);
@@ -1973,10 +2142,17 @@
goto next;
}
/*
+ * Before doing clients names lookup, check if it's individual
+ * IP address specified without @ prefix.
+ */
+ if (strcmp(gr, cln->host) == 0)
+ return (response);
+
+ /*
* No other checks can be performed if client address
* can't be resolved.
*/
if ((clnames = cln_getclientsnames(cln)) == NULL)
goto next;
@@ -3223,22 +3399,15 @@
errno = 0;
if (!svc_sendreply(transp, xdr_void, (char *)NULL))
log_cant_reply_cln(&cln);
host = cln_gethost(&cln);
- if (host == NULL) {
- /*
- * Without the hostname we can't do audit or delete
- * this host from the mount entries.
- */
- svc_freeargs(transp, xdr_dirpath, (caddr_t)&path);
- return;
- }
if (verbose)
syslog(LOG_NOTICE, "UNMOUNT: %s unmounted %s", host, path);
+ if (mountd_bsm_audit)
audit_mountd_umount(host, path);
remove_path = rpath; /* assume we will use the cannonical path */
if (realpath(path, rpath) == NULL) {
if (verbose)
@@ -3277,14 +3446,10 @@
svcerr_systemerr(transp);
cln_init(&cln, transp);
host = cln_gethost(&cln);
- if (host == NULL) {
- /* Can't do anything without the name of the client */
- return;
- }
/*
* Remove all hosts entries from mount list
*/
mntlist_delete_all(host);