xref: /netbsd-src/usr.sbin/rpc.yppasswdd/yppasswdd_mkpw.c (revision 4472dbe5e3bd91ef2540bada7a7ca7384627ff9b)
1 /*	$NetBSD: yppasswdd_mkpw.c,v 1.4 1998/11/06 13:07:18 is Exp $	*/
2 
3 /*
4  * Copyright (c) 1996 Jason R. Thorpe <thorpej@NetBSD.ORG>
5  * All rights reserved.
6  *
7  * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by Mats O Jansson
21  * 4. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
25  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
28  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <sys/time.h>
40 #include <sys/resource.h>
41 #include <sys/wait.h>
42 #include <err.h>
43 #include <fcntl.h>
44 #include <stdio.h>
45 #include <pwd.h>
46 #include <signal.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <util.h>
50 
51 #include <rpc/rpc.h>
52 #include <rpc/xdr.h>
53 #include <rpcsvc/yppasswd.h>
54 
55 extern int noshell;
56 extern int nogecos;
57 extern int nopw;
58 extern int make;
59 extern char make_arg[];
60 
61 void	make_passwd __P((yppasswd *, struct svc_req *, SVCXPRT *));
62 
63 int	handling_request;		/* simple mutex */
64 
65 void
66 make_passwd(argp, rqstp, transp)
67 	yppasswd *argp;
68 	struct svc_req *rqstp;
69 	SVCXPRT *transp;
70 {
71 	struct passwd *pw;
72 	int pfd, tfd;
73 
74 #define REPLY(val)	do { \
75 		int res = (val); \
76 		if (!svc_sendreply(transp, xdr_int, (caddr_t)&res)) \
77 			svcerr_systemerr(transp); \
78 	} while (0)
79 
80 #define RETURN(val)	do { \
81 		REPLY((val)); \
82 		handling_request = 0; \
83 		return; \
84 	} while (0)
85 
86 	if (handling_request) {
87 		warnx("already handling request; try again later");
88 		REPLY(1);
89 		return;
90 	}
91 	handling_request = 1;
92 
93 	pw = getpwnam(argp->newpw.pw_name);
94 	if (!pw)
95 		RETURN(1);
96 
97 	if (*pw->pw_passwd &&
98 	    strcmp(crypt(argp->oldpass, pw->pw_passwd), pw->pw_passwd) != 0)
99 		RETURN(1);
100 
101 	pw_init();
102 	tfd = pw_lock(0);
103 	if (tfd < 0) {
104 		warnx("the passwd file is busy.");
105 		RETURN(1);
106 	}
107 	pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
108 	if (pfd < 0) {
109 		pw_abort();
110 		warnx(_PATH_MASTERPASSWD);
111 		RETURN(1);
112 	}
113 
114 	/*
115 	 * Get the new password.  Reset passwd change time to zero; when
116 	 * classes are implemented, go and get the "offset" value for this
117 	 * class and reset the timer.
118 	 */
119 	if (!nopw) {
120 		pw->pw_passwd = argp->newpw.pw_passwd;
121 		pw->pw_change = 0;
122 	}
123 	if (!nogecos)
124 		pw->pw_gecos = argp->newpw.pw_gecos;
125 	if (!noshell)
126 		pw->pw_shell = argp->newpw.pw_shell;
127 
128 	pw_copy(pfd, tfd, pw, NULL);
129 
130 	if (pw_mkdb() < 0) {
131 		warnx("pw_mkdb failed");
132 		pw_abort();
133 		RETURN(1);
134 	}
135 
136 	/* XXX RESTORE SIGNAL STATE? XXX */
137 
138 	/* Notify caller we succeeded. */
139 	REPLY(0);
140 
141 	/* Update the YP maps. */
142 	if (chdir("/var/yp"))
143 		err(1, "/var/yp");
144 	(void) umask(022);
145 	(void) system(make_arg);
146 
147 	handling_request = 0;
148 }
149