From brewhq!uucpgate.hrz.th-darmstadt.de!infm.ulst.ac.uk!tjarls Tue Aug 30 21:56:00 1994
Return-Path: <brewhq!uucpgate.hrz.th-darmstadt.de!infm.ulst.ac.uk!tjarls>
Received: from brewhq by monad.swb.de  with uucp
	(smail3.1.28.1 #1) id m0qfZHe-000KkTC; Tue, 30 Aug 94 21:55 MET DST
Received: from uucpgate.hrz.th-darmstadt.de by brewhq.swb.de  with uucp
	(Linux Smail3.1.28.1 #1) id m0qfXLC-0005AnC; Tue, 30 Aug 94 19:51 MET DST
Received: from rs2.hrz.th-darmstadt.de by modem.hrz.th-darmstadt.de  with smtp
	(/\==/\ Smail3.1.28.1 #28.6) id <m0qfX1m-0005N3C>; Tue, 30 Aug 94 19:31 MEST
Received: from petrel.infm.ulst.ac.uk by rs2.hrz.th-darmstadt.de with SMTP id AA20105
  (5.65c/IDA-1.4.4 for <okir@monad.swb.de>); Tue, 30 Aug 1994 19:31:15 +0200
Received: (from tjarls@localhost) by petrel.infm.ulst.ac.uk (8.6.9/8.6.9) id SAA01142; Tue, 30 Aug 1994 18:34:07 +0100
Received: from Messages.8.5.N.CUILIB.3.45.SNAP.NOT.LINKED.petrel.infm.ulst.ac.uk.i386.Linux
          via MS.5.6.petrel.infm.ulst.ac.uk.i386_Linux;
          Tue, 30 Aug 1994 18:34:07 +0100 (BST)
Message-Id: <0iMqqDVz0001Q2_l5g@petrel.infm.ulst.ac.uk>
Date: Tue, 30 Aug 1994 18:34:07 +0100 (BST)
From: Charles Lopes <tjarls@infm.ulst.ac.uk>
To: info-nys@se.liu.lysator
Subject: yppasswdd + shadow
Cc: okir@monad.swb.de
Status: RO

Hi!
I've managed to add shadow support to yppasswdd-0.1 so /etc/shadow gets
updated. As you said, Olaf, it was straightforward. My yp.pwupdate
script still needs rewriting and so I didn't include it in my patches. I
linked yppasswdd with libc-nys and a "lite" version of libshadow (I
removed duplicated functions from libshadow) and tested it using two
linux boxes.It works but it still needs a few small changes. Here are my
patches (for whatever they are worth):
diff -ur yppasswd-0.1/Makefile yppasswd-0.1.new/Makefile
--- yppasswd-0.1/Makefile	Sun Aug  7 18:34:31 1994
+++ yppasswd-0.1.new/Makefile	Tue Aug 30 16:13:07 1994
@@ -4,9 +4,9 @@
 
 CFLAGS  = $(OPTFLAGS) $(INC) $(XCFLAGS)
 OPTFLAGS= -O2 -fomit-frame-pointer
-XCFLAGS = -D_GNU_SOURCE -DDEBUG
+XCFLAGS = -D_GNU_SOURCE -DSHADOWPWD
 CC	= gcc -Wall
-LIBS	= -lnsl
+LIBS	= -lshadow
 
 CLNTOBJ = yppasswd.o  yppasswd_xdr.o
 SRVROBJ = yppasswdd.o yppasswd_xdr.o yppasswd_svc.o
diff -ur yppasswd-0.1/yppasswdd.c yppasswd-0.1.new/yppasswdd.c
--- yppasswd-0.1/yppasswdd.c	Sun Aug  7 18:21:37 1994
+++ yppasswd-0.1.new/yppasswdd.c	Tue Aug 30 16:50:29 1994
@@ -20,6 +20,9 @@
 #include <ctype.h>
 #include <time.h>
 #include <pwd.h>
+#ifdef SHADOWPWD
+#include <shadow.h>
+#endif
 
 #include <getopt.h>
 #include <syslog.h>
@@ -77,14 +80,19 @@
  * The update handler
  *===============================================================*/
 int *
-yppasswdproc_update_1(yppasswd *yppw, struct svc_req *rqstp)
+yppasswdproc_update_1_svc(yppasswd *yppw, struct svc_req *rqstp)
 {
-    struct xpasswd *newpw;	/* passwd struct passed ba the client */
+    struct xpasswd *newpw;	/* passwd struct passed by the client */
+#ifndef SHADOWPWD
     struct passwd *pw;		/* passwd struct obtained from getpwent() */
-    static int	res;
     int		retries, gotit, fd, c;
-    char	logbuf[255];
     FILE	*oldfp, *newfp;
+#else
+    struct spwd *spw;
+    int		retries, c;
+#endif
+    static int	res;
+    char	logbuf[255];
 
     res = 1;
 
@@ -101,8 +109,12 @@
      * instead? This procedure is already slow enough...
      */
     retries = 0;
+#ifndef SHADOWPWD
     while ((fd = open(_PATH_PTMP, O_CREAT|O_WRONLY|O_EXCL)) < 0
       && errno == EEXIST && retries < MAX_RETRIES) {
+#else
+    while (!spw_lock() && retries < MAX_RETRIES) {
+#endif
         sleep (1);
         retries++;
     }
@@ -112,7 +124,8 @@
         syslog ( LOG_NOTICE, "password file locked" );
         return &res;
     }
-    
+
+#ifndef SHADOWPWD    
     if (fd < 0 || (newfp = fdopen(fd, "w")) == NULL) {
         syslog ( LOG_ERR, "%s failed", logbuf );
         syslog ( LOG_ERR, "Can't create %s. %m", _PATH_PTMP );
@@ -130,7 +143,6 @@
         return &res;
     }
 
-
     gotit = 0;
     newpw = &yppw->newpw;
 
@@ -195,12 +207,60 @@
     unlink (_PATH_PTMP);
     chmod (_PATH_PASSWD, 0644);
 
+#else
+
+    if (!spw_open(O_RDWR)) {
+        syslog ( LOG_ERR, "%s failed", logbuf );
+        syslog ( LOG_ERR, "Can't open %s: %m", _PATH_SHADOW);
+        spw_unlock();
+        return &res;
+    }
+
+    newpw = &yppw->newpw;
+    /*
+     * Get old shadow password entry
+     */
+    if (!(spw=spw_locate(newpw->pw_name))) {
+        syslog ( LOG_ERR, "%s failed", logbuf );
+        syslog ( LOG_ERR, "User not in password file." );
+        spw_close();
+	spw_unlock();
+        return (&res);
+    }
+    /*
+     * Check the password.
+     */
+    if (strcmp(crypt(yppw->oldpass, spw->sp_pwdp), spw->sp_pwdp)) {
+	syslog ( LOG_ERR, "%s rejected", logbuf );
+	syslog ( LOG_ERR, "Invalid password." );
+	spw_close();
+	spw_unlock();
+	return (&res);
+    }
+
+    spw->sp_pwdp=newpw->pw_passwd;
+
+    if (!spw_update(spw)) {
+	syslog ( LOG_ERR, "%s failed", logbuf );
+	syslog ( LOG_ERR, "Error while updating %s",  _PATH_SHADOW);
+	spw_close();
+	spw_unlock();
+	return (&res);
+    }
+
+    spw_close();
+    spw_unlock();
+
+#endif
+
     /* Fork off process to rebuild NIS passwd.* maps. If the fork
      * fails, restore old passwd file and return an error.
      */
     if ((c = fork()) < 0) {
+#ifndef SHADOWPWD
     	unlink( _PATH_PASSWD );
     	link( _PATH_OLDPASSWD, _PATH_PASSWD );
+#endif
     	syslog( LOG_ERR, "%s failed", logbuf );
     	syslog( LOG_ERR, "Couldn't fork map update process: %m" );
     	return (&res);


 ------------------
 Charles Lopes                       | Internet: Charles.Lopes@infm.ulst.ac.uk
 Computing Officer                   | Phone: +44 (0504) 265621
 Faculty of Informatics              | Phone extension: 5315
 Magee College, University of Ulster | Office: MB023

