17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 27004388ebScasper #include <stdio_ext.h> 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <unistd.h> 307c478bd9Sstevel@tonic-gate #include <signal.h> 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <memory.h> 337c478bd9Sstevel@tonic-gate #include <stropts.h> 347c478bd9Sstevel@tonic-gate #include <netconfig.h> 357c478bd9Sstevel@tonic-gate #include <stdarg.h> 367c478bd9Sstevel@tonic-gate #include <sys/resource.h> 377c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 387c478bd9Sstevel@tonic-gate #include <syslog.h> 397c478bd9Sstevel@tonic-gate #include <errno.h> 407c478bd9Sstevel@tonic-gate #include <sys/sockio.h> 417c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 427c478bd9Sstevel@tonic-gate #include <net/if.h> 437c478bd9Sstevel@tonic-gate #include <netdir.h> 447c478bd9Sstevel@tonic-gate #include <string.h> 457c478bd9Sstevel@tonic-gate #include <thread.h> 467c478bd9Sstevel@tonic-gate #include <locale.h> 4739d3e169Sevanl #include <door.h> 48*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include <limits.h> 497c478bd9Sstevel@tonic-gate #include "automount.h" 507c478bd9Sstevel@tonic-gate #include <sys/vfs.h> 517c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 527c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 537c478bd9Sstevel@tonic-gate #include <rpcsvc/daemon_utils.h> 547c478bd9Sstevel@tonic-gate #include <deflt.h> 557c478bd9Sstevel@tonic-gate #include <strings.h> 5645916cd2Sjpk #include <priv.h> 5745916cd2Sjpk #include <tsol/label.h> 5839d3e169Sevanl #include <sys/utsname.h> 5939d3e169Sevanl #include <sys/thread.h> 6039d3e169Sevanl #include <nfs/rnode.h> 6139d3e169Sevanl #include <nfs/nfs.h> 628548bf79Snr123932 #include <wait.h> 63*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include <libshare.h> 64*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include <libscf.h> 65*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States #include "smfcfg.h" 667c478bd9Sstevel@tonic-gate 6739d3e169Sevanl static void autofs_doorfunc(void *, char *, size_t, door_desc_t *, uint_t); 6839d3e169Sevanl static void autofs_setdoor(int); 693bfb48feSsemery static void autofs_mntinfo_1_r(autofs_lookupargs *, autofs_mountres *); 707c478bd9Sstevel@tonic-gate static void autofs_mount_1_free_r(struct autofs_mountres *); 713bfb48feSsemery static void autofs_lookup_1_r(autofs_lookupargs *, autofs_lookupres *); 7239d3e169Sevanl static void autofs_lookup_1_free_args(autofs_lookupargs *); 733bfb48feSsemery static void autofs_unmount_1_r(umntrequest *, umntres *); 7439d3e169Sevanl static void autofs_unmount_1_free_args(umntrequest *); 753bfb48feSsemery static void autofs_readdir_1_r(autofs_rddirargs *, autofs_rddirres *); 767c478bd9Sstevel@tonic-gate static void autofs_readdir_1_free_r(struct autofs_rddirres *); 7739d3e169Sevanl static int decode_args(xdrproc_t, autofs_door_args_t *, caddr_t *, int); 7839d3e169Sevanl static bool_t encode_res(xdrproc_t, autofs_door_res_t **, caddr_t, int *); 797c478bd9Sstevel@tonic-gate static void usage(); 807c478bd9Sstevel@tonic-gate static void warn_hup(int); 817c478bd9Sstevel@tonic-gate static void free_action_list(); 8239d3e169Sevanl static int start_autofs_svcs(); 838548bf79Snr123932 static void automountd_wait_for_cleanup(pid_t); 847c478bd9Sstevel@tonic-gate 8539d3e169Sevanl /* 8639d3e169Sevanl * Private autofs system call 8739d3e169Sevanl */ 8839d3e169Sevanl extern int _autofssys(int, void *); 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate #define CTIME_BUF_LEN 26 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate #define RESOURCE_FACTOR 8 9339d3e169Sevanl #ifdef DEBUG 9439d3e169Sevanl #define AUTOFS_DOOR "/var/run/autofs_door" 9539d3e169Sevanl #endif /* DEBUG */ 9639d3e169Sevanl 9739d3e169Sevanl static thread_key_t s_thr_key; 987c478bd9Sstevel@tonic-gate 997c478bd9Sstevel@tonic-gate struct autodir *dir_head; 1007c478bd9Sstevel@tonic-gate struct autodir *dir_tail; 1017c478bd9Sstevel@tonic-gate char self[64]; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate time_t timenow; 1047c478bd9Sstevel@tonic-gate int verbose = 0; 1057c478bd9Sstevel@tonic-gate int trace = 0; 1067c478bd9Sstevel@tonic-gate int automountd_nobrowse = 0; 1077c478bd9Sstevel@tonic-gate 1087c478bd9Sstevel@tonic-gate int 1097c478bd9Sstevel@tonic-gate main(argc, argv) 1107c478bd9Sstevel@tonic-gate int argc; 1117c478bd9Sstevel@tonic-gate char *argv[]; 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate { 1147c478bd9Sstevel@tonic-gate pid_t pid; 11539d3e169Sevanl int c, error; 1167c478bd9Sstevel@tonic-gate struct rlimit rlset; 117*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States char defval[6]; 118*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States int ret = 0, bufsz; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate if (geteuid() != 0) { 1217c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s must be run as root\n", argv[0]); 1227c478bd9Sstevel@tonic-gate exit(1); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate /* 126*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States * Read in the values from SMF first before we check 1277c478bd9Sstevel@tonic-gate * commandline options so the options override the file. 1287c478bd9Sstevel@tonic-gate */ 129*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States bufsz = 6; 130*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States ret = autofs_smf_get_prop("automountd_verbose", defval, 131*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States DEFAULT_INSTANCE, SCF_TYPE_BOOLEAN, AUTOMOUNTD, &bufsz); 132*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States if (ret == SA_OK) { 1337c478bd9Sstevel@tonic-gate if (strncasecmp("true", defval, 4) == 0) 1347c478bd9Sstevel@tonic-gate verbose = TRUE; 1357c478bd9Sstevel@tonic-gate else 1367c478bd9Sstevel@tonic-gate verbose = FALSE; 1377c478bd9Sstevel@tonic-gate } 138*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States bufsz = 6; 139*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States ret = autofs_smf_get_prop("nobrowse", defval, DEFAULT_INSTANCE, 140*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States SCF_TYPE_BOOLEAN, AUTOMOUNTD, &bufsz); 141*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States if (ret == SA_OK) { 1427c478bd9Sstevel@tonic-gate if (strncasecmp("true", defval, 4) == 0) 1437c478bd9Sstevel@tonic-gate automountd_nobrowse = TRUE; 1447c478bd9Sstevel@tonic-gate else 1457c478bd9Sstevel@tonic-gate automountd_nobrowse = FALSE; 1467c478bd9Sstevel@tonic-gate } 147*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States bufsz = 6; 148*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States ret = autofs_smf_get_prop("trace", defval, DEFAULT_INSTANCE, 149*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States SCF_TYPE_INTEGER, AUTOMOUNTD, &bufsz); 150*dd51520eSPavan Mettu - Oracle Corporation - Menlo Park United States if (ret == SA_OK) { 1517c478bd9Sstevel@tonic-gate errno = 0; 1527c478bd9Sstevel@tonic-gate trace = strtol(defval, (char **)NULL, 10); 1537c478bd9Sstevel@tonic-gate if (errno != 0) 1547c478bd9Sstevel@tonic-gate trace = 0; 1557c478bd9Sstevel@tonic-gate } 1566012a713Spetede put_automountd_env(); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "vnTD:")) != EOF) { 1597c478bd9Sstevel@tonic-gate switch (c) { 1607c478bd9Sstevel@tonic-gate case 'v': 1617c478bd9Sstevel@tonic-gate verbose++; 1627c478bd9Sstevel@tonic-gate break; 1637c478bd9Sstevel@tonic-gate case 'n': 1647c478bd9Sstevel@tonic-gate automountd_nobrowse++; 1657c478bd9Sstevel@tonic-gate break; 1667c478bd9Sstevel@tonic-gate case 'T': 1677c478bd9Sstevel@tonic-gate trace++; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case 'D': 1707c478bd9Sstevel@tonic-gate (void) putenv(optarg); 1717c478bd9Sstevel@tonic-gate break; 1727c478bd9Sstevel@tonic-gate default: 1737c478bd9Sstevel@tonic-gate usage(); 1747c478bd9Sstevel@tonic-gate } 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if (sysinfo(SI_HOSTNAME, self, sizeof (self)) == -1) { 1787c478bd9Sstevel@tonic-gate error = errno; 17939d3e169Sevanl (void) fprintf(stderr, 1807c478bd9Sstevel@tonic-gate "automountd: can't determine hostname, error: %d\n", 1817c478bd9Sstevel@tonic-gate error); 1827c478bd9Sstevel@tonic-gate exit(1); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate #ifndef DEBUG 1867c478bd9Sstevel@tonic-gate pid = fork(); 1877c478bd9Sstevel@tonic-gate if (pid < 0) { 1887c478bd9Sstevel@tonic-gate perror("cannot fork"); 1897c478bd9Sstevel@tonic-gate exit(1); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate if (pid) 1927c478bd9Sstevel@tonic-gate exit(0); 1937c478bd9Sstevel@tonic-gate #endif 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate (void) setsid(); 1967c478bd9Sstevel@tonic-gate openlog("automountd", LOG_PID, LOG_DAEMON); 1977c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 1987c478bd9Sstevel@tonic-gate 1998548bf79Snr123932 /* 2008548bf79Snr123932 * Create the door_servers to manage fork/exec requests for 2018548bf79Snr123932 * mounts and executable automount maps 2028548bf79Snr123932 */ 2038548bf79Snr123932 if ((did_fork_exec = door_create(automountd_do_fork_exec, 2048548bf79Snr123932 NULL, NULL)) == -1) { 2058548bf79Snr123932 syslog(LOG_ERR, "door_create failed: %m, Exiting."); 2068548bf79Snr123932 exit(errno); 2078548bf79Snr123932 } 2088548bf79Snr123932 if ((did_exec_map = door_create(automountd_do_exec_map, 2098548bf79Snr123932 NULL, NULL)) == -1) { 2108548bf79Snr123932 syslog(LOG_ERR, "door_create failed: %m, Exiting."); 2118548bf79Snr123932 if (door_revoke(did_fork_exec) == -1) { 2128548bf79Snr123932 syslog(LOG_ERR, "failed to door_revoke(%d) %m", 2138548bf79Snr123932 did_fork_exec); 2148548bf79Snr123932 } 2158548bf79Snr123932 exit(errno); 2168548bf79Snr123932 } 2178548bf79Snr123932 /* 2188548bf79Snr123932 * Before we become multithreaded we fork allowing the parent 2198548bf79Snr123932 * to become a door server to handle all mount and unmount 2208548bf79Snr123932 * requests. This works around a potential hang in using 2218548bf79Snr123932 * fork1() within a multithreaded environment 2228548bf79Snr123932 */ 2238548bf79Snr123932 2248548bf79Snr123932 pid = fork1(); 2258548bf79Snr123932 if (pid < 0) { 2268548bf79Snr123932 syslog(LOG_ERR, 2278548bf79Snr123932 "can't fork the automountd mount process %m"); 2288548bf79Snr123932 if (door_revoke(did_fork_exec) == -1) { 2298548bf79Snr123932 syslog(LOG_ERR, "failed to door_revoke(%d) %m", 2308548bf79Snr123932 did_fork_exec); 2318548bf79Snr123932 } 2328548bf79Snr123932 if (door_revoke(did_exec_map) == -1) { 2338548bf79Snr123932 syslog(LOG_ERR, "failed to door_revoke(%d) %m", 2348548bf79Snr123932 did_exec_map); 2358548bf79Snr123932 } 2368548bf79Snr123932 exit(1); 2378548bf79Snr123932 } else if (pid > 0) { 2388548bf79Snr123932 /* this is the door server process */ 2398548bf79Snr123932 automountd_wait_for_cleanup(pid); 2408548bf79Snr123932 } 2418548bf79Snr123932 2428548bf79Snr123932 2437c478bd9Sstevel@tonic-gate (void) rwlock_init(&cache_lock, USYNC_THREAD, NULL); 24439d3e169Sevanl (void) rwlock_init(&autofs_rddir_cache_lock, USYNC_THREAD, NULL); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * initialize the name services, use NULL arguments to ensure 2487c478bd9Sstevel@tonic-gate * we don't initialize the stack of files used in file service 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate (void) ns_setup(NULL, NULL); 2517c478bd9Sstevel@tonic-gate 2527c478bd9Sstevel@tonic-gate /* 2538f379ff8Sevanl * we're using doors and its thread management now so we need to 2548f379ff8Sevanl * make sure we have more than the default of 256 file descriptors 2558f379ff8Sevanl * available. 2568f379ff8Sevanl */ 2578f379ff8Sevanl rlset.rlim_cur = RLIM_INFINITY; 2588f379ff8Sevanl rlset.rlim_max = RLIM_INFINITY; 2598f379ff8Sevanl if (setrlimit(RLIMIT_NOFILE, &rlset) == -1) 2608f379ff8Sevanl syslog(LOG_ERR, "setrlimit failed for %s: %s", AUTOMOUNTD, 2618f379ff8Sevanl strerror(errno)); 2628f379ff8Sevanl 2638f379ff8Sevanl (void) enable_extended_FILE_stdio(-1, -1); 2648f379ff8Sevanl 2658f379ff8Sevanl /* 2667c478bd9Sstevel@tonic-gate * establish our lock on the lock file and write our pid to it. 2677c478bd9Sstevel@tonic-gate * exit if some other process holds the lock, or if there's any 2687c478bd9Sstevel@tonic-gate * error in writing/locking the file. 2697c478bd9Sstevel@tonic-gate */ 2707c478bd9Sstevel@tonic-gate pid = _enter_daemon_lock(AUTOMOUNTD); 2717c478bd9Sstevel@tonic-gate switch (pid) { 2727c478bd9Sstevel@tonic-gate case 0: 2737c478bd9Sstevel@tonic-gate break; 2747c478bd9Sstevel@tonic-gate case -1: 2758548bf79Snr123932 syslog(LOG_ERR, "error locking for %s: %m", AUTOMOUNTD); 2767c478bd9Sstevel@tonic-gate exit(2); 2777c478bd9Sstevel@tonic-gate default: 2787c478bd9Sstevel@tonic-gate /* daemon was already running */ 2797c478bd9Sstevel@tonic-gate exit(0); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate 2827c478bd9Sstevel@tonic-gate /* 2837c478bd9Sstevel@tonic-gate * If we coredump it'll be /core. 2847c478bd9Sstevel@tonic-gate */ 2857c478bd9Sstevel@tonic-gate if (chdir("/") < 0) 2867c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "chdir /: %m"); 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate /* 2897c478bd9Sstevel@tonic-gate * Create cache_cleanup thread 2907c478bd9Sstevel@tonic-gate */ 2917c478bd9Sstevel@tonic-gate if (thr_create(NULL, 0, (void *(*)(void *))cache_cleanup, NULL, 2927c478bd9Sstevel@tonic-gate THR_DETACHED | THR_DAEMON | THR_NEW_LWP, NULL)) { 2937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "unable to create cache_cleanup thread"); 2947c478bd9Sstevel@tonic-gate exit(1); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* other initializations */ 2987c478bd9Sstevel@tonic-gate (void) rwlock_init(&portmap_cache_lock, USYNC_THREAD, NULL); 2997c478bd9Sstevel@tonic-gate 30092373f0aSrica /* 30192373f0aSrica * On a labeled system, allow read-down nfs mounts if privileged 30292373f0aSrica * (PRIV_NET_MAC_AWARE) to do so. Otherwise, ignore the error 30392373f0aSrica * and "mount equal label only" behavior will result. 30492373f0aSrica */ 30545916cd2Sjpk if (is_system_labeled()) { 30692373f0aSrica (void) setpflags(NET_MAC_AWARE, 1); 30792373f0aSrica (void) setpflags(NET_MAC_AWARE_INHERIT, 1); 30845916cd2Sjpk } 30945916cd2Sjpk 3107c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, warn_hup); 3117c478bd9Sstevel@tonic-gate 31239d3e169Sevanl /* start services */ 31339d3e169Sevanl return (start_autofs_svcs()); 31439d3e169Sevanl 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate /* 3187c478bd9Sstevel@tonic-gate * The old automounter supported a SIGHUP 3197c478bd9Sstevel@tonic-gate * to allow it to resynchronize internal 3207c478bd9Sstevel@tonic-gate * state with the /etc/mnttab. 3217c478bd9Sstevel@tonic-gate * This is no longer relevant, but we 3227c478bd9Sstevel@tonic-gate * need to catch the signal and warn 3237c478bd9Sstevel@tonic-gate * the user. 3247c478bd9Sstevel@tonic-gate */ 3257c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3267c478bd9Sstevel@tonic-gate static void 3277c478bd9Sstevel@tonic-gate warn_hup(i) 3287c478bd9Sstevel@tonic-gate int i; 3297c478bd9Sstevel@tonic-gate { 3307c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "SIGHUP received: ignored"); 3317c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, warn_hup); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate static void 3357c478bd9Sstevel@tonic-gate usage() 3367c478bd9Sstevel@tonic-gate { 3377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage: automountd\n" 3387c478bd9Sstevel@tonic-gate "\t[-T]\t\t(trace requests)\n" 3397c478bd9Sstevel@tonic-gate "\t[-v]\t\t(verbose error msgs)\n" 3407c478bd9Sstevel@tonic-gate "\t[-D n=s]\t(define env variable)\n"); 3417c478bd9Sstevel@tonic-gate exit(1); 3427c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate static void 34639d3e169Sevanl autofs_readdir_1_r( 34739d3e169Sevanl autofs_rddirargs *req, 3483bfb48feSsemery autofs_rddirres *res) 3497c478bd9Sstevel@tonic-gate { 3507c478bd9Sstevel@tonic-gate if (trace > 0) 3517c478bd9Sstevel@tonic-gate trace_prt(1, "READDIR REQUEST : %s @ %ld\n", 3527c478bd9Sstevel@tonic-gate req->rda_map, req->rda_offset); 3537c478bd9Sstevel@tonic-gate 3543bfb48feSsemery do_readdir(req, res); 3557c478bd9Sstevel@tonic-gate if (trace > 0) 356d6c8399bSrmesta trace_prt(1, "READDIR REPLY : status=%d\n", res->rd_status); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate static void 36039d3e169Sevanl autofs_readdir_1_free_r(struct autofs_rddirres *res) 3617c478bd9Sstevel@tonic-gate { 3627c478bd9Sstevel@tonic-gate if (res->rd_status == AUTOFS_OK) { 3637c478bd9Sstevel@tonic-gate if (res->rd_rddir.rddir_entries) 3647c478bd9Sstevel@tonic-gate free(res->rd_rddir.rddir_entries); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 36839d3e169Sevanl 3697c478bd9Sstevel@tonic-gate /* ARGSUSED */ 3707c478bd9Sstevel@tonic-gate static void 37139d3e169Sevanl autofs_unmount_1_r( 37239d3e169Sevanl umntrequest *m, 3733bfb48feSsemery umntres *res) 3747c478bd9Sstevel@tonic-gate { 3757c478bd9Sstevel@tonic-gate struct umntrequest *ul; 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate if (trace > 0) { 3787c478bd9Sstevel@tonic-gate char ctime_buf[CTIME_BUF_LEN]; 3797c478bd9Sstevel@tonic-gate if (ctime_r(&timenow, ctime_buf, CTIME_BUF_LEN) == NULL) 3807c478bd9Sstevel@tonic-gate ctime_buf[0] = '\0'; 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate trace_prt(1, "UNMOUNT REQUEST: %s", ctime_buf); 3837c478bd9Sstevel@tonic-gate for (ul = m; ul; ul = ul->next) 3847c478bd9Sstevel@tonic-gate trace_prt(1, " resource=%s fstype=%s mntpnt=%s" 3857c478bd9Sstevel@tonic-gate " mntopts=%s %s\n", 3867c478bd9Sstevel@tonic-gate ul->mntresource, 3877c478bd9Sstevel@tonic-gate ul->fstype, 3887c478bd9Sstevel@tonic-gate ul->mntpnt, 3897c478bd9Sstevel@tonic-gate ul->mntopts, 3907c478bd9Sstevel@tonic-gate ul->isdirect ? "direct" : "indirect"); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 39339d3e169Sevanl 3947c478bd9Sstevel@tonic-gate res->status = do_unmount1(m); 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate if (trace > 0) 3977c478bd9Sstevel@tonic-gate trace_prt(1, "UNMOUNT REPLY: status=%d\n", res->status); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate static void 40139d3e169Sevanl autofs_lookup_1_r( 40239d3e169Sevanl autofs_lookupargs *m, 4033bfb48feSsemery autofs_lookupres *res) 4047c478bd9Sstevel@tonic-gate { 40539d3e169Sevanl autofs_action_t action; 4067c478bd9Sstevel@tonic-gate struct linka link; 4077c478bd9Sstevel@tonic-gate int status; 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate if (trace > 0) { 4107c478bd9Sstevel@tonic-gate char ctime_buf[CTIME_BUF_LEN]; 4117c478bd9Sstevel@tonic-gate if (ctime_r(&timenow, ctime_buf, CTIME_BUF_LEN) == NULL) 4127c478bd9Sstevel@tonic-gate ctime_buf[0] = '\0'; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate trace_prt(1, "LOOKUP REQUEST: %s", ctime_buf); 4157c478bd9Sstevel@tonic-gate trace_prt(1, " name=%s[%s] map=%s opts=%s path=%s direct=%d\n", 416d6c8399bSrmesta m->name, m->subdir, m->map, m->opts, m->path, m->isdirect); 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate 41939d3e169Sevanl bzero(&link, sizeof (struct linka)); 42039d3e169Sevanl 4217c478bd9Sstevel@tonic-gate status = do_lookup1(m->map, m->name, m->subdir, m->opts, m->path, 4223bfb48feSsemery (uint_t)m->isdirect, m->uid, &action, &link); 4237c478bd9Sstevel@tonic-gate if (status == 0) { 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * Return action list to kernel. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate res->lu_res = AUTOFS_OK; 42839d3e169Sevanl if ((res->lu_type.action = action) == AUTOFS_LINK_RQ) { 4297c478bd9Sstevel@tonic-gate res->lu_type.lookup_result_type_u.lt_linka = link; 43039d3e169Sevanl } 4317c478bd9Sstevel@tonic-gate } else { 4327c478bd9Sstevel@tonic-gate /* 4337c478bd9Sstevel@tonic-gate * Entry not found 4347c478bd9Sstevel@tonic-gate */ 4357c478bd9Sstevel@tonic-gate res->lu_res = AUTOFS_NOENT; 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate res->lu_verbose = verbose; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate if (trace > 0) 4407c478bd9Sstevel@tonic-gate trace_prt(1, "LOOKUP REPLY : status=%d\n", res->lu_res); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate static void 44439d3e169Sevanl autofs_mntinfo_1_r( 44539d3e169Sevanl autofs_lookupargs *m, 4463bfb48feSsemery autofs_mountres *res) 4477c478bd9Sstevel@tonic-gate { 4487c478bd9Sstevel@tonic-gate int status; 4497c478bd9Sstevel@tonic-gate action_list *alp = NULL; 4507c478bd9Sstevel@tonic-gate 4517c478bd9Sstevel@tonic-gate if (trace > 0) { 4527c478bd9Sstevel@tonic-gate char ctime_buf[CTIME_BUF_LEN]; 4537c478bd9Sstevel@tonic-gate if (ctime_r(&timenow, ctime_buf, CTIME_BUF_LEN) == NULL) 4547c478bd9Sstevel@tonic-gate ctime_buf[0] = '\0'; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate trace_prt(1, "MOUNT REQUEST: %s", ctime_buf); 4577c478bd9Sstevel@tonic-gate trace_prt(1, " name=%s[%s] map=%s opts=%s path=%s direct=%d\n", 458d6c8399bSrmesta m->name, m->subdir, m->map, m->opts, m->path, m->isdirect); 4597c478bd9Sstevel@tonic-gate } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate status = do_mount1(m->map, m->name, m->subdir, m->opts, m->path, 4625e1e04ceSdm120769 (uint_t)m->isdirect, m->uid, &alp, DOMOUNT_USER); 4637c478bd9Sstevel@tonic-gate if (status != 0) { 4647c478bd9Sstevel@tonic-gate /* 4657c478bd9Sstevel@tonic-gate * An error occurred, free action list if allocated. 4667c478bd9Sstevel@tonic-gate */ 4677c478bd9Sstevel@tonic-gate if (alp != NULL) { 4687c478bd9Sstevel@tonic-gate free_action_list(alp); 4697c478bd9Sstevel@tonic-gate alp = NULL; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate } 4727c478bd9Sstevel@tonic-gate if (alp != NULL) { 4735e1e04ceSdm120769 /* 4745e1e04ceSdm120769 * Return action list to kernel. 4755e1e04ceSdm120769 */ 4767c478bd9Sstevel@tonic-gate res->mr_type.status = AUTOFS_ACTION; 4777c478bd9Sstevel@tonic-gate res->mr_type.mount_result_type_u.list = alp; 4787c478bd9Sstevel@tonic-gate } else { 4797c478bd9Sstevel@tonic-gate /* 4807c478bd9Sstevel@tonic-gate * No work to do left for the kernel 4817c478bd9Sstevel@tonic-gate */ 4827c478bd9Sstevel@tonic-gate res->mr_type.status = AUTOFS_DONE; 4837c478bd9Sstevel@tonic-gate res->mr_type.mount_result_type_u.error = status; 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate if (trace > 0) { 4877c478bd9Sstevel@tonic-gate switch (res->mr_type.status) { 4887c478bd9Sstevel@tonic-gate case AUTOFS_ACTION: 4897c478bd9Sstevel@tonic-gate trace_prt(1, 4907c478bd9Sstevel@tonic-gate "MOUNT REPLY : status=%d, AUTOFS_ACTION\n", 4917c478bd9Sstevel@tonic-gate status); 4927c478bd9Sstevel@tonic-gate break; 4937c478bd9Sstevel@tonic-gate case AUTOFS_DONE: 4947c478bd9Sstevel@tonic-gate trace_prt(1, 4957c478bd9Sstevel@tonic-gate "MOUNT REPLY : status=%d, AUTOFS_DONE\n", 4967c478bd9Sstevel@tonic-gate status); 4977c478bd9Sstevel@tonic-gate break; 4987c478bd9Sstevel@tonic-gate default: 4997c478bd9Sstevel@tonic-gate trace_prt(1, "MOUNT REPLY : status=%d, UNKNOWN\n", 5007c478bd9Sstevel@tonic-gate status); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate if (status && verbose) { 5057c478bd9Sstevel@tonic-gate if (m->isdirect) { 5067c478bd9Sstevel@tonic-gate /* direct mount */ 5077c478bd9Sstevel@tonic-gate syslog(LOG_ERR, "mount of %s failed", m->path); 5087c478bd9Sstevel@tonic-gate } else { 5097c478bd9Sstevel@tonic-gate /* indirect mount */ 5107c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 5117c478bd9Sstevel@tonic-gate "mount of %s/%s failed", m->path, m->name); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate } 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate static void 51739d3e169Sevanl autofs_mount_1_free_r(struct autofs_mountres *res) 5187c478bd9Sstevel@tonic-gate { 5197c478bd9Sstevel@tonic-gate if (res->mr_type.status == AUTOFS_ACTION) { 5207c478bd9Sstevel@tonic-gate if (trace > 2) 5217c478bd9Sstevel@tonic-gate trace_prt(1, "freeing action list\n"); 5227c478bd9Sstevel@tonic-gate free_action_list(res->mr_type.mount_result_type_u.list); 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate } 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate /* 527ace1a5f1Sdp * Used for reporting messages from code shared with automount command. 528ace1a5f1Sdp * Formats message into a buffer and calls syslog. 5297c478bd9Sstevel@tonic-gate * 530ace1a5f1Sdp * Print an error. Works like printf (fmt string and variable args) 531ace1a5f1Sdp * except that it will subsititute an error message for a "%m" string 532ace1a5f1Sdp * (like syslog). 5337c478bd9Sstevel@tonic-gate */ 5347c478bd9Sstevel@tonic-gate void 5357c478bd9Sstevel@tonic-gate pr_msg(const char *fmt, ...) 5367c478bd9Sstevel@tonic-gate { 5377c478bd9Sstevel@tonic-gate va_list ap; 5387c478bd9Sstevel@tonic-gate char fmtbuff[BUFSIZ], buff[BUFSIZ]; 5397c478bd9Sstevel@tonic-gate const char *p1; 5407c478bd9Sstevel@tonic-gate char *p2; 5417c478bd9Sstevel@tonic-gate 5427c478bd9Sstevel@tonic-gate p2 = fmtbuff; 5437c478bd9Sstevel@tonic-gate fmt = gettext(fmt); 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate for (p1 = fmt; *p1; p1++) { 5467c478bd9Sstevel@tonic-gate if (*p1 == '%' && *(p1 + 1) == 'm') { 547ace1a5f1Sdp (void) strcpy(p2, strerror(errno)); 5487c478bd9Sstevel@tonic-gate p2 += strlen(p2); 5497c478bd9Sstevel@tonic-gate p1++; 5507c478bd9Sstevel@tonic-gate } else { 5517c478bd9Sstevel@tonic-gate *p2++ = *p1; 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate if (p2 > fmtbuff && *(p2-1) != '\n') 5557c478bd9Sstevel@tonic-gate *p2++ = '\n'; 5567c478bd9Sstevel@tonic-gate *p2 = '\0'; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate va_start(ap, fmt); 5597c478bd9Sstevel@tonic-gate (void) vsprintf(buff, fmtbuff, ap); 5607c478bd9Sstevel@tonic-gate va_end(ap); 5617c478bd9Sstevel@tonic-gate syslog(LOG_ERR, buff); 5627c478bd9Sstevel@tonic-gate } 5637c478bd9Sstevel@tonic-gate 5647c478bd9Sstevel@tonic-gate static void 5657c478bd9Sstevel@tonic-gate free_action_list(action_list *alp) 5667c478bd9Sstevel@tonic-gate { 5677c478bd9Sstevel@tonic-gate action_list *p, *next = NULL; 5687c478bd9Sstevel@tonic-gate struct mounta *mp; 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate for (p = alp; p != NULL; p = next) { 5717c478bd9Sstevel@tonic-gate switch (p->action.action) { 5727c478bd9Sstevel@tonic-gate case AUTOFS_MOUNT_RQ: 5737c478bd9Sstevel@tonic-gate mp = &(p->action.action_list_entry_u.mounta); 5747c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */ 57539d3e169Sevanl if (mp->fstype) { 57639d3e169Sevanl if (strcmp(mp->fstype, "autofs") == 0) { 57739d3e169Sevanl free_autofs_args((autofs_args *) 57839d3e169Sevanl mp->dataptr); 579d6c8399bSrmesta } else if (strncmp(mp->fstype, "nfs", 3) == 0) { 58039d3e169Sevanl free_nfs_args((struct nfs_args *) 58139d3e169Sevanl mp->dataptr); 58239d3e169Sevanl } 58339d3e169Sevanl } 5847c478bd9Sstevel@tonic-gate mp->dataptr = NULL; 5857c478bd9Sstevel@tonic-gate mp->datalen = 0; 5867c478bd9Sstevel@tonic-gate free_mounta(mp); 5877c478bd9Sstevel@tonic-gate break; 5887c478bd9Sstevel@tonic-gate case AUTOFS_LINK_RQ: 5897c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 5907c478bd9Sstevel@tonic-gate "non AUTOFS_MOUNT_RQ requests not implemented\n"); 5917c478bd9Sstevel@tonic-gate break; 5927c478bd9Sstevel@tonic-gate default: 5937c478bd9Sstevel@tonic-gate syslog(LOG_ERR, 5947c478bd9Sstevel@tonic-gate "non AUTOFS_MOUNT_RQ requests not implemented\n"); 5957c478bd9Sstevel@tonic-gate break; 5967c478bd9Sstevel@tonic-gate } 5977c478bd9Sstevel@tonic-gate next = p->next; 5987c478bd9Sstevel@tonic-gate free(p); 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate } 60139d3e169Sevanl 60239d3e169Sevanl static void 60339d3e169Sevanl autofs_lookup_1_free_args(autofs_lookupargs *args) 60439d3e169Sevanl { 60539d3e169Sevanl if (args->map) 60639d3e169Sevanl free(args->map); 60739d3e169Sevanl if (args->path) 60839d3e169Sevanl free(args->path); 60939d3e169Sevanl if (args->name) 61039d3e169Sevanl free(args->name); 61139d3e169Sevanl if (args->subdir) 61239d3e169Sevanl free(args->subdir); 61339d3e169Sevanl if (args->opts) 61439d3e169Sevanl free(args->opts); 61539d3e169Sevanl } 61639d3e169Sevanl 61739d3e169Sevanl static void 61839d3e169Sevanl autofs_unmount_1_free_args(umntrequest *args) 61939d3e169Sevanl { 62039d3e169Sevanl if (args->mntresource) 62139d3e169Sevanl free(args->mntresource); 62239d3e169Sevanl if (args->mntpnt) 62339d3e169Sevanl free(args->mntpnt); 62439d3e169Sevanl if (args->fstype) 62539d3e169Sevanl free(args->fstype); 62639d3e169Sevanl if (args->mntopts) 62739d3e169Sevanl free(args->mntopts); 62839d3e169Sevanl if (args->next) 62939d3e169Sevanl autofs_unmount_1_free_args(args->next); 63039d3e169Sevanl } 63139d3e169Sevanl 63239d3e169Sevanl static void 63339d3e169Sevanl autofs_setdoor(int did) 63439d3e169Sevanl { 63539d3e169Sevanl 63639d3e169Sevanl if (did < 0) { 63739d3e169Sevanl did = 0; 63839d3e169Sevanl } 63939d3e169Sevanl 64039d3e169Sevanl (void) _autofssys(AUTOFS_SETDOOR, &did); 64139d3e169Sevanl } 64239d3e169Sevanl 64339d3e169Sevanl void * 64439d3e169Sevanl autofs_get_buffer(size_t size) 64539d3e169Sevanl { 64639d3e169Sevanl autofs_tsd_t *tsd = NULL; 64739d3e169Sevanl 64839d3e169Sevanl /* 64939d3e169Sevanl * Make sure the buffer size is aligned 65039d3e169Sevanl */ 65139d3e169Sevanl (void) thr_getspecific(s_thr_key, (void **)&tsd); 65239d3e169Sevanl if (tsd == NULL) { 65339d3e169Sevanl tsd = (autofs_tsd_t *)malloc(sizeof (autofs_tsd_t)); 65439d3e169Sevanl if (tsd == NULL) { 65539d3e169Sevanl return (NULL); 65639d3e169Sevanl } 65739d3e169Sevanl tsd->atsd_buf = malloc(size); 65839d3e169Sevanl if (tsd->atsd_buf != NULL) 65939d3e169Sevanl tsd->atsd_len = size; 66039d3e169Sevanl else 66139d3e169Sevanl tsd->atsd_len = 0; 66239d3e169Sevanl (void) thr_setspecific(s_thr_key, tsd); 66339d3e169Sevanl } else { 66439d3e169Sevanl if (tsd->atsd_buf && (tsd->atsd_len < size)) { 66539d3e169Sevanl free(tsd->atsd_buf); 66639d3e169Sevanl tsd->atsd_buf = malloc(size); 66739d3e169Sevanl if (tsd->atsd_buf != NULL) 66839d3e169Sevanl tsd->atsd_len = size; 66939d3e169Sevanl else { 67039d3e169Sevanl tsd->atsd_len = 0; 67139d3e169Sevanl } 67239d3e169Sevanl } 67339d3e169Sevanl } 67439d3e169Sevanl if (tsd->atsd_buf) { 67539d3e169Sevanl bzero(tsd->atsd_buf, size); 67639d3e169Sevanl return (tsd->atsd_buf); 67739d3e169Sevanl } else { 678d6c8399bSrmesta syslog(LOG_ERR, 679d6c8399bSrmesta gettext("Can't Allocate tsd buffer, size %d"), size); 68039d3e169Sevanl return (NULL); 68139d3e169Sevanl } 68239d3e169Sevanl } 68339d3e169Sevanl 68439d3e169Sevanl /* 68539d3e169Sevanl * Each request will automatically spawn a new thread with this 68639d3e169Sevanl * as its entry point. 68739d3e169Sevanl */ 68839d3e169Sevanl /* ARGUSED */ 68939d3e169Sevanl static void 69039d3e169Sevanl autofs_doorfunc( 69139d3e169Sevanl void *cookie, 69239d3e169Sevanl char *argp, 69339d3e169Sevanl size_t arg_size, 69439d3e169Sevanl door_desc_t *dp, 69539d3e169Sevanl uint_t n_desc) 69639d3e169Sevanl { 69739d3e169Sevanl char *res; 69839d3e169Sevanl int res_size; 699d6c8399bSrmesta int which; 700d6c8399bSrmesta int error = 0; 701d6c8399bSrmesta int srsz = 0; 70239d3e169Sevanl autofs_lookupargs *xdrargs; 70339d3e169Sevanl autofs_lookupres lookup_res; 70439d3e169Sevanl autofs_rddirargs *rddir_args; 70539d3e169Sevanl autofs_rddirres rddir_res; 70639d3e169Sevanl autofs_mountres mount_res; 70739d3e169Sevanl umntrequest *umnt_args; 70839d3e169Sevanl umntres umount_res; 70939d3e169Sevanl autofs_door_res_t *door_res; 71039d3e169Sevanl autofs_door_res_t failed_res; 71139d3e169Sevanl 71239d3e169Sevanl if (arg_size < sizeof (autofs_door_args_t)) { 71339d3e169Sevanl failed_res.res_status = EINVAL; 71439d3e169Sevanl error = door_return((char *)&failed_res, 71539d3e169Sevanl sizeof (autofs_door_res_t), NULL, 0); 71639d3e169Sevanl /* 71739d3e169Sevanl * If we got here the door_return() failed. 71839d3e169Sevanl */ 719d6c8399bSrmesta syslog(LOG_ERR, "Bad argument, door_return failure %d", error); 72039d3e169Sevanl return; 72139d3e169Sevanl } 72239d3e169Sevanl 72339d3e169Sevanl timenow = time((time_t *)NULL); 72439d3e169Sevanl 72539d3e169Sevanl which = ((autofs_door_args_t *)argp)->cmd; 72639d3e169Sevanl switch (which) { 72739d3e169Sevanl case AUTOFS_LOOKUP: 72839d3e169Sevanl if (error = decode_args(xdr_autofs_lookupargs, 72939d3e169Sevanl (autofs_door_args_t *)argp, (caddr_t *)&xdrargs, 73039d3e169Sevanl sizeof (autofs_lookupargs))) { 731d6c8399bSrmesta syslog(LOG_ERR, 732d6c8399bSrmesta "error allocating lookup arguments buffer"); 73339d3e169Sevanl failed_res.res_status = error; 73439d3e169Sevanl failed_res.xdr_len = 0; 73539d3e169Sevanl res = (caddr_t)&failed_res; 7365e1e04ceSdm120769 res_size = 0; 73739d3e169Sevanl break; 73839d3e169Sevanl } 73939d3e169Sevanl bzero(&lookup_res, sizeof (autofs_lookupres)); 74039d3e169Sevanl 7413bfb48feSsemery autofs_lookup_1_r(xdrargs, &lookup_res); 74239d3e169Sevanl 74339d3e169Sevanl autofs_lookup_1_free_args(xdrargs); 74439d3e169Sevanl free(xdrargs); 7455e1e04ceSdm120769 74639d3e169Sevanl if (!encode_res(xdr_autofs_lookupres, &door_res, 74739d3e169Sevanl (caddr_t)&lookup_res, &res_size)) { 748d6c8399bSrmesta syslog(LOG_ERR, 749d6c8399bSrmesta "error allocating lookup results buffer"); 7505e1e04ceSdm120769 failed_res.res_status = EINVAL; 75139d3e169Sevanl failed_res.xdr_len = 0; 75239d3e169Sevanl res = (caddr_t)&failed_res; 75339d3e169Sevanl } else { 75439d3e169Sevanl door_res->res_status = 0; 75539d3e169Sevanl res = (caddr_t)door_res; 75639d3e169Sevanl } 75739d3e169Sevanl break; 75839d3e169Sevanl 75939d3e169Sevanl case AUTOFS_MNTINFO: 76039d3e169Sevanl if (error = decode_args(xdr_autofs_lookupargs, 76139d3e169Sevanl (autofs_door_args_t *)argp, (caddr_t *)&xdrargs, 76239d3e169Sevanl sizeof (autofs_lookupargs))) { 763d6c8399bSrmesta syslog(LOG_ERR, 764d6c8399bSrmesta "error allocating lookup arguments buffer"); 76539d3e169Sevanl failed_res.res_status = error; 76639d3e169Sevanl failed_res.xdr_len = 0; 76739d3e169Sevanl res = (caddr_t)&failed_res; 7685e1e04ceSdm120769 res_size = 0; 76939d3e169Sevanl break; 77039d3e169Sevanl } 77139d3e169Sevanl 7725e1e04ceSdm120769 autofs_mntinfo_1_r((autofs_lookupargs *)xdrargs, &mount_res); 77339d3e169Sevanl 77439d3e169Sevanl autofs_lookup_1_free_args(xdrargs); 77539d3e169Sevanl free(xdrargs); 77639d3e169Sevanl 77739d3e169Sevanl /* 77839d3e169Sevanl * Only reason we would get a NULL res is because 77939d3e169Sevanl * we could not allocate a results buffer. Use 7805e1e04ceSdm120769 * a local one to return the error EAGAIN as has 7815e1e04ceSdm120769 * always been done when memory allocations fail. 78239d3e169Sevanl */ 78339d3e169Sevanl if (!encode_res(xdr_autofs_mountres, &door_res, 78439d3e169Sevanl (caddr_t)&mount_res, &res_size)) { 785d6c8399bSrmesta syslog(LOG_ERR, 786d6c8399bSrmesta "error allocating mount results buffer"); 7875e1e04ceSdm120769 failed_res.res_status = EAGAIN; 78839d3e169Sevanl failed_res.xdr_len = 0; 78939d3e169Sevanl res = (caddr_t)&failed_res; 79039d3e169Sevanl } else { 79139d3e169Sevanl door_res->res_status = 0; 79239d3e169Sevanl res = (caddr_t)door_res; 79339d3e169Sevanl } 79439d3e169Sevanl autofs_mount_1_free_r(&mount_res); 79539d3e169Sevanl break; 79639d3e169Sevanl 79739d3e169Sevanl case AUTOFS_UNMOUNT: 79839d3e169Sevanl if (error = decode_args(xdr_umntrequest, 79939d3e169Sevanl (autofs_door_args_t *)argp, 80039d3e169Sevanl (caddr_t *)&umnt_args, sizeof (umntrequest))) { 801d6c8399bSrmesta syslog(LOG_ERR, 802d6c8399bSrmesta "error allocating unmount argument buffer"); 80339d3e169Sevanl failed_res.res_status = error; 80439d3e169Sevanl failed_res.xdr_len = 0; 80539d3e169Sevanl res = (caddr_t)&failed_res; 80639d3e169Sevanl res_size = sizeof (autofs_door_res_t); 80739d3e169Sevanl break; 80839d3e169Sevanl } 80939d3e169Sevanl 8103bfb48feSsemery autofs_unmount_1_r(umnt_args, &umount_res); 81139d3e169Sevanl 81239d3e169Sevanl error = umount_res.status; 81339d3e169Sevanl 81439d3e169Sevanl autofs_unmount_1_free_args(umnt_args); 81539d3e169Sevanl free(umnt_args); 8165e1e04ceSdm120769 81739d3e169Sevanl if (!encode_res(xdr_umntres, &door_res, (caddr_t)&umount_res, 81839d3e169Sevanl &res_size)) { 819d6c8399bSrmesta syslog(LOG_ERR, 820d6c8399bSrmesta "error allocating unmount results buffer"); 8215e1e04ceSdm120769 failed_res.res_status = EINVAL; 82239d3e169Sevanl failed_res.xdr_len = 0; 82339d3e169Sevanl res = (caddr_t)&failed_res; 8245e1e04ceSdm120769 res_size = sizeof (autofs_door_res_t); 82539d3e169Sevanl } else { 82639d3e169Sevanl door_res->res_status = 0; 82739d3e169Sevanl res = (caddr_t)door_res; 82839d3e169Sevanl } 82939d3e169Sevanl break; 83039d3e169Sevanl 83139d3e169Sevanl case AUTOFS_READDIR: 83239d3e169Sevanl if (error = decode_args(xdr_autofs_rddirargs, 83339d3e169Sevanl (autofs_door_args_t *)argp, 83439d3e169Sevanl (caddr_t *)&rddir_args, 83539d3e169Sevanl sizeof (autofs_rddirargs))) { 83639d3e169Sevanl syslog(LOG_ERR, 83739d3e169Sevanl "error allocating readdir argument buffer"); 83839d3e169Sevanl failed_res.res_status = error; 83939d3e169Sevanl failed_res.xdr_len = 0; 84039d3e169Sevanl res = (caddr_t)&failed_res; 84139d3e169Sevanl res_size = sizeof (autofs_door_res_t); 84239d3e169Sevanl break; 84339d3e169Sevanl } 84439d3e169Sevanl 8453bfb48feSsemery autofs_readdir_1_r(rddir_args, &rddir_res); 84639d3e169Sevanl 84739d3e169Sevanl free(rddir_args->rda_map); 84839d3e169Sevanl free(rddir_args); 8495e1e04ceSdm120769 85039d3e169Sevanl if (!encode_res(xdr_autofs_rddirres, &door_res, 85139d3e169Sevanl (caddr_t)&rddir_res, &res_size)) { 852d6c8399bSrmesta syslog(LOG_ERR, 853d6c8399bSrmesta "error allocating readdir results buffer"); 85439d3e169Sevanl failed_res.res_status = ENOMEM; 85539d3e169Sevanl failed_res.xdr_len = 0; 85639d3e169Sevanl res = (caddr_t)&failed_res; 8575e1e04ceSdm120769 res_size = sizeof (autofs_door_res_t); 85839d3e169Sevanl } else { 85939d3e169Sevanl door_res->res_status = 0; 86039d3e169Sevanl res = (caddr_t)door_res; 86139d3e169Sevanl } 86239d3e169Sevanl autofs_readdir_1_free_r(&rddir_res); 86339d3e169Sevanl break; 86439d3e169Sevanl #ifdef MALLOC_DEBUG 86539d3e169Sevanl case AUTOFS_DUMP_DEBUG: 86639d3e169Sevanl check_leaks("/var/tmp/automountd.leak"); 86739d3e169Sevanl error = door_return(NULL, 0, NULL, 0); 86839d3e169Sevanl /* 86939d3e169Sevanl * If we got here, door_return() failed 87039d3e169Sevanl */ 87139d3e169Sevanl syslog(LOG_ERR, "dump debug door_return failure %d", 87239d3e169Sevanl error); 87339d3e169Sevanl return; 87439d3e169Sevanl #endif 87539d3e169Sevanl case NULLPROC: 87639d3e169Sevanl res = NULL; 87739d3e169Sevanl res_size = 0; 87839d3e169Sevanl break; 87939d3e169Sevanl default: 88039d3e169Sevanl failed_res.res_status = EINVAL; 88139d3e169Sevanl res = (char *)&failed_res; 88239d3e169Sevanl res_size = sizeof (autofs_door_res_t); 88339d3e169Sevanl break; 88439d3e169Sevanl } 885d6c8399bSrmesta 886d6c8399bSrmesta srsz = res_size; 887d6c8399bSrmesta errno = 0; 88839d3e169Sevanl error = door_return(res, res_size, NULL, 0); 889d6c8399bSrmesta 890d6c8399bSrmesta if (errno == E2BIG) { 89139d3e169Sevanl /* 892d6c8399bSrmesta * Failed due to encoded results being bigger than the 893d6c8399bSrmesta * kernel expected bufsize. Passing actual results size 894d6c8399bSrmesta * back down to kernel. 89539d3e169Sevanl */ 896d6c8399bSrmesta failed_res.res_status = EOVERFLOW; 897d6c8399bSrmesta failed_res.xdr_len = srsz; 898d6c8399bSrmesta res = (caddr_t)&failed_res; 899d6c8399bSrmesta res_size = sizeof (autofs_door_res_t); 900d6c8399bSrmesta } else { 901d6c8399bSrmesta syslog(LOG_ERR, "door_return failed %d, buffer %p, " 902d6c8399bSrmesta "buffer size %d", error, (void *)res, res_size); 903d6c8399bSrmesta res = NULL; 904d6c8399bSrmesta res_size = 0; 905d6c8399bSrmesta } 906d6c8399bSrmesta (void) door_return(res, res_size, NULL, 0); 907d6c8399bSrmesta /* NOTREACHED */ 90839d3e169Sevanl } 90939d3e169Sevanl 91039d3e169Sevanl static int 91139d3e169Sevanl start_autofs_svcs(void) 91239d3e169Sevanl { 91339d3e169Sevanl int doorfd; 91439d3e169Sevanl #ifdef DEBUG 91539d3e169Sevanl int dfd; 91639d3e169Sevanl #endif 91739d3e169Sevanl 91839d3e169Sevanl if ((doorfd = door_create(autofs_doorfunc, NULL, 91939d3e169Sevanl DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) == -1) { 92039d3e169Sevanl syslog(LOG_ERR, gettext("Unable to create door\n")); 92139d3e169Sevanl return (1); 92239d3e169Sevanl } 92339d3e169Sevanl 92439d3e169Sevanl #ifdef DEBUG 92539d3e169Sevanl /* 92639d3e169Sevanl * Create a file system path for the door 92739d3e169Sevanl */ 92839d3e169Sevanl if ((dfd = open(AUTOFS_DOOR, O_RDWR|O_CREAT|O_TRUNC, 92939d3e169Sevanl S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) { 93039d3e169Sevanl syslog(LOG_ERR, "Unable to open %s: %m\n", AUTOFS_DOOR); 93139d3e169Sevanl (void) close(doorfd); 93239d3e169Sevanl return (1); 93339d3e169Sevanl } 93439d3e169Sevanl 93539d3e169Sevanl /* 93639d3e169Sevanl * stale associations clean up 93739d3e169Sevanl */ 93839d3e169Sevanl (void) fdetach(AUTOFS_DOOR); 93939d3e169Sevanl 94039d3e169Sevanl /* 94139d3e169Sevanl * Register in the namespace to the kernel to door_ki_open. 94239d3e169Sevanl */ 94339d3e169Sevanl if (fattach(doorfd, AUTOFS_DOOR) == -1) { 94439d3e169Sevanl syslog(LOG_ERR, "Unable to fattach door %m\n", AUTOFS_DOOR); 94539d3e169Sevanl (void) close(dfd); 94639d3e169Sevanl (void) close(doorfd); 94739d3e169Sevanl return (1); 94839d3e169Sevanl } 94939d3e169Sevanl #endif /* DEBUG */ 95039d3e169Sevanl 95139d3e169Sevanl /* 95239d3e169Sevanl * Pass door name to kernel for door_ki_open 95339d3e169Sevanl */ 95439d3e169Sevanl autofs_setdoor(doorfd); 95539d3e169Sevanl 95639d3e169Sevanl (void) thr_keycreate(&s_thr_key, NULL); 95739d3e169Sevanl 95839d3e169Sevanl /* 95939d3e169Sevanl * Wait for incoming calls 96039d3e169Sevanl */ 96139d3e169Sevanl /*CONSTCOND*/ 96239d3e169Sevanl while (1) 96339d3e169Sevanl (void) pause(); 96439d3e169Sevanl 96539d3e169Sevanl /* NOTREACHED */ 96639d3e169Sevanl syslog(LOG_ERR, gettext("Door server exited")); 96739d3e169Sevanl return (10); 96839d3e169Sevanl } 96939d3e169Sevanl 97039d3e169Sevanl static int 97139d3e169Sevanl decode_args( 97239d3e169Sevanl xdrproc_t xdrfunc, 97339d3e169Sevanl autofs_door_args_t *argp, 97439d3e169Sevanl caddr_t *xdrargs, 97539d3e169Sevanl int size) 97639d3e169Sevanl { 97739d3e169Sevanl XDR xdrs; 97839d3e169Sevanl 97939d3e169Sevanl caddr_t tmpargs = (caddr_t)&((autofs_door_args_t *)argp)->xdr_arg; 98039d3e169Sevanl size_t arg_size = ((autofs_door_args_t *)argp)->xdr_len; 98139d3e169Sevanl 98239d3e169Sevanl xdrmem_create(&xdrs, tmpargs, arg_size, XDR_DECODE); 98339d3e169Sevanl 98439d3e169Sevanl *xdrargs = malloc(size); 98539d3e169Sevanl if (*xdrargs == NULL) { 986d6c8399bSrmesta syslog(LOG_ERR, "error allocating arguments buffer"); 98739d3e169Sevanl return (ENOMEM); 98839d3e169Sevanl } 98939d3e169Sevanl 99039d3e169Sevanl bzero(*xdrargs, size); 99139d3e169Sevanl 99239d3e169Sevanl if (!(*xdrfunc)(&xdrs, *xdrargs)) { 99339d3e169Sevanl free(*xdrargs); 99439d3e169Sevanl *xdrargs = NULL; 99539d3e169Sevanl syslog(LOG_ERR, "error decoding arguments"); 99639d3e169Sevanl return (EINVAL); 99739d3e169Sevanl } 99839d3e169Sevanl 99939d3e169Sevanl return (0); 100039d3e169Sevanl } 100139d3e169Sevanl 100239d3e169Sevanl 100339d3e169Sevanl static bool_t 100439d3e169Sevanl encode_res( 100539d3e169Sevanl xdrproc_t xdrfunc, 100639d3e169Sevanl autofs_door_res_t **results, 100739d3e169Sevanl caddr_t resp, 100839d3e169Sevanl int *size) 100939d3e169Sevanl { 101039d3e169Sevanl XDR xdrs; 101139d3e169Sevanl 101239d3e169Sevanl *size = xdr_sizeof((*xdrfunc), resp); 101339d3e169Sevanl *results = autofs_get_buffer( 101439d3e169Sevanl sizeof (autofs_door_res_t) + *size); 101539d3e169Sevanl if (*results == NULL) { 10165e1e04ceSdm120769 (*results)->res_status = ENOMEM; 101739d3e169Sevanl return (FALSE); 101839d3e169Sevanl } 101939d3e169Sevanl (*results)->xdr_len = *size; 102039d3e169Sevanl *size = sizeof (autofs_door_res_t) + (*results)->xdr_len; 102139d3e169Sevanl xdrmem_create(&xdrs, (caddr_t)((*results)->xdr_res), 1022d6c8399bSrmesta (*results)->xdr_len, XDR_ENCODE); 10235e1e04ceSdm120769 if (!(*xdrfunc)(&xdrs, resp)) { 10245e1e04ceSdm120769 (*results)->res_status = EINVAL; 10255e1e04ceSdm120769 syslog(LOG_ERR, "error encoding results"); 102639d3e169Sevanl return (FALSE); 102739d3e169Sevanl } 102839d3e169Sevanl (*results)->res_status = 0; 102939d3e169Sevanl return (TRUE); 103039d3e169Sevanl } 10318548bf79Snr123932 10328548bf79Snr123932 static void 10338548bf79Snr123932 automountd_wait_for_cleanup(pid_t pid) 10348548bf79Snr123932 { 10358548bf79Snr123932 int status; 10368548bf79Snr123932 int child_exitval; 10378548bf79Snr123932 10388548bf79Snr123932 /* 10398548bf79Snr123932 * Wait for the main automountd process to exit so we cleanup 10408548bf79Snr123932 */ 10418548bf79Snr123932 (void) waitpid(pid, &status, 0); 10428548bf79Snr123932 10438548bf79Snr123932 child_exitval = WEXITSTATUS(status); 10448548bf79Snr123932 10458548bf79Snr123932 /* 10468548bf79Snr123932 * Shutdown the door server for mounting and unmounting 10478548bf79Snr123932 * filesystems 10488548bf79Snr123932 */ 10498548bf79Snr123932 if (door_revoke(did_fork_exec) == -1) { 1050d6c8399bSrmesta syslog(LOG_ERR, "failed to door_revoke(%d) %m", did_fork_exec); 10518548bf79Snr123932 } 10528548bf79Snr123932 if (door_revoke(did_exec_map) == -1) { 1053d6c8399bSrmesta syslog(LOG_ERR, "failed to door_revoke(%d) %m", did_exec_map); 10548548bf79Snr123932 } 10558548bf79Snr123932 exit(child_exitval); 10568548bf79Snr123932 } 1057