chiark / gitweb /
Build bugfixes (re version.h) and changelog updated.
[userv.git] / process.c
index 9f6fbc0b946fa7ed9965e48db2c4ac03bb59abd3..64afd5c419aba03a85e2e29c6b0b2123fc78c1e0 100644 (file)
--- a/process.c
+++ b/process.c
@@ -2,7 +2,7 @@
  * userv - process.c
  * daemon code to process one request (is parent of service process)
  *
- * Copyright (C)1996-1997 Ian Jackson
+ * Copyright (C)1996-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
@@ -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>
@@ -60,6 +61,7 @@
 
 #include "config.h"
 #include "common.h"
+#include "both.h"
 #include "daemon.h"
 #include "lib.h"
 #include "tokens.h"
@@ -73,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;
@@ -147,7 +149,7 @@ static void xfflush(FILE *file) {
 
 static void xfread(void *p, size_t sz) {
   size_t nr;
-  nr= fread(p,1,sz,srfile); if (nr == sz) return;
+  nr= working_fread(p,sz,srfile); if (nr == sz) return;
   if (ferror(srfile)) syscallerror("reading from client");
   blocksignals();
   assert(feof(srfile));
@@ -413,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);
@@ -495,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);
@@ -507,6 +509,7 @@ static void lookup_uidsgids(void) {
   serviceuser_shell= xstrsave(pw->pw_shell);
   serviceuser_uid= pw->pw_uid;
   
+  if (setregid(pw->pw_gid,pw->pw_gid)) syscallerror("setregid 1");
   if (initgroups(pw->pw_name,pw->pw_gid)) syscallerror("initgroups");
   if (setreuid(pw->pw_uid,pw->pw_uid)) syscallerror("setreuid 1");
   if (setreuid(pw->pw_uid,pw->pw_uid)) syscallerror("setreuid 2");
@@ -514,6 +517,7 @@ static void lookup_uidsgids(void) {
     if (!setreuid(pw->pw_uid,0)) miscerror("setreuid 3 unexpectedly succeeded");
     if (errno != EPERM) syscallerror("setreuid 3 failed in unexpected way");
   }
+  if (setregid(pw->pw_gid,pw->pw_gid)) syscallerror("setregid 2");
 
   service_ngids= getgroups(0,0); if (service_ngids == -1) syscallerror("getgroups(0,0)");
   if (service_ngids > MAX_GIDS) miscerror("service user is in far too many groups");
@@ -597,6 +601,7 @@ static void makenonexistentfd(int fd) {
     if (fdarray[fd].holdfd != -1) {
       if (close(fdarray[fd].holdfd))
        syscallfailure("close unwanted hold descriptor for %d",fd);
+      fdarray[fd].holdfd= -1;
     }
   }
 }
@@ -719,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,