chiark / gitweb /
Portability and doc fixes, including my own portability patches and some suggestions...
authorian <ian>
Wed, 7 Apr 1999 22:33:33 +0000 (22:33 +0000)
committerian <ian>
Wed, 7 Apr 1999 22:33:33 +0000 (22:33 +0000)
15 files changed:
INSTALL
Makefile.in
acconfig.h
client.c
common.h
configure.in
daemon.h
debian/changelog
debug.c
lib.c
lib.h
overlord.c
parser.c
process.c
servexec.c

diff --git a/INSTALL b/INSTALL
index 304f2a3..3fe9052 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -14,7 +14,7 @@ Programs:
 
 * md5sum (GNU textutils; alternatively, Colin Plumb's, as shipped with
           Debian in the `dpkg' package) - used during build only
-* GNU m4 (only if you need to change the m4 input)
+* GNU m4 [fixme: should ship the output]
 * GNU make
 * GNU flex [fixme: should ship the output]
 * GCC is preferred but other compilers ought to work (though
@@ -205,3 +205,19 @@ PROBLEMS
   The bug is actually in your system header files, for not specifying
   the number and types of arguments to signal handler functions when
   they cast in the SIG_IGN and SIG_DFL macros.
+
+DEBUGGING VERSION
+
+If you run configure with --enable-debug, a debugging version will be
+built.  This will look in the current directory (the build directory)
+for the base of various things, including the IPC area (which you must
+therefore construct yourself).  The debugging version will produce
+extra output at various points.  It will not attempt to call
+setgroups(), instead just checking that the groups list is right, so
+it will work non-setuid if the daemon is invoked as the service user.
+The daemon won't fork for each request; instead, it will handle a
+single request and exit.
+
+There may be other changes.  Consult the code for details.  Making the
+debugging version of the client or daemon setuid root is probably a
+bad idea.  They may not work if they are run as different users.
index 593daec..88d8bb5 100644 (file)
@@ -1,6 +1,6 @@
 #  userv - Makefile.in
 #  
-#  Copyright (C)1996-1997 Ian Jackson
+#  Copyright (C)1996-1997,1999 Ian Jackson
 #  
 #  This is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@ CC=@CC@
 CFLAGS=@CFLAGS@ $(XCFLAGS) -DVERSION='"$(VERSION)"' -DVEREXT='"$(VEREXT)"' $(WERROR)
 OPTIMISE=@OPTIMISE@
 CPPFLAGS=@DEBUGDEFS@ $(XCPPFLAGS)
-LDLIBS=@DEBUGLIBS@ $(XLDLIBS)
+LDLIBS=@DEBUGLIBS@ @LIBS@ $(XLDLIBS)
 
 M4=m4
 M4FLAGS=
@@ -61,9 +61,9 @@ install:      all
                $(INSTALL_PROGRAM) -s -o root -g root -m 4755 client $(bindir)/userv
                $(INSTALL) -d -o root -g root -m 2755 $(etcsubdir) \
        $(etcsubdir)/default.d $(etcsubdir)/services.d $(etcsubdir)/override.d
-               if ! test -f $(etcsubdir)/system.default; then \
+               if test ! -f $(etcsubdir)/system.default; then \
                        $(INSTALL_DATA) -o root -g root system.default $(etcsubdir); fi
-               if ! test -f $(etcsubdir)/system.override; then \
+               if test ! -f $(etcsubdir)/system.override; then \
                        $(INSTALL_DATA) -o root -g root system.override $(etcsubdir); fi
 
 daemon:                overlord.o process.o servexec.o parserlexer.o debug.o lib.o both.o
@@ -95,7 +95,7 @@ parserlexer.o:        lexer.c parser.c config.h common.h pcsum.h daemon.h lib.h tokens.
                $(CC) -c $(CPPFLAGS) $(CFLAGS) lexer.c -o $@
 
 pcsum.h:       common.h config.h config.status Makefile
-               cat $^ | md5sum | sed -e 's/../0x&,/g; s/,$$//;' >pcsum.h.new
+               cat $^ | md5sum | sed -e 's/  -$$//; s/../0x&,/g; s/,$$//;' >pcsum.h.new
                cmp pcsum.h.new pcsum.h || mv -f pcsum.h.new pcsum.h
                @rm -f pcsum.h.new
 
index 6e2356e..80cec87 100644 (file)
@@ -2,7 +2,7 @@
  * userv - acconfig.h
  * extra stuff for config.h.in (autoconf)
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -22,6 +22,9 @@
 /* Define if EPROTO exists.  */
 #undef HAVE_EPROTO
 
+/* Define if LOG_AUTHPRIV exists.  */
+#undef HAVE_LOG_AUTHPRIV
+
 /* Define if function attributes a la GCC 2.5 and higher are available.  */
 #undef HAVE_GNUC25_ATTRIB
 
 #define EPROTO 0
 #endif
 
+/* LOG_AUTHPRIV */
+#ifndef HAVE_LOG_AUTHPRIV
+#define LOG_AUTHPRIV LOG_AUTH
+#endif
+
 /* GNU C attributes. */
 #ifndef FUNCATTR
 #ifdef HAVE_GNUC25_ATTRIB
index 243a333..ff9de73 100644 (file)
--- a/client.c
+++ b/client.c
@@ -2,7 +2,7 @@
  * userv - client.c
  * client code
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -128,7 +128,7 @@ static uid_t myuid, spoofuid;
 static gid_t mygid, spoofgid, *gidarray;
 static int ngids;
 static struct opening_msg opening_mbuf;
-static const char *logname;
+static const char *loginname;
 static char *cwdbuf;
 static size_t cwdbufsize;
 static char *ovbuf;
@@ -855,18 +855,18 @@ static void determine_users(void) {
   
   spoofuid= myuid;
   spoofgid= mygid;
-  logname= getenv("LOGNAME");
-  if (!logname) logname= getenv("USER");
-  if (logname) {
-    pw= getpwnam(logname);
-    if (!pw || pw->pw_uid != myuid) logname= 0;
+  loginname= getenv("LOGNAME");
+  if (!loginname) loginname= getenv("USER");
+  if (loginname) {
+    pw= getpwnam(loginname);
+    if (!pw || pw->pw_uid != myuid) loginname= 0;
   }
-  if (!logname) {
+  if (!loginname) {
     pw= getpwuid(myuid); if (!pw) miscerror("cannot determine your login name");
-    logname= pw->pw_name;
+    loginname= pw->pw_name;
   }
 
-  if (!strcmp(serviceuser,"-")) serviceuser= logname;
+  if (!strcmp(serviceuser,"-")) serviceuser= loginname;
   pw= getpwnam(serviceuser);
   if (!pw) miscerror("requested service user `%s' is not a user",serviceuser);
   serviceuid= pw->pw_uid;
@@ -876,9 +876,9 @@ static void determine_users(void) {
               " the user who will be providing the service");
 
   if (spoofuser) {
-    logname= spoofuser;
-    pw= getpwnam(logname);
-    if (!pw) miscerror("spoofed login name `%s' is not valid",logname);
+    loginname= spoofuser;
+    pw= getpwnam(loginname);
+    if (!pw) miscerror("spoofed login name `%s' is not valid",loginname);
     spoofuid= pw->pw_uid;
     spoofgid= pw->pw_gid;
     ngidssize= ngids; ngids= 0;
@@ -888,7 +888,7 @@ static void determine_users(void) {
     }
     gidarray[ngids++]= spoofgid;
     while ((gr= getgrent())) { /* ouch! getgrent has no error behaviour! */
-      for (mem= gr->gr_mem; *mem && strcmp(*mem,logname); mem++);
+      for (mem= gr->gr_mem; *mem && strcmp(*mem,loginname); mem++);
       if (!*mem) continue;
       if (ngids>=ngidssize) {
       if (ngids>=MAX_GIDS) miscerror("spoofed user is member of too many groups");
@@ -1050,7 +1050,7 @@ static void server_sendrequest(int argc, char *const *argv) {
   request_mbuf.clientpid= getpid();
   request_mbuf.serviceuserlen= strlen(serviceuser);
   request_mbuf.servicelen= strlen(argv[0]);
-  request_mbuf.lognamelen= strlen(logname);
+  request_mbuf.loginnamelen= strlen(loginname);
   request_mbuf.spoofed= spoofuser ? 1 : 0;
   request_mbuf.cwdlen= cwdbufsize;
   request_mbuf.callinguid= spoofuid;
@@ -1069,7 +1069,7 @@ static void server_sendrequest(int argc, char *const *argv) {
   xfwrite(&request_mbuf,sizeof(request_mbuf),swfile);
   xfwrite(serviceuser,sizeof(*serviceuser)*request_mbuf.serviceuserlen,swfile);
   xfwrite(argv[0],sizeof(*argv[0])*request_mbuf.servicelen,swfile);
-  xfwrite(logname,sizeof(*logname)*request_mbuf.lognamelen,swfile);
+  xfwrite(loginname,sizeof(*loginname)*request_mbuf.loginnamelen,swfile);
   xfwrite(cwdbuf,sizeof(*cwdbuf)*request_mbuf.cwdlen,swfile);
   if (ovused>=0) xfwrite(ovbuf,sizeof(*ovbuf)*ovused,swfile);
   xfwrite(&spoofgid,sizeof(gid_t),swfile);
index f385fc9..6b287da 100644 (file)
--- a/common.h
+++ b/common.h
@@ -2,7 +2,7 @@
  * userv - common.h
  * definitions shared between client and daemon
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -85,14 +85,14 @@ struct request_msg {
   pid_t clientpid; /* or -1 if no service is required and this was a version check */
   int serviceuserlen;
   int servicelen;
-  int lognamelen, spoofed; /* spoofed is 0 or 1 */
+  int loginnamelen, spoofed; /* spoofed is 0 or 1 */
   int cwdlen, overridelen;
   uid_t callinguid;
   int ngids, nreadfds, nwritefds, nargs, nvars;
   /* Followed by:
    *   serviceuserlen bytes for the service user (unterminated)
    *   servicelen bytes for the service (unterminated)
-   *   lognamelen bytes for the login name (unterminated)
+   *   loginnamelen bytes for the login name (unterminated)
    *   cwdlen bytes for the cwd (unterminated)
    *   overridelen bytes for the override data (with extra \n but unterminated),
    *    or nothing if overridelen==-1
index 2c7bb2d..ae8f041 100644 (file)
@@ -1,6 +1,6 @@
 #  userv - configure.in
 # 
-#  Copyright (C)1996-1997 Ian Jackson
+#  Copyright (C)1996-1997,1999 Ian Jackson
 #   
 #  This is free software; you can redistribute it and/or modify it
 #  under the terms of the GNU General Public License as published by
@@ -44,6 +44,9 @@ AC_PROG_INSTALL
 
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 
+AC_CHECK_LIB(socket,socket)
+AC_CHECK_FUNCS(setenv)
+
 AC_CACHE_CHECK(for EPROTO,userv_cv_hdr_eproto,
  AC_EGREP_CPP(yes,
 [
@@ -57,6 +60,19 @@ then
        AC_DEFINE(HAVE_EPROTO)
 fi
 
+AC_CACHE_CHECK(for LOG_AUTHPRIV,userv_cv_hdr_logauthpriv,
+ AC_EGREP_CPP(yes,
+[
+#include <syslog.h>
+#ifdef LOG_AUTHPRIV
+ yes
+#endif
+],userv_cv_hdr_logauthpriv=yes,userv_cv_hdr_logauthpriv=no))
+if test $userv_cv_hdr_logauthpriv = yes
+then
+       AC_DEFINE(HAVE_LOG_AUTHPRIV)
+fi
+
 AC_SUBST(OPTIMISE)
 if test "${GCC-no}" = yes; then
  OPTIMISE=-O2
index 945d651..7db8440 100644 (file)
--- a/daemon.h
+++ b/daemon.h
@@ -2,7 +2,7 @@
  * userv - daemon.h
  * definitions used in the daemon's source code
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -157,7 +157,7 @@ extern int fdarraysize, fdarrayused;
 extern int restfdwantstate, restfdwantrw;
 extern int service_ngids;
 extern char **argarray;
-extern char *serviceuser, *service, *logname, *cwd;
+extern char *serviceuser, *service, *loginname, *cwd;
 extern char *overridedata, *userrcfile;
 extern char *serviceuser_dir, *serviceuser_shell, *callinguser_shell;
 extern gid_t *calling_gids, *service_gids;
index 8abf253..02fd2e3 100644 (file)
@@ -1,8 +1,19 @@
-userv (0.61) unstable; urgency=low
-
-  * Document locations of required programs in INSTALL.
-
- --
+userv (0.61.0) unreleased; urgency=low
+
+  INSTALL improvements:
+  * Document locations of required programs.
+  * Sort-of document debugging version.
+  
+  Portability fixes for:
+  * md5sum with extra `-'.
+  * -lsocket required for socket().
+  * missing `LOG_AUTHPRIV'.
+  * `logname' name clash.    
+  * missing setenv() (synthesize using putenv).
+  * various required #include's were omitted.
+  * install rule in Makefile `if ! test ...' changed to `if test ! ...'
+
+ -- Ian Jackson <ian@davenant.greenend.org.uk>  Wed,  7 Apr 1999 23:32:45 +0100
 
 userv (0.60.3) frozen unstable; urgency=medium
 
diff --git a/debug.c b/debug.c
index 6612545..5ec6f94 100644 (file)
--- a/debug.c
+++ b/debug.c
@@ -2,7 +2,7 @@
  * userv - ddebug.c
  * routines which are different for -DDEBUG
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
@@ -160,7 +160,7 @@ void debug_dumprequest(pid_t mypid) {
         "calling uid: %ld\n"
          "calling user shell: `%s'\n"
         "calling groups:",
-        logname, (long)request_mbuf.callinguid,
+        loginname, (long)request_mbuf.callinguid,
         callinguser_shell);
   groupsdump(request_mbuf.ngids,calling_gids,calling_groups);
   printf("\n"
diff --git a/lib.c b/lib.c
index 7a22d19..bd40ee0 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -25,6 +25,7 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 #include <sys/types.h>
 
 #include "config.h"
@@ -112,3 +113,19 @@ void snytprintfcat(char *buffer, size_t size, const char *fmt, ...) {
   vsnytprintfcat(buffer,size,fmt,al);
   va_end(al);
 }
+
+#ifndef HAVE_SETENV
+int setenv(const char *name, const char *value, int overwrite) {
+  static char *buffer= 0;
+  static int avail= 0;
+
+  int r;
+  
+  assert(overwrite==1);
+  r= makeroom(&buffer,&avail,strlen(name)+strlen(value)+2);
+  if (r) { errno= EINVAL; return -1; }
+
+  sprintf(buffer,"%s=%s",name,value);
+  return putenv(buffer);
+}
+#endif /* HAVE_SETENV */
diff --git a/lib.h b/lib.h
index c38f243..7d78cb9 100644 (file)
--- a/lib.h
+++ b/lib.h
@@ -56,4 +56,8 @@ void vsnytprintfcat(char *buffer, size_t size, const char *fmt, va_list al);
 void snytprintfcat(char *buffer, size_t size, const char *fmt, ...) PRINTFFORMAT(3,4);
 void strnytcat(char *dest, const char *src, size_t size);
 
+#ifndef HAVE_SETENV
+int setenv(const char *name, const char *value, int overwrite);
+#endif /* HAVE_SETENV */
+
 #endif /* LIB_H */
index b18102f..dfb58a2 100644 (file)
@@ -2,7 +2,7 @@
  * userv - overlord.c
  * daemon main program, collects request and forks handlers
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-1997,1999 Ian Jackson
  *
  * This is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by
 #include <fnmatch.h>
 #include <sys/wait.h>
 #include <sys/types.h>
-#include <sys/time.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
+#include <time.h>
 #include <dirent.h>
 #include <sys/un.h>
 
@@ -228,7 +228,7 @@ static void NONRETURNING docheck(void) {
   request_mbuf.clientpid= -1;
   request_mbuf.serviceuserlen= 0;
   request_mbuf.servicelen= 0;
-  request_mbuf.lognamelen= 0;
+  request_mbuf.loginnamelen= 0;
   request_mbuf.spoofed= 0;
   request_mbuf.cwdlen= 0;
   request_mbuf.overridelen= -1;
index b00baac..5f6ebad 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -499,7 +499,7 @@ static int pf_service(int ptoken, char ***rvalues) {
 }
 
 static int pf_callinguser(int ptoken, char ***rvalues) {
-  return parm_usernameuid(rvalues,logname,request_mbuf.callinguid);
+  return parm_usernameuid(rvalues,loginname,request_mbuf.callinguid);
 }
 
 static int pf_serviceuser(int ptoken, char ***rvalues) {
index 3ca468c..64afd5c 100644 (file)
--- a/process.c
+++ b/process.c
@@ -52,7 +52,8 @@
 #include <ctype.h>
 #include <limits.h>
 #include <sys/wait.h>
-#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <sys/fcntl.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -74,7 +75,7 @@ int fdarraysize, fdarrayused;
 int restfdwantstate= tokv_word_rejectfd, restfdwantrw;
 int service_ngids;
 char **argarray;
-char *serviceuser, *service, *logname, *cwd;
+char *serviceuser, *service, *loginname, *cwd;
 char *overridedata, *userrcfile;
 char *serviceuser_dir, *serviceuser_shell, *callinguser_shell;
 gid_t *calling_gids, *service_gids;
@@ -414,7 +415,7 @@ static void receive_request(void) {
   serviceuser= xfreadsetstring(request_mbuf.serviceuserlen);
   service= xfreadsetstring(request_mbuf.servicelen);
   assert(request_mbuf.spoofed==0 || request_mbuf.spoofed==1);
-  logname= xfreadsetstring(request_mbuf.lognamelen);
+  loginname= xfreadsetstring(request_mbuf.loginnamelen);
   cwd= xfreadsetstring(request_mbuf.cwdlen);
   if (request_mbuf.overridelen >= 0) {
     assert(request_mbuf.overridelen <= MAX_OVERRIDE_LEN);
@@ -496,9 +497,9 @@ static void groupnames(int ngids, gid_t *gids, const char ***names_r) {
 static void lookup_uidsgids(void) {
   struct passwd *pw;
 
-  pw= getpwnam(logname);
+  pw= getpwnam(loginname);
   if (!pw) miscerror("look up calling user");
-  assert(!strcmp(pw->pw_name,logname));
+  assert(!strcmp(pw->pw_name,loginname));
   callinguser_shell= xstrsave(pw->pw_shell);
 
   pw= getpwnam(serviceuser);
@@ -723,7 +724,7 @@ void servicerequest(int sfd) {
   debug_dumprequest(mypid);
   syslog(LOG_INFO,"%s %s -> %s %c %s",
         request_mbuf.spoofed ? "spoof" : "user",
-        logname, serviceuser, overridedata?'!':':', service);
+        loginname, serviceuser, overridedata?'!':':', service);
 
   if (overridedata)
     r= parse_string(TOPLEVEL_OVERRIDDEN_CONFIGURATION,
index 95c77a5..c1614f0 100644 (file)
@@ -138,13 +138,13 @@ static void serv_resetsignal(int signo) {
   if (sigaction(signo,&sig,0)) serv_syscallfail("reset signal handler");
 }
 
-static const char *see_logname(void) { return serviceuser; }
+static const char *see_loginname(void) { return serviceuser; }
 static const char *see_home(void) { return serviceuser_dir; }
 static const char *see_shell(void) { return serviceuser_shell; }
 
 static const char *see_service(void) { return service; }
 static const char *see_c_cwd(void) { return cwd; }
-static const char *see_c_logname(void) { return logname; }
+static const char *see_c_loginname(void) { return loginname; }
 static const char *see_c_uid(void) {
   static char buf[CHAR_BIT*sizeof(uid_t)/3+4];
   snyprintf(buf,sizeof(buf),"%lu",(unsigned long)request_mbuf.callinguid);
@@ -184,18 +184,18 @@ static const struct serv_envinfo {
   const char *name;
   const char *(*fn)(void);
 } serv_envinfos[]= {
-  { "USER",           see_logname    },
-  { "LOGNAME",        see_logname    },
-  { "HOME",           see_home       },
-  { "SHELL",          see_shell      },
-  { "PATH",           defaultpath    },
-  { "USERV_SERVICE",  see_service    },
-  { "USERV_CWD",      see_c_cwd      },
-  { "USERV_USER",     see_c_logname  },
-  { "USERV_UID",      see_c_uid      },
-  { "USERV_GROUP",    see_c_group    },
-  { "USERV_GID",      see_c_gid      },
-  {  0                               }
+  { "USER",           see_loginname   },
+  { "LOGNAME",        see_loginname   },
+  { "HOME",           see_home        },
+  { "SHELL",          see_shell       },
+  { "PATH",           defaultpath     },
+  { "USERV_SERVICE",  see_service     },
+  { "USERV_CWD",      see_c_cwd       },
+  { "USERV_USER",     see_c_loginname },
+  { "USERV_UID",      see_c_uid       },
+  { "USERV_GROUP",    see_c_group     },
+  { "USERV_GID",      see_c_gid       },
+  {  0                                }
 };
 
 void execservice(const int synchsocket[], int clientfd) {