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,30 ****
* CDDL HEADER END
*/
/*
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
* 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 */
--- 19,30 ----
* 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 (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
*** 61,70 ****
--- 61,71 ----
#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,95 ****
--- 87,97 ----
#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,138 ****
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;
typedef struct logging_data {
char *ld_host;
char *ld_path;
char *ld_rpath;
int ld_status;
--- 129,147 ----
extern void nfscmd_func(void *, char *, size_t, door_desc_t *, uint_t);
thread_t nfsauth_thread;
thread_t cmd_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,170 ****
} logging_data;
static logging_data *logging_head = NULL;
static logging_data *logging_tail = NULL;
/*
* 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 */
/* ARGSUSED */
static void *
nfsauth_svc(void *arg)
{
- int doorfd = -1;
uint_t darg;
#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");
exit(10);
}
#ifdef DEBUG
/*
--- 151,340 ----
} 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)
{
uint_t darg;
+ uint_t flags = (DOOR_PRIVATE | DOOR_NO_CANCEL | DOOR_REFUSE_DESC);
#ifdef DEBUG
int dfd;
#endif
! /* 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,181 ****
* 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);
exit(11);
}
/*
* Clean up any stale namespace associations
--- 341,351 ----
* 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(auth_door);
exit(11);
}
/*
* Clean up any stale namespace associations
*** 183,208 ****
(void) fdetach(MOUNTD_DOOR);
/*
* Register in namespace to pass to the kernel to door_ki_open
*/
! if (fattach(doorfd, MOUNTD_DOOR) == -1) {
syslog(LOG_ERR, "Unable to fattach door: %m\n");
(void) close(dfd);
! (void) close(doorfd);
exit(12);
}
(void) close(dfd);
#endif
/*
* Must pass the doorfd down to the kernel.
*/
! darg = doorfd;
(void) _nfssys(MOUNTD_ARGS, &darg);
/*
* Wait for incoming calls
*/
/*CONSTCOND*/
for (;;)
(void) pause();
--- 353,385 ----
(void) fdetach(MOUNTD_DOOR);
/*
* Register in namespace to pass to the kernel to door_ki_open
*/
! if (fattach(auth_door, MOUNTD_DOOR) == -1) {
syslog(LOG_ERR, "Unable to fattach door: %m\n");
(void) close(dfd);
! (void) close(auth_door);
exit(12);
}
(void) close(dfd);
#endif
/*
* Must pass the doorfd down to the kernel.
*/
! 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,244 ****
/*
* 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;
! if ((doorfd = door_create(nfscmd_func, NULL,
! DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) {
syslog(LOG_ERR, "Unable to create cmd door: %m\n");
exit(10);
}
/*
! * Must pass the doorfd down to the kernel.
*/
! darg = doorfd;
(void) _nfssys(NFSCMD_ARGS, &darg);
/*
* Wait for incoming calls
*/
/*CONSTCOND*/
for (;;)
(void) pause();
--- 392,431 ----
/*
* 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)
{
uint_t darg;
+ uint_t flags = (DOOR_PRIVATE | DOOR_NO_CANCEL | DOOR_REFUSE_DESC);
! /* 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 cmd_door down to the kernel.
*/
! 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,258 ****
--- 436,447 ----
}
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,279 ****
--- 459,470 ----
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,303 ****
--- 485,496 ----
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,338 ****
--- 522,533 ----
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,519 ****
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) {
switch (c) {
case 'd':
debug++;
break;
case 'v':
--- 704,714 ----
if (ret != SA_OK) {
syslog(LOG_ERR, "Reading of mountd_port from SMF "
"failed, using default value");
}
! while ((c = getopt(argc, argv, "dvrm:p:A")) != EOF) {
switch (c) {
case 'd':
debug++;
break;
case 'v':
*** 529,538 ****
--- 724,735 ----
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,607 ****
--- 793,806 ----
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,648 ****
--- 838,848 ----
default:
/* daemon was already running */
exit(0);
}
+ if (mountd_bsm_audit)
audit_mountd_setup(); /* BSM */
/*
* Get required system variables
*/
*** 699,712 ****
/*
* 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)) {
fprintf(stderr, "unable to set max_threads\n");
exit(1);
}
if (mountd_port < 0 || mountd_port > UINT16_MAX) {
fprintf(stderr, "unable to use specified port\n");
exit(1);
}
--- 899,916 ----
/*
* If max_threads was specified, then set the
* maximum number of threads to the value specified.
*/
! 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,726 ****
--- 921,942 ----
*/
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,760 ****
* 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"));
exit(2);
}
/*
* Enumerate network transports and create service listeners
* as appropriate for each.
*/
--- 963,979 ----
* 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 (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,861 ****
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
--- 1069,1078 ----
*** 1076,1085 ****
--- 1293,1304 ----
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,1163 ****
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)
{
--- 1372,1381 ----
*** 1168,1182 ****
} else {
cln->netid = netid;
cln->nbuf = nbuf;
}
- cln->nconf = NULL;
cln->clnames = NULL;
- cln->host = NULL;
-
cln->flags = 0;
}
void
cln_init(struct cln *cln, SVCXPRT *transp)
{
--- 1386,1419 ----
} else {
cln->netid = netid;
cln->nbuf = nbuf;
}
cln->clnames = 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,1206 ****
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)
{
--- 1432,1441 ----
*** 1209,1291 ****
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)
(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
--- 1444,1469 ----
struct nd_hostservlist *
cln_getclientsnames(struct cln *cln)
{
if ((cln->flags & CLN_CLNAMES) == 0) {
! if (cln->nconf != NULL && cln->nbuf != NULL) {
(void) __netdir_getbyaddr_nosrv(cln->nconf,
&cln->clnames, cln->nbuf);
! }
cln->flags |= CLN_CLNAMES;
}
return (cln->clnames);
}
char *
cln_gethost(struct cln *cln)
{
if (cln_getclientsnames(cln) != NULL)
return (cln->clnames->h_hostservs[0].h_host);
return (cln->host);
}
/*
* Check mount requests, add to mounted list if ok
*** 1328,1348 ****
* 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;
}
- }
/*
* If the version being used is less than the minimum version,
* the filehandle translation should not be provided to the
* client.
--- 1506,1517 ----
* get the host name now in case we need to spit out an
* error message.
*/
if (verbose) {
DTRACE_PROBE(mountd, name_by_verbose);
! 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,1578 ****
audit_status = mountres3.fhs_status;
break;
}
! if (cln_havehost(&cln))
host = cln_gethost(&cln);
if (verbose)
! syslog(LOG_NOTICE, "MOUNT: %s %s %s",
! (host == NULL) ? "unknown host" : host,
error ? "denied" : "mounted", path);
/*
* 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);
- }
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 (path != NULL)
svc_freeargs(transp, xdr_dirpath, (caddr_t)&path);
if (sh)
sharefree(sh);
--- 1712,1747 ----
audit_status = mountres3.fhs_status;
break;
}
! if (host == NULL)
host = cln_gethost(&cln);
if (verbose)
! 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) {
DTRACE_PROBE(mountd, logged_in_thread);
audit_mountd_mount(host, path, audit_status); /* BSM */
}
+ }
+ 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,1982 ****
--- 2142,2158 ----
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,3244 ****
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);
audit_mountd_umount(host, path);
remove_path = rpath; /* assume we will use the cannonical path */
if (realpath(path, rpath) == NULL) {
if (verbose)
--- 3399,3413 ----
errno = 0;
if (!svc_sendreply(transp, xdr_void, (char *)NULL))
log_cant_reply_cln(&cln);
host = cln_gethost(&cln);
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,3290 ****
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);
--- 3446,3455 ----