Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 31 Mar 1997 20:51:07 -0500 (EST)
From:      Ron Bickers <rbickers@intercenter.net>
To:        Russ Panula <rpanula@dacmail.net>
Cc:        isp@FreeBSD.ORG
Subject:   Re: poppassd-4.0 port not working
Message-ID:  <Pine.BSI.3.95.970331204817.4236B-200000@gemini.intercenter.net>
In-Reply-To: <334644ab.11308130@mail.digitaladvantage.net>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
On Mon, 31 Mar 1997, Russ Panula wrote:

> >I've just installed a clean FreeBSD 2.2.1-RELEASE and the poppassd-4.0
> >port. It is hanging at waitpid() when I run it directly and returning a
> >500 Unable to change password error when run from inetd. 
> >
> >I've added the necessary NIS strings since they aren't in the port, so
> >I've covered that base.
> >
> >Anyone have a working port?
> 
> Just upgraded a box last night to 2.2.1-RELEASE.  I'm running into the same
> problem.
> 
> It looks like passwd gets forked, but the error message I end up with is:
> "passwd: getlogin: Undefined error: 0"
> 
> My C skills are pretty lacking, but if I get any further, I'll let you know.

I had a chance to plow through it and figure it out myself.  I've attached
a replacement 'patch-ab' from the ports collection and sent it to the
maintainer as well.

Use at your own risk as always.  There were some changes to the setuid
section.

---
Ron

[-- Attachment #2 --]
--- poppassd.c.orig	Mon Mar 31 16:00:34 1997
+++ poppassd.c	Mon Mar 31 16:03:16 1997
@@ -13,11 +13,11 @@
  * 
  * Doesn't actually change any passwords itself.  It simply listens for
  * incoming requests, gathers the required information (user name, old
- * password, new password) and executes /bin/passwd, talking to it over
+ * password, new password) and executes /usr/bin/passwd, talking to it over
  * a pseudo-terminal pair.  The advantage of this is that we don't need
  * to have any knowledge of either the password file format (which may
  * include dbx files that need to be rebuilt) or of any file locking
