1*cacf2d0fSgrant /* $NetBSD: yppasswdd_mkpw.c,v 1.11 2003/11/12 13:31:07 grant Exp $ */ 2d3e1a366Sthorpej 3d3e1a366Sthorpej /* 4*cacf2d0fSgrant * Copyright (c) 1996 Jason R. Thorpe <thorpej@NetBSD.org> 5d3e1a366Sthorpej * All rights reserved. 6d3e1a366Sthorpej * 7d3e1a366Sthorpej * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se> 8d3e1a366Sthorpej * All rights reserved. 9d3e1a366Sthorpej * 10d3e1a366Sthorpej * Redistribution and use in source and binary forms, with or without 11d3e1a366Sthorpej * modification, are permitted provided that the following conditions 12d3e1a366Sthorpej * are met: 13d3e1a366Sthorpej * 1. Redistributions of source code must retain the above copyright 14d3e1a366Sthorpej * notice, this list of conditions and the following disclaimer. 15d3e1a366Sthorpej * 2. Redistributions in binary form must reproduce the above copyright 16d3e1a366Sthorpej * notice, this list of conditions and the following disclaimer in the 17d3e1a366Sthorpej * documentation and/or other materials provided with the distribution. 18d3e1a366Sthorpej * 3. All advertising materials mentioning features or use of this software 19d3e1a366Sthorpej * must display the following acknowledgement: 20d3e1a366Sthorpej * This product includes software developed by Mats O Jansson 21d3e1a366Sthorpej * 4. The name of the author may not be used to endorse or promote products 22d3e1a366Sthorpej * derived from this software without specific prior written permission. 23d3e1a366Sthorpej * 24d3e1a366Sthorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 25d3e1a366Sthorpej * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26d3e1a366Sthorpej * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27d3e1a366Sthorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 28d3e1a366Sthorpej * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29d3e1a366Sthorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30d3e1a366Sthorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31d3e1a366Sthorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32d3e1a366Sthorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33d3e1a366Sthorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34d3e1a366Sthorpej * SUCH DAMAGE. 35d3e1a366Sthorpej */ 36d3e1a366Sthorpej 37308c65aaSad #include <sys/cdefs.h> 38308c65aaSad #ifndef lint 39*cacf2d0fSgrant __RCSID("$NetBSD: yppasswdd_mkpw.c,v 1.11 2003/11/12 13:31:07 grant Exp $"); 40308c65aaSad #endif /* not lint */ 41308c65aaSad 42d3e1a366Sthorpej #include <sys/types.h> 437ebe3b4aStron #include <sys/param.h> 44d3e1a366Sthorpej #include <sys/stat.h> 45d3e1a366Sthorpej #include <sys/time.h> 46d3e1a366Sthorpej #include <sys/resource.h> 47d3e1a366Sthorpej #include <sys/wait.h> 48308c65aaSad 49a5e58d3dSthorpej #include <err.h> 50d3e1a366Sthorpej #include <fcntl.h> 51d3e1a366Sthorpej #include <stdio.h> 52d3e1a366Sthorpej #include <pwd.h> 53d3e1a366Sthorpej #include <signal.h> 54d3e1a366Sthorpej #include <stdlib.h> 553ab02a87Smatt #include <string.h> 56d3e1a366Sthorpej #include <unistd.h> 57d3e1a366Sthorpej #include <util.h> 58308c65aaSad #include <limits.h> 59d3e1a366Sthorpej 60d3e1a366Sthorpej #include <rpc/rpc.h> 61d3e1a366Sthorpej #include <rpc/xdr.h> 62d3e1a366Sthorpej #include <rpcsvc/yppasswd.h> 63d3e1a366Sthorpej 64308c65aaSad #include "extern.h" 65d3e1a366Sthorpej 66d3e1a366Sthorpej int handling_request; /* simple mutex */ 67d3e1a366Sthorpej 68d3e1a366Sthorpej void 69308c65aaSad make_passwd(yppasswd *argp, struct svc_req *rqstp, SVCXPRT *transp) 70d3e1a366Sthorpej { 7127b46820Sbouyer struct passwd pw; 72a5e58d3dSthorpej int pfd, tfd; 737ebe3b4aStron char mpwd[MAXPATHLEN]; 7427b46820Sbouyer char buf[8192]; /* from libutil */ 7527b46820Sbouyer FILE *fpw; 76d3e1a366Sthorpej 77d3e1a366Sthorpej #define REPLY(val) do { \ 78d3e1a366Sthorpej int res = (val); \ 79d3e1a366Sthorpej if (!svc_sendreply(transp, xdr_int, (caddr_t)&res)) \ 80d3e1a366Sthorpej svcerr_systemerr(transp); \ 81d3e1a366Sthorpej } while (0) 82d3e1a366Sthorpej 83d3e1a366Sthorpej #define RETURN(val) do { \ 84d3e1a366Sthorpej REPLY((val)); \ 85d3e1a366Sthorpej handling_request = 0; \ 86d3e1a366Sthorpej return; \ 87d3e1a366Sthorpej } while (0) 88d3e1a366Sthorpej 89d3e1a366Sthorpej if (handling_request) { 90d3e1a366Sthorpej warnx("already handling request; try again later"); 91d3e1a366Sthorpej REPLY(1); 92d3e1a366Sthorpej return; 93d3e1a366Sthorpej } 94d3e1a366Sthorpej handling_request = 1; 95d3e1a366Sthorpej 9627b46820Sbouyer (void)strlcpy(mpwd, pw_getprefix(), sizeof(mpwd)); 9727b46820Sbouyer (void)strlcat(mpwd, _PATH_MASTERPASSWD, sizeof(mpwd)); 9827b46820Sbouyer fpw = fopen(mpwd, "r"); 9927b46820Sbouyer if (fpw == NULL) { 10027b46820Sbouyer warnx("%s", mpwd); 101d3e1a366Sthorpej RETURN(1); 10227b46820Sbouyer } 10327b46820Sbouyer for(;;) { 10427b46820Sbouyer if (fgets(buf, sizeof(buf), fpw) == NULL) { 10527b46820Sbouyer if (feof(fpw)) 10627b46820Sbouyer warnx("%s: %s not found", mpwd, 10727b46820Sbouyer argp->newpw.pw_name); 10827b46820Sbouyer else 10927b46820Sbouyer warnx("%s: %s", mpwd, strerror(errno)); 11027b46820Sbouyer RETURN(1); 11127b46820Sbouyer } 11227b46820Sbouyer if (pw_scan(buf, &pw, NULL) == 0) 11327b46820Sbouyer continue; 11427b46820Sbouyer if (strncmp(argp->newpw.pw_name, pw.pw_name, MAXLOGNAME) == 0) 11527b46820Sbouyer break; 11627b46820Sbouyer } 11727b46820Sbouyer fclose(fpw); 11827b46820Sbouyer if (*pw.pw_passwd && 11927b46820Sbouyer strcmp(crypt(argp->oldpass, pw.pw_passwd), pw.pw_passwd) != 0) 120d3e1a366Sthorpej RETURN(1); 121d3e1a366Sthorpej 122d3e1a366Sthorpej pw_init(); 123d3e1a366Sthorpej tfd = pw_lock(0); 124d3e1a366Sthorpej if (tfd < 0) { 125d3e1a366Sthorpej warnx("the passwd file is busy."); 126d3e1a366Sthorpej RETURN(1); 127d3e1a366Sthorpej } 1287ebe3b4aStron pfd = open(mpwd, O_RDONLY, 0); 129d3e1a366Sthorpej if (pfd < 0) { 130d3e1a366Sthorpej pw_abort(); 1317ebe3b4aStron warnx("%s", mpwd); 132d3e1a366Sthorpej RETURN(1); 133d3e1a366Sthorpej } 134d3e1a366Sthorpej 135d3e1a366Sthorpej /* 136d3e1a366Sthorpej * Get the new password. Reset passwd change time to zero; when 137d3e1a366Sthorpej * classes are implemented, go and get the "offset" value for this 138d3e1a366Sthorpej * class and reset the timer. 139d3e1a366Sthorpej */ 140d3e1a366Sthorpej if (!nopw) { 14127b46820Sbouyer pw.pw_passwd = argp->newpw.pw_passwd; 14227b46820Sbouyer pw.pw_change = 0; 143d3e1a366Sthorpej } 144d3e1a366Sthorpej if (!nogecos) 14527b46820Sbouyer pw.pw_gecos = argp->newpw.pw_gecos; 146d3e1a366Sthorpej if (!noshell) 14727b46820Sbouyer pw.pw_shell = argp->newpw.pw_shell; 148d3e1a366Sthorpej 14927b46820Sbouyer pw_copy(pfd, tfd, &pw, NULL); 150d3e1a366Sthorpej 15127b46820Sbouyer if (pw_mkdb(pw.pw_name, 0) < 0) { 152d3e1a366Sthorpej warnx("pw_mkdb failed"); 153d3e1a366Sthorpej pw_abort(); 154d3e1a366Sthorpej RETURN(1); 155d3e1a366Sthorpej } 156d3e1a366Sthorpej 157d3e1a366Sthorpej /* XXX RESTORE SIGNAL STATE? XXX */ 158d3e1a366Sthorpej 159d3e1a366Sthorpej /* Notify caller we succeeded. */ 160d3e1a366Sthorpej REPLY(0); 161d3e1a366Sthorpej 162d3e1a366Sthorpej /* Update the YP maps. */ 163d3e1a366Sthorpej if (chdir("/var/yp")) 164308c65aaSad err(EXIT_FAILURE, "/var/yp"); 165d3e1a366Sthorpej (void) umask(022); 166d3e1a366Sthorpej (void) system(make_arg); 167d3e1a366Sthorpej 168d3e1a366Sthorpej handling_request = 0; 169d3e1a366Sthorpej } 170