diff options
Diffstat (limited to 'contrib/amd/hlfsd')
-rw-r--r-- | contrib/amd/hlfsd/hlfsd.8 | 23 | ||||
-rw-r--r-- | contrib/amd/hlfsd/hlfsd.c | 186 | ||||
-rw-r--r-- | contrib/amd/hlfsd/hlfsd.h | 13 | ||||
-rw-r--r-- | contrib/amd/hlfsd/homedir.c | 121 | ||||
-rw-r--r-- | contrib/amd/hlfsd/nfs_prot_svc.c | 5 | ||||
-rw-r--r-- | contrib/amd/hlfsd/stubs.c | 57 |
6 files changed, 172 insertions, 233 deletions
diff --git a/contrib/amd/hlfsd/hlfsd.8 b/contrib/amd/hlfsd/hlfsd.8 index bed4480..8c6fb49 100644 --- a/contrib/amd/hlfsd/hlfsd.8 +++ b/contrib/amd/hlfsd/hlfsd.8 @@ -1,5 +1,5 @@ .\" -.\" Copyright (c) 1997-2004 Erez Zadok +.\" Copyright (c) 1997-2006 Erez Zadok .\" Copyright (c) 1989 Jan-Simon Pendry .\" Copyright (c) 1989 Imperial College of Science, Technology & Medicine .\" Copyright (c) 1989 The Regents of the University of California. @@ -36,7 +36,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: hlfsd.8,v 1.3.2.5 2004/01/06 03:15:23 ezk Exp $ +.\" $Id: hlfsd.8,v 1.11.2.1 2006/01/02 18:48:25 ezk Exp $ .\" .\" HLFSD was written at Columbia University Computer Science Department, by .\" Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@smarts.com> @@ -263,7 +263,6 @@ are read and checked. All other fields are ignored. The file must otherwise be compliant with Unix System 7 colon-delimited format .IR passwd (4). .SH FILES -.PD 0 .TP 5 .B /hlfs directory under which @@ -303,8 +302,22 @@ user's home directory is accessible. in .IR "Proc. LISA-VII, The 7th Usenix System Administration Conference" , November 1993. +.LP +``am-utils'' +.BR info (1) +entry. +.LP +.I "Linux NFS and Automounter Administration" +by Erez Zadok, ISBN 0-7821-2739-8, (Sybex, 2001). +.LP +.I http://www.am-utils.org .SH AUTHORS -Erez Zadok <ezk@cs.columbia.edu>, Computer Science Department, -Columbia University, New York City, New York, USA, and +Erez Zadok <ezk@cs.sunysb.edu>, Computer Science Department, Stony Brook +University, Stony Brook, New York, USA. +and Alexander Dupuy <dupuy@smarts.com>, System Management ARTS, White Plains, New York, USA. +.P +Other authors and contributors to am-utils are listed in the +.B AUTHORS +file distributed with am-utils. diff --git a/contrib/amd/hlfsd/hlfsd.c b/contrib/amd/hlfsd/hlfsd.c index 355509d..8703f59 100644 --- a/contrib/amd/hlfsd/hlfsd.c +++ b/contrib/amd/hlfsd/hlfsd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: hlfsd.c,v 1.7.2.9 2004/01/19 00:25:55 ezk Exp $ + * File: am-utils/hlfsd/hlfsd.c * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> @@ -85,7 +84,7 @@ char *logfile = DEFAULT_LOGFILE; char *passwdfile = NULL; /* alternate passwd file to use */ char *slinkname = 0; char hostname[MAXHOSTNAMELEN + 1] = "localhost"; -int cache_interval = DEFAULT_CACHE_INTERVAL; +u_int cache_interval = DEFAULT_CACHE_INTERVAL; gid_t hlfs_gid = (gid_t) INVALIDID; int masterpid = 0; int noverify = 0; @@ -121,6 +120,17 @@ usage(void) } +void +fatalerror(char *str) +{ +#define ERRM ": %m" + size_t l = strlen(str) + sizeof(ERRM) - 1; + char *tmp = strnsave(str, l); + xstrlcat(tmp, ERRM, l); + fatal(tmp); +} + + int main(int argc, char *argv[]) { @@ -308,12 +318,12 @@ main(int argc, char *argv[]) *dot = '\0'; orig_umask = umask(0); if (logfile) - switch_to_logfile(logfile, orig_umask); + switch_to_logfile(logfile, orig_umask, 0); -#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) - if (debug_flags & D_MTAB) +#ifndef MOUNT_TABLE_ON_FILE + if (amuDebug(D_MTAB)) dlog("-D mtab option ignored"); -#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */ +#endif /* not MOUNT_TABLE_ON_FILE */ /* avoid hanging on other NFS servers if started elsewhere */ if (chdir("/") < 0) @@ -337,8 +347,6 @@ main(int argc, char *argv[]) exit(3); } - clock_valid = 0; /* invalidate logging clock */ - if (!forcefast) { /* make sure mount point exists and is at least mode 555 */ if (stat(dir_name, &stmodes) < 0) @@ -383,7 +391,7 @@ main(int argc, char *argv[]) chmod(alt_spooldir, OPEN_SPOOLMODE); /* create failsafe link to alternate spool directory */ - slinkname[-1] = '/'; /* unsplit dir_name to include link */ + *(slinkname-1) = '/'; /* unsplit dir_name to include link */ if (lstat(dir_name, &stmodes) == 0 && (stmodes.st_mode & S_IFMT) != S_IFLNK) { fprintf(stderr, "%s: failsafe %s not a symlink\n", @@ -404,7 +412,7 @@ main(int argc, char *argv[]) } } - slinkname[-1] = '\0'; /* resplit dir_name */ + *(slinkname-1) = '\0'; /* resplit dir_name */ } /* end of "if (!forcefast) {" */ /* @@ -420,7 +428,7 @@ main(int argc, char *argv[]) #ifdef HAVE_SIGACTION sa.sa_handler = proceed; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR2); sigaction(SIGUSR2, &sa, NULL); @@ -433,7 +441,7 @@ main(int argc, char *argv[]) #ifdef HAVE_SIGACTION sa.sa_handler = reaper; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); @@ -441,53 +449,57 @@ main(int argc, char *argv[]) signal(SIGCHLD, reaper); #endif /* not HAVE_SIGACTION */ -#ifdef DEBUG /* - * In the parent, if -D nodaemon (or -D daemon) , we don't need to + * In the parent, if -D daemon, we don't need to * set this signal handler. */ - amuDebug(D_DAEMON) { -#endif /* DEBUG */ - /* XXX: port to use pure svr4 signals */ + if (!amuDebug(D_DAEMON)) { s = -99; while (stoplight != SIGUSR2) { plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight); +#ifdef HAVE_SIGSUSPEND + { + sigset_t mask; + sigemptyset(&mask); + s = sigsuspend(&mask); /* wait for child to set up */ + } +#else /* not HAVE_SIGSUSPEND */ s = sigpause(0); /* wait for child to set up */ +#endif /* not HAVE_SIGSUSPEND */ sleep(1); } -#ifdef DEBUG } -#endif /* DEBUG */ /* * setup options to mount table (/etc/{mtab,mnttab}) entry */ - sprintf(hostpid_fs, "%s:(pid%d)", hostname, masterpid); + xsnprintf(hostpid_fs, sizeof(hostpid_fs), + "%s:(pid%d)", hostname, masterpid); memset((char *) &mnt, 0, sizeof(mnt)); mnt.mnt_dir = dir_name; /* i.e., "/mail" */ mnt.mnt_fsname = hostpid_fs; if (mntopts) { mnt.mnt_opts = mntopts; } else { - strcpy(preopts, default_mntopts); + xstrlcpy(preopts, default_mntopts, sizeof(preopts)); /* * Turn off all kinds of attribute and symlink caches as * much as possible. Also make sure that mount does not * show up to df. */ #ifdef MNTTAB_OPT_INTR - strcat(preopts, ","); - strcat(preopts, MNTTAB_OPT_INTR); + xstrlcat(preopts, ",", sizeof(preopts)); + xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts)); #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_IGNORE - strcat(preopts, ","); - strcat(preopts, MNTTAB_OPT_IGNORE); + xstrlcat(preopts, ",", sizeof(preopts)); + xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts)); #endif /* MNTTAB_OPT_IGNORE */ #ifdef MNT2_GEN_OPT_CACHE - strcat(preopts, ",nocache"); + xstrlcat(preopts, ",nocache", sizeof(preopts)); #endif /* MNT2_GEN_OPT_CACHE */ #ifdef MNT2_NFS_OPT_SYMTTL - strcat(preopts, ",symttl=0"); + xstrlcat(preopts, ",symttl=0", sizeof(preopts)); #endif /* MNT2_NFS_OPT_SYMTTL */ mnt.mnt_opts = preopts; } @@ -498,11 +510,15 @@ main(int argc, char *argv[]) * If they don't appear to support the either the "ignore" mnttab * option entry, or the "auto" one, set the mount type to "nfs". */ +#ifdef HIDE_MOUNT_TYPE mnt.mnt_type = HIDE_MOUNT_TYPE; +#else /* not HIDE_MOUNT_TYPE */ + mnt.mnt_type = "nfs"; +#endif /* not HIDE_MOUNT_TYPE */ /* some systems don't have a mount type, but a mount flag */ #ifndef HAVE_TRANSPORT_TYPE_TLI - amu_get_myaddress(&localsocket.sin_addr); + amu_get_myaddress(&localsocket.sin_addr, NULL); localsocket.sin_family = AF_INET; localsocket.sin_port = htons(nfsxprt->xp_port); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ @@ -511,11 +527,13 @@ main(int argc, char *argv[]) * Update hostname field. * Make some name prog:pid (i.e., hlfsd:174) for hostname */ - sprintf(progpid_fs, "%s:%d", am_get_progname(), masterpid); + xsnprintf(progpid_fs, sizeof(progpid_fs), + "%s:%d", am_get_progname(), masterpid); /* Most kernels have a name length restriction. */ if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN) - strcpy(progpid_fs + MAXHOSTNAMELEN - 3, ".."); + xstrlcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..", + sizeof(progpid_fs) - MAXHOSTNAMELEN + 3); genflags = compute_mount_flags(&mnt); @@ -523,7 +541,7 @@ main(int argc, char *argv[]) if (retry <= 0) retry = 1; /* XXX */ - memmove(&anh.v2.fhs_fh, root_fhp, sizeof(*root_fhp)); + memmove(&anh.v2, root_fhp, sizeof(*root_fhp)); #ifdef HAVE_TRANSPORT_TYPE_TLI compute_nfs_args(&nfs_args, &mnt, @@ -549,6 +567,7 @@ main(int argc, char *argv[]) compute_nfs_args(&nfs_args, &mnt, genflags, + NULL, &localsocket, NFS_VERSION, /* version 2 */ "udp", /* XXX: shouldn't this be "udp"? */ @@ -564,33 +583,26 @@ main(int argc, char *argv[]) *************************************************************************/ compute_automounter_nfs_args(&nfs_args, &mnt); - clock_valid = 0; /* invalidate logging clock */ - -/* - * The following code could be cleverly ifdef-ed, but I duplicated the - * mount_fs call three times for simplicity and readability. - */ -#ifdef DEBUG /* * For some reason, this mount may have to be done in the background, if I am - * using -D nodebug. I suspect that the actual act of mounting requires + * using -D daemon. I suspect that the actual act of mounting requires * calling to hlfsd itself to invoke one or more of its nfs calls, to stat - * /mail. That means that even if you say -D nodaemon, at least the mount + * /mail. That means that even if you say -D daemon, at least the mount * of hlfsd itself on top of /mail will be done in the background. * The other alternative I have is to run svc_run, but set a special * signal handler to perform the mount in N seconds via some alarm. * -Erez Zadok. */ - if (debug_flags & D_DAEMON) { /* asked for -D daemon */ - plog(XLOG_INFO, "parent NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) + if (!amuDebug(D_DAEMON)) { /* Normal case */ + plog(XLOG_INFO, "normal NFS mounting hlfsd service points"); + if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) fatal("nfsmount: %m"); - } else { /* asked for -D nodaemon */ + } else { /* asked for -D daemon */ if (fork() == 0) { /* child runs mount */ am_set_mypid(); foreground = 0; plog(XLOG_INFO, "child NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0) { + if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name, 0) < 0) { fatal("nfsmount: %m"); } exit(0); /* all went well */ @@ -598,11 +610,6 @@ main(int argc, char *argv[]) plog(XLOG_INFO, "parent waiting 1sec for mount..."); } } -#else /* not DEBUG */ - plog(XLOG_INFO, "normal NFS mounting hlfsd service points"); - if (mount_fs(&mnt, genflags, (caddr_t) &nfs_args, retry, type, 2, "udp", mnttab_file_name) < 0) - fatal("nfsmount: %m"); -#endif /* not DEBUG */ #ifdef HAVE_TRANSPORT_TYPE_TLI /* @@ -620,15 +627,14 @@ main(int argc, char *argv[]) printf("%d\n", masterpid); plog(XLOG_INFO, "hlfsd ready to serve"); -#ifdef DEBUG /* - * If asked not to fork a daemon (-D nodaemon), then hlfsd_init() + * If asked not to fork a daemon (-D daemon), then hlfsd_init() * will not run svc_run. We must start svc_run here. */ - dlog("starting no-daemon debugging svc_run"); - amuDebugNo(D_DAEMON) + if (amuDebug(D_DAEMON)) { + plog(XLOG_DEBUG, "starting no-daemon debugging svc_run"); svc_run(); -#endif /* DEBUG */ + } cleanup(0); /* should never happen here */ return (0); /* everything went fine? */ @@ -643,20 +649,16 @@ hlfsd_init(void) struct sigaction sa; #endif /* HAVE_SIGACTION */ - clock_valid = 0; /* invalidate logging clock */ - /* * Initialize file handles. */ plog(XLOG_INFO, "initializing hlfsd file handles"); hlfsd_init_filehandles(); -#ifdef DEBUG /* - * If -D daemon then we must fork. + * If not -D daemon then we must fork. */ - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) child = fork(); if (child < 0) @@ -685,7 +687,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = reload; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGALRM); sigaddset(&(sa.sa_mask), SIGHUP); @@ -701,7 +703,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = cleanup; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGTERM); sigaction(SIGTERM, &sa, NULL); @@ -714,7 +716,7 @@ hlfsd_init(void) */ #ifdef HAVE_SIGACTION sa.sa_handler = interlock; - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGCHLD); sigaction(SIGCHLD, &sa, NULL); @@ -731,7 +733,7 @@ hlfsd_init(void) # else /* not defined(DEBUG) || defined(DEBUG_PRINT) */ sa.sa_handler = SIG_IGN; # endif /* not defined(DEBUG) || defined(DEBUG_PRINT) */ - sa.sa_flags = SA_RESTART; + sa.sa_flags = 0; sigemptyset(&(sa.sa_mask)); sigaddset(&(sa.sa_mask), SIGUSR1); sigaction(SIGUSR1, &sa, NULL); @@ -746,17 +748,14 @@ hlfsd_init(void) if (setitimer(ITIMER_REAL, &reloadinterval, (struct itimerval *) 0) < 0) fatal("setitimer: %m"); - gettimeofday((struct timeval *) ((void *)&startup), (struct timezone *) 0); + clocktime(&startup); -#ifdef DEBUG /* - * If -D daemon, then start serving here in the child, - * and the parent will exit. But if -D nodaemon, then + * If not -D daemon, then start serving here in the child, + * and the parent will exit. But if -D daemon, then * skip this code and make sure svc_run is entered elsewhere. */ - amuDebug(D_DAEMON) { -#endif /* DEBUG */ - + if (!amuDebug(D_DAEMON)) { /* * Dissociate from the controlling terminal */ @@ -771,9 +770,7 @@ hlfsd_init(void) plog(XLOG_INFO, "starting svc_run"); svc_run(); cleanup(0); /* should never happen, just in case */ -#ifdef DEBUG - } /* end of code that runs iff hlfsd daemonizes */ -#endif /* DEBUG */ + } } @@ -791,8 +788,6 @@ reload(int signum) int child; int status; - clock_valid = 0; /* invalidate logging clock */ - if (getpid() != masterpid) return; @@ -801,7 +796,7 @@ reload(int signum) * can be rotated) */ if (signum == SIGHUP && logfile) - switch_to_logfile(logfile, orig_umask); + switch_to_logfile(logfile, orig_umask, 0); /* * parent performs the reload, while the child continues to serve @@ -844,29 +839,21 @@ cleanup(int signum) struct stat stbuf; int umount_result; - clock_valid = 0; /* invalidate logging clock */ - -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) { if (getpid() != masterpid) return; -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ if (fork() != 0) { masterpid = 0; am_set_mypid(); return; } + } am_set_mypid(); for (;;) { - while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name)) == EBUSY) { -#ifdef DEBUG + while ((umount_result = UMOUNT_FS(dir_name, mnttab_file_name, 0)) == EBUSY) { dlog("cleanup(): umount delaying for 10 seconds"); -#endif /* DEBUG */ sleep(10); } if (stat(dir_name, &stbuf) == 0 && stbuf.st_ino == ROOTID) { @@ -878,19 +865,14 @@ cleanup(int signum) break; } -#ifdef DEBUG - dlog("cleanup(): killing processes and terminating"); - amuDebug(D_DAEMON) -#endif /* DEBUG */ + if (!amuDebug(D_DAEMON)) { + plog(XLOG_INFO, "cleanup(): killing processes and terminating"); kill(masterpid, SIGKILL); - -#ifdef DEBUG - amuDebug(D_DAEMON) -#endif /* DEBUG */ kill(serverpid, SIGKILL); + } plog(XLOG_INFO, "hlfsd terminating with status 0\n"); - exit(0); + _exit(0); } @@ -900,7 +882,7 @@ reaper(int signum) int result; if (wait(&result) == masterpid) { - exit(4); + _exit(4); } } @@ -931,7 +913,7 @@ fatal(char *mess) if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM)) fprintf(stderr, "%s: %s\n", am_get_progname(), mess); else { - strcpy(lessmess, mess); + xstrlcpy(lessmess, mess, sizeof(lessmess)); lessmess[messlen - 4] = '\0'; fprintf(stderr, "%s: %s: %s\n", diff --git a/contrib/amd/hlfsd/hlfsd.h b/contrib/amd/hlfsd/hlfsd.h index 645c2f8..ed136b6 100644 --- a/contrib/amd/hlfsd/hlfsd.h +++ b/contrib/amd/hlfsd/hlfsd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: hlfsd.h,v 1.4.2.7 2004/01/06 03:15:23 ezk Exp $ + * File: am-utils/hlfsd/hlfsd.h * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> @@ -100,9 +99,6 @@ # define DEFAULT_LOGFILE 0 #endif /* not HAVE)_SYSLOG */ -#define ERRM ": %m" -#define fatalerror(str) \ - (fatal (strcat (strnsave ((str), strlen ((str)) + sizeof (ERRM) - 1), ERRM))) /* * TYPEDEFS: @@ -142,16 +138,15 @@ extern char *homedir(int, int); extern char *mailbox(int, char *); extern char *passwdfile; extern char *slinkname; -extern char mboxfile[]; extern gid_t hlfs_gid; -extern int cache_interval; +extern u_int cache_interval; extern int noverify; extern int serverpid; extern int untab_index(char *username); extern am_nfs_fh *root_fhp; extern am_nfs_fh root; extern nfstime startup; -extern uid2home_t *plt_search(int); +extern uid2home_t *plt_search(u_int); extern username2uid_t *untab; /* user name table */ extern void fatal(char *); extern void plt_init(void); diff --git a/contrib/amd/hlfsd/homedir.c b/contrib/amd/hlfsd/homedir.c index 533b7f4..2ade32f 100644 --- a/contrib/amd/hlfsd/homedir.c +++ b/contrib/amd/hlfsd/homedir.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: homedir.c,v 1.5.2.11 2004/01/06 03:15:23 ezk Exp $ + * File: am-utils/hlfsd/homedir.c * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> @@ -66,7 +65,7 @@ static struct passwd passwd_ent; static uid2home_t *lastchild; static uid2home_t *pwtab; static void delay(uid2home_t *, int); -static void table_add(int, const char *, const char *); +static void table_add(u_int, const char *, const char *); static char mboxfile[MAXPATHLEN]; static char *root_home; /* root's home directory */ @@ -90,8 +89,6 @@ homedir(int userid, int groupid) struct stat homestat; int old_groupid, old_userid; - clock_valid = 0; /* invalidate logging clock */ - if ((found = plt_search(userid)) == (uid2home_t *) NULL) { return alt_spooldir; /* use alt spool for unknown uid */ } @@ -102,9 +99,9 @@ homedir(int userid, int groupid) return alt_spooldir; /* use alt spool for / or rel. home */ } if ((int) userid == 0) /* force all uid 0 to use root's home */ - sprintf(linkval, "%s/%s", root_home, home_subdir); + xsnprintf(linkval, sizeof(linkval), "%s/%s", root_home, home_subdir); else - sprintf(linkval, "%s/%s", homename, home_subdir); + xsnprintf(linkval, sizeof(linkval), "%s/%s", homename, home_subdir); if (noverify) { found->last_status = 0; @@ -135,41 +132,18 @@ homedir(int userid, int groupid) } } -#ifdef DEBUG /* - * only run this forking code if asked for -D fork - * or if did not ask for -D nofork + * only run this forking code if did not ask for -D fork */ - amuDebug(D_FORK) { -#endif /* DEBUG */ + if (!amuDebug(D_FORK)) { /* fork child to process request if none in progress */ - if (found->child && kill(found->child, 0) < 0) + if (found->child && kill(found->child, 0)) found->child = 0; if (found->child) delay(found, 5); /* wait a bit if in progress */ - -#if defined(DEBUG) && defined(HAVE_WAITPID) - if (found->child) { - /* perhaps it's a child we lost count of? let's wait on it */ - int status, child; - if ((child = waitpid((pid_t) found->child, &status, WNOHANG)) > 0) { - plog(XLOG_ERROR, "found lost child %d", child); - found->child = 0; - if (WIFEXITED(status)) - found->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - found->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - found->last_status = 255; - } - } - } -#endif /* DEBUG && HAVE_WAITPID */ - - if (found->child) { - found->last_status = 1; /* better safe than sorry - maybe */ + if (found->child) { /* better safe than sorry - maybe */ + found->last_status = 1; return alt_spooldir; } if ((found->child = fork()) < 0) { @@ -177,21 +151,17 @@ homedir(int userid, int groupid) return alt_spooldir; } if (found->child) { /* PARENT */ -#ifdef DEBUG if (lastchild) - plog(XLOG_INFO, "cache spill uid = %ld, pid = %ld, home = %s", + dlog("cache spill uid = %ld, pid = %ld, home = %s", (long) lastchild->uid, (long) lastchild->child, lastchild->home); -#endif /* DEBUG */ lastchild = found; return (char *) NULL; /* return NULL to parent, so it can continue */ } -#ifdef DEBUG - } /* end of Debug(D_FORK) */ -#endif /* DEBUG */ + } /* - * CHILD: (or parent if -D nofork) + * CHILD: (or parent if -D fork) * * Check and create dir if needed. * Check disk space and/or quotas too. @@ -257,9 +227,7 @@ hlfsd_diskspace(char *path) char buf[MAXPATHLEN]; int fd, len; - clock_valid = 0; /* invalidate logging clock */ - - sprintf(buf, "%s/._hlfstmp_%lu", path, (long) getpid()); + xsnprintf(buf, sizeof(buf), "%s/._hlfstmp_%lu", path, (long) getpid()); if ((fd = open(buf, O_RDWR | O_CREAT, 0600)) < 0) { plog(XLOG_ERROR, "cannot open %s: %m", buf); return -1; @@ -297,10 +265,7 @@ delay(uid2home_t *found, int secs) { struct timeval tv; -#ifdef DEBUG - if (found) - dlog("delaying on child %ld for %d seconds", (long) found->child, secs); -#endif /* DEBUG */ + dlog("delaying on child %ld for %d seconds", (long) found->child, secs); tv.tv_usec = 0; @@ -323,55 +288,30 @@ interlock(int signum) int child; uid2home_t *lostchild; int status; - int max_errors = 10; /* avoid infinite loops */ #ifdef HAVE_WAITPID - while ((child = waitpid((pid_t) -1, &status, WNOHANG)) != 0) { + while ((child = waitpid((pid_t) -1, &status, WNOHANG)) > 0) { #else /* not HAVE_WAITPID */ - while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) != 0) { + while ((child = wait3(&status, WNOHANG, (struct rusage *) 0)) > 0) { #endif /* not HAVE_WAITPID */ - if (child < 0) { - plog(XLOG_WARNING, "waitpid/wait3: %m"); - if (--max_errors > 0) - continue; - else - break; - } - /* high chances this was the last child forked */ if (lastchild && lastchild->child == child) { lastchild->child = 0; if (WIFEXITED(status)) lastchild->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - lastchild->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - lastchild->last_status = 255; - } lastchild = (uid2home_t *) NULL; } else { /* and if not, we have to search for it... */ - int found = 0; for (lostchild = pwtab; lostchild < &pwtab[cur_pwtab_num]; lostchild++) { if (lostchild->child == child) { - lostchild->child = 0; if (WIFEXITED(status)) lostchild->last_status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) - lostchild->last_status = -WTERMSIG(status); - else { - plog(XLOG_ERROR, "unknown child exit status (%d) ???", status); - lostchild->last_status = 255; - } - found = 1; + lostchild->child = 0; break; } } - if (!found) - plog(XLOG_ERROR, "no record of child %d found???", child); } } } @@ -455,15 +395,18 @@ mailbox(int uid, char *username) if ((home = homeof(username)) == (char *) NULL) return (char *) NULL; if (STREQ(home, "/")) - sprintf(mboxfile, "/%s/%s", home_subdir, username); + xsnprintf(mboxfile, sizeof(mboxfile), + "/%s/%s", home_subdir, username); else - sprintf(mboxfile, "%s/%s/%s", home, home_subdir, username); + xsnprintf(mboxfile, sizeof(mboxfile), + "%s/%s/%s", home, home_subdir, username); return mboxfile; } static int plt_compare_fxn(const voidp x, const voidp y) + { uid2home_t *i = (uid2home_t *) x; uid2home_t *j = (uid2home_t *) y; @@ -538,8 +481,6 @@ hlfsd_getpwent(void) return getpwent(); } - clock_valid = 0; /* invalidate logging clock */ - /* return here to read another entry */ readent: @@ -562,7 +503,8 @@ readent: plog(XLOG_ERROR, "no user name on line %d of %s", passwd_line, passwdfile); goto readent; } - strcpy(pw_name, cp); /* will show up in passwd_ent.pw_name */ + /* pw_name will show up in passwd_ent.pw_name */ + xstrlcpy(pw_name, cp, sizeof(pw_name)); /* skip passwd */ strtok(NULL, ":"); @@ -585,7 +527,8 @@ readent: plog(XLOG_ERROR, "no home dir on line %d of %s", passwd_line, passwdfile); goto readent; } - strcpy(pw_dir, cp); /* will show up in passwd_ent.pw_dir */ + /* pw_dir will show up in passwd_ent.pw_dir */ + xstrlcpy(pw_dir, cp, sizeof(pw_dir)); /* the rest of the fields are unimportant and not being considered */ @@ -648,8 +591,6 @@ plt_reset(void) { int i; - clock_valid = 0; /* invalidate logging clock */ - hlfsd_setpwent(); if (hlfsd_getpwent() == (struct passwd *) NULL) { hlfsd_endpwent(); @@ -690,12 +631,10 @@ plt_reset(void) * n: user ID name */ static void -table_add(int u, const char *h, const char *n) +table_add(u_int u, const char *h, const char *n) { int i; - clock_valid = 0; /* invalidate logging clock */ - if (max_pwtab_num <= 0) { /* was never initialized */ max_pwtab_num = 1; pwtab = (uid2home_t *) xmalloc(max_pwtab_num * @@ -726,10 +665,8 @@ table_add(int u, const char *h, const char *n) /* do NOT add duplicate entries (this is an O(N^2) algorithm... */ for (i=0; i<cur_pwtab_num; ++i) if (u == pwtab[i].uid && u != 0 ) { -#ifdef DEBUG dlog("ignoring duplicate home %s for uid %d (already %s)", h, u, pwtab[i].home); -#endif /* DEBUG */ return; } @@ -757,7 +694,7 @@ table_add(int u, const char *h, const char *n) * return entry in lookup table */ uid2home_t * -plt_search(int u) +plt_search(u_int u) { int max, min, mid; diff --git a/contrib/amd/hlfsd/nfs_prot_svc.c b/contrib/amd/hlfsd/nfs_prot_svc.c index b9150e3..8cea0dc 100644 --- a/contrib/amd/hlfsd/nfs_prot_svc.c +++ b/contrib/amd/hlfsd/nfs_prot_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: nfs_prot_svc.c,v 1.4.2.5 2004/01/06 03:15:23 ezk Exp $ + * File: am-utils/hlfsd/nfs_prot_svc.c * */ diff --git a/contrib/amd/hlfsd/stubs.c b/contrib/amd/hlfsd/stubs.c index 4038c05..becf402 100644 --- a/contrib/amd/hlfsd/stubs.c +++ b/contrib/amd/hlfsd/stubs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: stubs.c,v 1.5.2.7 2004/01/06 03:15:23 ezk Exp $ + * File: am-utils/hlfsd/stubs.c * * HLFSD was written at Columbia University Computer Science Department, by * Erez Zadok <ezk@cs.columbia.edu> and Alexander Dupuy <dupuy@cs.columbia.edu> @@ -127,8 +126,18 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) res.ns_status = NFSERR_STALE; return &res; } - if (eq_fh(argp, &root)) { +#if 0 + /* + * XXX: increment mtime of parent directory, causes NFS clients to + * invalidate their cache for that directory. + * Some NFS clients may need this code. + */ + if (uid != rootfattr.na_uid) { + clocktime(&rootfattr.na_mtime); + rootfattr.na_uid = uid; + } +#endif res.ns_status = NFS_OK; res.ns_u.ns_attr_u = rootfattr; } else if (eq_fh(argp, &slink)) { @@ -144,7 +153,7 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) * so we must update the nt_seconds field every time. */ if (uid != slinkfattr.na_uid) { - slinkfattr.na_mtime.nt_seconds++; + clocktime(&slinkfattr.na_mtime); slinkfattr.na_uid = uid; } #endif /* not MNT2_NFS_OPT_SYMTTL */ @@ -161,10 +170,8 @@ nfsproc_getattr_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) res.ns_status = NFS_OK; un_fattr.na_fileid = uid; res.ns_u.ns_attr_u = un_fattr; -#ifdef DEBUG dlog("nfs_getattr: successful search for uid=%ld, gid=%ld", (long) uid, (long) gid); -#endif /* DEBUG */ } else { /* not found */ res.ns_status = NFSERR_STALE; } @@ -219,12 +226,22 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) res.dr_status = NFSERR_NOENT; return &res; } - if (eq_fh(&argp->da_fhandle, &root)) { if (argp->da_name[0] == '.' && (argp->da_name[1] == '\0' || (argp->da_name[1] == '.' && argp->da_name[2] == '\0'))) { +#if 0 + /* + * XXX: increment mtime of parent directory, causes NFS clients to + * invalidate their cache for that directory. + * Some NFS clients may need this code. + */ + if (uid != rootfattr.na_uid) { + clocktime(&rootfattr.na_mtime); + rootfattr.na_uid = uid; + } +#endif res.dr_u.dr_drok_u.drok_fhandle = root; res.dr_u.dr_drok_u.drok_attributes = rootfattr; res.dr_status = NFS_OK; @@ -243,7 +260,7 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) * so we must update the nt_seconds field every time. */ if (uid != slinkfattr.na_uid) { - slinkfattr.na_mtime.nt_seconds++; + clocktime(&slinkfattr.na_mtime); slinkfattr.na_uid = uid; } #endif /* not MNT2_NFS_OPT_SYMTTL */ @@ -267,15 +284,13 @@ nfsproc_lookup_2_svc(nfsdiropargs *argp, struct svc_req *rqstp) res.dr_u.dr_drok_u.drok_attributes = un_fattr; memset((char *) &un_fhandle, 0, sizeof(am_nfs_fh)); *(u_int *) un_fhandle.fh_data = (u_int) untab[idx].uid; - strncpy((char *) &un_fhandle.fh_data[sizeof(int)], - untab[idx].username, - sizeof(am_nfs_fh) - sizeof(int)); + xstrlcpy((char *) &un_fhandle.fh_data[sizeof(int)], + untab[idx].username, + sizeof(am_nfs_fh) - sizeof(int)); res.dr_u.dr_drok_u.drok_fhandle = un_fhandle; res.dr_status = NFS_OK; -#ifdef DEBUG dlog("nfs_lookup: successful lookup for uid=%ld, gid=%ld: username=%s", (long) uid, (long) gid, untab[idx].username); -#endif /* DEBUG */ return &res; } } /* end of "if (eq_fh(argp->dir.data, root.data)) {" */ @@ -302,7 +317,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) if (getcreds(rqstp, &userid, &groupid, nfsxprt) < 0) return (nfsreadlinkres *) NULL; - gettimeofday((struct timeval *) &slinkfattr.na_atime, (struct timezone *) 0); + clocktime(&slinkfattr.na_atime); res.rlr_status = NFS_OK; if (groupid == hlfs_gid) { @@ -340,7 +355,7 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) last_uid = userid; } - /* I don't think will pass this if -D nofork */ + /* I don't think it will pass this if -D fork */ if (serverpid == getpid()) return &res; @@ -359,15 +374,13 @@ nfsproc_readlink_2_svc(am_nfs_fh *argp, struct svc_req *rqstp) else retval = 0; -#ifdef DEBUG /* - * If asked for -D nofork, then must return the value, + * If asked for -D fork, then must return the value, * NOT exit, or else the main hlfsd server exits. - * Bug where is that status information being collected? + * Bug: where is that status information being collected? */ - amuDebugNo(D_FORK) + if (amuDebug(D_FORK)) return &res; -#endif /* DEBUG */ exit(retval); } @@ -476,7 +489,7 @@ nfsproc_readdir_2_svc(nfsreaddirargs *argp, struct svc_req *rqstp) if (eq_fh(&argp->rda_fhandle, &slink)) { res.rdr_status = NFSERR_NOTDIR; } else if (eq_fh(&argp->rda_fhandle, &root)) { - gettimeofday((struct timeval *) &rootfattr.na_atime, (struct timezone *) 0); + clocktime(&rootfattr.na_atime); res.rdr_status = NFS_OK; switch (argp->rda_cookie[0]) { |