- * protocol /bin/passwd and cohorts may use (and which isn't documented).
+ * protocol /usr/bin/passwd and cohorts may use (and which isn't documented).
  *
  * The current version has been tested at NU under SunOS release 4.1.2 
  * and 4.1.3, and under HP-UX 8.02 and 9.01. We have tested the server 
@@ -29,7 +29,7 @@
  * Note that unencrypted passwords are transmitted over the network.  If
  * this bothers you, think hard about whether you want to implement the
  * password changing feature.  On the other hand, it's no worse than what
- * happens when you run /bin/passwd while connected via telnet or rlogin.
+ * happens when you run /usr/bin/passwd while connected via telnet or rlogin.
  * Well, maybe it is, since the use of a dedicated port makes it slightly
  * easier for a network snooper to snarf passwords off the wire.
  *
@@ -47,7 +47,7 @@
  * (which talks to /bin/password) is directly descended from Smith's
  * version, with changes for SunOS and HP-UX by Norstad (with help from
  * sample code in "Advanced Programming in the UNIX Environment"
- * by W. Richard Stevens). The code to report /bin/passwd error messages
+ * by W. Richard Stevens). The code to report /usr/bin/passwd error messages
  * back to the client in the final 500 response, and a new version of the
  * code to find the next free pty, is by Norstad.
  *        
@@ -145,8 +145,9 @@
 static char *P1[] =
    {"Old password:",
     "Changing password for *.\nOld password:",
+    "Changing local password for *.\nOld password:",
     "Changing password for * on *.\nOld password:",
-    "Changing NIS password for * on *.\nOld password:",
+    "Changing NIS password for * on *.\nOld Password: ",
     "Changing password for *\n*'s Old password:",
     ""};
 
@@ -165,7 +166,9 @@
     
 static char *P4[] =
    {"\n",
+    "\npasswd: rebuilding the database...\npasswd: done\n",
     "NIS entry changed on *\n",
+    "\n\nNIS password has been changed on *.\n",
     ""};
 
 
@@ -186,11 +189,7 @@
      
      *user = *oldpass = *newpass = 0;
      
-     if (openlog ("poppassd", LOG_PID, LOG_LOCAL2) < 0)
-     {
-	  WriteToClient ("500 Can't open syslog.");
-	       exit (1);
-     }
+     openlog("poppassd", LOG_PID, LOG_LOCAL2);
      
      WriteToClient ("200 poppassd v%s hello, who are you?", VERSION);
      ReadFromClient (line);
@@ -218,6 +217,7 @@
 
      if (chkPass (user, oldpass, pw) == FAILURE)
      {
+	  syslog(LOG_ERR, "Incorrect password from %s", user);
 	  WriteToClient ("500 Old password is incorrect.");
 	  exit(1);
      }
@@ -264,28 +264,28 @@
 
 	  if ((wpid = waitpid (pid, &wstat, 0)) < 0)
 	  {
-	       syslog (LOG_ERR, "wait for /bin/passwd child failed: %m");
+	       syslog (LOG_ERR, "wait for /usr/bin/passwd child failed: %m");
 	       WriteToClient ("500 Server error (wait failed), get help!");
 	       exit (1);
 	  }
 
 	  if (pid != wpid)
 	  {
-	       syslog (LOG_ERR, "wrong child (/bin/passwd waited for!");
+	       syslog (LOG_ERR, "wrong child (/usr/bin/passwd) waited for!");
 	       WriteToClient ("500 Server error (wrong child), get help!");
 	       exit (1);
 	  }
 
 	  if (WIFEXITED (wstat) == 0)
 	  {
-	       syslog (LOG_ERR, "child (/bin/passwd) killed?");
+	       syslog (LOG_ERR, "child (/usr/bin/passwd) killed?");
 	       WriteToClient ("500 Server error (funny wstat), get help!");
 	       exit (1);
 	  }
 
 	  if (WEXITSTATUS (wstat) != 0)
 	  {
-	       syslog (LOG_ERR, "child (/bin/passwd) exited abnormally");
+	       syslog (LOG_ERR, "child (/usr/bin/passwd) exited abnormally");
 	       WriteToClient ("500 Server error (abnormal exit), get help!");
 	       exit (1);
 	  }
@@ -304,17 +304,19 @@
      }
      else      /* Child */
      {
-	  /*
-	   * Become the user trying who's password is being changed.  We're
-	   * about to exec /bin/passwd with is setuid root anyway, but this
-	   * way it looks to the child completely like it's being run by
-	   * the normal user, which makes it do its own password verification
-	   * before doing any thing.  In theory, we've already verified the
-	   * password, but this extra level of checking doesn't hurt.  Besides,
-	   * the way I do it here, if somebody manages to change somebody
-	   * else's password, you can complain to your vendor about security
-	   * holes, not to me!
-	   */
+          /* Start new session - gets rid of controlling terminal. */
+   
+          if (setsid() < 0) {
+               syslog(LOG_ERR, "setsid failed: %m");
+               return(0);
+	  }
+
+	  /* Set login name */
+
+	  if (setlogin(user) < 0) {
+	       syslog(LOG_ERR, "setlogin failed: %m");
+	       return(0);
+          }
 	  setuid (pw->pw_uid);
 	  setgid (pw->pw_gid);
 	  dochild (master, slavedev, user);
@@ -324,7 +326,7 @@
 /*
  * dochild
  *
- * Do child stuff - set up slave pty and execl /bin/passwd.
+ * Do child stuff - set up slave pty and execl /usr/bin/passwd.
  *
  * Code adapted from "Advanced Programming in the UNIX Environment"
  * by W. Richard Stevens.
@@ -338,13 +340,6 @@
    int slave;
    struct termios stermios;
 
-   /* Start new session - gets rid of controlling terminal. */
-   
-   if (setsid() < 0) {
-      syslog(LOG_ERR, "setsid failed: %m");
-      return(0);
-   }
-
    /* Open slave pty and acquire as new controlling terminal. */
 
    if ((slave = open(slavedev, O_RDWR)) < 0) {
@@ -387,10 +382,10 @@
       return(0);
    }
 
-   /* Fork /bin/passwd. */
+   /* Fork /usr/bin/passwd. */
 
-   if (execl("/bin/passwd", "passwd", user, (char*)0) < 0) {
-      syslog(LOG_ERR, "can't exec /bin/passwd: %m");
+   if (execl("/usr/bin/passwd", "passwd", user, (char*)0) < 0) {
+      syslog(LOG_ERR, "can't exec /usr/bin/passwd: %m");
       return(0);
    }
 }
@@ -408,15 +403,20 @@
  *
  * Modified by Norstad to remove assumptions about number of pty's allocated
  * on this UNIX box.
+ *
+ * Modified by Stephen Melvin to allocate local space for static character
+ * array, rather than local space to pointer to constant string, which is
+ * not kosher and was crashing FreeBSD 1.1.5.1.
  */
 findpty (slave)
 char **slave;
 {
    int master;
-   static char *line = "/dev/ptyXX";
+   static char line[11];
    DIR *dirp;
    struct dirent *dp;
 
+   strcpy(line,"/dev/ptyXX");
    dirp = opendir("/dev");
    while ((dp = readdir(dirp)) != NULL) {
       if (strncmp(dp->d_name, "pty", 3) == 0 && strlen(dp->d_name) == 5) {
@@ -485,9 +485,11 @@
      }
 
      writestring(master, pswd);
-
+     sleep(2);
      if (!expect(master, P4, buf)) return FAILURE;
 
+     close(master);
+
      return SUCCESS;
 }
 
@@ -566,6 +568,7 @@
 	}
 	n += m;
 	buf[n] = 0;
+/* syslog(LOG_ERR, "read from child: %s",buf); */
 	initialSegment = 0;
         for (s = expected; **s != 0; s++) {
            result = match(buf, *s);

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSI.3.95.970331204817.4236B-200000>