version 1.42, 2015/11/18 19:26:45 |
version 1.43, 2015/11/26 19:01:47 |
|
|
|
|
enum { NEWSH, LOADENTRY, EDITENTRY } op; |
enum { NEWSH, LOADENTRY, EDITENTRY } op; |
uid_t uid; |
uid_t uid; |
#ifdef YP |
|
int use_yp; |
|
int force_yp = 0; |
|
#endif |
|
|
|
void baduser(void); |
void baduser(void); |
void kbintr(int); |
void kbintr(int); |
|
|
char *tz, *arg = NULL; |
char *tz, *arg = NULL; |
sigset_t fullset; |
sigset_t fullset; |
|
|
#ifdef YP |
|
use_yp = _yp_check(NULL); |
|
#endif |
|
/* We need to use the system timezone for date conversions. */ |
/* We need to use the system timezone for date conversions. */ |
if ((tz = getenv("TZ")) != NULL) { |
if ((tz = getenv("TZ")) != NULL) { |
unsetenv("TZ"); |
unsetenv("TZ"); |
|
|
} |
} |
|
|
op = EDITENTRY; |
op = EDITENTRY; |
while ((ch = getopt(argc, argv, "a:s:ly")) != -1) |
while ((ch = getopt(argc, argv, "a:s:")) != -1) |
switch(ch) { |
switch(ch) { |
case 'a': |
case 'a': |
op = LOADENTRY; |
op = LOADENTRY; |
|
|
op = NEWSH; |
op = NEWSH; |
arg = optarg; |
arg = optarg; |
break; |
break; |
#ifdef YP |
|
case 'l': |
|
use_yp = 0; |
|
break; |
|
case 'y': |
|
if (!use_yp) { |
|
warnx("YP not in use."); |
|
usage(); |
|
} |
|
force_yp = 1; |
|
break; |
|
#endif |
|
case '?': |
case '?': |
default: |
default: |
usage(); |
usage(); |
|
|
argc -= optind; |
argc -= optind; |
argv += optind; |
argv += optind; |
|
|
#ifdef YP |
|
if (op == LOADENTRY && use_yp) |
|
errx(1, "cannot load using YP, use -l to load local."); |
|
#endif |
|
uid = getuid(); |
uid = getuid(); |
|
|
if (op == EDITENTRY || op == NEWSH) |
if (op == EDITENTRY || op == NEWSH) |
switch(argc) { |
switch(argc) { |
case 0: |
case 0: |
pw = getpwuid_shadow(uid); |
pw = getpwuid_shadow(uid); |
#ifdef YP |
|
if (pw && !force_yp) |
|
use_yp = 0; |
|
else if (use_yp) |
|
pw = ypgetpwuid(uid); |
|
#endif /* YP */ |
|
if (!pw) |
if (!pw) |
errx(1, "unknown user: uid %u", uid); |
errx(1, "unknown user: uid %u", uid); |
break; |
break; |
case 1: |
case 1: |
pw = getpwnam_shadow(*argv); |
pw = getpwnam_shadow(*argv); |
#ifdef YP |
|
if (pw && !force_yp) |
|
use_yp = 0; |
|
else if (use_yp) |
|
pw = ypgetpwnam(*argv); |
|
#endif /* YP */ |
|
if (!pw) |
if (!pw) |
errx(1, "unknown user: %s", *argv); |
errx(1, "unknown user: %s", *argv); |
if (uid && uid != pw->pw_uid) |
if (uid && uid != pw->pw_uid) |
|
|
if (dfd == -1) |
if (dfd == -1) |
pw_error(tempname, 1, 1); |
pw_error(tempname, 1, 1); |
display(tempname, dfd, pw); |
display(tempname, dfd, pw); |
|
|
|
if (pledge("stdio rpath wpath cpath id proc exec", |
|
NULL) == -1) |
|
err(1, "pledge"); |
|
|
edit_status = edit(tempname, pw); |
edit_status = edit(tempname, pw); |
close(dfd); |
close(dfd); |
unlink(tempname); |
unlink(tempname); |
|
|
} |
} |
|
|
if (op == NEWSH) { |
if (op == NEWSH) { |
|
if (pledge("stdio rpath wpath cpath id proc exec", |
|
NULL) == -1) |
|
err(1, "pledge"); |
|
|
/* protect p_shell -- it thinks NULL is /bin/sh */ |
/* protect p_shell -- it thinks NULL is /bin/sh */ |
if (!arg[0]) |
if (!arg[0]) |
usage(); |
usage(); |
|
|
sigdelset(&fullset, SIGINT); |
sigdelset(&fullset, SIGINT); |
sigprocmask(SIG_BLOCK, &fullset, NULL); |
sigprocmask(SIG_BLOCK, &fullset, NULL); |
|
|
|
if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) |
|
err(1, "pledge"); |
|
|
/* Get the passwd lock file and open the passwd file for reading. */ |
/* Get the passwd lock file and open the passwd file for reading. */ |
pw_init(); |
pw_init(); |
for (i = 1; (tfd = pw_lock(0)) == -1; i++) { |
for (i = 1; (tfd = pw_lock(0)) == -1; i++) { |
|
|
if (pfd == -1) |
if (pfd == -1) |
pw_error(_PATH_MASTERPASSWD, 1, 1); |
pw_error(_PATH_MASTERPASSWD, 1, 1); |
|
|
#ifdef YP |
/* Copy the passwd file to the lock file, updating pw. */ |
if (use_yp) { |
pw_copy(pfd, tfd, pw, opw); |
if (pw_yp(pw, uid)) |
|
pw_error(NULL, 0, 1); |
|
else { |
|
pw_abort(); |
|
exit(0); |
|
} |
|
} else |
|
#endif /* YP */ |
|
{ |
|
/* Copy the passwd file to the lock file, updating pw. */ |
|
pw_copy(pfd, tfd, pw, opw); |
|
|
|
/* If username changed we need to rebuild the entire db. */ |
/* If username changed we need to rebuild the entire db. */ |
arg = !strcmp(opw->pw_name, pw->pw_name) ? pw->pw_name : NULL; |
arg = !strcmp(opw->pw_name, pw->pw_name) ? pw->pw_name : NULL; |
|
|
/* Now finish the passwd file update. */ |
/* Now finish the passwd file update. */ |
if (pw_mkdb(arg, 0) == -1) |
if (pw_mkdb(arg, 0) == -1) |
pw_error(NULL, 0, 1); |
pw_error(NULL, 0, 1); |
} |
|
|
|
exit(0); |
exit(0); |
} |
} |
|
|
|
|
usage(void) |
usage(void) |
{ |
{ |
|
|
#ifdef YP |
|
(void)fprintf(stderr, |
|
"usage: %s [-l%s] [-s newshell] [user]\n", |
|
__progname, use_yp ? "y" : ""); |
|
(void)fprintf(stderr, |
|
" %s [-l] -a list\n", __progname); |
|
#else |
|
(void)fprintf(stderr, "usage: %s [-s newshell] [user]\n", __progname); |
(void)fprintf(stderr, "usage: %s [-s newshell] [user]\n", __progname); |
(void)fprintf(stderr, " %s -a list\n", __progname); |
(void)fprintf(stderr, " %s -a list\n", __progname); |
#endif |
|
exit(1); |
exit(1); |
} |
} |