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 ----