chiark / gitweb /
changelog: we are 2.1.2~ not 2.1.2
[authbind.git] / libauthbind.c
index 183a206b25eb611193a0b574fd9443ccdba0b11c..42630e41a00686b66e3a41a6596deea8a16a1087 100644 (file)
@@ -31,8 +31,6 @@
 #include <sys/wait.h>
 #include <netinet/in.h>
 
-static const char *rcsid="$Id$";
-
 #include "authbind.h"
 
 typedef void anyfn_type(void);
@@ -148,9 +146,10 @@ int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
   pid_t child, rchild;
   char portarg[5], addrarg[33];
   const char *afarg;
-  int i, r, status;
+  int i, r, status, restore_sigchild;
   const int *evilsignal;
   sigset_t block, saved;
+  struct sigaction old_sigchild;
   unsigned int portval;
 
   switch (addr->sa_family) {
@@ -166,7 +165,7 @@ int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
     goto bail;
   }
 
-  if (!geteuid() || portval == 0 || portval >= IPPORT_RESERVED) {
+  if (!geteuid() || portval == 0 || ntohs(portval) >= IPPORT_RESERVED) {
   bail:
     return old_bind(fd,addr,addrlen);
   }
@@ -197,6 +196,18 @@ int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
   sprintf(portarg,"%04x",
          portval&0x0ffff);
 
+  restore_sigchild= 0;
+  if (sigaction(SIGCHLD,NULL,&old_sigchild)) return -1;
+  if (old_sigchild.sa_handler == SIG_IGN) {
+    struct sigaction new_sigchild;
+
+    new_sigchild.sa_handler= SIG_DFL;
+    sigemptyset(&new_sigchild.sa_mask);
+    new_sigchild.sa_flags= 0;
+    if (sigaction(SIGCHLD,&new_sigchild,&old_sigchild)) return -1;
+    restore_sigchild= 1;
+  }
+
   child= fork(); if (child==-1) goto x_err;
 
   if (!child) {
@@ -205,9 +216,7 @@ int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
     execl(HELPER,HELPER,addrarg,portarg,afarg,(char*)0);
     status= errno > 0 && errno < 127 ? errno : 127;
     STDERRSTR_CONST("libauthbind: possible installation problem - "
-                   "could not invoke " HELPER " (");
-    STDERRSTR_STRING(rcsid);
-    STDERRSTR_CONST(")\n");
+                   "could not invoke " HELPER "\n");
     exiterrno(status);
   }
 
@@ -232,5 +241,13 @@ x_err:
   r= -1;
 x:
   if (sigprocmask(SIG_SETMASK,&saved,0)) abort();
+  if (restore_sigchild) {
+    if (sigaction(SIGCHLD,&old_sigchild,NULL)) return -1;
+    if (old_sigchild.sa_handler == SIG_IGN) {
+      int discard;
+      while (waitpid(-1, &discard, WNOHANG) > 0)
+       ;
+    }
+  }
   return r;
 }