[7891] in Athena Bugs
rpc.mountd
daemon@ATHENA.MIT.EDU (John Carr)
Fri Aug 9 10:12:33 1991
To: bugs@ATHENA.MIT.EDU
Date: Fri, 09 Aug 91 10:04:30 EDT
From: John Carr <jfc@ATHENA.MIT.EDU>
These are some changes I've made to rpc.mountd and mkcred. The
interesting changes:
. Use syslog to report errors.
. If BSD_NDBM is defined, notice immediately when the credentials
database is modified.
(The second change is useful because the next message I send to bugs
will be patches to nfsc to add a user to the credentials database
without running mkcred.)
Also included are AIX 1.2 support and code to log requests (enabled if
LOG_REQUESTS is defined).
*** ref/dbmcred.h Tue Feb 2 15:18:14 1988
--- dbmcred.h Mon Jul 29 16:14:39 1991
***************
*** 5,10 ****
--- 5,14 ----
* $Header: dbmcred.h,v 1.2 88/02/02 15:17:54 kubitron Exp $
*/
+ #ifdef _AIX
+ typedef int rpc_uid_t, rpc_gid_t;
+ #endif
+
struct dbmcred {
rpc_uid_t uid;
rpc_gid_t gid;
*** ref/mkcred.c Tue Jul 16 14:47:47 1991
--- mkcred.c Fri Aug 9 09:29:48 1991
***************
*** 8,15 ****
--- 8,20 ----
#include <stdio.h>
#include <dbm.h>
#include <sys/types.h>
+ #ifdef _AIX
+ #include <rpc/rpctypes.h>
+ #else
#include <rpc/types.h>
+ #endif
#include <sys/param.h>
+ #include "dbmcred.h"
#define LINESIZE 4096
***************
*** 36,48 ****
exit(0);
}
- struct ucred {
- rpc_uid_t uid;
- rpc_gid_t gid;
- int glen;
- rpc_gid_t gids[NGROUPS];
- };
-
open_cred(name)
char *name;
{
--- 41,46 ----
***************
*** 59,68 ****
}
add_cred(str)
! char *str;
{
char *name;
! struct ucred u;
datum k, d;
int i;
--- 57,66 ----
}
add_cred(str)
! register char *str;
{
char *name;
! struct dbmcred u;
datum k, d;
int i;
***************
*** 90,94 ****
k.dsize = strlen(name);
d.dptr = (char *) &u;
d.dsize = sizeof(u);
! store(k, d);
}
--- 88,93 ----
k.dsize = strlen(name);
d.dptr = (char *) &u;
d.dsize = sizeof(u);
! if (store(k, d) < 0)
! fprintf (stderr, "Can't store entry for user \"%s\".\n", name);
}
*** ref/xdr_krb.c Fri Aug 7 21:26:03 1987
--- xdr_krb.c Mon Jul 29 16:21:08 1991
***************
*** 1,5 ****
--- 1,9 ----
#include <krb.h>
+ #ifdef _AIX
+ #include <rpc/rpctypes.h>
+ #else
#include <rpc/types.h>
+ #endif
#include <rpc/rpc.h>
bool_t xdr_krbtkt(xdrs, authp)
*** ref/rpc.mountd.c Sun Jun 30 21:46:34 1991
--- rpc.mountd.c Fri Aug 9 09:59:11 1991
***************
*** 23,30 ****
--- 23,36 ----
/* NFS server */
+ #define NFSSERVER
+
#include <sys/param.h>
+ #ifdef _AIX
+ #include <sys/filsys.h>
+ #else
#include <ufs/fs.h>
+ #endif
#include <rpc/rpc.h>
#include <sys/stat.h>
#include <sys/socket.h>
***************
*** 36,49 ****
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <nfs/nfs.h>
#include <sys/vfs.h> /* ... from kernel sources */
#include <rpcsvc/mount.h>
#include <netdb.h>
#ifdef KERBEROS
#define CREDFILE "/usr/etc/credentials"
! /* Extra time (in secs) beyond the authenticator to keep the mapping */
! /* We use 5 minutes so as the default in case this machine is a translator */
#ifndef KRB_SLOP_TIME
#define KRB_SLOP_TIME 300
#endif
--- 42,67 ----
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
+ #ifdef _AIX
+ #include <rpc/nfs.h>
+ #include <rpc/nfs_clnt.h>
+ #else
#include <nfs/nfs.h>
+ #endif
#include <sys/vfs.h> /* ... from kernel sources */
+ #ifdef _AIX
+ #include <rpc/nfsmount.h>
+ #include "mount.h"
+ #else
#include <rpcsvc/mount.h>
+ #endif
#include <netdb.h>
#ifdef KERBEROS
+ #ifdef _AIX
+ #define CREDFILE "/local/athena/credentials/credentials"
+ #else
#define CREDFILE "/usr/etc/credentials"
! #endif
#ifndef KRB_SLOP_TIME
#define KRB_SLOP_TIME 300
#endif
***************
*** 57,62 ****
--- 75,83 ----
#define RMTAB "/etc/rmtab"
#endif
+ #include <syslog.h>
+ #include <arpa/inet.h>
+
extern int errno;
int mnt();
***************
*** 80,89 ****
--- 101,121 ----
#ifdef KERBEROS
DBM *dbmfile;
+ #ifdef BSD_NDBM
+ long cred_ctime;
+ #else
struct timeval timep;
struct timeval savetime;
#endif
+ #endif
+ #ifndef __STDC__
+ #define const
+ #endif
+ static const char *mountproc_names[] =
+ { "null", "mount", "dump", "unmount", "unmountall", "export", "exportall",
+ "uid map", "uid unmap", "uid purge", "uid user-purge"};
+
usage()
{
fprintf(stderr, "Usage: %s [-d] [-s]\n", prog);
***************
*** 97,103 ****
int len = sizeof(struct sockaddr_in);
int i,j;
SVCXPRT *transp;
! #ifdef KERBEROS
int sig_handler();
struct itimerval itimer;
#endif
--- 129,135 ----
int len = sizeof(struct sockaddr_in);
int i,j;
SVCXPRT *transp;
! #if defined(KERBEROS) && !defined(BSD_NDBM)
int sig_handler();
struct itimerval itimer;
#endif
***************
*** 126,131 ****
--- 158,165 ----
exit(1);
}
+ openlog ("mountd", LOG_PID, LOG_DAEMON);
+
if (set_exports_only) {
set_exports();
exit(exports ? 0 : 1);
***************
*** 159,173 ****
}
if (getsockname(0, &addr, &len) != 0) {
perror("rstat: getsockname");
exit(1);
}
if ((transp = svcudp_create(0)) == NULL) {
fprintf(stderr, "couldn't create udp transport\n");
exit(1);
}
if (!svc_register(transp, MOUNTPROG, MOUNTVERS, mnt, 0)) {
! fprintf(stderr, "couldn't register MOUNTPROG");
exit(1);
}
--- 193,212 ----
}
if (getsockname(0, &addr, &len) != 0) {
+ int oerr = errno;
perror("rstat: getsockname");
+ errno = oerr;
+ syslog (LOG_ERR, "getsockname: %m");
exit(1);
}
if ((transp = svcudp_create(0)) == NULL) {
fprintf(stderr, "couldn't create udp transport\n");
+ syslog (LOG_ERR, "couldn't create udp transport\n");
exit(1);
}
if (!svc_register(transp, MOUNTPROG, MOUNTVERS, mnt, 0)) {
! fprintf(stderr, "couldn't register MOUNTPROG\n");
! syslog(LOG_ERR, "couldn't register MOUNTPROG\n");
exit(1);
}
***************
*** 183,188 ****
--- 222,239 ----
set_exports();
#ifdef KERBEROS
dbmfile = dbm_open(CREDFILE, DBM_INSERT, 0600);
+ #ifdef BSD_NDBM
+ if (dbmfile)
+ {
+ struct stat st;
+ fstat(dbmfile->dbm_pagf, &st);
+ cred_ctime = st.st_ctime;
+ #ifdef DEBUG
+ fprintf (stderr,"Credentials file fd %d has mtime %u.\n",
+ dbmfile->dbm_pags, cred_ctime);
+ #endif
+ }
+ #else
(void) gettimeofday(&savetime, (struct timezone *)0);
(void) signal(SIGALRM, sig_handler);
***************
*** 191,199 ****
--- 242,254 ----
itimer.it_interval.tv_sec = 1800;
itimer.it_interval.tv_usec = 0;
if (setitimer(ITIMER_REAL, &itimer, (struct itimerval *)NULL)) {
+ int oerr = errno;
perror("rpc.mountd: setitimer");
+ errno = oerr;
+ syslog(LOG_WARNING, "setitimer: %m");
}
#endif
+ #endif
/*
* Start serving
***************
*** 200,205 ****
--- 255,261 ----
*/
svc_run();
fprintf(stderr, "Error: svc_run shouldn't have returned\n");
+ syslog(LOG_ERR, "Error: svc_run shouldn't have returned\n");
abort();
}
***************
*** 210,216 ****
--- 266,294 ----
struct svc_req *rqstp;
SVCXPRT *transp;
{
+ register int proc = rqstp->rq_proc;
+
#ifdef KERBEROS
+ #ifdef BSD_NDBM
+ if (dbmfile)
+ {
+ struct stat st;
+ fstat(dbmfile->dbm_pagf, &st);
+ if (st.st_ctime != cred_ctime)
+ {
+ dbm_close(dbmfile);
+ dbmfile = dbm_open(CREDFILE, DBM_INSERT, 0600);
+ fstat(dbmfile->dbm_pagf, &st);
+ cred_ctime = st.st_ctime;
+ }
+ }
+ else
+ {
+ struct stat st;
+ if (stat(CREDFILE, &st) != -1)
+ dbmfile = dbm_open(CREDFILE, DBM_INSERT, 0600);
+ }
+ #else
gettimeofday(&timep, (struct timezone *)0);
if (timep.tv_sec - savetime.tv_sec > 60*5) {
if (debug)
***************
*** 219,228 ****
dbmfile = dbm_open(CREDFILE, DBM_INSERT, 0600);
savetime.tv_sec = timep.tv_sec;
}
! #endif KERBEROS
switch(rqstp->rq_proc) {
case NULLPROC:
if (!svc_sendreply(transp, xdr_void, 0)) {
fprintf(stderr,
"couldn't reply to rpc call\n");
return;
--- 297,315 ----
dbmfile = dbm_open(CREDFILE, DBM_INSERT, 0600);
savetime.tv_sec = timep.tv_sec;
}
! #endif
! #endif
! #ifdef LOG_REQUESTS
! syslog(LOG_INFO, "request: procedure %x (%s) from host %s", proc,
! (proc > 10) ? "???" : mountproc_names[proc],
! inet_ntoa(svc_getcaller(transp)->sin_addr));
! #endif
switch(rqstp->rq_proc) {
case NULLPROC:
if (!svc_sendreply(transp, xdr_void, 0)) {
+ syslog(LOG_WARNING,
+ "couldn't reply to NULLPROC call");
+ if (debug)
fprintf(stderr,
"couldn't reply to rpc call\n");
return;
***************
*** 232,237 ****
--- 319,328 ----
if (debug)
fprintf(stdout, "about to do a mount\n");
if (imposter(rqstp,transp)) {
+ syslog (LOG_NOTICE, "bad mount request");
+ #ifdef DEBUG
+ fprintf (stderr, "bad mount request");
+ #endif
svcerr_weakauth(transp);
return;
}
***************
*** 242,247 ****
--- 333,340 ----
if (debug)
fprintf(stdout, "about to do a dump\n");
if (!svc_sendreply(transp,xdr_mountlist,&mountlist)) {
+ syslog(LOG_NOTICE, "dump failed");
+ if (debug)
fprintf(stderr,
"couldn't reply to rpc call\n");
return;
***************
*** 251,256 ****
--- 344,353 ----
if (debug)
fprintf(stdout, "about to do an unmount\n");
if (imposter(rqstp,transp)) {
+ #ifdef DEBUG
+ fprintf (stderr, "bad unmount request");
+ #endif
+ syslog (LOG_NOTICE, "bad unmount request");
svcerr_weakauth(transp);
return;
}
***************
*** 260,265 ****
--- 357,363 ----
if (debug)
fprintf(stdout, "about to do an unmountall\n");
if (imposter(rqstp,transp)) {
+ syslog (LOG_NOTICE, "bad unmountall request");
svcerr_weakauth(transp);
return;
}
***************
*** 318,323 ****
--- 416,425 ----
if (rqstp->rq_cred.oa_flavor != AUTH_UNIX) {
+ syslog(LOG_WARNING, "bad auth type %d",rqstp->rq_cred.oa_flavor);
+ #ifdef DEBUG
+ fprintf (stderr, "bad auth type %d",rqstp->rq_cred.oa_flavor);
+ #endif
svcerr_weakauth(transp);
return(1);
}
***************
*** 324,329 ****
--- 426,437 ----
actual = *svc_getcaller(transp);
if (nfs_portmon) {
if (ntohs(actual.sin_port) >= IPPORT_RESERVED) {
+ #ifdef DEBUG
+ fprintf(stderr,"request from unprivileged port %s:%d\n",
+ inet_ntoa(actual.sin_addr), ntohs(actual.sin_port));
+ #endif
+ syslog(LOG_WARNING, "request from unprivileged port %s:%d\n",
+ inet_ntoa(actual.sin_addr), ntohs(actual.sin_port));
return(1);
}
}
***************
*** 337,347 ****
rqstp->rq_clntcred)->aup_machname;
hp = gethostbyname(machine);
if (hp == NULL) {
svcerr_auth(transp,AUTH_BADCRED);
return(1);
}
bcopy(hp->h_addr,&claim,sizeof(struct in_addr));
! if (actual.sin_addr.s_addr != claim.s_addr) {;
svcerr_auth(transp,AUTH_REJECTEDVERF);
return(1);
}
--- 445,466 ----
rqstp->rq_clntcred)->aup_machname;
hp = gethostbyname(machine);
if (hp == NULL) {
+ #ifdef DEBUG
+ fprintf(stderr, "unable to resolve hostname \"%s\"", machine);
+ #endif
+ syslog(LOG_WARNING, "unable to resolve hostname \"%s\"",
+ machine);
svcerr_auth(transp,AUTH_BADCRED);
return(1);
}
bcopy(hp->h_addr,&claim,sizeof(struct in_addr));
! if (actual.sin_addr.s_addr != claim.s_addr) {
! #ifdef DEBUG
! fprintf(stderr, "bad request: %s (%s) != %s",
! inet_ntoa(claim), machine, inet_ntoa(actual.sin_addr));
! #endif
! syslog(LOG_WARNING, "bad request: %s (%s) != %s",
! inet_ntoa(claim), machine, inet_ntoa(actual.sin_addr));
svcerr_auth(transp,AUTH_REJECTEDVERF);
return(1);
}
***************
*** 394,399 ****
--- 513,521 ----
goto fail;
}
close(fd);
+ #ifdef LOG_REQUESTS
+ syslog(LOG_INFO, "mount request for %s from %s", path, machine);
+ #endif
for(ex = exports; ex != NULL; ex = ex->ex_next) {
if (debug)
fprintf(stdout, "checking %s %o for %o\n", ex->ex_name, ex->ex_dev, statbuf.st_dev);
***************
*** 824,829 ****
--- 946,952 ----
fclose(fp);
exports = ex;
+ #ifndef _AIX
while (ex) {
if (debug)
printf("exportfs: fs=%s, rootid=%d, flags=%x\n",
***************
*** 832,838 ****
ex = ex->ex_next;
}
ex = exports;
!
return;
}
--- 955,961 ----
ex = ex->ex_next;
}
ex = exports;
! #endif
return;
}
***************
*** 840,850 ****
--- 963,975 ----
char *str;
struct exports *ex;
{
+ #ifdef EX_FASCIST
if (!strcmp(str,"fascist") || !strcmp(str,"restricted")) {
ex->ex_flags |= EX_FASCIST;
fascist++;
return;
}
+ #endif
if (!strcmp(str,"ro")) {
ex->ex_flags |= EX_RDONLY;
return;
***************
*** 905,911 ****
register struct authunix_parms *credp =
(struct authunix_parms *) rqstp->rq_clntcred;
struct authunix_parms ncred, *np = &ncred;
- struct passwd *pw, pwbuf;
static char thishost[255];
rpc_uid_t uid;
gid_t *initgroups();
--- 1030,1035 ----
***************
*** 915,921 ****
long time();
if (thishost[0] == '\0')
! gethostname(thishost, 255);
if (!svc_getargs(transp, xdr_krbtkt, &kauth)) {
svcerr_decode(transp);
return;
--- 1039,1045 ----
long time();
if (thishost[0] == '\0')
! gethostname(thishost, sizeof (thishost));
if (!svc_getargs(transp, xdr_krbtkt, &kauth)) {
svcerr_decode(transp);
return;
***************
*** 945,951 ****
if (d.dptr == NULL) {
#ifdef OLDFASCIST
if (fascist) break;
! #endif OLDFASCIST
svc_freeargs(transp, xdr_krbtkt, &kauth);
svcerr_weakauth(transp);
return;
--- 1069,1078 ----
if (d.dptr == NULL) {
#ifdef OLDFASCIST
if (fascist) break;
! #endif
! #ifdef DEBUG
! fprintf (stderr, "Couldn't find user \"%s\".\n", user);
! #endif
svc_freeargs(transp, xdr_krbtkt, &kauth);
svcerr_weakauth(transp);
return;
***************
*** 963,969 ****
np->aup_gid = up.gid;
np->aup_len = up.glen;
np->aup_gids = up.gids;
-
if (debug) {
fprintf(stdout,
"Mapping user \"%s\", uid %d on %s to uid %d\n",
--- 1090,1095 ----
***************
*** 972,978 ****
fflush(stdout);
disp_cred(np);
}
!
errno = 0;
if (nfsmapctl(NFSMC_SET, &client_addr,
sizeof(struct sockaddr_in), uid, np) < 0) {
--- 1098,1107 ----
fflush(stdout);
disp_cred(np);
}
! #ifdef LOG_REQUESTS
! syslog (LOG_INFO, "map %s:%d to local uid %d",
! inet_ntoa(client_addr.sin_addr), uid, up.uid);
! #endif
errno = 0;
if (nfsmapctl(NFSMC_SET, &client_addr,
sizeof(struct sockaddr_in), uid, np) < 0) {
***************
*** 983,988 ****
--- 1112,1121 ----
case KUID_DELETE:
uid = credp->aup_uid;
+ #ifdef LOG_REQUESTS
+ syslog (LOG_INFO, "unmap %s:%d",
+ inet_ntoa(client_addr.sin_addr), uid);
+ #endif
if (nfsmapctl (NFSMC_DELETE, &client_addr,
sizeof(struct sockaddr_in), uid, NULL) < 0) {
perror("nfs_mapctl(NFSMC_DELETE)");
***************
*** 992,997 ****
--- 1125,1134 ----
case KUID_PURGE:
uid = credp->aup_uid;
+ #ifdef LOG_REQUESTS
+ syslog (LOG_INFO, "purge %s:%d",
+ inet_ntoa(client_addr.sin_addr), uid);
+ #endif
if (nfsmapctl (NFSMC_FLUSH, &client_addr,
sizeof(struct sockaddr_in), uid, NULL) < 0) {
perror("nfs_mapctl(NFSMC_FLUSH)");
***************
*** 1021,1027 ****
uid, inet_ntoa(client_addr.sin_addr));
fflush(stdout);
}
!
if (nfsmapctl(NFSMC_UFLUSH, &client_addr,
sizeof(struct sockaddr_in), uid, NULL) < 0) {
perror("nfs_mapctl(NFSMC_UFLUSH)");
--- 1158,1166 ----
uid, inet_ntoa(client_addr.sin_addr));
fflush(stdout);
}
! #ifdef LOG_REQUESTS
! syslog (LOG_INFO, "user-purge uid %d", uid);
! #endif
if (nfsmapctl(NFSMC_UFLUSH, &client_addr,
sizeof(struct sockaddr_in), uid, NULL) < 0) {
perror("nfs_mapctl(NFSMC_UFLUSH)");
***************
*** 1080,1089 ****
}
if (nfsmapctl(NFSMC_EXPIRE,
(struct sockaddr_in *)NULL, sizeof(struct sockaddr_in),
! 0, (struct authunix_parms *)NULL) < 0) {
! perror("nfs_mapctl(NFSMC_EXPIRE)");
! fprintf(stderr, "Errno = %d\n", errno);
! }
break;
--- 1219,1226 ----
}
if (nfsmapctl(NFSMC_EXPIRE,
(struct sockaddr_in *)NULL, sizeof(struct sockaddr_in),
! 0, (struct authunix_parms *)NULL) < 0)
! syslog (LOG_ERR, "nfs_mapctl(NFSMC_EXPIRE): %m");
break;
***************
*** 1091,1095 ****
--- 1228,1279 ----
break;
}
return;
+ }
+ #endif
+
+ #ifdef _AIX
+
+ #include <sys/dstat.h>
+ #include <sys/dustat.h>
+
+ /*
+ * Manufacture a file system handle
+ */
+ getfh(fd, filehp)
+ int fd;
+ struct svcfh *filehp;
+ {
+ struct dstat dbuf;
+ struct dustat ubuf;
+ register int i;
+ char *point;
+
+ /* zero out the file handle */
+ point = (char *)filehp;
+ for (i=0; i<NFS_FHSIZE; i++)
+ point[i] = 0;
+
+ if (dfstat(fd, &dbuf, sizeof(dbuf)) < 0)
+ return -1;
+ else {
+ filehp->fh_gfs = dbuf.dst_gfs;
+ filehp->fh_inode = dbuf.dst_ino;
+ filehp->fh_uniqid = dbuf.dst_uniqid;
+ /* filehp->fh_root = TRUE; */
+ if (site(0) == dbuf.dst_css)
+ filehp->fh_local = 1;
+ else {
+ ubuf.du_pckno = -1;
+ dustat(dbuf.dst_gfs, -1, &ubuf, sizeof(ubuf));
+ /* errno = ENOSTORE if this site
+ * does not have a copy of the file system
+ */
+ if ((!errno) && ((int)ubuf.du_flags & SB_REPLTYPE))
+ filehp->fh_local = 2;
+ else
+ filehp->fh_local = 3;
+ }
+ }
+ return 0;
}
#endif