8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / ypcmd / yppasswd / changepasswd.c
blob8dca5c3cbd04e00eadec48bb0afe4c29db973b21
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Beware those who enter here.
28 * The logic may appear hairy, but it's been ARCed.
29 * See /shared/sac/PSARC/1995/122/mail
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <ctype.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <errno.h>
40 #include <syslog.h>
41 #include <pwd.h>
42 #include <shadow.h>
43 #include <signal.h>
44 #include <crypt.h>
45 #include <rpc/rpc.h>
46 #include <rpcsvc/yppasswd.h>
47 #include <utmpx.h>
48 #include <nss_dbdefs.h>
50 #define STRSIZE 100
51 #define FINGERSIZE (4 * STRSIZE - 4)
52 #define SHELLSIZE (STRSIZE - 2)
53 #define UTUSERLEN (sizeof (((struct utmpx *)0)->ut_user))
55 /* Prototypes */
56 extern bool_t validloginshell(char *sh, char *arg, int);
57 extern int validstr(char *str, size_t size);
58 extern int yplckpwdf();
59 extern int ypulckpwdf();
61 static char *
62 cryptoldpasswd(char *oldpass, char *salt, char *acctname)
64 char *oldpass_crypt = NULL;
66 if ((oldpass_crypt = crypt(oldpass, salt)) == NULL) {
67 if (errno == EINVAL) {
68 syslog(LOG_ERR,
69 "yppasswdd: password not changed for \"%s\" - "
70 "crypt module not supported on the master\n",
71 acctname);
72 } else {
73 syslog(LOG_ERR,
74 "yppasswdd: password not changed for \"%s\" - "
75 "%s\n", acctname, strerror(errno));
78 return (oldpass_crypt);
81 void
82 changepasswd(SVCXPRT *transp)
85 * Put these numeric constants into const variables so
86 * a) they're visible in a debugger
87 * b) the compiler can play it's cool games with em
89 static const int cryptpwsize = CRYPT_MAXCIPHERTEXTLEN;
90 static const int fingersize = FINGERSIZE;
91 static const int shellsize = SHELLSIZE;
93 struct yppasswd yppwd;
94 struct passwd newpw, opwd;
95 struct spwd ospwd;
96 struct sigaction sa, osa1, osa2, osa3;
97 struct stat pwstat, spstat, adjstat;
98 char *oldpass_crypt = NULL;
100 char newpasswdfile[FILENAME_MAX];
101 char newshadowfile[FILENAME_MAX];
102 char newadjunctfile[FILENAME_MAX];
103 char tmppasswdfile[FILENAME_MAX];
104 char tmpshadowfile[FILENAME_MAX];
105 char tmpadjunctfile[FILENAME_MAX];
106 char pwbuf[NSS_LINELEN_PASSWD], spbuf[NSS_LINELEN_SHADOW];
107 char adjbuf[BUFSIZ+1], adjbuf_new[BUFSIZ+1], cmdbuf[BUFSIZ];
108 char adj_encrypt[CRYPT_MAXCIPHERTEXTLEN + 1];
110 * The adj_crypt_* pointers are used to point into adjbuf
111 * NOT adj_encrypt
113 char *adj_crypt_begin, *adj_crypt_end;
114 char name[UTUSERLEN + sizeof (":")];
115 char *p;
117 FILE *opwfp = NULL, *ospfp = NULL, *oadjfp = NULL,
118 *npwfp = NULL, *nspfp = NULL, *nadjfp = NULL;
119 int npwfd = -1, nspfd = -1, nadjfd = -1;
121 int i, ans, chsh, chpw, chgecos, namelen;
122 int gotadjunct = 0, gotshadow = 0, gotpasswd = 0;
123 int doneflag = 0, root_on_master = 0;
124 pid_t retval;
126 time_t now;
128 long pwpos = 0, sppos = 0;
130 /* Globals :-( */
131 extern int single, nogecos, noshell, nopw, mflag, Mstart, Argc;
132 extern char **Argv;
133 extern char passwd_file[], shadow_file[], adjunct_file[];
134 extern int useadjunct;
135 extern int useshadow;
137 /* Clean out yppwd */
138 memset(&yppwd, 0, sizeof (struct yppasswd));
140 /* Get the RPC args */
141 if (!svc_getargs(transp, xdr_yppasswd, (caddr_t)&yppwd)) {
142 svcerr_decode(transp);
143 return;
146 /* Perform basic validation */
147 if (/* (!validstr(yppwd.oldpass, PWSIZE)) || */ /* see PR:nis/38 */
148 (!validstr(yppwd.newpw.pw_passwd, cryptpwsize)) ||
149 (!validstr(yppwd.newpw.pw_name, UTUSERLEN)) ||
150 (!validstr(yppwd.newpw.pw_gecos, fingersize)) ||
151 (!validstr(yppwd.newpw.pw_shell, shellsize))) {
152 svcerr_decode(transp);
153 return;
157 * Special case: root on the master server can change other users'
158 * passwords without first entering the old password. We need to
159 * ensure that this is indeed root on the master server. (bug 1253949)
161 if (strcmp(transp->xp_netid, "ticlts") == 0) {
162 svc_local_cred_t cred;
163 if (!svc_get_local_cred(transp, &cred)) {
164 syslog(LOG_ERR, "yppasswdd: Couldn't get "
165 "local user credentials.\n");
166 } else if (cred.ruid == 0)
167 root_on_master = 1;
170 newpw = yppwd.newpw;
171 strcpy(name, newpw.pw_name);
172 strcat(name, ":");
173 namelen = strlen(name);
174 ans = 2;
175 chsh = chpw = chgecos = 0;
177 /* Get all the filenames straight */
178 strcpy(newpasswdfile, passwd_file);
179 strcat(newpasswdfile, ".ptmp");
180 strcpy(newshadowfile, shadow_file);
181 strcat(newshadowfile, ".ptmp");
182 strcpy(newadjunctfile, adjunct_file);
183 strcat(newadjunctfile, ".ptmp");
185 memset(&sa, 0, sizeof (struct sigaction));
186 sa.sa_handler = SIG_IGN;
187 sigaction(SIGTSTP, &sa, (struct sigaction *)0);
188 sigaction(SIGHUP, &sa, &osa1);
189 sigaction(SIGINT, &sa, &osa2);
190 sigaction(SIGQUIT, &sa, &osa3);
192 /* Lock, then open the passwd and shadow files */
194 if (yplckpwdf() < 0) {
195 syslog(LOG_ERR,
196 "yppasswdd: Password file(s) busy. "
197 "Try again later.\n");
198 ans = 8;
199 goto cleanup;
202 if ((opwfp = fopen(passwd_file, "r")) == NULL) {
203 syslog(LOG_ERR, "yppasswdd: Could not open %s\n", passwd_file);
204 goto cleanup;
207 fstat(fileno(opwfp), &pwstat);
209 if (useshadow) {
210 if ((ospfp = fopen(shadow_file, "r")) == NULL) {
211 syslog(LOG_ERR,
212 "yppasswdd: Could not open %s\n", shadow_file);
213 goto cleanup;
216 fstat(fileno(ospfp), &spstat);
219 if (useadjunct) {
220 if ((oadjfp = fopen(adjunct_file, "r")) == NULL) {
221 syslog(LOG_ERR,
222 "yppasswdd: Could not open %s\n",
223 adjunct_file);
224 goto cleanup;
227 fstat(fileno(oadjfp), &adjstat);
231 * Open the new passwd and shadow tmp files,
232 * first with open and then create a FILE * with fdopen()
234 if ((npwfd = open(newpasswdfile, O_WRONLY | O_CREAT | O_EXCL,
235 pwstat.st_mode)) < 0) {
236 if (errno == EEXIST) {
237 syslog(LOG_WARNING,
238 "yppasswdd: passwd file busy - try again\n");
239 ans = 8;
240 } else {
241 syslog(LOG_ERR, "yppasswdd: %s: %m",
242 newpasswdfile);
243 ans = 9;
245 goto cleanup;
248 fchown(npwfd, pwstat.st_uid, pwstat.st_gid);
250 if ((npwfp = fdopen(npwfd, "w")) == NULL) {
251 syslog(LOG_ERR,
252 "yppasswdd: fdopen() on %s failed\n", newpasswdfile);
253 goto cleanup;
256 if (useshadow) {
257 if ((nspfd = open(newshadowfile, O_WRONLY | O_CREAT | O_EXCL,
258 spstat.st_mode)) < 0) {
259 if (errno == EEXIST) {
260 syslog(LOG_WARNING,
261 "yppasswdd: shadow file busy - try "
262 "again\n");
263 ans = 8;
264 } else {
265 syslog(LOG_ERR, "yppasswdd: %s: %m",
266 newshadowfile);
267 ans = 9;
269 goto cleanup;
272 fchown(nspfd, spstat.st_uid, spstat.st_gid);
274 if ((nspfp = fdopen(nspfd, "w")) == NULL) {
275 syslog(LOG_ERR,
276 "yppasswdd: fdopen() on %s failed\n",
277 newshadowfile);
278 goto cleanup;
282 if (useadjunct) {
283 if ((nadjfd = open(newadjunctfile, O_WRONLY | O_CREAT | O_EXCL,
284 adjstat.st_mode)) < 0) {
285 if (errno == EEXIST) {
286 syslog(LOG_WARNING,
287 "yppasswdd: adjunct file busy - try "
288 "again\n");
289 ans = 8;
290 } else {
291 syslog(LOG_ERR, "yppasswdd: %s: %m",
292 newadjunctfile);
293 ans = 9;
295 goto cleanup;
298 fchown(nadjfd, adjstat.st_uid, adjstat.st_gid);
300 if ((nadjfp = fdopen(nadjfd, "w")) == NULL) {
301 syslog(LOG_ERR,
302 "yppasswdd: fdopen() on %s failed\n",
303 newadjunctfile);
304 goto cleanup;
309 * The following code may not seem all that elegant, but my
310 * interpretation of the man pages relating to the passwd and
311 * shadow files would seem to indicate that there is no guarantee
312 * that the entries contained in those files will be in the same
313 * order...
315 * So here's the high level overview:
317 * Loop through the passwd file reading in lines and writing them
318 * out to the new file UNTIL we get to the correct entry.
319 * IF we have a shadow file, loop through it reading in lines and
320 * writing them out to the new file UNTIL we get to the correct
321 * entry. IF we have an adjunct file, loop through it reading in
322 * lines and writing them out to the new file UNTIL we get to the
323 * correct entry.
325 * Figure out what's changing, contruct the new passwd, shadow,
326 * and adjunct entries and spit em out to the temp files.
327 * At this point, set the done flag and leap back into the loop(s)
328 * until you're finished with the files and then leap to the
329 * section that installs the new files.
332 loop_in_files:
333 /* While we find things in the passwd file */
334 while (fgets(pwbuf, NSS_LINELEN_PASSWD, opwfp)) {
337 * Is this the passwd entry we want?
338 * If not, then write it out to the new passwd temp file
339 * and remember our position.
341 if (doneflag || strncmp(name, pwbuf, namelen)) {
342 if (fputs(pwbuf, npwfp) == EOF) {
343 syslog(LOG_ERR,
344 "yppasswdd: write to passwd file "
345 "failed.\n");
346 goto cleanup;
348 pwpos = ftell(opwfp);
349 continue;
351 gotpasswd = 1;
352 break;
355 /* no match */
356 if (!gotpasswd) {
357 syslog(LOG_ERR, "yppasswdd: user %s does not exist\n", name);
358 goto cleanup;
361 /* While we find things in the shadow file */
362 while (useshadow && fgets(spbuf, NSS_LINELEN_SHADOW, ospfp)) {
365 * Is this the shadow entry that we want?
366 * If not, write it out to the new shadow temp file
367 * and remember our position.
369 if (doneflag || strncmp(name, spbuf, namelen)) {
370 if (fputs(spbuf, nspfp) == EOF) {
371 syslog(LOG_ERR,
372 "yppasswdd: write to shadow file "
373 "failed.\n");
374 goto cleanup;
376 sppos = ftell(ospfp);
377 continue;
379 gotshadow = 1;
380 break;
383 /* While we find things in the adjunct file */
384 while (useadjunct && fgets(adjbuf, BUFSIZ, oadjfp)) {
387 * is this the adjunct entry that we want?
388 * If not, write it out to the new temp file
389 * and remember our position.
391 if (doneflag || strncmp(name, adjbuf, namelen)) {
392 if (fputs(adjbuf, nadjfp) == EOF) {
393 syslog(LOG_ERR,
394 "yppasswdd: write to adjunct file "
395 "failed.\n");
396 goto cleanup;
398 continue;
400 gotadjunct = 1;
401 break;
404 if (doneflag)
405 goto install_files;
407 if (useshadow && !gotshadow) {
408 syslog(LOG_ERR, "yppasswdd: no passwd in shadow for %s\n",
409 newpw.pw_name);
410 ans = 4;
411 goto cleanup;
413 if (useadjunct && !gotadjunct) {
414 syslog(LOG_ERR, "yppasswdd: no passwd in adjunct for %s\n",
415 newpw.pw_name);
416 ans = 4;
417 goto cleanup;
421 * Now that we've read in the correct passwd AND
422 * shadow lines, we'll rewind to the beginning of
423 * those lines and let the fget*ent() calls do
424 * the work. Since we are only working with the
425 * first two fields of the adjunct entry, leave
426 * it as a char array.
428 fseek(opwfp, pwpos, SEEK_SET);
429 opwd = *fgetpwent(opwfp);
431 if (useshadow) {
432 fseek(ospfp, sppos, SEEK_SET);
433 ospwd = *fgetspent(ospfp);
436 oldpass_crypt = cryptoldpasswd(yppwd.oldpass, newpw.pw_passwd,
437 newpw.pw_name);
438 if (oldpass_crypt == NULL) {
439 ans = 3;
440 goto cleanup;
442 p = newpw.pw_passwd;
443 if ((!nopw) &&
444 p && *p &&
445 !((*p++ == '#') && (*p++ == '#') &&
446 (strcmp(p, opwd.pw_name) == 0)) &&
447 (strcmp(oldpass_crypt, newpw.pw_passwd) != 0))
448 chpw = 1;
449 oldpass_crypt = NULL;
451 if ((!noshell) && (strcmp(opwd.pw_shell, newpw.pw_shell) != 0)) {
452 if (single)
453 chpw = 0;
454 chsh = 1;
457 if ((!nogecos) && (strcmp(opwd.pw_gecos, newpw.pw_gecos) != 0)) {
458 if (single) {
459 chpw = 0;
460 chsh = 0;
462 chgecos = 1;
465 if (!(chpw + chsh + chgecos)) {
466 syslog(LOG_NOTICE, "yppasswdd: no change for %s\n",
467 newpw.pw_name);
468 ans = 3;
469 goto cleanup;
472 if (useshadow && !root_on_master) {
473 oldpass_crypt = cryptoldpasswd(yppwd.oldpass, ospwd.sp_pwdp,
474 newpw.pw_name);
475 if (oldpass_crypt == NULL)
476 goto cleanup;
477 if (ospwd.sp_pwdp && *ospwd.sp_pwdp &&
478 (strcmp(oldpass_crypt, ospwd.sp_pwdp) != 0)) {
480 syslog(LOG_NOTICE, "yppasswdd: passwd incorrect\n",
481 newpw.pw_name);
482 ans = 7;
483 goto cleanup;
485 } else if (useadjunct) {
487 * Clear the adj_encrypt array. Extract the encrypted passwd
488 * into adj_encrypt by setting adj_crypt_begin and
489 * adj_crypt_end to point at the first character of the
490 * encrypted passwd and the first character following the
491 * encrypted passwd in adjbuf, respectively, and copy the
492 * stuff between (there may not be anything) into adj_ecrypt.
493 * Then, check that adj_encrypt contains something and that
494 * the old passwd is correct.
496 memset(adj_encrypt, 0, sizeof (adj_encrypt));
497 adj_crypt_begin = adjbuf + namelen;
498 adj_crypt_end = strchr(adj_crypt_begin, ':');
499 strncpy(adj_encrypt, adj_crypt_begin,
500 adj_crypt_end - adj_crypt_begin);
501 oldpass_crypt = cryptoldpasswd(yppwd.oldpass, adj_encrypt,
502 newpw.pw_name);
503 if (oldpass_crypt == NULL)
504 goto cleanup;
505 if (!root_on_master && *adj_encrypt &&
506 (strcmp(oldpass_crypt, adj_encrypt) != 0)) {
508 syslog(LOG_NOTICE, "yppasswdd: passwd incorrect\n",
509 newpw.pw_name);
510 ans = 7;
511 goto cleanup;
513 } else {
514 oldpass_crypt = cryptoldpasswd(yppwd.oldpass, opwd.pw_passwd,
515 newpw.pw_name);
516 if (oldpass_crypt == NULL)
517 goto cleanup;
518 if (!root_on_master && opwd.pw_passwd && *opwd.pw_passwd &&
519 (strcmp(oldpass_crypt, opwd.pw_passwd) != 0)) {
521 syslog(LOG_NOTICE, "yppasswdd: passwd incorrect\n",
522 newpw.pw_name);
523 ans = 7;
524 goto cleanup;
528 #ifdef DEBUG
529 printf("%d %d %d\n", chsh, chgecos, chpw);
531 printf("%s %s %s\n",
532 yppwd.newpw.pw_shell,
533 yppwd.newpw.pw_gecos,
534 yppwd.newpw.pw_passwd);
536 printf("%s %s %s\n",
537 opwd.pw_shell,
538 opwd.pw_gecos,
539 ospwd.sp_pwdp);
540 #endif
542 if (chsh &&
543 !validloginshell(opwd.pw_shell, newpw.pw_shell, root_on_master)) {
544 goto cleanup;
547 /* security hole fix from original source */
548 for (p = newpw.pw_name; (*p != '\0'); p++)
549 if ((*p == ':') || !(isprint(*p)))
550 *p = '$'; /* you lose buckwheat */
551 for (p = newpw.pw_passwd; (*p != '\0'); p++)
552 if ((*p == ':') || !(isprint(*p)))
553 *p = '$'; /* you lose buckwheat */
555 if (chgecos)
556 opwd.pw_gecos = newpw.pw_gecos;
558 if (chsh)
559 opwd.pw_shell = newpw.pw_shell;
562 * If we're changing the shell or gecos fields and we're
563 * using a shadow or adjunct file or not changing the passwd
564 * then go ahead and update the passwd file. The case where
565 * the passwd is being changed and we are not using a shadow
566 * or adjunct file is handled later.
568 if ((chsh || chgecos) && (useshadow || useadjunct || !chpw) &&
569 putpwent(&opwd, npwfp)) {
571 syslog(LOG_ERR, "yppasswdd: putpwent failed: %s\n",
572 passwd_file);
573 goto cleanup;
576 if (chpw) {
577 if (useshadow) {
578 ospwd.sp_pwdp = newpw.pw_passwd;
579 now = DAY_NOW;
580 /* password aging - bug for bug compatibility */
581 if (ospwd.sp_max != -1) {
582 if (now < ospwd.sp_lstchg + ospwd.sp_min) {
583 syslog(LOG_ERR,
584 "yppasswdd: Sorry: < %ld days "
585 "since the last change.\n",
586 ospwd.sp_min);
587 goto cleanup;
590 ospwd.sp_lstchg = now;
591 if (putspent(&ospwd, nspfp)) {
592 syslog(LOG_ERR,
593 "yppasswdd: putspent failed: %s\n",
594 shadow_file);
595 goto cleanup;
597 } else if (useadjunct) {
598 sprintf(adjbuf_new,
599 "%s%s%s", name, newpw.pw_passwd, adj_crypt_end);
600 if (fputs(adjbuf_new, nadjfp) == EOF) {
601 syslog(LOG_ERR,
602 "yppasswdd: write to adjunct failed: %s\n",
603 adjunct_file);
604 goto cleanup;
606 } else {
607 opwd.pw_passwd = newpw.pw_passwd;
608 if (putpwent(&opwd, npwfp)) {
609 syslog(LOG_ERR,
610 "yppasswdd: putpwent failed: %s\n",
611 passwd_file);
612 goto cleanup;
617 if (!doneflag) {
618 doneflag = 1;
619 goto loop_in_files;
622 install_files:
624 * Critical section, nothing special needs to be done since we
625 * hold exclusive access to the *.ptmp files
627 fflush(npwfp);
628 if (useshadow)
629 fflush(nspfp);
630 if (useadjunct)
631 fflush(nadjfp);
633 strcpy(tmppasswdfile, passwd_file);
634 strcat(tmppasswdfile, "-");
635 if (useshadow) {
636 strcpy(tmpshadowfile, shadow_file);
637 strcat(tmpshadowfile, "-");
639 if (useadjunct) {
640 strcpy(tmpadjunctfile, adjunct_file);
641 strcat(tmpadjunctfile, "-");
644 if ((!useshadow && !useadjunct) || (chsh || chgecos)) {
645 if (rename(passwd_file, tmppasswdfile) < 0) {
646 syslog(LOG_CRIT, "yppasswdd: failed to backup "
647 "passwd file: %m");
648 goto cleanup;
649 } else {
650 if (rename(newpasswdfile, passwd_file) < 0) {
651 syslog(LOG_CRIT,
652 "yppasswdd: failed to mv passwd: %m");
653 if (rename(tmppasswdfile, passwd_file) < 0) {
654 syslog(LOG_CRIT,
655 "yppasswdd: failed to restore "
656 "backup of passwd file: %m");
658 goto cleanup;
663 if (useshadow && chpw) {
664 if (rename(shadow_file, tmpshadowfile) < 0) {
665 syslog(LOG_CRIT, "yppasswdd: failed to back up "
666 "shadow file: %m");
667 if (rename(tmppasswdfile, passwd_file) < 0) {
668 syslog(LOG_CRIT,
669 "yppasswdd: failed to restore "
670 "backup of passwd file: %m");
672 goto cleanup;
673 } else {
674 if (rename(newshadowfile, shadow_file) < 0) {
675 syslog(LOG_CRIT,
676 "yppasswdd: failed to mv shadow: %m");
677 if (rename(tmpshadowfile, shadow_file) < 0) {
678 syslog(LOG_CRIT,
679 "yppasswdd: failed to restore "
680 "backup of shadow file: %m");
682 if (rename(tmppasswdfile, passwd_file) < 0) {
683 syslog(LOG_CRIT,
684 "yppasswdd: failed to restore "
685 "backup of passwd file: %m");
687 goto cleanup;
690 } else if (useadjunct && chpw) {
691 if (rename(adjunct_file, tmpadjunctfile) < 0) {
692 syslog(LOG_CRIT, "yppasswdd: failed to back up "
693 "adjunct file: %m");
694 if (rename(tmppasswdfile, passwd_file) < 0) {
695 syslog(LOG_CRIT,
696 "yppasswdd: failed to restore backup "
697 "of passwd: %m");
699 goto cleanup;
700 } else {
701 if (rename(newadjunctfile, adjunct_file) < 0) {
702 syslog(LOG_CRIT,
703 "yppassdd: failed to mv adjunct: %m");
704 if (rename(tmppasswdfile, passwd_file) < 0) {
705 syslog(LOG_CRIT,
706 "yppasswdd: failed to restore "
707 "backup of passwd file: %m");
709 if (rename(tmpadjunctfile, adjunct_file) < 0) {
710 syslog(LOG_CRIT,
711 "yppasswdd: failed to restore "
712 "backup of adjunct file: %m");
714 goto cleanup;
719 if (doneflag)
720 ans = 0;
721 /* End critical section */
724 * Here we have come only after the new files have been successfully
725 * renamed to original files. At this point, the temp files would still
726 * be existing we need to remove them from the /etc directory
728 unlink(tmppasswdfile);
729 if (useshadow)
730 unlink(tmpshadowfile);
731 if (useadjunct)
732 unlink(tmpadjunctfile);
734 cleanup:
736 /* If we don't have opwfp, then we didn't do anything */
737 if (opwfp) {
738 fclose(opwfp);
740 if (ospfp) {
741 fclose(ospfp);
744 if (oadjfp) {
745 fclose(oadjfp);
748 unlink(newpasswdfile);
749 /* These tests are cheaper than failing syscalls */
750 if (useshadow)
751 unlink(newshadowfile);
752 if (useadjunct)
753 unlink(newadjunctfile);
755 if (npwfp) {
756 fclose(npwfp);
758 if (nspfp) {
759 fclose(nspfp);
761 if (nadjfp) {
762 fclose(nadjfp);
767 ypulckpwdf();
769 if (doneflag && mflag) {
770 retval = fork();
771 if (retval < 0) {
772 syslog(LOG_ERR, "yppasswdd: Fork failed %m");
773 } else if (retval == 0) {
774 strcpy(cmdbuf, "/usr/ccs/bin/make");
775 for (i = Mstart + 1; i < Argc; i++) {
776 strcat(cmdbuf, " ");
777 strcat(cmdbuf, Argv[i]);
780 #ifdef DEBUG
781 syslog(LOG_ERR, "yppasswdd: about to "
782 "execute %s\n", cmdbuf);
783 #else
784 if (yplckpwdf() < 0) {
785 syslog(LOG_ERR, "yppasswdd: Couldn't get the "
786 "lock to update the maps");
787 } else {
788 setpgrp();
789 system(cmdbuf);
790 ypulckpwdf();
792 #endif
793 exit(0);
797 sigaction(SIGHUP, &osa1, (struct sigaction *)0);
798 sigaction(SIGINT, &osa2, (struct sigaction *)0);
799 sigaction(SIGQUIT, &osa3, (struct sigaction *)0);
801 if (!svc_sendreply(transp, xdr_int, (char *)&ans))
802 syslog(LOG_WARNING,
803 "yppasswdd: couldn\'t reply to RPC call\n");