Switch to NetBSD passwd format
Based on work by Vivek Prakash and Gianluca Guida. See UPDATING about caveats on currently existing accounts. . restores netbsd libc pwcache functions
This commit is contained in:
parent
cedeabb357
commit
5c00743626
96 changed files with 10891 additions and 1220 deletions
6
Makefile
6
Makefile
|
@ -62,6 +62,7 @@ commands: includes libraries
|
|||
$(MAKE) -C bin all
|
||||
$(MAKE) -C usr.bin all
|
||||
$(MAKE) -C libexec all
|
||||
$(MAKE) -C usr.sbin all
|
||||
|
||||
dep-all:
|
||||
$(MAKE) CC=cc -C boot dependall
|
||||
|
@ -69,6 +70,7 @@ dep-all:
|
|||
$(MAKE) -C bin dependall
|
||||
$(MAKE) -C usr.bin dependall
|
||||
$(MAKE) -C libexec dependall
|
||||
$(MAKE) -C usr.sbin dependall
|
||||
$(MAKE) -C kernel dependall
|
||||
$(MAKE) -C servers dependall
|
||||
$(MAKE) -C drivers dependall
|
||||
|
@ -85,6 +87,7 @@ all:
|
|||
$(MAKE) -C bin all
|
||||
$(MAKE) -C usr.bin all
|
||||
$(MAKE) -C libexec all
|
||||
$(MAKE) -C usr.sbin all
|
||||
$(MAKE) -C tools all
|
||||
|
||||
install:
|
||||
|
@ -94,6 +97,7 @@ install:
|
|||
$(MAKE) -C commands install
|
||||
$(MAKE) -C bin install
|
||||
$(MAKE) -C usr.bin install
|
||||
$(MAKE) -C usr.sbin install
|
||||
$(MAKE) -C servers install
|
||||
$(MAKE) -C share install
|
||||
$(MAKE) -C tools install
|
||||
|
@ -104,6 +108,7 @@ clean: mkfiles
|
|||
$(MAKE) -C bin clean
|
||||
$(MAKE) -C usr.bin clean
|
||||
$(MAKE) -C libexec clean
|
||||
$(MAKE) -C usr.sbin clean
|
||||
$(MAKE) -C tools clean
|
||||
$(MAKE) -C lib clean_all
|
||||
$(MAKE) -C test clean
|
||||
|
@ -115,4 +120,5 @@ cleandepend: mkfiles
|
|||
$(MAKE) -C bin cleandepend
|
||||
$(MAKE) -C usr.bin cleandepend
|
||||
$(MAKE) -C libexec cleandepend
|
||||
$(MAKE) -C usr.sbin cleandepend
|
||||
$(MAKE) -C tools cleandepend
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
SUBDIR= aal add_route adduser arp ash at autil awk \
|
||||
SUBDIR= aal add_route arp ash at autil awk \
|
||||
backup badblocks banner basename binpackage \
|
||||
binpackages bzip2 bzip2recover cal calendar \
|
||||
cat cawf cd cdprobe checkhier chmem \
|
||||
|
@ -19,7 +19,7 @@ SUBDIR= aal add_route adduser arp ash at autil awk \
|
|||
lpd ls lspci M mail make MAKEDEV \
|
||||
mdb mesg mined ackmkdep mkfifo mkfs.mfs mknod \
|
||||
mkproto modem mount mt netconf newroot nice acknm nohup \
|
||||
nonamed od passwd paste patch pax \
|
||||
nonamed od paste patch pax \
|
||||
ping postinstall poweroff pr prep printf printroot \
|
||||
profile progressbar proto pr_routes ps pwd pwdauth \
|
||||
ramdisk rarpd rawspeed rcp rdate readall readclock \
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
SCRIPTS= adduser.sh
|
||||
MAN=
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,121 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# adduser 1.0 - add a new user to the system Author: Kees J. Bot
|
||||
# 16 Jan 1996
|
||||
|
||||
# Check arguments.
|
||||
case "$#" in
|
||||
3) user="$1"; group="$2"; home="$3"
|
||||
;;
|
||||
*) echo "Usage: adduser user group home-dir" >&2; exit 1
|
||||
esac
|
||||
|
||||
# We need to be root.
|
||||
case "`id`" in
|
||||
'uid=0('*)
|
||||
;;
|
||||
*) echo "adduser: you must be root to add users" >&2; exit 1
|
||||
esac
|
||||
|
||||
# User and group names must be alphanumeric and no longer than 8 characters.
|
||||
len=`expr "$user" : '[a-z][a-z0-9]*$'`
|
||||
if [ "$len" -eq 0 -o "$len" -gt 8 ]
|
||||
then
|
||||
echo >&2 \
|
||||
"adduser: the user name must be alphanumeric and no longer than 8 characters"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
len=`expr "$group" : '[a-z][a-z0-9]*$'`
|
||||
if [ "$len" -eq 0 -o "$len" -gt 8 ]
|
||||
then
|
||||
echo >&2 \
|
||||
"adduser: the group name must be alphanumeric and no longer than 8 characters"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The new user name must not exist, but the group must exist.
|
||||
if grep "^$user:" /etc/passwd >/dev/null
|
||||
then
|
||||
echo "adduser: user $user already exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gid=`sed -e "/^$group:/!d" -e 's/^[^:]*:[^:]*:\\([^:]*\\):.*/\\1/' /etc/group`
|
||||
if [ `expr "$gid" : '[0-9]*$'` -eq 0 ]
|
||||
then
|
||||
echo "adduser: group $group does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Find the first free user-id of 10 or higher.
|
||||
uid=10
|
||||
while grep "^[^:]*:[^:]*:$uid:.*" /etc/passwd >/dev/null
|
||||
do
|
||||
uid=`expr $uid + 1`
|
||||
done
|
||||
|
||||
# No interruptions.
|
||||
trap '' 1 2 3 15
|
||||
|
||||
# Lock the password file.
|
||||
ln /etc/passwd /etc/ptmp || {
|
||||
echo "adduser: password file busy, try again later"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make the new home directory, it should not exist already.
|
||||
mkdir "$home" || {
|
||||
rm -rf /etc/ptmp
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make the new home directory by copying the honorary home directory of our
|
||||
# fearless leader.
|
||||
echo cpdir /usr/ast "$home"
|
||||
cpdir /usr/ast "$home" || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Change the ownership to the new user.
|
||||
echo chown -R $uid:$gid "$home"
|
||||
chown -R $uid:$group "$home" || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is there a shadow password file? If so add an entry.
|
||||
if [ -f /etc/shadow ]
|
||||
then
|
||||
echo "echo $user::0:0::: >>/etc/shadow"
|
||||
echo "$user::0:0:::" >>/etc/shadow || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
pwd="##$user"
|
||||
else
|
||||
pwd=
|
||||
fi
|
||||
|
||||
# Finish up by adding a password file entry.
|
||||
echo "echo $user:$pwd:$uid:$gid:$user:$home: >>/etc/passwd"
|
||||
echo "$user:$pwd:$uid:$gid:$user:$home:" >>/etc/passwd || {
|
||||
rm -rf /etc/ptmp "$home"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Remove the lock.
|
||||
rm /etc/ptmp || exit
|
||||
|
||||
echo "
|
||||
The new user $user has been added to the system. Note that the password,
|
||||
full name, and shell may be changed with the commands passwd(1), chfn(1),
|
||||
and chsh(1). The password is now empty, so only console logins are possible."
|
||||
if [ $gid = 0 ]
|
||||
then
|
||||
echo "\
|
||||
Also note that a new operator needs an executable search path (\$PATH) that
|
||||
does not contain the current directory (an empty field or "." in \$PATH)."
|
||||
fi
|
||||
exit 0
|
|
@ -31,7 +31,7 @@
|
|||
#define S_IUGID (S_ISUID|S_ISGID)
|
||||
|
||||
/* Global variables, such as flags and path names */
|
||||
int gflag, oflag, rflag, error;
|
||||
int gflag, oflag, rflag, error, hflag = 0;
|
||||
char *pgmname, path[PATH_MAX + 1];
|
||||
uid_t nuid;
|
||||
gid_t ngid;
|
||||
|
@ -44,9 +44,6 @@ _PROTOTYPE(void usage, (void));
|
|||
* identical, except that the default when a single name is given as an
|
||||
* argument is to take a group id rather than an user id. This allow the
|
||||
* non-Posix "chgrp user:group file".
|
||||
* The single option switch used by chown/chgrp (-R) does not warrant a
|
||||
* call to the getopt stuff. The two others flags (-g, -u) are set from
|
||||
* the program name and arguments.
|
||||
*/
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
|
@ -55,20 +52,30 @@ char *argv[];
|
|||
char *id, *id2;
|
||||
struct group *grp;
|
||||
struct passwd *pwp;
|
||||
int ch;
|
||||
|
||||
if (pgmname = strrchr(*argv, '/'))
|
||||
pgmname++;
|
||||
else
|
||||
pgmname = *argv;
|
||||
argc--;
|
||||
argv++;
|
||||
gflag = strcmp(pgmname, "chgrp");
|
||||
|
||||
if (argc && **argv == '-' && argv[0][1] == 'R') {
|
||||
argc--;
|
||||
argv++;
|
||||
rflag = 1;
|
||||
while((ch = getopt(argc, argv, "Rh")) != -1) {
|
||||
switch(ch) {
|
||||
case 'R':
|
||||
rflag = 1;
|
||||
break;
|
||||
case 'h':
|
||||
hflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 2) usage();
|
||||
|
||||
id = *argv++;
|
||||
|
@ -131,6 +138,11 @@ char *file;
|
|||
|
||||
if (S_ISLNK(st.st_mode) && rflag) return; /* Note: violates POSIX. */
|
||||
|
||||
if (S_ISLNK(st.st_mode) && hflag) {
|
||||
fprintf(stderr, "chown: cannot lchown %s\n", file);
|
||||
error = 1;
|
||||
}
|
||||
|
||||
if (chown(file, oflag ? nuid : st.st_uid, gflag ? ngid : st.st_gid)) {
|
||||
perror(file);
|
||||
error = 1;
|
||||
|
|
|
@ -8,8 +8,7 @@ SRCS= ftpd.c access.c file.c net.c
|
|||
MAN= ftpd.8
|
||||
SCRIPTS= ftpdsh
|
||||
FILES= setup.anonftp
|
||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
NEED_NBSDLIBC=y
|
||||
LDADD+= -lcrypt
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.include <minix.newlibc.mk>
|
||||
|
||||
PROG= login
|
||||
MAN=
|
||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
|
|
|
@ -339,9 +339,8 @@ char *argv[];
|
|||
* pre-authorized users.
|
||||
*/
|
||||
} else
|
||||
if (pwd && secure && strcmp(crypt("", pwd->pw_passwd),
|
||||
pwd->pw_passwd) == 0) {
|
||||
check_pw= 0; /* empty password */
|
||||
if (pwd && secure && (pwd->pw_passwd[0] == '\0')) {
|
||||
check_pw= 0; /* empty password, pretend password okay */
|
||||
}
|
||||
|
||||
if (check_pw) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
PROG= ls
|
||||
BINDIR= /bin
|
||||
MAN=
|
||||
NEED_NBSDLIBC=yes
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
PROG= passwd
|
||||
BINMODE= 4755
|
||||
MAN=
|
||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
LDADD+= -lcrypt
|
||||
.endif
|
||||
|
||||
LINKS+= ${BINDIR}/passwd ${BINDIR}/chsh
|
||||
LINKS+= ${BINDIR}/passwd ${BINDIR}/chfn
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -1,260 +0,0 @@
|
|||
/* passwd - change a passwd Author: Adri Koppes */
|
||||
|
||||
/* chfn, chsh - change full name, shell Added by: Kees J. Bot */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <minix/minlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
_PROTOTYPE(void report, (char *label));
|
||||
_PROTOTYPE(void quit, (int ex_stat));
|
||||
_PROTOTYPE(void fatal, (char *label));
|
||||
_PROTOTYPE(void usage, (void));
|
||||
_PROTOTYPE(int goodchars, (char *s));
|
||||
_PROTOTYPE(int main, (int argc, char **argv));
|
||||
|
||||
char pw_file[] = "/etc/passwd";
|
||||
char sh_file[] = "/etc/shadow";
|
||||
char pw_tmp[] = "/etc/ptmp";
|
||||
char bad[] = "Permission denied\n";
|
||||
char buf[1024];
|
||||
|
||||
enum action {
|
||||
PASSWD, CHFN, CHSH
|
||||
} action = PASSWD;
|
||||
|
||||
char *arg0;
|
||||
|
||||
void report(label)
|
||||
char *label;
|
||||
{
|
||||
int e = errno;
|
||||
fprintf(stderr, "%s: ", arg0);
|
||||
fflush(stderr);
|
||||
errno = e;
|
||||
perror(label);
|
||||
}
|
||||
|
||||
void quit(ex_stat)
|
||||
int ex_stat;
|
||||
{
|
||||
if (unlink(pw_tmp) < 0 && errno != ENOENT) {
|
||||
report(pw_tmp);
|
||||
ex_stat = 1;
|
||||
}
|
||||
exit(ex_stat);
|
||||
}
|
||||
|
||||
void fatal(label)
|
||||
char *label;
|
||||
{
|
||||
report(label);
|
||||
quit(1);
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
static char *usages[] = {
|
||||
"passwd [user]\n",
|
||||
"chfn [user] fullname\n",
|
||||
"chsh [user] shell\n"
|
||||
};
|
||||
std_err(usages[(int) action]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int goodchars(s)
|
||||
char *s;
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = *s++) != 0) {
|
||||
if (c == ':' || c < ' ' || c >= 127) return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int uid, cn, n;
|
||||
int fd_pwd, fd_tmp;
|
||||
FILE *fp_tmp;
|
||||
time_t salt;
|
||||
struct passwd *pwd;
|
||||
char *name, pwname[9], oldpwd[9], newpwd[9], newcrypted[14], sl[2];
|
||||
char *argn;
|
||||
int shadow = 0;
|
||||
|
||||
if ((arg0 = strrchr(argv[0], '/')) != 0)
|
||||
arg0++;
|
||||
else
|
||||
arg0 = argv[0];
|
||||
|
||||
if (strcmp(arg0, "chfn") == 0)
|
||||
action = CHFN;
|
||||
else if (strcmp(arg0, "chsh") == 0)
|
||||
action = CHSH;
|
||||
|
||||
uid = getuid();
|
||||
|
||||
n = action == PASSWD ? 1 : 2;
|
||||
|
||||
if (argc != n && argc != n + 1) usage();
|
||||
|
||||
if (argc == n) {
|
||||
pwd = getpwuid(uid);
|
||||
strcpy(pwname, pwd->pw_name);
|
||||
name = pwname;
|
||||
} else {
|
||||
name = argv[1];
|
||||
pwd = getpwnam(name);
|
||||
}
|
||||
if (pwd == NULL || ((uid != pwd->pw_uid) && uid != 0)) {
|
||||
std_err(bad);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case PASSWD:
|
||||
if (pwd->pw_passwd[0] == '#' && pwd->pw_passwd[1] == '#') {
|
||||
/* The password is found in the shadow password file. */
|
||||
shadow = 1;
|
||||
strncpy(pwname, pwd->pw_passwd + 2, 8);
|
||||
pwname[8] = 0;
|
||||
name = pwname;
|
||||
setpwfile(sh_file);
|
||||
if ((pwd= getpwnam(name)) == NULL) {
|
||||
std_err(bad);
|
||||
exit(1);
|
||||
}
|
||||
printf("Changing the shadow password of %s\n", name);
|
||||
} else {
|
||||
printf("Changing the password of %s\n", name);
|
||||
}
|
||||
|
||||
oldpwd[0] = 0;
|
||||
if (pwd->pw_passwd[0] != '\0' && uid != 0) {
|
||||
strcpy(oldpwd, getpass("Old password:"));
|
||||
if (strcmp(pwd->pw_passwd, crypt(oldpwd, pwd->pw_passwd)) != 0)
|
||||
{
|
||||
std_err(bad);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
strcpy(newpwd, getpass("New password:"));
|
||||
|
||||
if (newpwd[0] == '\0')
|
||||
std_err("Password cannot be null");
|
||||
else if (strcmp(newpwd, getpass("Retype password:")) != 0)
|
||||
std_err("Passwords don't match");
|
||||
else
|
||||
break;
|
||||
|
||||
std_err(", try again\n");
|
||||
}
|
||||
time(&salt);
|
||||
sl[0] = (salt & 077) + '.';
|
||||
sl[1] = ((salt >> 6) & 077) + '.';
|
||||
for (cn = 0; cn < 2; cn++) {
|
||||
if (sl[cn] > '9') sl[cn] += 7;
|
||||
if (sl[cn] > 'Z') sl[cn] += 6;
|
||||
}
|
||||
strcpy(newcrypted, crypt(newpwd, sl));
|
||||
break;
|
||||
|
||||
case CHFN:
|
||||
case CHSH:
|
||||
argn = argv[argc - 1];
|
||||
|
||||
if (strlen(argn) > (action == CHFN ? 80 : 60) || !goodchars(argn)) {
|
||||
std_err(bad);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
|
||||
umask(0);
|
||||
n = 10;
|
||||
while ((fd_tmp = open(pw_tmp, O_RDWR | O_CREAT | O_EXCL, 0400)) < 0) {
|
||||
if (errno != EEXIST) fatal("Can't create temporary file");
|
||||
|
||||
if (n-- > 0) {
|
||||
sleep(2);
|
||||
} else {
|
||||
fprintf(stderr, "Password file busy, try again later.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((fp_tmp = fdopen(fd_tmp, "w+")) == NULL) fatal(pw_tmp);
|
||||
|
||||
setpwent();
|
||||
while ((pwd = getpwent()) != 0) {
|
||||
if (strcmp(name, pwd->pw_name) == 0) {
|
||||
switch (action) {
|
||||
case PASSWD:
|
||||
pwd->pw_passwd = newcrypted;
|
||||
break;
|
||||
case CHFN:
|
||||
pwd->pw_gecos = argn;
|
||||
break;
|
||||
case CHSH:
|
||||
pwd->pw_shell = argn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (strcmp(pwd->pw_shell, "/bin/sh") == 0
|
||||
|| strcmp(pwd->pw_shell, "/usr/bin/sh") == 0
|
||||
)
|
||||
pwd->pw_shell = "";
|
||||
|
||||
fprintf(fp_tmp, "%s:%s:%s:",
|
||||
pwd->pw_name,
|
||||
pwd->pw_passwd,
|
||||
itoa(pwd->pw_uid)
|
||||
);
|
||||
if (ferror(fp_tmp)) fatal(pw_tmp);
|
||||
|
||||
fprintf(fp_tmp, "%s:%s:%s:%s\n",
|
||||
itoa(pwd->pw_gid),
|
||||
pwd->pw_gecos,
|
||||
pwd->pw_dir,
|
||||
pwd->pw_shell
|
||||
);
|
||||
if (ferror(fp_tmp)) fatal(pw_tmp);
|
||||
}
|
||||
endpwent();
|
||||
if (fflush(fp_tmp) == EOF) fatal(pw_tmp);
|
||||
|
||||
if (lseek(fd_tmp, (off_t) 0, SEEK_SET) != 0)
|
||||
fatal("Can't reread temp file");
|
||||
|
||||
if ((fd_pwd = open(shadow ? sh_file : pw_file, O_WRONLY | O_TRUNC)) < 0)
|
||||
fatal("Can't recreate password file");
|
||||
|
||||
while ((n = read(fd_tmp, buf, sizeof(buf))) != 0) {
|
||||
if (n < 0 || write(fd_pwd, buf, n) != n) {
|
||||
report("Error rewriting password file, tell root!");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
close(fd_tmp);
|
||||
close(fd_pwd);
|
||||
quit(0);
|
||||
}
|
|
@ -2,5 +2,8 @@ PROG= pwdauth
|
|||
BINDIR= /usr/lib
|
||||
BINMODE= 4755
|
||||
MAN=
|
||||
NEED_NBSDLIBC=y
|
||||
|
||||
LDADD+=-lcrypt
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
* a no-password login.
|
||||
*/
|
||||
#define nil 0
|
||||
#define crypt CRYPT /* The true crypt is included here. */
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -30,7 +29,6 @@
|
|||
#endif
|
||||
|
||||
#define LEN 1024
|
||||
char SHADOW[] = "/etc/shadow";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
@ -51,11 +49,6 @@ int main(int argc, char **argv)
|
|||
salt = key + strlen(key) + 1;
|
||||
|
||||
if (salt[0] == '#' && salt[1] == '#') {
|
||||
/* Get the encrypted password from the shadow password file,
|
||||
* encrypt key and compare.
|
||||
*/
|
||||
setpwfile(SHADOW);
|
||||
|
||||
if ((pw= getpwnam(salt + 2)) == nil) return 2;
|
||||
|
||||
/* A null encrypted password matches a null key, otherwise
|
||||
|
@ -80,283 +73,3 @@ int main(int argc, char **argv)
|
|||
if (write(1, salt, strlen(salt) + 1) < 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The one and only crypt(3) function. */
|
||||
|
||||
/* From Andy Tanenbaum's book "Computer Networks",
|
||||
rewritten in C
|
||||
*/
|
||||
|
||||
struct block {
|
||||
unsigned char b_data[64];
|
||||
};
|
||||
|
||||
struct ordering {
|
||||
unsigned char o_data[64];
|
||||
};
|
||||
|
||||
static struct block key;
|
||||
|
||||
static struct ordering InitialTr = {
|
||||
58,50,42,34,26,18,10, 2,60,52,44,36,28,20,12, 4,
|
||||
62,54,46,38,30,22,14, 6,64,56,48,40,32,24,16, 8,
|
||||
57,49,41,33,25,17, 9, 1,59,51,43,35,27,19,11, 3,
|
||||
61,53,45,37,29,21,13, 5,63,55,47,39,31,23,15, 7,
|
||||
};
|
||||
|
||||
static struct ordering FinalTr = {
|
||||
40, 8,48,16,56,24,64,32,39, 7,47,15,55,23,63,31,
|
||||
38, 6,46,14,54,22,62,30,37, 5,45,13,53,21,61,29,
|
||||
36, 4,44,12,52,20,60,28,35, 3,43,11,51,19,59,27,
|
||||
34, 2,42,10,50,18,58,26,33, 1,41, 9,49,17,57,25,
|
||||
};
|
||||
|
||||
static struct ordering swap = {
|
||||
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
|
||||
49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,
|
||||
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
|
||||
};
|
||||
|
||||
static struct ordering KeyTr1 = {
|
||||
57,49,41,33,25,17, 9, 1,58,50,42,34,26,18,
|
||||
10, 2,59,51,43,35,27,19,11, 3,60,52,44,36,
|
||||
63,55,47,39,31,23,15, 7,62,54,46,38,30,22,
|
||||
14, 6,61,53,45,37,29,21,13, 5,28,20,12, 4,
|
||||
};
|
||||
|
||||
static struct ordering KeyTr2 = {
|
||||
14,17,11,24, 1, 5, 3,28,15, 6,21,10,
|
||||
23,19,12, 4,26, 8,16, 7,27,20,13, 2,
|
||||
41,52,31,37,47,55,30,40,51,45,33,48,
|
||||
44,49,39,56,34,53,46,42,50,36,29,32,
|
||||
};
|
||||
|
||||
static struct ordering etr = {
|
||||
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
|
||||
8, 9,10,11,12,13,12,13,14,15,16,17,
|
||||
16,17,18,19,20,21,20,21,22,23,24,25,
|
||||
24,25,26,27,28,29,28,29,30,31,32, 1,
|
||||
};
|
||||
|
||||
static struct ordering ptr = {
|
||||
16, 7,20,21,29,12,28,17, 1,15,23,26, 5,18,31,10,
|
||||
2, 8,24,14,32,27, 3, 9,19,13,30, 6,22,11, 4,25,
|
||||
};
|
||||
|
||||
static unsigned char s_boxes[8][64] = {
|
||||
{ 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
|
||||
0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
|
||||
4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
|
||||
15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,
|
||||
},
|
||||
|
||||
{ 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
|
||||
3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
|
||||
0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
|
||||
13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,
|
||||
},
|
||||
|
||||
{ 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
|
||||
13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
|
||||
13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
|
||||
1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,
|
||||
},
|
||||
|
||||
{ 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
|
||||
13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
|
||||
10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
|
||||
3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,
|
||||
},
|
||||
|
||||
{ 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
|
||||
14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
|
||||
4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
|
||||
11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,
|
||||
},
|
||||
|
||||
{ 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
|
||||
10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
|
||||
9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
|
||||
4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,
|
||||
},
|
||||
|
||||
{ 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
|
||||
13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
|
||||
1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
|
||||
6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,
|
||||
},
|
||||
|
||||
{ 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
|
||||
1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
|
||||
7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
|
||||
2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
|
||||
},
|
||||
};
|
||||
|
||||
static int rots[] = {
|
||||
1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
|
||||
};
|
||||
|
||||
static void transpose(struct block *data, struct ordering *t, int n)
|
||||
{
|
||||
struct block x;
|
||||
|
||||
x = *data;
|
||||
|
||||
while (n-- > 0) {
|
||||
data->b_data[n] = x.b_data[t->o_data[n] - 1];
|
||||
}
|
||||
}
|
||||
|
||||
static void rotate(struct block *key)
|
||||
{
|
||||
unsigned char *p = key->b_data;
|
||||
unsigned char *ep = &(key->b_data[55]);
|
||||
int data0 = key->b_data[0], data28 = key->b_data[28];
|
||||
|
||||
while (p++ < ep) *(p-1) = *p;
|
||||
key->b_data[27] = data0;
|
||||
key->b_data[55] = data28;
|
||||
}
|
||||
|
||||
static struct ordering *EP = &etr;
|
||||
|
||||
static void f(int i, struct block *key, struct block *a, struct block *x)
|
||||
{
|
||||
struct block e, ikey, y;
|
||||
int k;
|
||||
unsigned char *p, *q, *r;
|
||||
|
||||
e = *a;
|
||||
transpose(&e, EP, 48);
|
||||
for (k = rots[i]; k; k--) rotate(key);
|
||||
ikey = *key;
|
||||
transpose(&ikey, &KeyTr2, 48);
|
||||
p = &(y.b_data[48]);
|
||||
q = &(e.b_data[48]);
|
||||
r = &(ikey.b_data[48]);
|
||||
while (p > y.b_data) {
|
||||
*--p = *--q ^ *--r;
|
||||
}
|
||||
q = x->b_data;
|
||||
for (k = 0; k < 8; k++) {
|
||||
int xb, r;
|
||||
|
||||
r = *p++ << 5;
|
||||
r += *p++ << 3;
|
||||
r += *p++ << 2;
|
||||
r += *p++ << 1;
|
||||
r += *p++;
|
||||
r += *p++ << 4;
|
||||
|
||||
xb = s_boxes[k][r];
|
||||
|
||||
*q++ = (xb >> 3) & 1;
|
||||
*q++ = (xb>>2) & 1;
|
||||
*q++ = (xb>>1) & 1;
|
||||
*q++ = (xb & 1);
|
||||
}
|
||||
transpose(x, &ptr, 32);
|
||||
}
|
||||
|
||||
static void setkey(char *k)
|
||||
{
|
||||
|
||||
key = *((struct block *) k);
|
||||
transpose(&key, &KeyTr1, 56);
|
||||
}
|
||||
|
||||
static void encrypt(char *blck, int edflag)
|
||||
{
|
||||
struct block *p = (struct block *) blck;
|
||||
int i;
|
||||
|
||||
transpose(p, &InitialTr, 64);
|
||||
for (i = 15; i>= 0; i--) {
|
||||
int j = edflag ? i : 15 - i;
|
||||
int k;
|
||||
struct block b, x;
|
||||
|
||||
b = *p;
|
||||
for (k = 31; k >= 0; k--) {
|
||||
p->b_data[k] = b.b_data[k + 32];
|
||||
}
|
||||
f(j, &key, p, &x);
|
||||
for (k = 31; k >= 0; k--) {
|
||||
p->b_data[k+32] = b.b_data[k] ^ x.b_data[k];
|
||||
}
|
||||
}
|
||||
transpose(p, &swap, 64);
|
||||
transpose(p, &FinalTr, 64);
|
||||
}
|
||||
|
||||
char *crypt(const char *pw, const char *salt)
|
||||
{
|
||||
char pwb[66];
|
||||
char *cp;
|
||||
static char result[16];
|
||||
char *p = pwb;
|
||||
struct ordering new_etr;
|
||||
int i;
|
||||
|
||||
while (*pw && p < &pwb[64]) {
|
||||
int j = 7;
|
||||
|
||||
while (j--) {
|
||||
*p++ = (*pw >> j) & 01;
|
||||
}
|
||||
pw++;
|
||||
*p++ = 0;
|
||||
}
|
||||
while (p < &pwb[64]) *p++ = 0;
|
||||
|
||||
setkey(p = pwb);
|
||||
|
||||
while (p < &pwb[66]) *p++ = 0;
|
||||
|
||||
new_etr = etr;
|
||||
EP = &new_etr;
|
||||
if (salt[0] == 0 || salt[1] == 0) salt = "**";
|
||||
for (i = 0; i < 2; i++) {
|
||||
char c = *salt++;
|
||||
int j;
|
||||
|
||||
result[i] = c;
|
||||
if ( c > 'Z') c -= 6 + 7 + '.'; /* c was a lower case letter */
|
||||
else if ( c > '9') c -= 7 + '.';/* c was upper case letter */
|
||||
else c -= '.'; /* c was digit, '.' or '/'. */
|
||||
/* now, 0 <= c <= 63 */
|
||||
for (j = 0; j < 6; j++) {
|
||||
if ((c >> j) & 01) {
|
||||
int t = 6*i + j;
|
||||
int temp = new_etr.o_data[t];
|
||||
new_etr.o_data[t] = new_etr.o_data[t+24];
|
||||
new_etr.o_data[t+24] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result[1] == 0) result[1] = result[0];
|
||||
|
||||
for (i = 0; i < 25; i++) encrypt(pwb,0);
|
||||
EP = &etr;
|
||||
|
||||
p = pwb;
|
||||
cp = result+2;
|
||||
while (p < &pwb[66]) {
|
||||
int c = 0;
|
||||
int j = 6;
|
||||
|
||||
while (j--) {
|
||||
c <<= 1;
|
||||
c |= *p++;
|
||||
}
|
||||
c += '.'; /* becomes >= '.' */
|
||||
if (c > '9') c += 7; /* not in [./0-9], becomes upper */
|
||||
if (c > 'Z') c += 6; /* not in [A-Z], becomes lower */
|
||||
*cp++ = c;
|
||||
}
|
||||
*cp = 0;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
PROG= su
|
||||
BINMODE= 4755
|
||||
MAN=
|
||||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
NEED_NBSDLIBC=y
|
||||
LDADD+= -lcrypt
|
||||
.endif
|
||||
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -1,3 +1,37 @@
|
|||
20111109:
|
||||
Switch to NetBSD passwd system.
|
||||
|
||||
You have to bootstrap pwd_mkdb:
|
||||
# make clean includes elf-libraries
|
||||
# make -C usr.sbin/pwd_mkdb install
|
||||
|
||||
Now build world. WARNING: this will blind your system to
|
||||
/etc/shadow, making current user accounts vanish. Updating the
|
||||
group file is necessary to add a 'users' group so the new stock
|
||||
useradd will work.
|
||||
|
||||
# make clean world
|
||||
# cp etc/group /etc/group
|
||||
|
||||
The new shadow file is /etc/master.passwd. Add your old user
|
||||
accounts back with useradd(8), groups with groupadd(8), and
|
||||
set a root pw with passwd(1) if you want. Use vipw(8) to edit
|
||||
/etc/master.passwd if you want. See useradd(8) to get started
|
||||
with the new pw format. Test your new system now by logging in.
|
||||
|
||||
Once you're satisfied your new system works, remove the old
|
||||
adduser, and rely exclusively on the new useradd and
|
||||
master.passwd.
|
||||
# rm /usr/bin/adduser
|
||||
# mv /etc/shadow /etc/shadow.orig
|
||||
|
||||
pwdauth is updated so that current binaries (e.g. sshd) will
|
||||
work with the new pw db.
|
||||
|
||||
By default your new users are in the 'users' group. Add yourself
|
||||
to the 'operator' group if you want to be able to su without
|
||||
typing in the password.
|
||||
|
||||
20111109:
|
||||
fstab format change. /etc/rc reads both formats for a while.
|
||||
Please convert your /etc/fstab to the new format though as
|
||||
|
|
|
@ -25,7 +25,7 @@ PROTO= proto.small
|
|||
STRIPFLAG+= -s
|
||||
.endif
|
||||
|
||||
EXTRA=system.conf passwd rs.single
|
||||
EXTRA=system.conf master.passwd passwd pwd.db rs.single
|
||||
|
||||
CPPFLAGS+= -I${MINIXSRCDIR}/servers -I${MINIXSRCDIR}
|
||||
CLEANFILES += $(PROGRAMS) $(SCRIPTS) $(EXTRA) bintoc image image.c t proto.gen
|
||||
|
@ -150,7 +150,16 @@ ext2: ../../servers/ext2/ext2
|
|||
system.conf: ../../etc/system.conf
|
||||
install ${STRIPFLAG} ../../etc/$@ $@
|
||||
|
||||
passwd: ../../etc/passwd
|
||||
passwd: ../../etc/master.passwd
|
||||
rm -f ../../etc/master.passwd.orig ../../etc/passwd.orig
|
||||
rm -f ../../etc/pwd.db.tmp ../../etc/spwd.db.tmp
|
||||
../../usr.sbin/pwd_mkdb/pwd_mkdb -V 0 -p -d ../../ ../../etc/master.passwd
|
||||
install ${STRIPFLAG} ../../etc/$@ $@
|
||||
|
||||
master.passwd: ../../etc/master.passwd
|
||||
install ${STRIPFLAG} ../../etc/$@ $@
|
||||
|
||||
pwd.db: passwd
|
||||
install ${STRIPFLAG} ../../etc/$@ $@
|
||||
|
||||
rs.single: ../../etc/rs.single
|
||||
|
|
17
etc/Makefile
17
etc/Makefile
|
@ -1,23 +1,24 @@
|
|||
ETC=/etc/
|
||||
USR=/usr/
|
||||
USRETC=/usr/etc/
|
||||
FILES1=group hostname.file inet.conf motd.install mtab passwd profile \
|
||||
FILES1=group hostname.file inet.conf motd.install mtab profile \
|
||||
protocols rc services termcap ttytab utmp rc.cd binary_sizes \
|
||||
binary_sizes.big binary_sizes.xxl syslog.conf rc.daemons.dist \
|
||||
rs.inet rs.single make.conf system.conf ttys resolv.conf rc.conf \
|
||||
rc.subr rc.subr.minix man.conf
|
||||
|
||||
FILES2=shadow
|
||||
PWFILES=master.passwd
|
||||
FILES3=daily dhcptags.conf rc
|
||||
USRFILES=Makefile
|
||||
|
||||
TOOL_PWD_MKDB= pwd_mkdb
|
||||
|
||||
clean::
|
||||
|
||||
install::
|
||||
install:: installpw # installpw needed to bootstrap pw db
|
||||
@echo "Installing /etc, /usr/etc and /usr/lib.."
|
||||
mkdir -p $(ETC) $(USRLIB)
|
||||
@for f in $(FILES1); do if [ -f $(ETC)/$$f ]; then :; else cp $$f $(ETC)/$$f; chmod 755 $(ETC)/$$f; fi; done
|
||||
@for f in $(FILES2); do if [ -f $(ETC)/$$f ]; then :; else cp $$f $(ETC)/$$f; chmod 600 $(ETC)/$$f; fi; done
|
||||
@for f in $(USRFILES); do cp usr/$$f $(USR)/$$f; chmod 644 $(USR)/$$f; done
|
||||
@echo "Making hierarchy.."
|
||||
sh mtree.sh mtree/minix.tree
|
||||
|
@ -33,7 +34,13 @@ install::
|
|||
@echo "Installing /usr/lib/descr.."
|
||||
install -m 644 -o root -g operator descr /usr/lib/
|
||||
|
||||
installforce:: $(ETC)/rc $(ETC)/rs.inet $(ETC)/rs.single $(ETC)/system.conf $(USRETC)/rc $(USR)/Makefile
|
||||
|
||||
installforce:: $(ETC)/rc $(ETC)/rs.inet $(ETC)/rs.single $(ETC)/system.conf $(USRETC)/rc $(USR)/Makefile installpw
|
||||
|
||||
installpw::
|
||||
if [ ! -d $(ETC) ]; then mkdir $(ETC); chmod 755 $(ETC); fi
|
||||
@for f in $(PWFILES); do if [ -f $(ETC)/$$f ]; then :; else cp $$f $(ETC)/$$f; chmod 600 $(ETC)/$$f; fi; done
|
||||
touch /etc/pwd.db; touch /etc/spwd.db; ${TOOL_PWD_MKDB} -p -V 0 /etc/master.passwd
|
||||
|
||||
$(ETC)/rc: rc
|
||||
install -m 755 -o root -g operator $> $@
|
||||
|
|
20
etc/group
20
etc/group
|
@ -11,9 +11,19 @@ www:*:9:
|
|||
driver:*:10:
|
||||
server:*:11:
|
||||
games:*:13:
|
||||
sshd:*:23:
|
||||
smtpd:*:26:
|
||||
postfix:*:27:
|
||||
maildrop:*:28:
|
||||
mail:*:29:
|
||||
_pflogd:*:18:
|
||||
_rwhod:*:19:
|
||||
_proxy:*:21:
|
||||
_timedc:*:22:
|
||||
_sdpd:*:23:
|
||||
_httpd:*:24:
|
||||
_mdnsd:*:25:
|
||||
_tests:*:26:
|
||||
_tcpdump:*:27:
|
||||
smtpd:*:40:
|
||||
postfix:*:41:
|
||||
maildrop:*:42:
|
||||
mail:*:43:
|
||||
sshd:*:44:
|
||||
nogroup:*:99:
|
||||
users:*:100:
|
||||
|
|
17
etc/master.passwd
Normal file
17
etc/master.passwd
Normal file
|
@ -0,0 +1,17 @@
|
|||
root::0:0::0:0:Big Brother:/root:/bin/sh
|
||||
daemon:*:1:1::0:0:The Deuce:/etc:/bin/sh
|
||||
bin:*:2:0::0:0:Binaries:/home/bin:/bin/sh
|
||||
uucp:*:5:5::0:0:UNIX to UNIX copy:/usr/spool/uucp:/usr/bin/uucico
|
||||
news:*:6:6::0:0:Usenet news:/usr/spool/news:/bin/sh
|
||||
ftp:*:7:7::0:0:Anonymous FTP:/usr/ftp:/bin/sh
|
||||
ast:*:8:3::0:0:Andrew S. Tanenbaum:/home/ast:/bin/sh
|
||||
www:*:9:9::0:0:World Wide Web:/usr/www:/bin/sh
|
||||
driver:*:10:10::0:0:Device Drivers:/:/bin/sh
|
||||
server:*:11:11::0:0:OS Servers:/:/bin/sh
|
||||
service:*:12:12::0:0:System Services:/:/bin/sh
|
||||
sshd:*:22:22::0:0:sshd:/:/bin/sh
|
||||
smtpd:*:25:25::0:0:smtpd:/:/bin/sh
|
||||
postfix:*:27:27::0:0:postfix:/usr/var/spool/postfix:/bin/false
|
||||
postgres:*:30:30::0:0:postgresql:/:/bin/false
|
||||
games:*:9998:13::0:0:games:/:/bin/sh
|
||||
nobody:*:9999:39::0:0:Unprivileged user:/tmp:/bin/sh
|
17
etc/passwd
17
etc/passwd
|
@ -1,17 +0,0 @@
|
|||
root:##root:0:0:Big Brother:/root:
|
||||
daemon:*:1:1:The Deuce:/etc:
|
||||
bin:##root:2:0:Binaries:/home/bin:
|
||||
uucp:*:5:5:UNIX to UNIX copy:/usr/spool/uucp:/usr/bin/uucico
|
||||
news:*:6:6:Usenet news:/usr/spool/news:
|
||||
ftp:*:7:7:Anonymous FTP:/usr/ftp:
|
||||
ast:*:8:3:Andrew S. Tanenbaum:/home/ast:
|
||||
www:*:9:9:World Wide Web:/usr/www:
|
||||
driver:*:10:10:Device Drivers:/:
|
||||
server:*:11:11:OS Servers:/:
|
||||
service:*:12:12:System Services:/:
|
||||
sshd:*:22:22:sshd:/:
|
||||
smtpd:*:25:25:smtpd:/:
|
||||
postfix:*:27:27:postfix:/usr/var/spool/postfix:/bin/false
|
||||
postgres:*:30:30:postgresql:/:/bin/false
|
||||
games:*:9998:98::/:
|
||||
nobody:*:9999:99::/tmp:
|
|
@ -1 +0,0 @@
|
|||
root::0:0:::
|
|
@ -3,6 +3,7 @@
|
|||
.if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no")
|
||||
LIBC_DIR= nbsd_libc
|
||||
LIBM_DIR= nbsd_libm
|
||||
LIBUTIL_DIR= libutil
|
||||
LIBCOMPAT_DIR= nbsd_libcompat_minix
|
||||
LIBMINLIB_DIR= nbsd_libminlib
|
||||
LIBASYN_DIR= nbsd_libasyn
|
||||
|
@ -10,12 +11,13 @@ LIBASYN_DIR= nbsd_libasyn
|
|||
|
||||
LIBC_DIR?= libc
|
||||
LIBM_DIR?= libm
|
||||
LIBUTIL_DIR?= libminixutil
|
||||
LIBCOMPAT_DIR?=
|
||||
LIBMINLIB_DIR?=
|
||||
LIBASYN_DIR?=
|
||||
|
||||
SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \
|
||||
libedit ${LIBM_DIR} libsys libtimers libminixutil libbz2 libl libhgfs \
|
||||
libedit ${LIBM_DIR} libsys libtimers ${LIBUTIL_DIR} libbz2 libl libhgfs \
|
||||
libz libfetch libarchive libvtreefs libaudiodriver libmthread \
|
||||
libexec libdevman libusb ${LIBMINLIB_DIR} ${LIBASYN_DIR} \
|
||||
libddekit libminixfs libbdev
|
||||
|
|
|
@ -41,7 +41,6 @@ SRCS+= \
|
|||
bcopy.c \
|
||||
bzero.c \
|
||||
configfile.c \
|
||||
crypt.c \
|
||||
ctermid.c \
|
||||
cuserid.c \
|
||||
dirname.c \
|
||||
|
@ -64,7 +63,6 @@ SRCS+= \
|
|||
getpagesize.c \
|
||||
getpass.c \
|
||||
getprogname.c \
|
||||
getpwent.c \
|
||||
getsubopt.c \
|
||||
getttyent.c \
|
||||
getw.c \
|
||||
|
@ -85,7 +83,6 @@ SRCS+= \
|
|||
popen.c \
|
||||
putenv.c \
|
||||
putw.c \
|
||||
pwcache.c \
|
||||
random.c \
|
||||
read_tsc.S \
|
||||
read_tsc_64.c \
|
||||
|
@ -125,3 +122,9 @@ SRCS+= \
|
|||
vwarnx.c \
|
||||
warn.c \
|
||||
warnx.c
|
||||
|
||||
# XXX To be removed after full
|
||||
# XXX switch to NetBSD passwd.
|
||||
SRCS+= \
|
||||
getpwent.c \
|
||||
pwcache.c
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
/* crypt() - one-way password encryption function Author: Kees J. Bot
|
||||
* 7 Feb 1994
|
||||
* This routine does not encrypt anything, it uses the pwdauth
|
||||
* program to do the hard work.
|
||||
*/
|
||||
#define nil ((void*)0)
|
||||
#define pipe _pipe
|
||||
#define fork _fork
|
||||
#define close _close
|
||||
#define dup2 _dup2
|
||||
#define execl _execl
|
||||
#define read _read
|
||||
#define _exit __exit
|
||||
#define write _write
|
||||
#define waitpid _waitpid
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
/* Set-uid root program to read /etc/shadow or encrypt passwords. */
|
||||
static char PWDAUTH[] = "/usr/lib/pwdauth";
|
||||
#define LEN 1024
|
||||
|
||||
static void tell(const char *s0, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *s;
|
||||
|
||||
va_start(ap, s0);
|
||||
s= s0;
|
||||
while (s != nil) {
|
||||
(void) write(2, s, strlen(s));
|
||||
s= va_arg(ap, const char *);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
char *crypt(const char *key, const char *salt)
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
int pfd[2];
|
||||
static char pwdata[LEN];
|
||||
char *p= pwdata;
|
||||
const char *k= key;
|
||||
const char *s= salt;
|
||||
int n;
|
||||
|
||||
/* Fill pwdata[] with the key and salt. */
|
||||
while ((*p++ = *k++) != 0) if (p == pwdata+LEN-1) goto fail;
|
||||
while ((*p++ = *s++) != 0) if (p == pwdata+LEN-0) goto fail;
|
||||
|
||||
if (pipe(pfd) < 0) goto fail;
|
||||
|
||||
/* Prefill the pipe. */
|
||||
(void) write(pfd[1], pwdata, p - pwdata);
|
||||
|
||||
switch ((pid= fork())) {
|
||||
case -1:
|
||||
close(pfd[0]);
|
||||
close(pfd[1]);
|
||||
goto fail;
|
||||
case 0:
|
||||
/* Connect both input and output to the pipe. */
|
||||
if (pfd[0] != 0) {
|
||||
dup2(pfd[0], 0);
|
||||
close(pfd[0]);
|
||||
}
|
||||
if (pfd[1] != 1) {
|
||||
dup2(pfd[1], 1);
|
||||
close(pfd[1]);
|
||||
}
|
||||
|
||||
execl(PWDAUTH, PWDAUTH, (char *) nil);
|
||||
|
||||
tell("crypt(): ", PWDAUTH, ": ", strerror(errno), "\r\n",
|
||||
(char *) nil);
|
||||
/* No pwdauth? Fail! */
|
||||
(void) read(0, pwdata, LEN);
|
||||
_exit(1);
|
||||
}
|
||||
close(pfd[1]);
|
||||
|
||||
status= -1;
|
||||
while (waitpid(pid, &status, 0) == -1 && errno == EINTR) {}
|
||||
if (status != 0) {
|
||||
close(pfd[0]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Read and return the result. Check if it contains exactly one
|
||||
* string.
|
||||
*/
|
||||
n= read(pfd[0], pwdata, LEN);
|
||||
close(pfd[0]);
|
||||
if (n < 0) goto fail;
|
||||
p = pwdata + n;
|
||||
n = 0;
|
||||
while (p > pwdata) if (*--p == 0) n++;
|
||||
if (n != 1) goto fail;
|
||||
return pwdata;
|
||||
|
||||
fail:
|
||||
pwdata[0] = salt[0] ^ 1; /* make result != salt */
|
||||
pwdata[1] = 0;
|
||||
return pwdata;
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: crypt.c,v 1.5 1996/04/11 07:46:11 philip Exp $
|
||||
*/
|
|
@ -17,7 +17,7 @@ SRCS= efun.c getbootfile.c \
|
|||
passwd.c pw_scan.c pidfile.c pidlock.c pty.c \
|
||||
raise_default_signal.c \
|
||||
secure_path.c snprintb.c \
|
||||
ttyaction.c
|
||||
ttyaction.c login_cap.c
|
||||
#disklabel_dkcksum.c disklabel_scan.c \
|
||||
#if_media.c \
|
||||
#sockaddr_snprintf.c
|
||||
|
@ -25,7 +25,6 @@ SRCS= efun.c getbootfile.c \
|
|||
#getmaxpartitions.c
|
||||
#stat_flags.c
|
||||
#getrawpartition.c
|
||||
#login_cap.c
|
||||
#ttymsg.c
|
||||
#parsedate.y
|
||||
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
.PATH: ${.CURDIR}/compat
|
||||
|
||||
CPPFLAGS+=-I${.CURDIR}/../libc -I${.CURDIR}/../../sys
|
||||
SRCS+=compat_passwd.c compat_loginx.c compat_login.c compat_parsedate.c \
|
||||
SRCS+=compat_passwd.c compat_loginx.c compat_parsedate.c \
|
||||
compat_login_cap.c
|
||||
# compat_login.c
|
||||
|
|
|
@ -417,12 +417,16 @@ static struct {
|
|||
{ RLIMIT_FSIZE, R_CSIZE, "filesize", },
|
||||
{ RLIMIT_DATA, R_CSIZE, "datasize", },
|
||||
{ RLIMIT_STACK, R_CSIZE, "stacksize", },
|
||||
#ifndef __minix
|
||||
{ RLIMIT_RSS, R_CSIZE, "memoryuse", },
|
||||
{ RLIMIT_MEMLOCK, R_CSIZE, "memorylocked", },
|
||||
{ RLIMIT_NPROC, R_CNUMB, "maxproc", },
|
||||
#endif
|
||||
{ RLIMIT_NOFILE, R_CNUMB, "openfiles", },
|
||||
{ RLIMIT_CORE, R_CSIZE, "coredumpsize", },
|
||||
#ifdef RLIMIT_SBSIZE
|
||||
{ RLIMIT_SBSIZE, R_CSIZE, "sbsize", },
|
||||
#endif
|
||||
{ -1, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -472,11 +476,13 @@ gsetrl(login_cap_t *lc, int what, const char *name, int type)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef __minix
|
||||
if (setrlimit(what, &rl)) {
|
||||
syslog(LOG_ERR, "%s: setting resource limit %s: %m",
|
||||
lc->lc_class, name);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
#undef RCUR
|
||||
#undef RMAX
|
||||
return (0);
|
||||
|
@ -570,6 +576,7 @@ setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags)
|
|||
if (!lc)
|
||||
flc = lc = login_getclass(pwd ? pwd->pw_class : NULL);
|
||||
|
||||
#define LOGIN_SETLOGIN 0
|
||||
/*
|
||||
* Without the pwd entry being passed we cannot set either
|
||||
* the group or the login. We could complain about it.
|
||||
|
|
|
@ -59,6 +59,16 @@
|
|||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
#include "nbtool_config.h"
|
||||
/*
|
||||
* XXX Undefine the renames of these functions so that we don't
|
||||
* XXX rename the versions found in the host's <pwd.h> by mistake!
|
||||
*/
|
||||
#undef group_from_gid
|
||||
#undef user_from_uid
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
|
@ -81,6 +91,18 @@ __RCSID("$NetBSD: pwcache.c,v 1.31 2010/03/23 20:28:59 drochner Exp $");
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if HAVE_NBTOOL_CONFIG_H
|
||||
/* XXX Now, re-apply the renaming that we undid above. */
|
||||
#define group_from_gid __nbcompat_group_from_gid
|
||||
#define user_from_uid __nbcompat_user_from_uid
|
||||
#endif
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(user_from_uid,_user_from_uid)
|
||||
__weak_alias(group_from_gid,_group_from_gid)
|
||||
__weak_alias(pwcache_groupdb,_pwcache_groupdb)
|
||||
#endif
|
||||
|
||||
#if !HAVE_PWCACHE_USERDB || HAVE_NBTOOL_CONFIG_H
|
||||
#include "pwcache.h"
|
||||
|
||||
|
@ -226,6 +248,273 @@ grptb_start(void)
|
|||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* user_from_uid()
|
||||
* caches the name (if any) for the uid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
user_from_uid(uid_t uid, int noname)
|
||||
{
|
||||
struct passwd *pw;
|
||||
UIDC *ptr, **pptr;
|
||||
|
||||
if ((uidtb == NULL) && (uidtb_start() < 0))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* see if we have this uid cached
|
||||
*/
|
||||
pptr = uidtb + (uid % UID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
|
||||
/*
|
||||
* have an entry for this uid
|
||||
*/
|
||||
if (!noname || (ptr->valid == VALID))
|
||||
return (ptr->name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* No entry for this uid, we will add it
|
||||
*/
|
||||
if (!pwopn) {
|
||||
if (_pwcache_setpassent != NULL)
|
||||
(*_pwcache_setpassent)(1);
|
||||
++pwopn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
|
||||
|
||||
if ((pw = (*_pwcache_getpwuid)(uid)) == NULL) {
|
||||
/*
|
||||
* no match for this uid in the local password file
|
||||
* a string that is the uid in numeric format
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (NULL);
|
||||
ptr->uid = uid;
|
||||
(void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
|
||||
ptr->valid = INVALID;
|
||||
if (noname)
|
||||
return (NULL);
|
||||
} else {
|
||||
/*
|
||||
* there is an entry for this uid in the password file
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (pw->pw_name);
|
||||
ptr->uid = uid;
|
||||
(void)strlcpy(ptr->name, pw->pw_name, UNMLEN);
|
||||
ptr->valid = VALID;
|
||||
}
|
||||
return (ptr->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* group_from_gid()
|
||||
* caches the name (if any) for the gid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
group_from_gid(gid_t gid, int noname)
|
||||
{
|
||||
struct group *gr;
|
||||
GIDC *ptr, **pptr;
|
||||
|
||||
if ((gidtb == NULL) && (gidtb_start() < 0))
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* see if we have this gid cached
|
||||
*/
|
||||
pptr = gidtb + (gid % GID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
|
||||
/*
|
||||
* have an entry for this gid
|
||||
*/
|
||||
if (!noname || (ptr->valid == VALID))
|
||||
return (ptr->name);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* No entry for this gid, we will add it
|
||||
*/
|
||||
if (!gropn) {
|
||||
if (_pwcache_setgroupent != NULL)
|
||||
(*_pwcache_setgroupent)(1);
|
||||
++gropn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
|
||||
|
||||
if ((gr = (*_pwcache_getgrgid)(gid)) == NULL) {
|
||||
/*
|
||||
* no match for this gid in the local group file, put in
|
||||
* a string that is the gid in numberic format
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (NULL);
|
||||
ptr->gid = gid;
|
||||
(void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
|
||||
ptr->valid = INVALID;
|
||||
if (noname)
|
||||
return (NULL);
|
||||
} else {
|
||||
/*
|
||||
* there is an entry for this group in the group file
|
||||
*/
|
||||
if (ptr == NULL)
|
||||
return (gr->gr_name);
|
||||
ptr->gid = gid;
|
||||
(void)strlcpy(ptr->name, gr->gr_name, GNMLEN);
|
||||
ptr->valid = VALID;
|
||||
}
|
||||
return (ptr->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* uid_from_user()
|
||||
* caches the uid for a given user name. We use a simple hash table.
|
||||
* Return
|
||||
* the uid (if any) for a user name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
uid_from_user(const char *name, uid_t *uid)
|
||||
{
|
||||
struct passwd *pw;
|
||||
UIDC *ptr, **pptr;
|
||||
size_t namelen;
|
||||
|
||||
/*
|
||||
* return -1 for mangled names
|
||||
*/
|
||||
if (name == NULL || ((namelen = strlen(name)) == 0))
|
||||
return (-1);
|
||||
if ((usrtb == NULL) && (usrtb_start() < 0))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* look up in hash table, if found and valid return the uid,
|
||||
* if found and invalid, return a -1
|
||||
*/
|
||||
pptr = usrtb + st_hash(name, namelen, UNM_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
|
||||
if (ptr->valid == INVALID)
|
||||
return (-1);
|
||||
*uid = ptr->uid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!pwopn) {
|
||||
if (_pwcache_setpassent != NULL)
|
||||
(*_pwcache_setpassent)(1);
|
||||
++pwopn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
|
||||
|
||||
/*
|
||||
* no match, look it up, if no match store it as an invalid entry,
|
||||
* or store the matching uid
|
||||
*/
|
||||
if (ptr == NULL) {
|
||||
if ((pw = (*_pwcache_getpwnam)(name)) == NULL)
|
||||
return (-1);
|
||||
*uid = pw->pw_uid;
|
||||
return (0);
|
||||
}
|
||||
(void)strlcpy(ptr->name, name, UNMLEN);
|
||||
if ((pw = (*_pwcache_getpwnam)(name)) == NULL) {
|
||||
ptr->valid = INVALID;
|
||||
return (-1);
|
||||
}
|
||||
ptr->valid = VALID;
|
||||
*uid = ptr->uid = pw->pw_uid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* gid_from_group()
|
||||
* caches the gid for a given group name. We use a simple hash table.
|
||||
* Return
|
||||
* the gid (if any) for a group name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
gid_from_group(const char *name, gid_t *gid)
|
||||
{
|
||||
struct group *gr;
|
||||
GIDC *ptr, **pptr;
|
||||
size_t namelen;
|
||||
|
||||
/*
|
||||
* return -1 for mangled names
|
||||
*/
|
||||
if (name == NULL || ((namelen = strlen(name)) == 0))
|
||||
return (-1);
|
||||
if ((grptb == NULL) && (grptb_start() < 0))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* look up in hash table, if found and valid return the uid,
|
||||
* if found and invalid, return a -1
|
||||
*/
|
||||
pptr = grptb + st_hash(name, namelen, GID_SZ);
|
||||
ptr = *pptr;
|
||||
|
||||
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
|
||||
if (ptr->valid == INVALID)
|
||||
return (-1);
|
||||
*gid = ptr->gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!gropn) {
|
||||
if (_pwcache_setgroupent != NULL)
|
||||
(*_pwcache_setgroupent)(1);
|
||||
++gropn;
|
||||
}
|
||||
|
||||
if (ptr == NULL)
|
||||
*pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
|
||||
|
||||
/*
|
||||
* no match, look it up, if no match store it as an invalid entry,
|
||||
* or store the matching gid
|
||||
*/
|
||||
if (ptr == NULL) {
|
||||
if ((gr = (*_pwcache_getgrnam)(name)) == NULL)
|
||||
return (-1);
|
||||
*gid = gr->gr_gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
(void)strlcpy(ptr->name, name, GNMLEN);
|
||||
if ((gr = (*_pwcache_getgrnam)(name)) == NULL) {
|
||||
ptr->valid = INVALID;
|
||||
return (-1);
|
||||
}
|
||||
ptr->valid = VALID;
|
||||
*gid = ptr->gid = gr->gr_gid;
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define FLUSHTB(arr, len, fail) \
|
||||
do { \
|
||||
if (arr != NULL) { \
|
||||
|
|
|
@ -24,11 +24,6 @@ SRCS+= nlist.c
|
|||
# NetBSD's 'mtab' format.
|
||||
SRCS+= mtab.c
|
||||
|
||||
# Minix legacy passwd format
|
||||
# These should be removed when we switch to
|
||||
# NetBSD's 'passwd' db-based format.
|
||||
SRCS+= getpwent.c
|
||||
|
||||
# fttyslot(fd), a Minix-specific extension
|
||||
SRCS+= fttyslot.c
|
||||
|
||||
|
@ -36,11 +31,6 @@ SRCS+= fttyslot.c
|
|||
# Now considered "compat" feature in NetBSD.
|
||||
SRCS+= cuserid.c
|
||||
|
||||
# XXX: hack
|
||||
# user_from_uid(), uid_from_user()
|
||||
# group_from_gid(), gid_from_group()
|
||||
SRCS+= passwd.c
|
||||
|
||||
.include "include/Makefile.inc"
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
/* getpwent(), getpwuid(), getpwnam() - password file routines
|
||||
*
|
||||
* Author: Kees J. Bot
|
||||
* 31 Jan 1994
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <compat/pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define arraylimit(a) ((a) + arraysize(a))
|
||||
|
||||
static char PASSWD[]= "/etc/passwd"; /* The password file. */
|
||||
static const char *pwfile; /* Current password file. */
|
||||
|
||||
static char buf[1024]; /* Read buffer. */
|
||||
static char pwline[256]; /* One line from the password file. */
|
||||
static struct passwd entry; /* Entry to fill and return. */
|
||||
static int pwfd= -1; /* Filedescriptor to the file. */
|
||||
static char *bufptr; /* Place in buf. */
|
||||
static ssize_t buflen= 0; /* Remaining characters in buf. */
|
||||
static char *lineptr; /* Place in the line. */
|
||||
|
||||
void endpwent(void)
|
||||
/* Close the password file. */
|
||||
{
|
||||
if (pwfd >= 0) {
|
||||
(void) close(pwfd);
|
||||
pwfd= -1;
|
||||
buflen= 0;
|
||||
}
|
||||
}
|
||||
|
||||
int setpwent(void)
|
||||
/* Open the password file. */
|
||||
{
|
||||
if (pwfd >= 0) endpwent();
|
||||
|
||||
if (pwfile == NULL) pwfile= PASSWD;
|
||||
|
||||
if ((pwfd= open(pwfile, O_RDONLY)) < 0) return -1;
|
||||
(void) fcntl(pwfd, F_SETFD, fcntl(pwfd, F_GETFD) | FD_CLOEXEC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setpwfile(const char *file)
|
||||
/* Prepare for reading an alternate password file. */
|
||||
{
|
||||
endpwent();
|
||||
pwfile= file;
|
||||
}
|
||||
|
||||
static int getline(void)
|
||||
/* Get one line from the password file, return 0 if bad or EOF. */
|
||||
{
|
||||
lineptr= pwline;
|
||||
|
||||
do {
|
||||
if (buflen == 0) {
|
||||
if ((buflen= read(pwfd, buf, sizeof(buf))) <= 0)
|
||||
return 0;
|
||||
bufptr= buf;
|
||||
}
|
||||
|
||||
if (lineptr == arraylimit(pwline)) return 0;
|
||||
buflen--;
|
||||
} while ((*lineptr++ = *bufptr++) != '\n');
|
||||
|
||||
lineptr= pwline;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *scan_colon(void)
|
||||
/* Scan for a field separator in a line, return the start of the field. */
|
||||
{
|
||||
char *field= lineptr;
|
||||
char *last;
|
||||
|
||||
for (;;) {
|
||||
last= lineptr;
|
||||
if (*lineptr == 0) return NULL;
|
||||
if (*lineptr == '\n') break;
|
||||
if (*lineptr++ == ':') break;
|
||||
}
|
||||
*last= 0;
|
||||
return field;
|
||||
}
|
||||
|
||||
struct passwd *getpwent(void)
|
||||
/* Read one entry from the password file. */
|
||||
{
|
||||
char *p;
|
||||
|
||||
/* Open the file if not yet open. */
|
||||
if (pwfd < 0 && setpwent() < 0) return NULL;
|
||||
|
||||
/* Until a good line is read. */
|
||||
for (;;) {
|
||||
if (!getline()) return NULL; /* EOF or corrupt. */
|
||||
|
||||
if ((entry.pw_name= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_passwd= scan_colon()) == NULL) continue;
|
||||
if ((p= scan_colon()) == NULL) continue;
|
||||
entry.pw_uid= strtol(p, NULL, 0);
|
||||
if ((p= scan_colon()) == NULL) continue;
|
||||
entry.pw_gid= strtol(p, NULL, 0);
|
||||
if ((entry.pw_gecos= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_dir= scan_colon()) == NULL) continue;
|
||||
if ((entry.pw_shell= scan_colon()) == NULL) continue;
|
||||
|
||||
if (*lineptr == 0) return &entry;
|
||||
}
|
||||
}
|
||||
|
||||
struct passwd *getpwuid(uid_t uid)
|
||||
/* Return the password file entry belonging to the user-id. */
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
endpwent();
|
||||
while ((pw= getpwent()) != NULL && pw->pw_uid != uid) {}
|
||||
endpwent();
|
||||
return pw;
|
||||
}
|
||||
|
||||
struct passwd *getpwnam(const char *name)
|
||||
/* Return the password file entry belonging to the user name. */
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
endpwent();
|
||||
while ((pw= getpwent()) != NULL && strcmp(pw->pw_name, name) != 0) {}
|
||||
endpwent();
|
||||
return pw;
|
||||
}
|
||||
|
||||
#ifndef L_cuserid
|
||||
#define L_cuserid 9
|
||||
#endif
|
||||
|
||||
char *getlogin()
|
||||
{
|
||||
static char userid[L_cuserid];
|
||||
struct passwd *pw_entry;
|
||||
|
||||
pw_entry = getpwuid(getuid());
|
||||
|
||||
if (pw_entry == (struct passwd *)NULL) return((char *)NULL);
|
||||
|
||||
strcpy(userid, pw_entry->pw_name);
|
||||
|
||||
return(userid);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* grotesque hack to get these functions working.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <compat/pwd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* group_from_gid()
|
||||
* caches the name (if any) for the gid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
group_from_gid(gid_t gid, int noname)
|
||||
{
|
||||
static char buf[16];
|
||||
struct group *g = getgrgid(gid);
|
||||
if (g == NULL) {
|
||||
if (noname) {
|
||||
return NULL;
|
||||
} else {
|
||||
sprintf(buf, "%d", gid);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return g->gr_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* user_from_uid()
|
||||
* caches the name (if any) for the uid. If noname clear, we always
|
||||
* return the stored name (if valid or invalid match).
|
||||
* We use a simple hash table.
|
||||
* Return
|
||||
* Pointer to stored name (or a empty string)
|
||||
*/
|
||||
const char *
|
||||
user_from_uid(uid_t uid, int noname)
|
||||
{
|
||||
static char buf[16];
|
||||
struct passwd *p = getpwuid(uid);
|
||||
if (p == NULL) {
|
||||
if (noname) {
|
||||
return NULL;
|
||||
} else {
|
||||
sprintf(buf, "%d", uid);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
return p->pw_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* uid_from_user()
|
||||
* caches the uid for a given user name. We use a simple hash table.
|
||||
* Return
|
||||
* the uid (if any) for a user name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
uid_from_user(const char *name, uid_t *uid)
|
||||
{
|
||||
struct passwd *p = getpwnam(name);
|
||||
if (p == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*uid = p->pw_uid;
|
||||
return *uid;
|
||||
}
|
||||
|
||||
/*
|
||||
* gid_from_group()
|
||||
* caches the gid for a given group name. We use a simple hash table.
|
||||
* Return
|
||||
* the gid (if any) for a group name, or a -1 if no match can be found
|
||||
*/
|
||||
int
|
||||
gid_from_group(const char *name, gid_t *gid)
|
||||
{
|
||||
struct group *g = getgrnam(name);
|
||||
if (g == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*gid = g->gr_gid;
|
||||
return *gid;
|
||||
}
|
|
@ -13,7 +13,6 @@ MAN= acd.1 anm.1 ar.1 ash.1 asize.1 at.1 banner.1 basename.1 \
|
|||
look.1 lp.1 ls.1 lspci.1 M.1 mail.1 \
|
||||
mesg.1 mixer.1 ackmkdep.1 mkfs.1 \
|
||||
mkproto.1 modem.1 mount.1 mt.1 nice.1 nm.1 nohup.1 od.1 \
|
||||
passwd.1 \
|
||||
paste.1 ping.1 playwave.1 postmort.1 pr.1 prep.1 \
|
||||
profile.1 ps.1 pwd.1 rcp.1 readall.1 recwave.1 \
|
||||
ref.1 remsync.1 rget.1 rlogin.1 rmdir.1 rsh.1 rz.1 \
|
||||
|
@ -61,7 +60,6 @@ MLINKS += cp.1 cpdir.1
|
|||
MLINKS += elvis.1 ex.1
|
||||
MLINKS += expr.1 test.1
|
||||
MLINKS += expr.1 [.1
|
||||
MLINKS += passwd.1 chfn.1
|
||||
MLINKS += svc.1 ci.1
|
||||
MLINKS += svc.1 co.1
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
.TH PASSWD 1
|
||||
.SH NAME
|
||||
passwd, chfn, chsh \- change a login password, full name or shell
|
||||
.SH SYNOPSIS
|
||||
\fBpasswd\fR [\fIuser\fR]\fR
|
||||
.br
|
||||
\fBchfn\fR [\fIuser\fR] \fIfullname\fR\fR
|
||||
.br
|
||||
\fBchsh\fR [\fIuser\fR] \fIshell\fR\fR
|
||||
.br
|
||||
.de FL
|
||||
.TP
|
||||
\\fB\\$1\\fR
|
||||
\\$2
|
||||
..
|
||||
.de EX
|
||||
.TP 20
|
||||
\\fB\\$1\\fR
|
||||
# \\$2
|
||||
..
|
||||
.SH EXAMPLES
|
||||
.EX "passwd" "Change current user's password"
|
||||
.EX "passwd ast" "Change ast's password (super\-user only)"
|
||||
.EX "chsh /usr/bin/mail" "For those who only read mail"
|
||||
.EX "chfn 'Jane Doe'" "Current user is Jane Doe"
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I Passwd
|
||||
is used to change your password.
|
||||
It prompts for the old and new passwords.
|
||||
It asks for the new password twice, to reduce the effect of a typing error.
|
||||
.I Chfn
|
||||
changes the full name (GECOS field) in the password file.
|
||||
.I Chsh
|
||||
changes your login shell.
|
||||
Do not forget to copy the modified password file back to the root file system,
|
||||
or the changes will be lost when the system is rebooted.
|
||||
.SH "SEE ALSO"
|
||||
.BR login (1),
|
||||
.BR su (1),
|
||||
.BR crypt (3),
|
||||
.BR getpwent (3),
|
||||
.BR passwd (5),
|
||||
.BR adduser (8).
|
|
@ -1,4 +1,4 @@
|
|||
MAN= add_route.8 adduser.8 backup.8 badblocks.8 boot.8 \
|
||||
MAN= add_route.8 backup.8 badblocks.8 boot.8 \
|
||||
cdprobe.8 checkhier.8 chown.8 cleantmp.8 config.8 cron.8 \
|
||||
dhcpd.8 diskctl.8 dosminix.8 elvprsv.8 fdisk.8 fingerd.8 ftpd.8 \
|
||||
getty.8 halt.8 hgfs.8 httpd.8 ifconfig.8 inet.8 init.8 \
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
.TH ADDUSER 8
|
||||
.SH NAME
|
||||
adduser \- add a new user to the system
|
||||
.SH SYNOPSIS
|
||||
\fBadduser \fIuser group home-dir\fR\fR
|
||||
.br
|
||||
.de FL
|
||||
.TP
|
||||
\\fB\\$1\\fR
|
||||
\\$2
|
||||
..
|
||||
.de EX
|
||||
.TP 20
|
||||
\\fB\\$1\\fR
|
||||
# \\$2
|
||||
..
|
||||
.SH EXAMPLES
|
||||
.EX "adduser ast other /usr/ast" "How user ast could be added"
|
||||
.EX "adduser bin operator /usr/src" "How user bin could be added"
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I Adduser
|
||||
adds a new user to the system by making new entries in
|
||||
.B /etc/passwd
|
||||
and
|
||||
.B /etc/shadow
|
||||
for the new user, creating a new home directory, and copying the contents
|
||||
of the template home directory
|
||||
.B /usr/ast
|
||||
into it. The user-id of this new user will be the first free number not less
|
||||
than 10. The password is initially empty, the full name must be set, and
|
||||
the shell is the Bourne Shell,
|
||||
.B /bin/sh .
|
||||
Use
|
||||
.I passwd ,
|
||||
.I chfn ,
|
||||
and
|
||||
.I chsh
|
||||
to change.
|
||||
.SH "SEE ALSO"
|
||||
.BR login (1),
|
||||
.BR passwd (1),
|
||||
.BR passwd (5).
|
|
@ -1,4 +1,3 @@
|
|||
.TH PWDAUTH
|
||||
.SH NAME
|
||||
pwdauth \- password authentication program
|
||||
.SH SYNOPSIS
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
#define PGOFSET (NBPG-1) /* byte offset into page */
|
||||
#define NPTEPG (NBPG/(sizeof (pt_entry_t)))
|
||||
|
||||
#ifndef MAXPHYS
|
||||
#define MAXPHYS (64 * 1024) /* max raw I/O transfer size */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mach derived conversion macros
|
||||
*/
|
||||
|
|
|
@ -43,7 +43,9 @@
|
|||
#define _PATH_LOGIN_CONF "/etc/login.conf"
|
||||
|
||||
#define LOGIN_OSETGROUP 0x0001 /* Obsolete setgroup */
|
||||
#ifndef __minix
|
||||
#define LOGIN_SETLOGIN 0x0002 /* Set login */
|
||||
#endif
|
||||
#define LOGIN_SETPATH 0x0004 /* Set path */
|
||||
#define LOGIN_SETPRIORITY 0x0008 /* Set priority */
|
||||
#define LOGIN_SETRESOURCES 0x0010 /* Set resource limits */
|
||||
|
|
|
@ -61,14 +61,6 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(__minix) && defined(_MINIX_COMPAT)
|
||||
#include <compat/pwd.h>
|
||||
/* Avoid inclusion of the rest of the header. */
|
||||
#ifndef _PWD_H_
|
||||
#define _PWD_H_
|
||||
#endif
|
||||
#endif /* __minix && _MINIX_COMPAT */
|
||||
|
||||
#ifndef _PWD_H_
|
||||
#define _PWD_H_
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ struct dirent { /* Largest entry (8 slots) */
|
|||
};
|
||||
|
||||
#if defined(_NETBSD_SOURCE)
|
||||
#define MAXNAMLEN 511
|
||||
#define d_fileno d_ino
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,15 +8,20 @@ lib/libutil src/lib/libutil
|
|||
common/lib/libutil src/common/lib/libutil
|
||||
nbsd_include src/include
|
||||
bin/mkdir src/bin/mkdir
|
||||
usr.bin/chpass src/usr.bin/chpass
|
||||
usr.bin/m4 src/usr.bin/m4
|
||||
usr.bin/indent src/usr.bin/indent
|
||||
usr.bin/sed src/usr.bin/sed
|
||||
usr.bin/stat src/usr.bin/stat
|
||||
usr.bin/tic src/usr.bin/tic
|
||||
usr.bin/mkdep src/usr.bin/mkdep
|
||||
usr.bin/newgrp src/usr.bin/newgrp
|
||||
usr.bin/uniq src/usr.bin/uniq
|
||||
usr.bin/seq src/usr.bin/seq
|
||||
usr.bin/man src/usr.bin/man
|
||||
usr.bin/apropos src/usr.bin/apropos
|
||||
usr.bin/mdocml src/external/bsd/mdocml
|
||||
usr.sbin/pwd_mkdb src/usr.sbin/pwd_mkdb
|
||||
usr.sbin/user src/usr.sbin/user
|
||||
usr.sbin/vipw src/usr.sbin/vipw
|
||||
libexec/makewhatis src/libexec/makewhatis
|
||||
|
|
|
@ -179,7 +179,7 @@ mkdir -p $RELEASEDIR/bin
|
|||
mkdir -p $RELEASEPACKAGE
|
||||
|
||||
echo " * Transfering bootstrap dirs to $RELEASEDIR"
|
||||
cp -p /bin/* /usr/bin/* /sbin/* $RELEASEDIR/$XBIN
|
||||
cp -p /bin/* /usr/bin/* /usr/sbin/* /sbin/* $RELEASEDIR/$XBIN
|
||||
cp -rp /usr/lib $RELEASEDIR/usr
|
||||
cp -rp /bin/sh /bin/echo /bin/install /bin/rm \
|
||||
/bin/date /bin/ls $RELEASEDIR/bin
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# NetBSD imports
|
||||
SUBDIR= indent m4 stat tic sed mkdep uniq seq man mdocml \
|
||||
apropos
|
||||
apropos chpass newgrp passwd
|
||||
|
||||
# Non-NetBSD imports
|
||||
SUBDIR+= ministat
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
.include <minix.newlibc.mk>
|
||||
|
||||
CPPFLAGS+= -D_NETBSD_SOURCE -D__NBSD_LIBC=1
|
||||
|
||||
BINDIR?=/usr/bin
|
||||
|
||||
|
|
42
usr.bin/chpass/Makefile
Normal file
42
usr.bin/chpass/Makefile
Normal file
|
@ -0,0 +1,42 @@
|
|||
# $NetBSD: Makefile,v 1.15 2007/05/28 12:06:25 tls Exp $
|
||||
# @(#)Makefile 8.2 (Berkeley) 4/2/94
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_FORT?= yes # setuid
|
||||
PROG= chpass
|
||||
SRCS= chpass.c edit.c field.c table.c util.c
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
.ifdef __MINIX
|
||||
.PATH: ${NETBSDSRCDIR}/lib/nbsd_libc/gen
|
||||
.else
|
||||
.PATH: ${NETBSDSRCDIR}/lib/libc/gen
|
||||
.endif
|
||||
LINKS= ${BINDIR}/chpass ${BINDIR}/chfn ${BINDIR}/chpass ${BINDIR}/chsh
|
||||
MLINKS= chpass.1 chfn.1 chpass.1 chsh.1
|
||||
|
||||
.ifdef __MINIX
|
||||
CPPFLAGS+=-I${NETBSDSRCDIR}/lib/nbsd_libc/include
|
||||
.else
|
||||
CPPFLAGS+=-I${NETBSDSRCDIR}/lib/libc/include
|
||||
.endif
|
||||
|
||||
.if defined(__MINIX)
|
||||
USE_YP= no
|
||||
.endif
|
||||
|
||||
.if (${USE_YP} != "no")
|
||||
SRCS+= pw_yp.c
|
||||
CPPFLAGS+=-DYP
|
||||
DPADD+= ${LIBRPCSVC}
|
||||
LDADD+= -lrpcsvc
|
||||
.else
|
||||
SRCS+= getpwent.c
|
||||
CPPFLAGS.getpwent.c=-UYP
|
||||
.endif
|
||||
|
||||
DPADD+= ${LIBUTIL}
|
||||
LDADD+= -lutil
|
||||
|
||||
.include <bsd.prog.mk>
|
268
usr.bin/chpass/chpass.1
Normal file
268
usr.bin/chpass/chpass.1
Normal file
|
@ -0,0 +1,268 @@
|
|||
.\" $NetBSD: chpass.1,v 1.23 2006/10/07 20:09:09 elad Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1988, 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)chpass.1 8.2 (Berkeley) 12/30/93
|
||||
.\"
|
||||
.Dd October 7, 2006
|
||||
.Dt CHPASS 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm chpass ,
|
||||
.Nm chfn ,
|
||||
.Nm chsh
|
||||
.Nd add or change user database information
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl a Ar list
|
||||
.Op Fl s Ar newshell
|
||||
.Op Fl l
|
||||
.Op user
|
||||
.Nm chpass
|
||||
.Op Fl a Ar list
|
||||
.Op Fl s Ar newshell
|
||||
.Op Fl y
|
||||
.Op user
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
allows editing of the user database information associated
|
||||
with
|
||||
.Ar user
|
||||
or, by default, the current user.
|
||||
The information is formatted and supplied to an editor for changes.
|
||||
.Pp
|
||||
Only the information that the user is allowed to change is displayed.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl a
|
||||
The super-user is allowed to directly supply a user database
|
||||
entry, in the format specified by
|
||||
.Xr passwd 5 ,
|
||||
as an argument.
|
||||
This argument must be a colon
|
||||
.Pq Dq \&:
|
||||
separated list of all the
|
||||
user database fields, although they may be empty.
|
||||
.It Fl s
|
||||
The
|
||||
.Fl s
|
||||
option attempts to change the user's shell to
|
||||
.Ar newshell .
|
||||
.It Fl l
|
||||
This option causes the password to be updated only in the local
|
||||
password file.
|
||||
When changing only the local password,
|
||||
.Xr pwd_mkdb 8
|
||||
is used to update the password databases.
|
||||
.It Fl y
|
||||
This forces the YP password database entry to be changed, even if
|
||||
the user has an entry in the local database.
|
||||
The
|
||||
.Xr rpc.yppasswdd 8
|
||||
daemon should be running on the YP master server.
|
||||
.El
|
||||
.Pp
|
||||
Possible display items are as follows:
|
||||
.Pp
|
||||
.Bl -tag -width "Home Directory:" -compact -offset indent
|
||||
.It Login :
|
||||
user's login name
|
||||
.It Password :
|
||||
user's encrypted password
|
||||
.It Uid :
|
||||
user's login
|
||||
.It Gid :
|
||||
user's login group
|
||||
.It Change :
|
||||
password change time
|
||||
.It Expire :
|
||||
account expiration time
|
||||
.It Class :
|
||||
user's general classification
|
||||
.It Home Directory :
|
||||
user's home directory
|
||||
.It Shell :
|
||||
user's login shell
|
||||
.It Full Name :
|
||||
user's real name
|
||||
.It Location :
|
||||
user's normal location
|
||||
.It Home Phone :
|
||||
user's home phone
|
||||
.It Office Phone :
|
||||
user's office phone
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar login
|
||||
field is the user name used to access the computer account.
|
||||
.Pp
|
||||
The
|
||||
.Ar password
|
||||
field contains the encrypted form of the user's password.
|
||||
.Pp
|
||||
The
|
||||
.Ar uid
|
||||
field is the number associated with the
|
||||
.Ar login
|
||||
field.
|
||||
Both of these fields should be unique across the system (and often
|
||||
across a group of systems) as they control file access.
|
||||
.Pp
|
||||
While it is possible to have multiple entries with identical login names
|
||||
and/or identical user id's, it is usually a mistake to do so.
|
||||
Routines
|
||||
that manipulate these files will often return only one of the multiple
|
||||
entries, and that one by random selection.
|
||||
.Pp
|
||||
The
|
||||
.Ar group
|
||||
field is the group that the user will be placed in at login.
|
||||
Since
|
||||
.Bx
|
||||
supports multiple groups (see
|
||||
.Xr groups 1 )
|
||||
this field currently has little special meaning.
|
||||
This field may be filled in with either a number or a group name (see
|
||||
.Xr group 5 ) .
|
||||
.Pp
|
||||
The
|
||||
.Ar change
|
||||
field is the date by which the password must be changed.
|
||||
.Pp
|
||||
The
|
||||
.Ar expire
|
||||
field is the date on which the account expires.
|
||||
.Pp
|
||||
Both the
|
||||
.Ar change
|
||||
and
|
||||
.Ar expire
|
||||
fields should be entered in the form
|
||||
.Dq month day year
|
||||
where
|
||||
.Ar month
|
||||
is the month name (the first three characters are sufficient),
|
||||
.Ar day
|
||||
is the day of the month, and
|
||||
.Ar year
|
||||
is the year.
|
||||
.Pp
|
||||
The
|
||||
.Ar class
|
||||
field is a key for a user's login class.
|
||||
Login classes are defined in
|
||||
.Xr login.conf 5 ,
|
||||
which is a
|
||||
.Xr termcap 5
|
||||
style database of user attributes, accounting, resource and
|
||||
environment settings.
|
||||
.Pp
|
||||
The user's
|
||||
.Ar home directory
|
||||
is the full
|
||||
.Ux
|
||||
path name where the user will be placed at login.
|
||||
.Pp
|
||||
The
|
||||
.Ar shell
|
||||
field is the command interpreter the user prefers.
|
||||
If the
|
||||
.Ar shell
|
||||
field is empty, the Bourne shell,
|
||||
.Pa /bin/sh ,
|
||||
is assumed.
|
||||
When altering a login shell, and not the super-user, the user
|
||||
may not change from a non-standard shell or to a non-standard
|
||||
shell.
|
||||
Non-standard is defined as a shell not found in
|
||||
.Pa /etc/shells .
|
||||
.Pp
|
||||
The last four fields are for storing the user's
|
||||
.Ar full name , office location ,
|
||||
and
|
||||
.Ar home
|
||||
and
|
||||
.Ar work telephone
|
||||
numbers.
|
||||
.Pp
|
||||
Once the information has been verified,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the user database.
|
||||
.Sh ENVIRONMENT
|
||||
The
|
||||
.Xr vi 1
|
||||
editor will be used unless the environment variable
|
||||
.Ev EDITOR
|
||||
is set to an alternative editor.
|
||||
When the editor terminates, the information is re-read and used to
|
||||
update the user database itself.
|
||||
Only the user, or the super-user, may edit the information associated
|
||||
with the user.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/master.passwd -compact
|
||||
.It Pa /etc/master.passwd
|
||||
The user database
|
||||
.It Pa /etc/passwd
|
||||
A Version 7 format password file
|
||||
.It Pa /etc/ptmp
|
||||
Lock file for the passwd database
|
||||
.It Pa /tmp/pw.XXXXXX
|
||||
Temporary copy of the user passwd information
|
||||
.It Pa /etc/shells
|
||||
The list of approved shells
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr finger 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr pwhash 1 ,
|
||||
.Xr getusershell 3 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr passwd.conf 5 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr vipw 8
|
||||
.Rs
|
||||
.%A Robert Morris
|
||||
.%A Ken Thompson
|
||||
.%T "UNIX Password Security"
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.3 Reno .
|
||||
.Sh BUGS
|
||||
This program's interface is poorly suited to cryptographic systems such as
|
||||
Kerberos, and consequently Kerberos password changing is not a feature of
|
||||
this program.
|
||||
.Pp
|
||||
User information should (and eventually will) be stored elsewhere.
|
316
usr.bin/chpass/chpass.c
Normal file
316
usr.bin/chpass/chpass.c
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* $NetBSD: chpass.c,v 1.33 2008/07/21 14:19:21 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)chpass.c 8.4 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: chpass.c,v 1.33 2008/07/21 14:19:21 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#include "chpass.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
static char tempname[] = "/tmp/pw.XXXXXX";
|
||||
uid_t uid;
|
||||
int use_yp;
|
||||
|
||||
void (*Pw_error)(const char *, int, int);
|
||||
|
||||
#ifdef YP
|
||||
extern int _yp_check(char **); /* buried deep inside libc */
|
||||
#endif
|
||||
|
||||
void baduser(void);
|
||||
void cleanup(void);
|
||||
void usage(void);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
enum { NEWSH, LOADENTRY, EDITENTRY } op;
|
||||
struct passwd *pw, lpw, old_pw;
|
||||
int ch, dfd, pfd, tfd;
|
||||
#ifdef YP
|
||||
int yflag = 0;
|
||||
#endif
|
||||
char *arg, *username = NULL;
|
||||
|
||||
#ifdef __GNUC__
|
||||
pw = NULL; /* XXX gcc -Wuninitialized */
|
||||
arg = NULL;
|
||||
#endif
|
||||
#ifdef YP
|
||||
use_yp = _yp_check(NULL);
|
||||
#endif
|
||||
|
||||
op = EDITENTRY;
|
||||
while ((ch = getopt(argc, argv, "a:s:ly")) != -1)
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
op = LOADENTRY;
|
||||
arg = optarg;
|
||||
break;
|
||||
case 's':
|
||||
op = NEWSH;
|
||||
arg = optarg;
|
||||
break;
|
||||
case 'l':
|
||||
use_yp = 0;
|
||||
break;
|
||||
case 'y':
|
||||
#ifdef YP
|
||||
if (!use_yp)
|
||||
errx(1, "YP not in use.");
|
||||
yflag = 1;
|
||||
#else
|
||||
errx(1, "YP support not compiled in.");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
uid = getuid();
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* nothing */
|
||||
break;
|
||||
|
||||
case 1:
|
||||
username = argv[0];
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
/*
|
||||
* We need to determine if we _really_ want to use YP.
|
||||
* If we defaulted to YP (i.e. were not given the -y flag),
|
||||
* and the master is not running rpc.yppasswdd, we check
|
||||
* to see if the user exists in the local passwd database.
|
||||
* If so, we use it, otherwise we error out.
|
||||
*/
|
||||
if (use_yp && yflag == 0) {
|
||||
if (check_yppasswdd()) {
|
||||
/*
|
||||
* We weren't able to contact rpc.yppasswdd.
|
||||
* Check to see if we're in the local
|
||||
* password database. If we are, use it.
|
||||
*/
|
||||
if (username != NULL)
|
||||
pw = getpwnam(username);
|
||||
else
|
||||
pw = getpwuid(uid);
|
||||
if (pw != NULL)
|
||||
use_yp = 0;
|
||||
else {
|
||||
warnx("master YP server not running yppasswd"
|
||||
" daemon.");
|
||||
errx(1, "Can't change password.");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef YP
|
||||
if (use_yp)
|
||||
Pw_error = yppw_error;
|
||||
else
|
||||
#endif
|
||||
Pw_error = pw_error;
|
||||
|
||||
#ifdef YP
|
||||
if (op == LOADENTRY && use_yp)
|
||||
errx(1, "cannot load entry using YP.\n"
|
||||
"\tUse the -l flag to load local.");
|
||||
#endif
|
||||
|
||||
if (op == EDITENTRY || op == NEWSH) {
|
||||
if (username != NULL) {
|
||||
pw = getpwnam(username);
|
||||
if (pw == NULL)
|
||||
errx(1, "unknown user: %s", username);
|
||||
if (uid && uid != pw->pw_uid)
|
||||
baduser();
|
||||
} else {
|
||||
pw = getpwuid(uid);
|
||||
if (pw == NULL)
|
||||
errx(1, "unknown user: uid %u", uid);
|
||||
}
|
||||
|
||||
/* Make a copy for later verification */
|
||||
old_pw = *pw;
|
||||
old_pw.pw_gecos = strdup(old_pw.pw_gecos);
|
||||
if (!old_pw.pw_gecos) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
if (op == NEWSH) {
|
||||
/* protect p_shell -- it thinks NULL is /bin/sh */
|
||||
if (!arg[0])
|
||||
usage();
|
||||
if (p_shell(arg, pw, NULL))
|
||||
(*Pw_error)(NULL, 0, 1);
|
||||
}
|
||||
|
||||
if (op == LOADENTRY) {
|
||||
if (uid)
|
||||
baduser();
|
||||
pw = &lpw;
|
||||
if (!pw_scan(arg, pw, NULL))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Edit the user passwd information if requested. */
|
||||
if (op == EDITENTRY) {
|
||||
struct stat sb;
|
||||
|
||||
dfd = mkstemp(tempname);
|
||||
if (dfd < 0 || fcntl(dfd, F_SETFD, 1) < 0)
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
if (atexit(cleanup)) {
|
||||
cleanup();
|
||||
errx(1, "couldn't register cleanup");
|
||||
}
|
||||
if (stat(dirname(tempname), &sb) == -1)
|
||||
err(1, "couldn't stat `%s'", dirname(tempname));
|
||||
if (!(sb.st_mode & S_ISTXT))
|
||||
errx(1, "temporary directory `%s' is not sticky",
|
||||
dirname(tempname));
|
||||
|
||||
display(tempname, dfd, pw);
|
||||
edit(tempname, pw);
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
if (use_yp) {
|
||||
if (pw_yp(pw, uid))
|
||||
yppw_error((char *)NULL, 0, 1);
|
||||
else
|
||||
exit(0);
|
||||
/* Will not exit from this if. */
|
||||
}
|
||||
#endif /* YP */
|
||||
|
||||
|
||||
/*
|
||||
* Get the passwd lock file and open the passwd file for
|
||||
* reading.
|
||||
*/
|
||||
pw_init();
|
||||
tfd = pw_lock(0);
|
||||
if (tfd < 0) {
|
||||
if (errno != EEXIST)
|
||||
err(1, "%s", _PATH_MASTERPASSWD_LOCK);
|
||||
warnx("The passwd file is busy, waiting...");
|
||||
tfd = pw_lock(10);
|
||||
if (tfd < 0) {
|
||||
if (errno != EEXIST)
|
||||
err(1, "%s", _PATH_MASTERPASSWD_LOCK);
|
||||
errx(1, "The passwd file is still busy, "
|
||||
"try again later.");
|
||||
}
|
||||
}
|
||||
if (fcntl(tfd, F_SETFD, 1) < 0)
|
||||
pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1);
|
||||
|
||||
pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (pfd < 0 || fcntl(pfd, F_SETFD, 1) < 0)
|
||||
pw_error(_PATH_MASTERPASSWD, 1, 1);
|
||||
|
||||
/* Copy the passwd file to the lock file, updating pw. */
|
||||
pw_copy(pfd, tfd, pw, (op == LOADENTRY) ? NULL : &old_pw);
|
||||
|
||||
close(pfd);
|
||||
close(tfd);
|
||||
|
||||
/* Now finish the passwd file update. */
|
||||
if (pw_mkdb(username, 0) < 0)
|
||||
pw_error(NULL, 0, 1);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
baduser(void)
|
||||
{
|
||||
|
||||
errx(1, "%s", strerror(EACCES));
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr,
|
||||
"usage: %s [-a list] [-s shell] [-l] [user]\n"
|
||||
" %s [-a list] [-s shell] [-y] [user]\n",
|
||||
getprogname(), getprogname());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
cleanup(void)
|
||||
{
|
||||
|
||||
(void)unlink(tempname);
|
||||
}
|
81
usr.bin/chpass/chpass.h
Normal file
81
usr.bin/chpass/chpass.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* $NetBSD: chpass.h,v 1.12 2005/02/17 17:09:48 xtraeme Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)chpass.h 8.4 (Berkeley) 4/2/94
|
||||
*/
|
||||
|
||||
struct passwd;
|
||||
|
||||
typedef struct _entry {
|
||||
const char *prompt;
|
||||
int (*func)(const char *, struct passwd *, struct _entry *), restricted, len;
|
||||
const char *except, *save;
|
||||
} ENTRY;
|
||||
|
||||
extern int use_yp;
|
||||
|
||||
/* Field numbers. */
|
||||
#define E_BPHONE 8
|
||||
#define E_HPHONE 9
|
||||
#define E_LOCATE 10
|
||||
#define E_NAME 7
|
||||
#define E_SHELL 12
|
||||
|
||||
extern ENTRY list[];
|
||||
extern uid_t uid;
|
||||
|
||||
int atot(const char *, time_t *);
|
||||
void display(char *, int, struct passwd *);
|
||||
void edit(char *, struct passwd *);
|
||||
const char *
|
||||
ok_shell(const char *);
|
||||
int p_change(const char *, struct passwd *, ENTRY *);
|
||||
int p_class(const char *, struct passwd *, ENTRY *);
|
||||
int p_expire(const char *, struct passwd *, ENTRY *);
|
||||
int p_gecos(const char *, struct passwd *, ENTRY *);
|
||||
int p_gid(const char *, struct passwd *, ENTRY *);
|
||||
int p_hdir(const char *, struct passwd *, ENTRY *);
|
||||
int p_login(const char *, struct passwd *, ENTRY *);
|
||||
int p_passwd(const char *, struct passwd *, ENTRY *);
|
||||
int p_shell(const char *, struct passwd *, ENTRY *);
|
||||
int p_uid(const char *, struct passwd *, ENTRY *);
|
||||
char *ttoa(char *, size_t, time_t);
|
||||
int verify(char *, struct passwd *);
|
||||
|
||||
#ifdef YP
|
||||
int check_yppasswdd(void);
|
||||
int pw_yp(struct passwd *, uid_t);
|
||||
void yppw_error(const char *name, int, int);
|
||||
void yppw_prompt(void);
|
||||
struct passwd *ypgetpwnam(const char *);
|
||||
struct passwd *ypgetpwuid(uid_t);
|
||||
#endif
|
||||
|
||||
extern void (*Pw_error)(const char *name, int, int);
|
227
usr.bin/chpass/edit.c
Normal file
227
usr.bin/chpass/edit.c
Normal file
|
@ -0,0 +1,227 @@
|
|||
/* $NetBSD: edit.c,v 1.20 2009/04/11 12:10:02 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)edit.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: edit.c,v 1.20 2009/04/11 12:10:02 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <util.h>
|
||||
|
||||
#include "chpass.h"
|
||||
|
||||
void
|
||||
edit(char *tempname, struct passwd *pw)
|
||||
{
|
||||
struct stat begin, end;
|
||||
|
||||
for (;;) {
|
||||
if (stat(tempname, &begin))
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
pw_edit(1, tempname);
|
||||
if (stat(tempname, &end))
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
if (begin.st_mtime == end.st_mtime) {
|
||||
warnx("no changes made");
|
||||
(*Pw_error)(NULL, 0, 0);
|
||||
}
|
||||
if (verify(tempname, pw))
|
||||
break;
|
||||
#ifdef YP
|
||||
if (use_yp)
|
||||
yppw_prompt();
|
||||
else
|
||||
#endif
|
||||
pw_prompt();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* display --
|
||||
* print out the file for the user to edit; strange side-effect:
|
||||
* set conditional flag if the user gets to edit the shell.
|
||||
*/
|
||||
void
|
||||
display(char *tempname, int fd, struct passwd *pw)
|
||||
{
|
||||
FILE *fp;
|
||||
char *bp, *p;
|
||||
char chgstr[256], expstr[256];
|
||||
|
||||
if (!(fp = fdopen(fd, "w")))
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
|
||||
(void)fprintf(fp,
|
||||
"#Changing user %sdatabase information for %s.\n",
|
||||
use_yp ? "YP " : "", pw->pw_name);
|
||||
if (!uid) {
|
||||
(void)fprintf(fp, "Login: %s\n", pw->pw_name);
|
||||
(void)fprintf(fp, "Password: %s\n", pw->pw_passwd);
|
||||
(void)fprintf(fp, "Uid [#]: %d\n", pw->pw_uid);
|
||||
(void)fprintf(fp, "Gid [# or name]: %d\n", pw->pw_gid);
|
||||
(void)fprintf(fp, "Change [month day year]: %s\n",
|
||||
ttoa(chgstr, sizeof chgstr, pw->pw_change));
|
||||
(void)fprintf(fp, "Expire [month day year]: %s\n",
|
||||
ttoa(expstr, sizeof expstr, pw->pw_expire));
|
||||
(void)fprintf(fp, "Class: %s\n", pw->pw_class);
|
||||
(void)fprintf(fp, "Home directory: %s\n", pw->pw_dir);
|
||||
(void)fprintf(fp, "Shell: %s\n",
|
||||
*pw->pw_shell ? pw->pw_shell : _PATH_BSHELL);
|
||||
}
|
||||
/* Only admin can change "restricted" shells. */
|
||||
else if (ok_shell(pw->pw_shell))
|
||||
/*
|
||||
* Make shell a restricted field. Ugly with a
|
||||
* necklace, but there's not much else to do.
|
||||
*/
|
||||
(void)fprintf(fp, "Shell: %s\n",
|
||||
*pw->pw_shell ? pw->pw_shell : _PATH_BSHELL);
|
||||
else
|
||||
list[E_SHELL].restricted = 1;
|
||||
bp = strdup(pw->pw_gecos);
|
||||
if (!bp) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
p = strsep(&bp, ",");
|
||||
(void)fprintf(fp, "Full Name: %s\n", p ? p : "");
|
||||
p = strsep(&bp, ",");
|
||||
(void)fprintf(fp, "Location: %s\n", p ? p : "");
|
||||
p = strsep(&bp, ",");
|
||||
(void)fprintf(fp, "Office Phone: %s\n", p ? p : "");
|
||||
p = strsep(&bp, ",");
|
||||
(void)fprintf(fp, "Home Phone: %s\n", p ? p : "");
|
||||
|
||||
(void)fchown(fd, getuid(), getgid());
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
||||
int
|
||||
verify(char *tempname, struct passwd *pw)
|
||||
{
|
||||
ENTRY *ep;
|
||||
char *p;
|
||||
struct stat sb;
|
||||
FILE *fp = NULL;
|
||||
int len, fd;
|
||||
static char buf[LINE_MAX];
|
||||
|
||||
#ifdef __minix
|
||||
if ((fd = open(tempname, O_RDONLY)) == -1 ||
|
||||
(fp = fdopen(fd, "r")) == NULL)
|
||||
#else
|
||||
if ((fd = open(tempname, O_RDONLY|O_NOFOLLOW)) == -1 ||
|
||||
(fp = fdopen(fd, "r")) == NULL)
|
||||
#endif
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
if (fstat(fd, &sb))
|
||||
(*Pw_error)(tempname, 1, 1);
|
||||
if (sb.st_size == 0 || sb.st_nlink != 1) {
|
||||
warnx("corrupted temporary file");
|
||||
goto bad;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (!buf[0] || buf[0] == '#')
|
||||
continue;
|
||||
if (!(p = strchr(buf, '\n'))) {
|
||||
warnx("line too long");
|
||||
goto bad;
|
||||
}
|
||||
*p = '\0';
|
||||
for (ep = list;; ++ep) {
|
||||
if (!ep->prompt) {
|
||||
warnx("unrecognized field");
|
||||
goto bad;
|
||||
}
|
||||
if (!strncasecmp(buf, ep->prompt, ep->len)) {
|
||||
if (ep->restricted && uid) {
|
||||
warnx(
|
||||
"you may not change the %s field",
|
||||
ep->prompt);
|
||||
goto bad;
|
||||
}
|
||||
if (!(p = strchr(buf, ':'))) {
|
||||
warnx("line corrupted");
|
||||
goto bad;
|
||||
}
|
||||
while (isspace((unsigned char)*++p));
|
||||
if (ep->except && strpbrk(p, ep->except)) {
|
||||
warnx(
|
||||
"illegal character in the \"%s\" field",
|
||||
ep->prompt);
|
||||
goto bad;
|
||||
}
|
||||
if ((ep->func)(p, pw, ep)) {
|
||||
bad: (void)fclose(fp);
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
(void)fclose(fp);
|
||||
|
||||
/* Build the gecos field. */
|
||||
len = strlen(list[E_NAME].save) + strlen(list[E_BPHONE].save) +
|
||||
strlen(list[E_HPHONE].save) + strlen(list[E_LOCATE].save) + 4;
|
||||
if (!(p = malloc(len)))
|
||||
err(1, "malloc");
|
||||
(void)snprintf(p, len, "%s,%s,%s,%s", list[E_NAME].save,
|
||||
list[E_LOCATE].save, list[E_BPHONE].save, list[E_HPHONE].save);
|
||||
pw->pw_gecos = p;
|
||||
|
||||
if (snprintf(buf, sizeof(buf),
|
||||
"%s:%s:%d:%d:%s:%lu:%lu:%s:%s:%s",
|
||||
pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid, pw->pw_class,
|
||||
(u_long)pw->pw_change, (u_long)pw->pw_expire, pw->pw_gecos,
|
||||
pw->pw_dir, pw->pw_shell) >= (int)sizeof(buf)) {
|
||||
warnx("entries too long");
|
||||
return (0);
|
||||
}
|
||||
return (pw_scan(buf, pw, (int *)NULL));
|
||||
}
|
253
usr.bin/chpass/field.c
Normal file
253
usr.bin/chpass/field.c
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* $NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "chpass.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_login(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!*p) {
|
||||
warnx("empty login field");
|
||||
return (1);
|
||||
}
|
||||
if (*p == '-') {
|
||||
warnx("login names may not begin with a hyphen");
|
||||
return (1);
|
||||
}
|
||||
if (!(pw->pw_name = strdup(p))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
if (strchr(p, '.'))
|
||||
warnx("\'.\' is dangerous in a login name");
|
||||
for (; *p; ++p)
|
||||
if (isupper((unsigned char)*p)) {
|
||||
warnx("upper-case letters are dangerous in a login name");
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_passwd(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!(pw->pw_passwd = strdup(p))) {
|
||||
warnx("can't save password entry");
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_uid(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
unsigned long id;
|
||||
char *np;
|
||||
|
||||
if (!*p) {
|
||||
warnx("empty uid field");
|
||||
return (1);
|
||||
}
|
||||
if (!isdigit((unsigned char)*p)) {
|
||||
warnx("illegal uid");
|
||||
return (1);
|
||||
}
|
||||
errno = 0;
|
||||
id = strtoul(p, &np, 10);
|
||||
/*
|
||||
* We don't need to check the return value of strtoul()
|
||||
* since ULONG_MAX is greater than UID_MAX.
|
||||
*/
|
||||
if (*np || id > UID_MAX) {
|
||||
warnx("illegal uid");
|
||||
return (1);
|
||||
}
|
||||
pw->pw_uid = (uid_t)id;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_gid(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
struct group *gr;
|
||||
unsigned long id;
|
||||
char *np;
|
||||
|
||||
if (!*p) {
|
||||
warnx("empty gid field");
|
||||
return (1);
|
||||
}
|
||||
if (!isdigit((unsigned char)*p)) {
|
||||
if (!(gr = getgrnam(p))) {
|
||||
warnx("unknown group %s", p);
|
||||
return (1);
|
||||
}
|
||||
pw->pw_gid = gr->gr_gid;
|
||||
return (0);
|
||||
}
|
||||
errno = 0;
|
||||
id = strtoul(p, &np, 10);
|
||||
/*
|
||||
* We don't need to check the return value of strtoul()
|
||||
* since ULONG_MAX is greater than GID_MAX.
|
||||
*/
|
||||
if (*np || id > GID_MAX) {
|
||||
warnx("illegal gid");
|
||||
return (1);
|
||||
}
|
||||
pw->pw_gid = (gid_t)id;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_class(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!(pw->pw_class = strdup(p))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_change(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!atot(p, &pw->pw_change))
|
||||
return (0);
|
||||
warnx("illegal date for change field");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_expire(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!atot(p, &pw->pw_expire))
|
||||
return (0);
|
||||
warnx("illegal date for expire field");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_gecos(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!(ep->save = strdup(p))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_hdir(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
|
||||
if (!*p) {
|
||||
warnx("empty home directory field");
|
||||
return (1);
|
||||
}
|
||||
if (!(pw->pw_dir = strdup(p))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
p_shell(const char *p, struct passwd *pw, ENTRY *ep)
|
||||
{
|
||||
const char *t;
|
||||
|
||||
if (!*p) {
|
||||
if (!(pw->pw_shell = strdup(_PATH_BSHELL))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/* only admin can change from or to "restricted" shells */
|
||||
if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) {
|
||||
warnx("%s: current shell non-standard", pw->pw_shell);
|
||||
return (1);
|
||||
}
|
||||
if (!(t = ok_shell(p))) {
|
||||
if (uid) {
|
||||
warnx("%s: non-standard shell", p);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
else
|
||||
p = t;
|
||||
if (!(pw->pw_shell = strdup(p))) {
|
||||
warnx("can't save entry");
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
37
usr.bin/chpass/pathnames.h
Normal file
37
usr.bin/chpass/pathnames.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* $NetBSD: pathnames.h,v 1.4 2003/08/07 11:13:19 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
||||
#undef _PATH_TMP
|
||||
#define _PATH_TMP "/tmp/chpass.XXXXXX"
|
239
usr.bin/chpass/pw_yp.c
Normal file
239
usr.bin/chpass/pw_yp.c
Normal file
|
@ -0,0 +1,239 @@
|
|||
/* $NetBSD: pw_yp.c,v 1.22 2009/04/11 12:10:02 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)pw_yp.c 1.0 2/2/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: pw_yp.c,v 1.22 2009/04/11 12:10:02 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef YP
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#define passwd yp_passwd_rec
|
||||
#include <rpcsvc/yppasswd.h>
|
||||
#undef passwd
|
||||
|
||||
#include "chpass.h"
|
||||
|
||||
static char *domain;
|
||||
|
||||
/*
|
||||
* Check if rpc.yppasswdd is running on the master YP server.
|
||||
* XXX this duplicates some code, but is much less complex
|
||||
* than the alternative.
|
||||
*/
|
||||
int
|
||||
check_yppasswdd(void)
|
||||
{
|
||||
char *master;
|
||||
int rpcport;
|
||||
|
||||
/*
|
||||
* Get local domain
|
||||
*/
|
||||
if (!domain && yp_get_default_domain(&domain) != 0)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Find the host for the passwd map; it should be running
|
||||
* the daemon.
|
||||
*/
|
||||
master = NULL;
|
||||
if (yp_master(domain, "passwd.byname", &master) != 0) {
|
||||
if (master != NULL)
|
||||
free (master);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the portmapper for the port of the daemon.
|
||||
*/
|
||||
if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
|
||||
IPPROTO_UDP)) == 0)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Successful contact with rpc.yppasswdd.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pw_yp(struct passwd *pw, uid_t ypuid)
|
||||
{
|
||||
char *master;
|
||||
int r, rpcport, status;
|
||||
struct yppasswd yppw;
|
||||
struct timeval tv;
|
||||
CLIENT *client;
|
||||
|
||||
/*
|
||||
* Get local domain
|
||||
*/
|
||||
if (!domain && (r = yp_get_default_domain(&domain)))
|
||||
errx(1, "can't get local YP domain. Reason: %s",
|
||||
yperr_string(r));
|
||||
|
||||
/*
|
||||
* Find the host for the passwd map; it should be running
|
||||
* the daemon.
|
||||
*/
|
||||
master = NULL;
|
||||
if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
|
||||
if (master)
|
||||
free (master);
|
||||
warnx("can't find the master YP server. Reason: %s",
|
||||
yperr_string(r));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the portmapper for the port of the daemon.
|
||||
*/
|
||||
if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
|
||||
IPPROTO_UDP)) == 0) {
|
||||
warnx("master YP server not running yppasswd daemon.\n\t%s\n",
|
||||
"Can't change password.");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Be sure the port is privileged
|
||||
*/
|
||||
if (rpcport >= IPPORT_RESERVED) {
|
||||
warnx("yppasswd daemon is on an invalid port.");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* prompt for old password */
|
||||
memset(&yppw, 0, sizeof yppw);
|
||||
yppw.oldpass = getpass("Old password:");
|
||||
if (!yppw.oldpass) {
|
||||
warnx("Cancelled.");
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* tell rpc.yppasswdd */
|
||||
yppw.newpw.pw_name = strdup(pw->pw_name);
|
||||
if (!yppw.newpw.pw_name) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
yppw.newpw.pw_passwd = strdup(pw->pw_passwd);
|
||||
if (!yppw.newpw.pw_passwd) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
yppw.newpw.pw_uid = pw->pw_uid;
|
||||
yppw.newpw.pw_gid = pw->pw_gid;
|
||||
yppw.newpw.pw_gecos = strdup(pw->pw_gecos);
|
||||
if (!yppw.newpw.pw_gecos) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
yppw.newpw.pw_dir = strdup(pw->pw_dir);
|
||||
if (!yppw.newpw.pw_dir) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
yppw.newpw.pw_shell = strdup(pw->pw_shell);
|
||||
if (!yppw.newpw.pw_shell) {
|
||||
err(1, "strdup");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
|
||||
if (client == NULL) {
|
||||
warnx("cannot contact yppasswdd on %s: Reason: %s",
|
||||
master, yperr_string(YPERR_YPBIND));
|
||||
return (1);
|
||||
}
|
||||
client->cl_auth = authunix_create_default();
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
r = clnt_call(client, YPPASSWDPROC_UPDATE,
|
||||
xdr_yppasswd, &yppw, xdr_int, &status, tv);
|
||||
if (r) {
|
||||
warnx("rpc to yppasswdd failed.");
|
||||
return (1);
|
||||
} else if (status)
|
||||
printf("Couldn't change YP password.\n");
|
||||
else
|
||||
printf("%s %s, %s\n",
|
||||
"The YP password information has been changed on",
|
||||
master, "the master YP passwd server.");
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
yppw_error(const char *name, int yperr, int eval)
|
||||
{
|
||||
|
||||
if (yperr) {
|
||||
if (name)
|
||||
warn("%s", name);
|
||||
else
|
||||
warn(NULL);
|
||||
}
|
||||
|
||||
errx(eval, "YP passwd information unchanged");
|
||||
}
|
||||
|
||||
void
|
||||
yppw_prompt(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
(void)printf("re-edit the password file? [y]: ");
|
||||
(void)fflush(stdout);
|
||||
c = getchar();
|
||||
if (c != EOF && c != '\n')
|
||||
while (getchar() != '\n');
|
||||
if (c == 'n')
|
||||
yppw_error(NULL, 0, 0);
|
||||
}
|
||||
#endif /* YP */
|
63
usr.bin/chpass/table.c
Normal file
63
usr.bin/chpass/table.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* $NetBSD: table.c,v 1.7 2009/04/11 12:10:02 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)table.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: table.c,v 1.7 2009/04/11 12:10:02 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include "chpass.h"
|
||||
|
||||
char e1[] = ": ";
|
||||
char e2[] = ":,";
|
||||
|
||||
ENTRY list[] = {
|
||||
{ "login", p_login, 1, 5, e1, NULL },
|
||||
{ "password", p_passwd, 1, 8, e1, NULL },
|
||||
{ "uid", p_uid, 1, 3, e1, NULL },
|
||||
{ "gid", p_gid, 1, 3, e1, NULL },
|
||||
{ "class", p_class, 1, 5, e1, NULL },
|
||||
{ "change", p_change, 1, 6, NULL, NULL },
|
||||
{ "expire", p_expire, 1, 6, NULL, NULL },
|
||||
{ "full name", p_gecos, 0, 9, e2, ""},
|
||||
{ "office phone", p_gecos, 0, 12, e2, ""},
|
||||
{ "home phone", p_gecos, 0, 10, e2, ""},
|
||||
{ "location", p_gecos, 0, 8, e2, ""},
|
||||
{ "home directory", p_hdir, 1, 14, e1, NULL },
|
||||
{ "shell", p_shell, 0, 5, e1, NULL },
|
||||
{ NULL, NULL, 0, 0, NULL, NULL },
|
||||
};
|
113
usr.bin/chpass/util.c
Normal file
113
usr.bin/chpass/util.c
Normal file
|
@ -0,0 +1,113 @@
|
|||
/* $NetBSD: util.c,v 1.12 2005/02/17 17:09:48 xtraeme Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)util.c 8.4 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: util.c,v 1.12 2005/02/17 17:09:48 xtraeme Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <tzfile.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "chpass.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
char *
|
||||
ttoa(char *buf, size_t len, time_t tval)
|
||||
{
|
||||
|
||||
if (tval) {
|
||||
struct tm *tp = localtime(&tval);
|
||||
|
||||
(void) strftime(buf, len, "%B %d, %Y", tp);
|
||||
buf[len - 1] = '\0';
|
||||
}
|
||||
else if (len > 0)
|
||||
*buf = '\0';
|
||||
return (buf);
|
||||
}
|
||||
|
||||
int
|
||||
atot(const char *p, time_t *store)
|
||||
{
|
||||
static struct tm *lt;
|
||||
struct tm tm;
|
||||
char *t;
|
||||
time_t tval;
|
||||
|
||||
if (!*p) {
|
||||
*store = 0;
|
||||
return (0);
|
||||
}
|
||||
if (!lt) {
|
||||
unsetenv("TZ");
|
||||
(void)time(&tval);
|
||||
lt = localtime(&tval);
|
||||
}
|
||||
(void) memset(&tm, 0, sizeof(tm));
|
||||
while ((t = strchr(p, ',')) != NULL)
|
||||
*t = ' ';
|
||||
t = strptime(p, "%B %d %Y", &tm);
|
||||
if (t == NULL || (*t != '\0' && *t != '\n'))
|
||||
return 1;
|
||||
if ((*store = mktime(&tm)) == (time_t) -1)
|
||||
return 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char *
|
||||
ok_shell(const char *name)
|
||||
{
|
||||
char *p;
|
||||
const char *sh;
|
||||
|
||||
setusershell();
|
||||
while ((sh = getusershell()) != NULL) {
|
||||
if (!strcmp(name, sh))
|
||||
return (name);
|
||||
/* allow just shell name, but use "real" path */
|
||||
if ((p = strrchr(sh, '/')) && strcmp(name, p + 1) == 0)
|
||||
return (sh);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
|
@ -16,8 +16,8 @@ SRCS+= ohash_create_entry.c ohash_delete.c ohash_do.c ohash_entries.c \
|
|||
ohash_qlookupi.c strtonum.c
|
||||
YHEADER=1
|
||||
.if (${HOSTPROG:U} == "")
|
||||
DPADD+= ${LIBMINIXUTIL} ${LIBL}
|
||||
LDADD+= -lminixutil -ll
|
||||
DPADD+= ${LIBUTIL} ${LIBL}
|
||||
LDADD+= -lutil -ll
|
||||
.endif
|
||||
|
||||
tokenizer.o: parser.h
|
||||
|
|
26
usr.bin/newgrp/Makefile
Normal file
26
usr.bin/newgrp/Makefile
Normal file
|
@ -0,0 +1,26 @@
|
|||
# $NetBSD: Makefile,v 1.4 2009/04/14 22:15:24 lukem Exp $
|
||||
#
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if defined(__MINIX)
|
||||
USE_KERBEROS= no
|
||||
.endif
|
||||
|
||||
PROG= newgrp
|
||||
SRCS= newgrp.c grutil.c
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
CPPFLAGS+=-DGRUTIL_ACCEPT_GROUP_NUMBERS
|
||||
CPPFLAGS+=-DGRUTIL_ALLOW_GROUP_ERRORS # for POSIX.1 compliance
|
||||
CPPFLAGS+= #-DLOGIN_CAP
|
||||
|
||||
DPADD+= ${LIBCRYPT} ${LIBUTIL}
|
||||
LDADD+= -lcrypt -lutil
|
||||
|
||||
.if (${USE_KERBEROS} != "no")
|
||||
CPPFLAGS+=-DKERBEROS
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
337
usr.bin/newgrp/grutil.c
Normal file
337
usr.bin/newgrp/grutil.c
Normal file
|
@ -0,0 +1,337 @@
|
|||
/* $NetBSD: grutil.c,v 1.2 2008/04/28 20:24:14 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Brian Ginsbach.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: grutil.c,v 1.2 2008/04/28 20:24:14 martin Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#endif
|
||||
|
||||
#include "grutil.h"
|
||||
|
||||
typedef enum {
|
||||
ADDGRP_NOERROR = 0, /* must be zero */
|
||||
ADDGRP_EMALLOC = 1,
|
||||
ADDGRP_EGETGROUPS = 2,
|
||||
ADDGRP_ESETGROUPS = 3
|
||||
} addgrp_ret_t;
|
||||
|
||||
static void
|
||||
free_groups(void *groups)
|
||||
{
|
||||
int oerrno;
|
||||
|
||||
oerrno = errno;
|
||||
free(groups);
|
||||
errno = oerrno;
|
||||
}
|
||||
|
||||
static addgrp_ret_t
|
||||
alloc_groups(int *ngroups, gid_t **groups, int *ngroupsmax)
|
||||
{
|
||||
*ngroupsmax = (int)sysconf(_SC_NGROUPS_MAX);
|
||||
if (*ngroupsmax < 0)
|
||||
*ngroupsmax = NGROUPS_MAX;
|
||||
|
||||
*groups = malloc(*ngroupsmax * sizeof(**groups));
|
||||
if (*groups == NULL)
|
||||
return ADDGRP_EMALLOC;
|
||||
|
||||
*ngroups = getgroups(*ngroupsmax, *groups);
|
||||
if (*ngroups == -1) {
|
||||
free_groups(*groups);
|
||||
return ADDGRP_ESETGROUPS;
|
||||
}
|
||||
return ADDGRP_NOERROR;
|
||||
}
|
||||
|
||||
static addgrp_ret_t
|
||||
addgid(gid_t *groups, int ngroups, int ngroupsmax, gid_t gid, int makespace)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* search for gid in supplemental group list */
|
||||
for (i = 0; i < ngroups && groups[i] != gid; i++)
|
||||
continue;
|
||||
|
||||
/* add the gid to the supplemental group list */
|
||||
if (i == ngroups) {
|
||||
if (ngroups < ngroupsmax)
|
||||
groups[ngroups++] = gid;
|
||||
else { /*
|
||||
* setgroups(2) will fail with errno = EINVAL
|
||||
* if ngroups > nmaxgroups. If makespace is
|
||||
* set, replace the last group with the new
|
||||
* one. Otherwise, fail the way setgroups(2)
|
||||
* would if we passed the larger groups array.
|
||||
*/
|
||||
if (makespace) {
|
||||
/*
|
||||
* Find a slot that doesn't contain
|
||||
* the primary group.
|
||||
*/
|
||||
struct passwd *pwd;
|
||||
gid_t pgid;
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd == NULL)
|
||||
goto error;
|
||||
pgid = pwd->pw_gid;
|
||||
for (i = ngroupsmax - 1; i >= 0; i--)
|
||||
if (groups[i] != pgid)
|
||||
break;
|
||||
if (i < 0)
|
||||
goto error;
|
||||
groups[i] = gid;
|
||||
}
|
||||
else {
|
||||
error:
|
||||
errno = EINVAL;
|
||||
return ADDGRP_ESETGROUPS;
|
||||
}
|
||||
}
|
||||
if (setgroups(ngroups, groups) < 0)
|
||||
return ADDGRP_ESETGROUPS;
|
||||
}
|
||||
return ADDGRP_NOERROR;
|
||||
}
|
||||
|
||||
static addgrp_ret_t
|
||||
addgrp(gid_t newgid, int makespace)
|
||||
{
|
||||
int ngroups, ngroupsmax, rval;
|
||||
gid_t *groups;
|
||||
gid_t oldgid;
|
||||
|
||||
oldgid = getgid();
|
||||
if (oldgid == newgid) /* nothing to do */
|
||||
return ADDGRP_NOERROR;
|
||||
|
||||
rval = alloc_groups(&ngroups, &groups, &ngroupsmax);
|
||||
if (rval != 0)
|
||||
return rval;
|
||||
|
||||
/*
|
||||
* BSD based systems normally have the egid in the supplemental
|
||||
* group list.
|
||||
*/
|
||||
#if (defined(BSD) && BSD >= 199306)
|
||||
/*
|
||||
* According to POSIX/XPG6:
|
||||
* On system where the egid is normally in the supplemental group list
|
||||
* (or whenever the old egid actually is in the supplemental group
|
||||
* list):
|
||||
* o If the new egid is in the supplemental group list,
|
||||
* just change the egid.
|
||||
* o If the new egid is not in the supplemental group list,
|
||||
* add the new egid to the list if there is room.
|
||||
*/
|
||||
|
||||
rval = addgid(groups, ngroups, ngroupsmax, newgid, makespace);
|
||||
#else
|
||||
/*
|
||||
* According to POSIX/XPG6:
|
||||
* On systems where the egid is not normally in the supplemental group
|
||||
* list (or whenever the old egid is not in the supplemental group
|
||||
* list):
|
||||
* o If the new egid is in the supplemental group list, delete
|
||||
* it from the list.
|
||||
* o If the old egid is not in the supplemental group list,
|
||||
* add the old egid to the list if there is room.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
|
||||
/* search for new egid in supplemental group list */
|
||||
for (i = 0; i < ngroups && groups[i] != newgid; i++)
|
||||
continue;
|
||||
|
||||
/* remove new egid from supplemental group list */
|
||||
if (i != ngroups)
|
||||
for (--ngroups; i < ngroups; i++)
|
||||
groups[i] = groups[i + 1];
|
||||
|
||||
rval = addgid(groups, ngroups, ngroupsmax, oldgid, makespace);
|
||||
}
|
||||
#endif
|
||||
free_groups(groups);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* If newgrp fails, it returns (gid_t)-1 and the errno variable is
|
||||
* set to:
|
||||
* [EINVAL] Unknown group.
|
||||
* [EPERM] Bad password.
|
||||
*/
|
||||
static gid_t
|
||||
newgrp(const char *gname, struct passwd *pwd, uid_t ruid, const char *prompt)
|
||||
{
|
||||
struct group *grp;
|
||||
char **ap;
|
||||
char *p;
|
||||
gid_t *groups;
|
||||
int ngroups, ngroupsmax;
|
||||
|
||||
if (gname == NULL)
|
||||
return pwd->pw_gid;
|
||||
|
||||
grp = getgrnam(gname);
|
||||
|
||||
#ifdef GRUTIL_ACCEPT_GROUP_NUMBERS
|
||||
if (grp == NULL) {
|
||||
gid_t gid;
|
||||
if (*gname != '-') {
|
||||
gid = (gid_t)strtol(gname, &p, 10);
|
||||
if (*p == '\0')
|
||||
grp = getgrgid(gid);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (grp == NULL) {
|
||||
errno = EINVAL;
|
||||
return (gid_t)-1;
|
||||
}
|
||||
|
||||
if (ruid == 0 || pwd->pw_gid == grp->gr_gid)
|
||||
return grp->gr_gid;
|
||||
|
||||
if (alloc_groups(&ngroups, &groups, &ngroupsmax) == 0) {
|
||||
int i;
|
||||
for (i = 0; i < ngroups; i++)
|
||||
if (groups[i] == grp->gr_gid) {
|
||||
free_groups(groups);
|
||||
return grp->gr_gid;
|
||||
}
|
||||
free_groups(groups);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the group membership list in case the groups[] array
|
||||
* was maxed out or the user has been added to it since login.
|
||||
*/
|
||||
for (ap = grp->gr_mem; *ap != NULL; ap++)
|
||||
if (strcmp(*ap, pwd->pw_name) == 0)
|
||||
return grp->gr_gid;
|
||||
|
||||
if (*grp->gr_passwd != '\0') {
|
||||
p = getpass(prompt);
|
||||
if (strcmp(grp->gr_passwd, crypt(p, grp->gr_passwd)) == 0) {
|
||||
(void)memset(p, '\0', _PASSWORD_LEN);
|
||||
return grp->gr_gid;
|
||||
}
|
||||
(void)memset(p, '\0', _PASSWORD_LEN);
|
||||
}
|
||||
|
||||
errno = EPERM;
|
||||
return (gid_t)-1;
|
||||
}
|
||||
|
||||
#ifdef GRUTIL_SETGROUPS_MAKESPACE
|
||||
# define ADDGRP_MAKESPACE 1
|
||||
#else
|
||||
# define ADDGRP_MAKESPACE 0
|
||||
#endif
|
||||
|
||||
#ifdef GRUTIL_ALLOW_GROUP_ERRORS
|
||||
# define maybe_exit(e)
|
||||
#else
|
||||
# define maybe_exit(e) exit(e);
|
||||
#endif
|
||||
|
||||
void
|
||||
addgroup(
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc,
|
||||
#endif
|
||||
const char *gname, struct passwd *pwd, uid_t ruid, const char *prompt)
|
||||
{
|
||||
pwd->pw_gid = newgrp(gname, pwd, ruid, prompt);
|
||||
if (pwd->pw_gid == (gid_t)-1) {
|
||||
switch (errno) {
|
||||
case EINVAL:
|
||||
warnx("Unknown group `%s'", gname);
|
||||
maybe_exit(EXIT_FAILURE);
|
||||
break;
|
||||
case EPERM: /* password failure */
|
||||
warnx("Sorry");
|
||||
maybe_exit(EXIT_FAILURE);
|
||||
break;
|
||||
default: /* XXX - should never happen */
|
||||
err(EXIT_FAILURE, "unknown error");
|
||||
break;
|
||||
}
|
||||
pwd->pw_gid = getgid();
|
||||
}
|
||||
|
||||
switch (addgrp(pwd->pw_gid, ADDGRP_MAKESPACE)) {
|
||||
case ADDGRP_NOERROR:
|
||||
break;
|
||||
case ADDGRP_EMALLOC:
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
break;
|
||||
case ADDGRP_EGETGROUPS:
|
||||
err(EXIT_FAILURE, "getgroups");
|
||||
break;
|
||||
case ADDGRP_ESETGROUPS:
|
||||
switch(errno) {
|
||||
case EINVAL:
|
||||
warnx("setgroups: ngroups > ngroupsmax");
|
||||
maybe_exit(EXIT_FAILURE);
|
||||
break;
|
||||
case EPERM:
|
||||
case EFAULT:
|
||||
default:
|
||||
warn("setgroups");
|
||||
maybe_exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGID) == -1)
|
||||
err(EXIT_FAILURE, "setting user context");
|
||||
#else
|
||||
if (setgid(pwd->pw_gid) == -1)
|
||||
err(EXIT_FAILURE, "setgid");
|
||||
#endif
|
||||
}
|
40
usr.bin/newgrp/grutil.h
Normal file
40
usr.bin/newgrp/grutil.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/* $NetBSD: grutil.h,v 1.2 2008/04/28 20:24:14 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Brian Ginsbach.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _GRUTIL_H_
|
||||
#define _GRUTIL_H_
|
||||
|
||||
void addgroup(
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *,
|
||||
#endif
|
||||
const char *, struct passwd *, uid_t, const char *);
|
||||
|
||||
#endif /* _GRUTIL_H_ */
|
121
usr.bin/newgrp/newgrp.1
Normal file
121
usr.bin/newgrp/newgrp.1
Normal file
|
@ -0,0 +1,121 @@
|
|||
.\" $NetBSD: newgrp.1,v 1.4 2010/05/14 17:28:23 joerg Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2007, The NetBSD Foundation.
|
||||
.\" All Rights Reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Brian Ginsbach.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd June 6, 2007
|
||||
.Dt NEWGRP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm newgrp
|
||||
.Nd change to a new primary group
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl l
|
||||
.Op Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
command changes a user to a new primary group
|
||||
.Pq real and effective group ID
|
||||
by starting a new shell.
|
||||
The user remains logged in and the current directory
|
||||
and file creation mask remain unchanged.
|
||||
The user is always given a new shell even if
|
||||
the primary group change fails.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
command accepts the following options:
|
||||
.Bl -tag -width indent
|
||||
.It Fl l
|
||||
The environment is changed to what would be expected if the user
|
||||
actually logged in again.
|
||||
This simulates a full login.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar group
|
||||
is a group name or non-negative numeric group ID from the group database.
|
||||
The real and effective group IDs are set to
|
||||
.Ar group
|
||||
or the group ID associated with the group name.
|
||||
.Pp
|
||||
If
|
||||
.Ar group
|
||||
is not specified,
|
||||
.Nm
|
||||
restores the user's real and effective group IDs to the user's
|
||||
primary group specified in the password database.
|
||||
The user's supplementary group IDs are restored to the set specified
|
||||
for the user in the group database.
|
||||
.Pp
|
||||
If the user is not a member of the specified group, and the group
|
||||
requires a password, the user will be prompted for the group password.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/master.passwd -compact
|
||||
.It Pa /etc/group
|
||||
The group database
|
||||
.It Pa /etc/master.passwd
|
||||
The user database
|
||||
.It Pa /etc/passwd
|
||||
A Version 7 format password file
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
If a new shell is started the exit status is the exit status of the shell.
|
||||
Otherwise the exit status will be \*[Gt]0.
|
||||
.Sh SEE ALSO
|
||||
.Xr csh 1 ,
|
||||
.Xr groups 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr su 1 ,
|
||||
.Xr umask 2 ,
|
||||
.Xr group 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr environ 7
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
command conforms to
|
||||
.St -p1003.1-2001 .
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v6 .
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.Nx 5.0 .
|
||||
.Sh BUGS
|
||||
There is no convenient way to enter a password into
|
||||
.Pa /etc/group .
|
||||
The use of group passwords is strongly discouraged
|
||||
since they are inherently insecure.
|
||||
It is not possible to stop users from obtaining the encrypted
|
||||
password from the group database.
|
195
usr.bin/newgrp/newgrp.c
Normal file
195
usr.bin/newgrp/newgrp.c
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*-
|
||||
* Copyright (c) 2007 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Brian Ginsbach.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: newgrp.c,v 1.6 2008/04/28 20:24:14 martin Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <grp.h>
|
||||
#include <libgen.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
#endif
|
||||
|
||||
#include "grutil.h"
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "usage: %s [-l] [group]\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
extern char **environ;
|
||||
struct passwd *pwd;
|
||||
int c, lflag;
|
||||
char *shell, sbuf[MAXPATHLEN + 2];
|
||||
uid_t uid;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
u_int flags = LOGIN_SETUSER;
|
||||
#endif
|
||||
|
||||
uid = getuid();
|
||||
pwd = getpwuid(uid);
|
||||
if (pwd == NULL)
|
||||
errx(EXIT_FAILURE, "who are you?");
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if ((lc = login_getclass(pwd->pw_class)) == NULL)
|
||||
errx(EXIT_FAILURE, "%s: unknown login class", pwd->pw_class);
|
||||
#endif
|
||||
|
||||
(void)setprogname(argv[0]);
|
||||
lflag = 0;
|
||||
while ((c = getopt(argc, argv, "-l")) != -1) {
|
||||
switch (c) {
|
||||
case '-':
|
||||
case 'l':
|
||||
if (lflag)
|
||||
usage();
|
||||
lflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 0) {
|
||||
#if 0
|
||||
pwd->pw_gid = newgrp(*argv, pwd);
|
||||
addgrp(pwd->pw_gid);
|
||||
if (setgid(pwd->pw_gid) < 0)
|
||||
err(1, "setgid");
|
||||
#endif
|
||||
#ifdef LOGIN_CAP
|
||||
addgroup(lc, *argv, pwd, getuid(), "Password:");
|
||||
#else
|
||||
addgroup(*argv, pwd, getuid(), "Password:");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef LOGIN_CAP
|
||||
flags |= LOGIN_SETGROUP;
|
||||
#else
|
||||
if (initgroups(pwd->pw_name, pwd->pw_gid) == -1)
|
||||
err(EXIT_FAILURE, "initgroups");
|
||||
if (setgid(pwd->pw_gid) == -1)
|
||||
err(EXIT_FAILURE, "setgid");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOGIN_CAP
|
||||
if (setusercontext(lc, pwd, uid, flags) == -1)
|
||||
err(EXIT_FAILURE, "setusercontext");
|
||||
if (!lflag)
|
||||
login_close(lc);
|
||||
#else
|
||||
if (setuid(pwd->pw_uid) == -1)
|
||||
err(EXIT_FAILURE, "setuid");
|
||||
#endif
|
||||
|
||||
if (*pwd->pw_shell == '\0') {
|
||||
#ifdef TRUST_ENV_SHELL
|
||||
shell = getenv("SHELL");
|
||||
if (shell != NULL)
|
||||
pwd->pw_shell = shell;
|
||||
else
|
||||
#endif
|
||||
pwd->pw_shell = __UNCONST(_PATH_BSHELL);
|
||||
}
|
||||
|
||||
shell = pwd->pw_shell;
|
||||
|
||||
if (lflag) {
|
||||
char *term;
|
||||
#ifdef KERBEROS
|
||||
char *krbtkfile;
|
||||
#endif
|
||||
|
||||
if (chdir(pwd->pw_dir) == -1)
|
||||
warn("%s", pwd->pw_dir);
|
||||
|
||||
term = getenv("TERM");
|
||||
#ifdef KERBEROS
|
||||
krbtkfile = getenv("KRBTKFILE");
|
||||
#endif
|
||||
|
||||
/* create an empty environment */
|
||||
if ((environ = malloc(sizeof(char *))) == NULL)
|
||||
err(EXIT_FAILURE, NULL);
|
||||
environ[0] = NULL;
|
||||
#ifdef LOGIN_CAP
|
||||
if (setusercontext(lc, pwd, uid, LOGIN_SETENV | LOGIN_SETPATH) == -1)
|
||||
err(EXIT_FAILURE, "setusercontext");
|
||||
login_close(lc);
|
||||
#else
|
||||
(void)setenv("PATH", _PATH_DEFPATH, 1);
|
||||
#endif
|
||||
if (term != NULL)
|
||||
(void)setenv("TERM", term, 1);
|
||||
#ifdef KERBEROS
|
||||
if (krbtkfile != NULL)
|
||||
(void)setenv("KRBTKFILE", krbtkfile, 1);
|
||||
#endif
|
||||
|
||||
(void)setenv("LOGNAME", pwd->pw_name, 1);
|
||||
(void)setenv("USER", pwd->pw_name, 1);
|
||||
(void)setenv("HOME", pwd->pw_dir, 1);
|
||||
(void)setenv("SHELL", pwd->pw_shell, 1);
|
||||
|
||||
sbuf[0] = '-';
|
||||
(void)strlcpy(sbuf + 1, basename(pwd->pw_shell),
|
||||
sizeof(sbuf) - 1);
|
||||
shell = sbuf;
|
||||
}
|
||||
|
||||
(void)execl(pwd->pw_shell, shell, NULL);
|
||||
err(EXIT_FAILURE, "%s", pwd->pw_shell);
|
||||
/* NOTREACHED */
|
||||
}
|
51
usr.bin/passwd/Makefile
Normal file
51
usr.bin/passwd/Makefile
Normal file
|
@ -0,0 +1,51 @@
|
|||
# $NetBSD: Makefile,v 1.41 2007/05/28 12:06:29 tls Exp $
|
||||
# from: @(#)Makefile 8.3 (Berkeley) 4/2/94
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
.if defined(__MINIX)
|
||||
USE_YP= no
|
||||
USE_KERBEROS= no
|
||||
USE_PAM= no
|
||||
.endif
|
||||
|
||||
USE_FORT?= yes # setuid
|
||||
PROG= passwd
|
||||
SRCS= local_passwd.c passwd.c
|
||||
MAN= passwd.1
|
||||
|
||||
CPPFLAGS+=-I${.CURDIR} #-DLOGIN_CAP
|
||||
|
||||
.if (${USE_YP} != "no")
|
||||
SRCS+= yp_passwd.c
|
||||
CPPFLAGS+=-DYP
|
||||
DPADD+= ${LIBRPCSVC}
|
||||
LDADD+= -lrpcsvc
|
||||
LINKS+= ${BINDIR}/passwd ${BINDIR}/yppasswd
|
||||
MAN+= yppasswd.1
|
||||
.endif
|
||||
|
||||
DPADD+= ${LIBCRYPT} ${LIBUTIL}
|
||||
LDADD+= -lcrypt -lutil
|
||||
|
||||
BINOWN= root
|
||||
BINMODE=4555
|
||||
|
||||
.if (${USE_KERBEROS} != "no")
|
||||
CPPFLAGS+= -DKERBEROS5 -I${DESTDIR}/usr/include/krb5
|
||||
SRCS+= krb5_passwd.c
|
||||
|
||||
DPADD+= ${LIBKRB5} ${LIBCRYPTO} ${LIBASN1} ${LIBCOM_ERR} ${LIBROKEN} ${LIBCRYPT}
|
||||
LDADD+= -lkrb5 -lcrypto -lasn1 -lcom_err -lroken -lcrypt
|
||||
LINKS+= ${BINDIR}/passwd ${BINDIR}/kpasswd
|
||||
MAN+= kpasswd.1
|
||||
.endif
|
||||
|
||||
.if (${USE_PAM} != "no")
|
||||
CPPFLAGS+=-DUSE_PAM
|
||||
SRCS+= pam_passwd.c
|
||||
LDADD+=-lpam ${PAM_STATIC_LDADD}
|
||||
DPADD+=${LIBPAM} ${PAM_STATIC_DPADD}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
85
usr.bin/passwd/extern.h
Normal file
85
usr.bin/passwd/extern.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* $NetBSD: extern.h,v 1.13 2006/03/23 23:37:07 wiz Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)extern.h 8.1 (Berkeley) 4/2/94
|
||||
*/
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
void usage(void);
|
||||
|
||||
#ifdef KERBEROS5
|
||||
void pwkrb5_usage(const char *);
|
||||
void pwkrb5_argv0_usage(const char *);
|
||||
void pwkrb5_process(const char *, int, char **);
|
||||
#endif
|
||||
|
||||
#ifdef YP
|
||||
void pwyp_usage(const char *);
|
||||
void pwyp_argv0_usage(const char *);
|
||||
void pwyp_process(const char *, int, char **);
|
||||
#endif
|
||||
|
||||
void pwlocal_usage(const char *);
|
||||
void pwlocal_process(const char *, int, char **);
|
||||
|
||||
void pwpam_process(const char *, int, char **);
|
||||
|
||||
#else /* ! USE_PAM */
|
||||
|
||||
/* return values from pw_init() and pw_arg_end() */
|
||||
enum {
|
||||
PW_USE_FORCE,
|
||||
PW_USE,
|
||||
PW_DONT_USE
|
||||
};
|
||||
|
||||
#ifdef KERBEROS5
|
||||
int krb5_init __P((const char *));
|
||||
int krb5_arg __P((char, const char *));
|
||||
int krb5_arg_end __P((void));
|
||||
void krb5_end __P((void));
|
||||
int krb5_chpw __P((const char *));
|
||||
#endif
|
||||
#ifdef YP
|
||||
int yp_init __P((const char *));
|
||||
int yp_arg __P((char, const char *));
|
||||
int yp_arg_end __P((void));
|
||||
void yp_end __P((void));
|
||||
int yp_chpw __P((const char *));
|
||||
#endif
|
||||
/* local */
|
||||
int local_init __P((const char *));
|
||||
int local_arg __P((char, const char *));
|
||||
int local_arg_end __P((void));
|
||||
void local_end __P((void));
|
||||
int local_chpw __P((const char *));
|
||||
|
||||
#endif /* USE_PAM */
|
48
usr.bin/passwd/kpasswd.1
Normal file
48
usr.bin/passwd/kpasswd.1
Normal file
|
@ -0,0 +1,48 @@
|
|||
.\" $NetBSD: kpasswd.1,v 1.3 2008/04/30 13:11:01 martin Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Jason R. Thorpe.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 25, 2005
|
||||
.Dt KPASSWD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm kpasswd
|
||||
.Nd modify a user's Kerberos 5 password
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar principal
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
changes the user's Kerberos 5 password.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
command is deprecated.
|
||||
See
|
||||
.Xr passwd 1
|
||||
for more information.
|
351
usr.bin/passwd/krb5_passwd.c
Normal file
351
usr.bin/passwd/krb5_passwd.c
Normal file
|
@ -0,0 +1,351 @@
|
|||
/* $NetBSD: krb5_passwd.c,v 1.18 2009/04/18 09:04:34 mlelstv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000, 2005 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Johan Danielsson; and by Jason R. Thorpe.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* uses the `Kerberos Change Password Protocol' */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/ui.h>
|
||||
#include <krb5.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
void
|
||||
pwkrb5_usage(const char *prefix)
|
||||
{
|
||||
|
||||
(void) fprintf(stderr, "%s %s [-d krb5 | -k] [principal]\n",
|
||||
prefix, getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
pwkrb5_argv0_usage(const char *prefix)
|
||||
{
|
||||
|
||||
(void) fprintf(stderr, "%s %s [principal]\n",
|
||||
prefix, getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
pwkrb5_process(const char *username, int argc, char **argv)
|
||||
{
|
||||
krb5_context context;
|
||||
krb5_error_code ret;
|
||||
krb5_get_init_creds_opt opt;
|
||||
krb5_principal principal;
|
||||
krb5_creds cred;
|
||||
int result_code;
|
||||
krb5_data result_code_string, result_string;
|
||||
char pwbuf[BUFSIZ];
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "5ku:")) != -1) {
|
||||
switch (ch) {
|
||||
case '5':
|
||||
/*
|
||||
* Compatibility option that historically
|
||||
* specified to use Kerberos 5. Silently
|
||||
* ignore it.
|
||||
*/
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
/*
|
||||
* Absorb the -k that may have gotten us here.
|
||||
*/
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
/*
|
||||
* Historical option to specify principal.
|
||||
*/
|
||||
username = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* username already provided */
|
||||
break;
|
||||
case 1:
|
||||
/* overrides -u <principal> */
|
||||
username = argv[0];
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
ret = krb5_init_context(&context);
|
||||
if (ret != 0) {
|
||||
if (ret == ENXIO)
|
||||
errx(1, "Kerberos 5 not in use.");
|
||||
warnx("Unable to initialize Kerberos 5: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_init(&opt);
|
||||
|
||||
krb5_get_init_creds_opt_set_tkt_life(&opt, 300L);
|
||||
krb5_get_init_creds_opt_set_forwardable(&opt, FALSE);
|
||||
krb5_get_init_creds_opt_set_proxiable(&opt, FALSE);
|
||||
|
||||
ret = krb5_parse_name(context, username, &principal);
|
||||
if (ret) {
|
||||
warnx("failed to parse principal: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
ret = krb5_get_init_creds_password(context,
|
||||
&cred,
|
||||
principal,
|
||||
NULL,
|
||||
krb5_prompter_posix,
|
||||
NULL,
|
||||
0L,
|
||||
"kadmin/changepw",
|
||||
&opt);
|
||||
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case KRB5_LIBOS_PWDINTR :
|
||||
/* XXX */
|
||||
goto bad;
|
||||
|
||||
case KRB5KRB_AP_ERR_BAD_INTEGRITY :
|
||||
case KRB5KRB_AP_ERR_MODIFIED :
|
||||
fprintf(stderr, "Password incorrect\n");
|
||||
goto bad;
|
||||
|
||||
default:
|
||||
warnx("failed to get credentials: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
krb5_data_zero(&result_code_string);
|
||||
krb5_data_zero(&result_string);
|
||||
|
||||
/* XXX use getpass? It has a broken interface. */
|
||||
if (UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf),
|
||||
"New password: ", 1) != 0)
|
||||
goto bad;
|
||||
|
||||
ret = krb5_set_password(context, &cred, pwbuf, NULL,
|
||||
&result_code,
|
||||
&result_code_string,
|
||||
&result_string);
|
||||
if (ret) {
|
||||
warnx("unable to set password: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
printf("%s%s%.*s\n",
|
||||
krb5_passwd_result_to_string(context, result_code),
|
||||
result_string.length > 0 ? " : " : "",
|
||||
(int)result_string.length,
|
||||
result_string.length > 0 ? (char *)result_string.data : "");
|
||||
|
||||
krb5_data_free(&result_code_string);
|
||||
krb5_data_free(&result_string);
|
||||
|
||||
krb5_free_cred_contents(context, &cred);
|
||||
krb5_free_context(context);
|
||||
if (result_code)
|
||||
exit(1);
|
||||
return;
|
||||
|
||||
bad:
|
||||
krb5_free_context(context);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#else /* ! USE_PAM */
|
||||
|
||||
static krb5_context defcontext;
|
||||
static krb5_principal defprinc;
|
||||
static int kusage = PW_USE;
|
||||
|
||||
int
|
||||
krb5_init(const char *progname)
|
||||
{
|
||||
return krb5_init_context(&defcontext);
|
||||
}
|
||||
|
||||
int
|
||||
krb5_arg (char ch, const char *opt)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
switch(ch) {
|
||||
case '5':
|
||||
case 'k':
|
||||
kusage = PW_USE_FORCE;
|
||||
return 1;
|
||||
case 'u':
|
||||
ret = krb5_parse_name(defcontext, opt, &defprinc);
|
||||
if(ret) {
|
||||
krb5_warn(defcontext, ret, "%s", opt);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
krb5_arg_end(void)
|
||||
{
|
||||
return kusage;
|
||||
}
|
||||
|
||||
void
|
||||
krb5_end(void)
|
||||
{
|
||||
if (defcontext == NULL)
|
||||
return;
|
||||
if(defprinc)
|
||||
krb5_free_principal(defcontext, defprinc);
|
||||
krb5_free_context(defcontext);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
krb5_chpw(const char *username)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_context context;
|
||||
krb5_principal principal;
|
||||
krb5_get_init_creds_opt opt;
|
||||
krb5_creds cred;
|
||||
int result_code;
|
||||
krb5_data result_code_string, result_string;
|
||||
char pwbuf[BUFSIZ];
|
||||
|
||||
ret = krb5_init_context (&context);
|
||||
if (ret) {
|
||||
warnx("failed kerberos initialisation: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
krb5_get_init_creds_opt_init (&opt);
|
||||
|
||||
krb5_get_init_creds_opt_set_tkt_life (&opt, 300);
|
||||
krb5_get_init_creds_opt_set_forwardable (&opt, FALSE);
|
||||
krb5_get_init_creds_opt_set_proxiable (&opt, FALSE);
|
||||
|
||||
if(username != NULL) {
|
||||
ret = krb5_parse_name (context, username, &principal);
|
||||
if (ret) {
|
||||
warnx("failed to parse principal: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
principal = defprinc;
|
||||
|
||||
ret = krb5_get_init_creds_password (context,
|
||||
&cred,
|
||||
principal,
|
||||
NULL,
|
||||
krb5_prompter_posix,
|
||||
NULL,
|
||||
0,
|
||||
"kadmin/changepw",
|
||||
&opt);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
break;
|
||||
case KRB5_LIBOS_PWDINTR :
|
||||
/* XXX */
|
||||
return 1;
|
||||
case KRB5KRB_AP_ERR_BAD_INTEGRITY :
|
||||
case KRB5KRB_AP_ERR_MODIFIED :
|
||||
fprintf(stderr, "Password incorrect\n");
|
||||
return 1;
|
||||
break;
|
||||
default:
|
||||
warnx("failed to get credentials: %s",
|
||||
krb5_get_err_text(context, ret));
|
||||
return 1;
|
||||
}
|
||||
krb5_data_zero (&result_code_string);
|
||||
krb5_data_zero (&result_string);
|
||||
|
||||
/* XXX use getpass? It has a broken interface. */
|
||||
if(UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), "New password: ", 1) != 0)
|
||||
return 1;
|
||||
|
||||
ret = krb5_set_password (context, &cred, pwbuf, NULL,
|
||||
&result_code,
|
||||
&result_code_string,
|
||||
&result_string);
|
||||
if (ret)
|
||||
krb5_err (context, 1, ret, "krb5_set_password");
|
||||
|
||||
printf ("%s%s%.*s\n", krb5_passwd_result_to_string(context, result_code),
|
||||
result_string.length > 0 ? " : " : "",
|
||||
(int)result_string.length,
|
||||
result_string.length > 0 ? (char *)result_string.data : "");
|
||||
|
||||
krb5_data_free (&result_code_string);
|
||||
krb5_data_free (&result_string);
|
||||
|
||||
krb5_free_cred_contents (context, &cred);
|
||||
krb5_free_context (context);
|
||||
return result_code;
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
345
usr.bin/passwd/local_passwd.c
Normal file
345
usr.bin/passwd/local_passwd.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/* $NetBSD: local_passwd.c,v 1.34 2010/03/02 16:19:13 gdt Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)local_passwd.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: local_passwd.c,v 1.34 2010/03/02 16:19:13 gdt Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <login_cap.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
static uid_t uid;
|
||||
|
||||
static char *
|
||||
getnewpasswd(struct passwd *pw, int min_pw_len)
|
||||
{
|
||||
int tries;
|
||||
char *p, *t;
|
||||
char buf[_PASSWORD_LEN+1], salt[_PASSWORD_LEN+1];
|
||||
char option[LINE_MAX], *key, *opt;
|
||||
|
||||
(void)printf("Changing local password for %s.\n", pw->pw_name);
|
||||
|
||||
if (uid && pw->pw_passwd[0] &&
|
||||
strcmp(crypt(getpass("Old password:"), pw->pw_passwd),
|
||||
pw->pw_passwd)) {
|
||||
errno = EACCES;
|
||||
syslog(LOG_AUTH | LOG_NOTICE,
|
||||
"user %s (UID %lu) failed to change the "
|
||||
"local password of user %s: %m",
|
||||
pw->pw_name, (unsigned long)uid, pw->pw_name);
|
||||
pw_error(NULL, 1, 1);
|
||||
}
|
||||
|
||||
for (buf[0] = '\0', tries = 0;;) {
|
||||
p = getpass("New password:");
|
||||
if (!*p) {
|
||||
(void)printf("Password unchanged.\n");
|
||||
pw_error(NULL, 0, 0);
|
||||
}
|
||||
if (min_pw_len > 0 && (int)strlen(p) < min_pw_len) {
|
||||
(void) printf("Password is too short.\n");
|
||||
continue;
|
||||
}
|
||||
if (strlen(p) <= 5 && ++tries < 2) {
|
||||
(void)printf("Please enter a longer password.\n");
|
||||
continue;
|
||||
}
|
||||
for (t = p; *t && islower((unsigned char)*t); ++t);
|
||||
if (!*t && ++tries < 2) {
|
||||
(void)printf("Please don't use an all-lower case "
|
||||
"password.\nUnusual capitalization, "
|
||||
"control characters or digits are "
|
||||
"suggested.\n");
|
||||
continue;
|
||||
}
|
||||
(void)strlcpy(buf, p, sizeof(buf));
|
||||
if (!strcmp(buf, getpass("Retype new password:")))
|
||||
break;
|
||||
(void)printf("Mismatch; try again, EOF to quit.\n");
|
||||
}
|
||||
|
||||
pw_getpwconf(option, sizeof(option), pw, "localcipher");
|
||||
opt = option;
|
||||
key = strsep(&opt, ",");
|
||||
if(pw_gensalt(salt, _PASSWORD_LEN, key, opt) == -1) {
|
||||
warn("Couldn't generate salt");
|
||||
pw_error(NULL, 0, 0);
|
||||
}
|
||||
return(crypt(buf, salt));
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
void
|
||||
pwlocal_usage(const char *prefix)
|
||||
{
|
||||
|
||||
(void) fprintf(stderr, "%s %s [-d files | -l] [user]\n",
|
||||
prefix, getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
pwlocal_process(const char *username, int argc, char **argv)
|
||||
{
|
||||
struct passwd *pw;
|
||||
struct passwd old_pw;
|
||||
time_t old_change;
|
||||
int pfd, tfd;
|
||||
int min_pw_len = 0;
|
||||
int pw_expiry = 0;
|
||||
int ch;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
while ((ch = getopt(argc, argv, "l")) != -1) {
|
||||
switch (ch) {
|
||||
case 'l':
|
||||
/*
|
||||
* Aborb the -l that may have gotten us here.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* username already provided */
|
||||
break;
|
||||
case 1:
|
||||
username = argv[0];
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
if (!(pw = getpwnam(username)))
|
||||
errx(1, "unknown user %s", username);
|
||||
|
||||
uid = getuid();
|
||||
if (uid && uid != pw->pw_uid)
|
||||
errx(1, "%s", strerror(EACCES));
|
||||
|
||||
/* Save the old pw information for comparing on pw_copy(). */
|
||||
old_pw = *pw;
|
||||
|
||||
/*
|
||||
* Get class restrictions for this user, then get the new password.
|
||||
*/
|
||||
#ifdef LOGIN_CAP
|
||||
if((lc = login_getclass(pw->pw_class)) != NULL) {
|
||||
min_pw_len = (int) login_getcapnum(lc, "minpasswordlen", 0, 0);
|
||||
pw_expiry = (int) login_getcaptime(lc, "passwordtime", 0, 0);
|
||||
login_close(lc);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
printf("AAA: pw_expiry = %x\n", pw_expiry);
|
||||
#endif
|
||||
pw->pw_passwd = getnewpasswd(pw, min_pw_len);
|
||||
old_change = pw->pw_change;
|
||||
pw->pw_change = pw_expiry ? pw_expiry + time(NULL) : 0;
|
||||
|
||||
/*
|
||||
* Now that the user has given us a new password, let us
|
||||
* change the database.
|
||||
*/
|
||||
pw_init();
|
||||
tfd = pw_lock(0);
|
||||
if (tfd < 0) {
|
||||
warnx ("The passwd file is busy, waiting...");
|
||||
tfd = pw_lock(10);
|
||||
if (tfd < 0)
|
||||
errx(1, "The passwd file is still busy, "
|
||||
"try again later.");
|
||||
}
|
||||
|
||||
pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (pfd < 0)
|
||||
pw_error(_PATH_MASTERPASSWD, 1, 1);
|
||||
|
||||
pw_copy(pfd, tfd, pw, &old_pw);
|
||||
|
||||
if (pw_mkdb(username, old_change == pw->pw_change) < 0)
|
||||
pw_error((char *)NULL, 0, 1);
|
||||
|
||||
syslog(LOG_AUTH | LOG_INFO,
|
||||
"user %s (UID %lu) successfully changed "
|
||||
"the local password of user %s",
|
||||
uid ? username : "root", (unsigned long)uid, username);
|
||||
}
|
||||
|
||||
#else /* ! USE_PAM */
|
||||
|
||||
static int force_local;
|
||||
|
||||
int
|
||||
local_init(progname)
|
||||
const char *progname;
|
||||
{
|
||||
force_local = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
local_arg(char ch, const char *arg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'l':
|
||||
force_local = 1;
|
||||
break;
|
||||
default:
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int
|
||||
local_arg_end()
|
||||
{
|
||||
if (force_local)
|
||||
return(PW_USE_FORCE);
|
||||
return(PW_USE);
|
||||
}
|
||||
|
||||
void
|
||||
local_end()
|
||||
{
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
int
|
||||
local_chpw(uname)
|
||||
const char *uname;
|
||||
{
|
||||
struct passwd *pw;
|
||||
struct passwd old_pw;
|
||||
time_t old_change;
|
||||
int pfd, tfd;
|
||||
int min_pw_len = 0;
|
||||
int pw_expiry = 0;
|
||||
#ifdef LOGIN_CAP
|
||||
login_cap_t *lc;
|
||||
#endif
|
||||
|
||||
if (!(pw = getpwnam(uname))) {
|
||||
warnx("unknown user %s", uname);
|
||||
return (1);
|
||||
}
|
||||
|
||||
uid = getuid();
|
||||
if (uid && uid != pw->pw_uid) {
|
||||
warnx("%s", strerror(EACCES));
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Save the old pw information for comparing on pw_copy(). */
|
||||
old_pw = *pw;
|
||||
|
||||
/*
|
||||
* Get class restrictions for this user, then get the new password.
|
||||
*/
|
||||
#ifdef LOGIN_CAP
|
||||
if((lc = login_getclass(pw->pw_class))) {
|
||||
min_pw_len = (int) login_getcapnum(lc, "minpasswordlen", 0, 0);
|
||||
pw_expiry = (int) login_getcaptime(lc, "passwordtime", 0, 0);
|
||||
login_close(lc);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
printf("pw_expiry = %x, pw->pw_expire = %x\n", pw_expiry, pw->pw_expire);
|
||||
#endif
|
||||
pw->pw_passwd = getnewpasswd(pw, min_pw_len);
|
||||
old_change = pw->pw_change;
|
||||
pw->pw_change = pw_expiry ? pw_expiry + time(NULL) : 0;
|
||||
|
||||
/*
|
||||
* Now that the user has given us a new password, let us
|
||||
* change the database.
|
||||
*/
|
||||
pw_init();
|
||||
tfd = pw_lock(0);
|
||||
if (tfd < 0) {
|
||||
warnx ("The passwd file is busy, waiting...");
|
||||
tfd = pw_lock(10);
|
||||
if (tfd < 0)
|
||||
errx(1, "The passwd file is still busy, "
|
||||
"try again later.");
|
||||
}
|
||||
|
||||
pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (pfd < 0)
|
||||
pw_error(_PATH_MASTERPASSWD, 1, 1);
|
||||
|
||||
pw_copy(pfd, tfd, pw, &old_pw);
|
||||
|
||||
if (pw_mkdb(uname, old_change == pw->pw_change) < 0)
|
||||
pw_error((char *)NULL, 0, 1);
|
||||
|
||||
syslog(LOG_AUTH | LOG_INFO,
|
||||
"user %s (UID %lu) successfully changed "
|
||||
"the local password of user %s",
|
||||
uid ? uname : "root", (unsigned long)uid, uname);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
149
usr.bin/passwd/pam_passwd.c
Normal file
149
usr.bin/passwd/pam_passwd.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* $NetBSD: pam_passwd.c,v 1.6 2010/03/09 16:14:08 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 Networks Associates Technologies, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by ThinkSec AS and
|
||||
* NAI Labs, the Security Research Division of Network Associates, Inc.
|
||||
* under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
|
||||
* DARPA CHATS research program.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __FreeBSD__
|
||||
__FBSDID("$FreeBSD: src/usr.bin/passwd/passwd.c,v 1.23 2003/04/18 21:27:09 nectar Exp $");
|
||||
#else
|
||||
__RCSID("$NetBSD: pam_passwd.c,v 1.6 2010/03/09 16:14:08 joerg Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/openpam.h>
|
||||
|
||||
static pam_handle_t *pamh;
|
||||
static struct pam_conv pamc = {
|
||||
openpam_ttyconv,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define pam_check(msg) \
|
||||
do { \
|
||||
if (pam_err != PAM_SUCCESS) { \
|
||||
warnx("%s: %s", (msg), pam_strerror(pamh, pam_err)); \
|
||||
goto end; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
void
|
||||
pwpam_process(const char *username, int argc, char **argv)
|
||||
{
|
||||
int ch, pam_err;
|
||||
char hostname[MAXHOSTNAMELEN + 1];
|
||||
|
||||
/* details about the invoking user for logging */
|
||||
const uid_t i_uid = getuid();
|
||||
const struct passwd *const i_pwd = getpwuid(i_uid);
|
||||
const char *const i_username = (i_pwd && i_pwd->pw_name)
|
||||
? i_pwd->pw_name : "(null)";
|
||||
|
||||
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||
switch (ch) {
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* username already provided */
|
||||
break;
|
||||
case 1:
|
||||
username = argv[0];
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
(void)printf("Changing password for %s.\n", username);
|
||||
|
||||
/* initialize PAM -- always use the program name "passwd" */
|
||||
pam_err = pam_start("passwd", username, &pamc, &pamh);
|
||||
if (pam_err != PAM_SUCCESS)
|
||||
errx(1, "unable to start PAM session: %s",
|
||||
pam_strerror(NULL, pam_err));
|
||||
|
||||
pam_err = pam_set_item(pamh, PAM_TTY, ttyname(STDERR_FILENO));
|
||||
pam_check("unable to set TTY");
|
||||
|
||||
(void)gethostname(hostname, sizeof hostname);
|
||||
pam_err = pam_set_item(pamh, PAM_RHOST, hostname);
|
||||
pam_check("unable to set RHOST");
|
||||
|
||||
pam_err = pam_set_item(pamh, PAM_RUSER, getlogin());
|
||||
pam_check("unable to set RUSER");
|
||||
|
||||
/* set new password */
|
||||
pam_err = pam_chauthtok(pamh, 0);
|
||||
if (pam_err != PAM_SUCCESS) {
|
||||
if (pam_err == PAM_PERM_DENIED) {
|
||||
syslog(LOG_AUTH | LOG_NOTICE,
|
||||
"user %s (UID %lu) failed to change the "
|
||||
"PAM authentication token of user %s: %s",
|
||||
i_username, (unsigned long)i_uid, username,
|
||||
pam_strerror(pamh, pam_err));
|
||||
}
|
||||
printf("Unable to change auth token: %s\n",
|
||||
pam_strerror(pamh, pam_err));
|
||||
} else {
|
||||
syslog(LOG_AUTH | LOG_INFO,
|
||||
"user %s (UID %lu) successfully changed the "
|
||||
"PAM authentication token of user %s",
|
||||
i_username, (unsigned long)i_uid, username);
|
||||
}
|
||||
|
||||
end:
|
||||
pam_end(pamh, pam_err);
|
||||
if (pam_err == PAM_SUCCESS)
|
||||
return;
|
||||
exit(1);
|
||||
}
|
142
usr.bin/passwd/passwd.1
Normal file
142
usr.bin/passwd/passwd.1
Normal file
|
@ -0,0 +1,142 @@
|
|||
.\" $NetBSD: passwd.1,v 1.28 2006/03/07 01:52:09 hubertf Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1990, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)passwd.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd February 25, 2005
|
||||
.Dt PASSWD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm passwd
|
||||
.Nd modify a user's password
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar user
|
||||
.Nm
|
||||
.Oo Fl d Ar files | Fl l Oc
|
||||
.Op Ar user
|
||||
.Nm
|
||||
.Oo Fl d Ar nis | Fl y Oc
|
||||
.Op Ar user
|
||||
.Nm
|
||||
.Oo Fl d Ar krb5 | Fl k Oc
|
||||
.Op Ar principal
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
changes the user's password.
|
||||
First, the user is
|
||||
prompted for their current password.
|
||||
If the current password is correctly typed, a new password is
|
||||
requested.
|
||||
The new password must be entered twice to avoid typing errors.
|
||||
.Pp
|
||||
The new password should be at least six characters long and not
|
||||
purely alphabetic.
|
||||
Its total length must be less than
|
||||
.Dv _PASSWORD_LEN
|
||||
(currently 128 characters).
|
||||
Numbers, upper case letters and meta characters
|
||||
are encouraged.
|
||||
.Pp
|
||||
All options may not be available on all systems.
|
||||
.Bl -tag -width flag
|
||||
.It Fl d Ar database
|
||||
This option specifies the password database that should be updated. The
|
||||
following databases are supported:
|
||||
.Bl -tag -width files
|
||||
.It files
|
||||
This specifies that the password change should be applied to the local
|
||||
password file.
|
||||
When changing only the local password,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the password databases.
|
||||
.It nis
|
||||
This specifies that the password change should be applied to the NIS
|
||||
password database.
|
||||
The
|
||||
.Xr rpc.yppasswdd 8
|
||||
daemon should be running on the master NIS server.
|
||||
.It krb5
|
||||
This specifies that the user's Kerberos 5 password should be changed.
|
||||
The host must be configured to use Kerberos.
|
||||
See
|
||||
.Xr krb5.conf 5 .
|
||||
.El
|
||||
.It Fl l
|
||||
This is the equivalent of
|
||||
.Fl d Ar files .
|
||||
.It Fl y
|
||||
This is the equivalent of
|
||||
.Fl d Ar nis .
|
||||
.It Fl k
|
||||
This is the equivalent of
|
||||
.Fl d Ar krb5 .
|
||||
.El
|
||||
.Pp
|
||||
If a password database is not specified,
|
||||
.Nm
|
||||
will change the password database as determined by the
|
||||
Pluggable Authentication Module
|
||||
.Pq PAM
|
||||
library.
|
||||
.Pp
|
||||
The type of cipher used to encrypt the password depends on the configuration
|
||||
in
|
||||
.Xr passwd.conf 5 .
|
||||
It can be different for local and NIS passwords.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/master.passwd -compact
|
||||
.It Pa /etc/master.passwd
|
||||
The user database
|
||||
.It Pa /etc/passwd
|
||||
A Version 7 format password file
|
||||
.It Pa /etc/passwd.XXXXXX
|
||||
Temporary copy of the password file
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr login 1 ,
|
||||
.Xr pwhash 1 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr passwd.conf 5 ,
|
||||
.Xr pam 8 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr vipw 8
|
||||
.Rs
|
||||
.%A Robert Morris
|
||||
.%A Ken Thompson
|
||||
.%T "UNIX password security"
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
command appeared in
|
||||
.At v6 .
|
405
usr.bin/passwd/passwd.c
Normal file
405
usr.bin/passwd/passwd.c
Normal file
|
@ -0,0 +1,405 @@
|
|||
/* $NetBSD: passwd.c,v 1.30 2009/04/17 20:25:08 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1988, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)passwd.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: passwd.c,v 1.30 2009/04/17 20:25:08 dyoung Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
static void global_usage(const char *);
|
||||
|
||||
static const struct pw_module_s {
|
||||
const char *argv0;
|
||||
const char *dbname;
|
||||
char compat_opt;
|
||||
void (*pw_usage)(const char *);
|
||||
void (*pw_process)(const char *, int, char **);
|
||||
} pw_modules[] = {
|
||||
/* "files" -- local password database */
|
||||
{ NULL, "files", 'l', pwlocal_usage, pwlocal_process },
|
||||
#ifdef YP
|
||||
/* "nis" -- YP/NIS password database */
|
||||
{ NULL, "nis", 'y', pwyp_usage, pwyp_process },
|
||||
{ "yppasswd", NULL, 0, pwyp_argv0_usage, pwyp_process },
|
||||
#endif
|
||||
#ifdef KERBEROS5
|
||||
/* "krb5" -- Kerberos 5 password database */
|
||||
{ NULL, "krb5", 'k', pwkrb5_usage, pwkrb5_process },
|
||||
{ "kpasswd", NULL, 0, pwkrb5_argv0_usage, pwkrb5_process },
|
||||
#endif
|
||||
/* default -- use whatever PAM decides */
|
||||
{ NULL, NULL, 0, NULL, pwpam_process },
|
||||
|
||||
{ NULL, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const struct pw_module_s *personality;
|
||||
|
||||
static void
|
||||
global_usage(const char *prefix)
|
||||
{
|
||||
const struct pw_module_s *pwm;
|
||||
|
||||
(void) fprintf(stderr, "%s %s [user]\n", prefix, getprogname());
|
||||
for (pwm = pw_modules; pwm->pw_process != NULL; pwm++) {
|
||||
if (pwm->argv0 == NULL && pwm->pw_usage != NULL)
|
||||
(*pwm->pw_usage)(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
if (personality != NULL && personality->pw_usage != NULL)
|
||||
(*personality->pw_usage)("usage:");
|
||||
else
|
||||
global_usage("usage:");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const struct pw_module_s *pwm;
|
||||
const char *username;
|
||||
int ch, i;
|
||||
char opts[16];
|
||||
|
||||
/* Build opts string from module compat_opts */
|
||||
i = 0;
|
||||
opts[i++] = 'd';
|
||||
opts[i++] = ':';
|
||||
for (pwm = pw_modules; pwm->pw_process != NULL; pwm++) {
|
||||
if (pwm->compat_opt != 0)
|
||||
opts[i++] = pwm->compat_opt;
|
||||
}
|
||||
opts[i++] = '\0';
|
||||
|
||||
/* First, look for personality based on argv[0]. */
|
||||
for (pwm = pw_modules; pwm->pw_process != NULL; pwm++) {
|
||||
if (pwm->argv0 != NULL &&
|
||||
strcmp(pwm->argv0, getprogname()) == 0)
|
||||
goto got_personality;
|
||||
}
|
||||
|
||||
/* Try based on compat_opt or -d. */
|
||||
for (ch = 0, pwm = pw_modules; pwm->pw_process != NULL; pwm++) {
|
||||
if (pwm->argv0 == NULL && pwm->dbname == NULL &&
|
||||
pwm->compat_opt == 0) {
|
||||
/*
|
||||
* We have reached the default personality case.
|
||||
* Make sure the user didn't provide a bogus
|
||||
* personality name.
|
||||
*/
|
||||
if (ch == 'd')
|
||||
usage();
|
||||
break;
|
||||
}
|
||||
|
||||
ch = getopt(argc, argv, opts);
|
||||
if (ch == '?')
|
||||
usage();
|
||||
|
||||
if (ch == 'd' && pwm->dbname != NULL &&
|
||||
strcmp(pwm->dbname, optarg) == 0) {
|
||||
/*
|
||||
* "passwd -d dbname" matches; this is our
|
||||
* chosen personality.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
if (pwm->compat_opt != 0 && ch == pwm->compat_opt) {
|
||||
/*
|
||||
* Legacy "passwd -l" or similar matches; this
|
||||
* is our chosen personality.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset getopt() and go around again. */
|
||||
optind = 1;
|
||||
optreset = 1;
|
||||
}
|
||||
|
||||
got_personality:
|
||||
personality = pwm;
|
||||
|
||||
/*
|
||||
* At this point, optind should be either 1 ("passwd"),
|
||||
* 2 ("passwd -l"), or 3 ("passwd -d files"). Consume
|
||||
* these arguments and reset getopt() for the modules to use.
|
||||
*/
|
||||
assert(optind >= 1 && optind <= 3);
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
optind = 0;
|
||||
optreset = 1;
|
||||
|
||||
username = getlogin();
|
||||
if (username == NULL)
|
||||
errx(1, "who are you ??");
|
||||
|
||||
(*personality->pw_process)(username, argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* ! USE_PAM */
|
||||
|
||||
static struct pw_module_s {
|
||||
const char *argv0;
|
||||
const char *args;
|
||||
const char *usage;
|
||||
int (*pw_init) __P((const char *));
|
||||
int (*pw_arg) __P((char, const char *));
|
||||
int (*pw_arg_end) __P((void));
|
||||
void (*pw_end) __P((void));
|
||||
|
||||
int (*pw_chpw) __P((const char*));
|
||||
int invalid;
|
||||
#define INIT_INVALID 1
|
||||
#define ARG_INVALID 2
|
||||
int use_class;
|
||||
} pw_modules[] = {
|
||||
#ifdef KERBEROS5
|
||||
{ NULL, "5ku:", "[-5] [-k] [-u principal]",
|
||||
krb5_init, krb5_arg, krb5_arg_end, krb5_end, krb5_chpw, 0, 0 },
|
||||
{ "kpasswd", "5ku:", "[-5] [-k] [-u principal]",
|
||||
krb5_init, krb5_arg, krb5_arg_end, krb5_end, krb5_chpw, 0, 0 },
|
||||
#endif
|
||||
#ifdef YP
|
||||
{ NULL, "y", "[-y]",
|
||||
yp_init, yp_arg, yp_arg_end, yp_end, yp_chpw, 0, 0 },
|
||||
{ "yppasswd", "", "[-y]",
|
||||
yp_init, yp_arg, yp_arg_end, yp_end, yp_chpw, 0, 0 },
|
||||
#endif
|
||||
/* local */
|
||||
{ NULL, "l", "[-l]",
|
||||
local_init, local_arg, local_arg_end, local_end, local_chpw, 0, 0 },
|
||||
|
||||
/* terminator */
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "usage:\n");
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++)
|
||||
if (! (pw_modules[i].invalid & INIT_INVALID))
|
||||
fprintf(stderr, "\t%s %s [user]\n", getprogname(),
|
||||
pw_modules[i].usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int ch;
|
||||
char *username;
|
||||
char optstring[64]; /* if we ever get more than 64 args, shoot me. */
|
||||
const char *curopt, *oopt;
|
||||
int i, j;
|
||||
int valid;
|
||||
int use_always;
|
||||
|
||||
/* allow passwd modules to do argv[0] specific processing */
|
||||
use_always = 0;
|
||||
valid = 0;
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++) {
|
||||
pw_modules[i].invalid = 0;
|
||||
if (pw_modules[i].argv0) {
|
||||
/*
|
||||
* If we have a module that matches this progname, be
|
||||
* sure that no modules but those that match this
|
||||
* progname can be used. If we have a module that
|
||||
* matches against a particular progname, but does NOT
|
||||
* match this one, don't use that module.
|
||||
*/
|
||||
if ((strcmp(getprogname(), pw_modules[i].argv0) == 0) &&
|
||||
use_always == 0) {
|
||||
for (j = 0; j < i; j++) {
|
||||
pw_modules[j].invalid |= INIT_INVALID;
|
||||
(*pw_modules[j].pw_end)();
|
||||
}
|
||||
use_always = 1;
|
||||
} else if (use_always == 0)
|
||||
pw_modules[i].invalid |= INIT_INVALID;
|
||||
} else if (use_always)
|
||||
pw_modules[i].invalid |= INIT_INVALID;
|
||||
|
||||
if (pw_modules[i].invalid)
|
||||
continue;
|
||||
|
||||
pw_modules[i].invalid |=
|
||||
(*pw_modules[i].pw_init)(getprogname()) ?
|
||||
/* zero on success, non-zero on error */
|
||||
INIT_INVALID : 0;
|
||||
|
||||
if (! pw_modules[i].invalid)
|
||||
valid = 1;
|
||||
}
|
||||
|
||||
if (valid == 0)
|
||||
errx(1, "Can't change password.");
|
||||
|
||||
/* Build the option string from the individual modules' option
|
||||
* strings. Note that two modules can share a single option
|
||||
* letter. */
|
||||
optstring[0] = '\0';
|
||||
j = 0;
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++) {
|
||||
if (pw_modules[i].invalid)
|
||||
continue;
|
||||
|
||||
curopt = pw_modules[i].args;
|
||||
while (*curopt != '\0') {
|
||||
if ((oopt = strchr(optstring, *curopt)) == NULL) {
|
||||
optstring[j++] = *curopt;
|
||||
if (curopt[1] == ':') {
|
||||
curopt++;
|
||||
optstring[j++] = *curopt;
|
||||
}
|
||||
optstring[j] = '\0';
|
||||
} else if ((oopt[1] == ':' && curopt[1] != ':') ||
|
||||
(oopt[1] != ':' && curopt[1] == ':')) {
|
||||
errx(1, "NetBSD ERROR! Different password "
|
||||
"modules have two different ideas about "
|
||||
"%c argument format.", curopt[0]);
|
||||
}
|
||||
curopt++;
|
||||
}
|
||||
}
|
||||
|
||||
while ((ch = getopt(argc, argv, optstring)) != -1)
|
||||
{
|
||||
valid = 0;
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++) {
|
||||
if (pw_modules[i].invalid)
|
||||
continue;
|
||||
if ((oopt = strchr(pw_modules[i].args, ch)) != NULL) {
|
||||
j = (oopt[1] == ':') ?
|
||||
! (*pw_modules[i].pw_arg)(ch, optarg) :
|
||||
! (*pw_modules[i].pw_arg)(ch, NULL);
|
||||
if (j != 0)
|
||||
pw_modules[i].invalid |= ARG_INVALID;
|
||||
if (pw_modules[i].invalid)
|
||||
(*pw_modules[i].pw_end)();
|
||||
} else {
|
||||
/* arg doesn't match this module */
|
||||
pw_modules[i].invalid |= ARG_INVALID;
|
||||
(*pw_modules[i].pw_end)();
|
||||
}
|
||||
if (! pw_modules[i].invalid)
|
||||
valid = 1;
|
||||
}
|
||||
if (! valid) {
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* select which module to use to actually change the password. */
|
||||
use_always = 0;
|
||||
valid = 0;
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++)
|
||||
if (! pw_modules[i].invalid) {
|
||||
pw_modules[i].use_class = (*pw_modules[i].pw_arg_end)();
|
||||
if (pw_modules[i].use_class != PW_DONT_USE)
|
||||
valid = 1;
|
||||
if (pw_modules[i].use_class == PW_USE_FORCE)
|
||||
use_always = 1;
|
||||
}
|
||||
|
||||
|
||||
if (! valid)
|
||||
/* hang the DJ */
|
||||
errx(1, "No valid password module specified.");
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
username = getlogin();
|
||||
if (username == NULL)
|
||||
errx(1, "who are you ??");
|
||||
|
||||
switch(argc) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
username = argv[0];
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* allow for fallback to other chpw() methods. */
|
||||
for (i = 0; pw_modules[i].pw_init != NULL; i++) {
|
||||
if (pw_modules[i].invalid)
|
||||
continue;
|
||||
if ((use_always && pw_modules[i].use_class == PW_USE_FORCE) ||
|
||||
(!use_always && pw_modules[i].use_class == PW_USE)) {
|
||||
valid = (*pw_modules[i].pw_chpw)(username);
|
||||
(*pw_modules[i].pw_end)();
|
||||
if (valid >= 0)
|
||||
exit(valid);
|
||||
/* return value < 0 indicates continuation. */
|
||||
}
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
468
usr.bin/passwd/yp_passwd.c
Normal file
468
usr.bin/passwd/yp_passwd.c
Normal file
|
@ -0,0 +1,468 @@
|
|||
/* $NetBSD: yp_passwd.c,v 1.35 2010/09/08 13:58:46 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "from: @(#)local_passwd.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: yp_passwd.c,v 1.35 2010/09/08 13:58:46 christos Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef YP
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <util.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#define passwd yp_passwd_rec
|
||||
#include <rpcsvc/yppasswd.h>
|
||||
#undef passwd
|
||||
|
||||
#ifndef _PASSWORD_LEN
|
||||
#define _PASSWORD_LEN PASS_MAX
|
||||
#endif
|
||||
|
||||
static uid_t uid;
|
||||
static char *domain;
|
||||
|
||||
static void
|
||||
pwerror(const char *name, int show_err, int eval)
|
||||
{
|
||||
|
||||
if (show_err)
|
||||
warn("%s", name);
|
||||
errx(eval, "NIS passwd database unchanged");
|
||||
}
|
||||
|
||||
static char *
|
||||
getnewpasswd(struct passwd *pw, char **old_pass)
|
||||
{
|
||||
int tries;
|
||||
const char *p, *t;
|
||||
char *result;
|
||||
static char buf[_PASSWORD_LEN + 1];
|
||||
char salt[_PASSWORD_LEN + 1];
|
||||
char option[LINE_MAX], *key, *opt;
|
||||
|
||||
(void)printf("Changing NIS password for %s.\n", pw->pw_name);
|
||||
|
||||
if (old_pass) {
|
||||
*old_pass = NULL;
|
||||
|
||||
if (pw->pw_passwd[0]) {
|
||||
if (strcmp(crypt(p = getpass("Old password:"),
|
||||
pw->pw_passwd), pw->pw_passwd)) {
|
||||
(void)printf("Sorry.\n");
|
||||
pwerror(NULL, 0, 1);
|
||||
}
|
||||
} else {
|
||||
p = "";
|
||||
}
|
||||
|
||||
*old_pass = strdup(p);
|
||||
if (!*old_pass) {
|
||||
(void)printf("not enough core.\n");
|
||||
pwerror(NULL, 0, 1);
|
||||
}
|
||||
}
|
||||
for (buf[0] = '\0', tries = 0;;) {
|
||||
p = getpass("New password:");
|
||||
if (!*p) {
|
||||
(void)printf("Password unchanged.\n");
|
||||
pwerror(NULL, 0, 0);
|
||||
}
|
||||
if (strlen(p) <= 5 && ++tries < 2) {
|
||||
(void)printf("Please enter a longer password.\n");
|
||||
continue;
|
||||
}
|
||||
for (t = p; *t && islower((unsigned char)*t); ++t);
|
||||
if (!*t && ++tries < 2) {
|
||||
(void)printf("Please don't use an all-lower case "
|
||||
"password.\nUnusual capitalization, "
|
||||
"control characters or digits are "
|
||||
"suggested.\n");
|
||||
continue;
|
||||
}
|
||||
(void)strlcpy(buf, p, sizeof(buf));
|
||||
if (!strcmp(buf, getpass("Retype new password:")))
|
||||
break;
|
||||
(void)printf("Mismatch; try again, EOF to quit.\n");
|
||||
}
|
||||
|
||||
pw_getpwconf(option, sizeof(option), pw, "ypcipher");
|
||||
opt = option;
|
||||
key = strsep(&opt, ",");
|
||||
if (pw_gensalt(salt, _PASSWORD_LEN, key, opt) == -1) {
|
||||
warn("Couldn't generate salt");
|
||||
pwerror(NULL, 0, 0);
|
||||
}
|
||||
result = strdup(crypt(buf, salt));
|
||||
if (!result) {
|
||||
(void)printf("not enough core.\n");
|
||||
pwerror(NULL, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
makeypp(struct yppasswd *ypp, struct passwd *pw)
|
||||
{
|
||||
/* prompt for new password */
|
||||
ypp->newpw.pw_passwd = getnewpasswd(pw, &ypp->oldpass);
|
||||
|
||||
/* tell rpc.yppasswdd */
|
||||
ypp->newpw.pw_name = estrdup(pw->pw_name);
|
||||
ypp->newpw.pw_uid = pw->pw_uid;
|
||||
ypp->newpw.pw_gid = pw->pw_gid;
|
||||
ypp->newpw.pw_gecos = estrdup(pw->pw_gecos);
|
||||
ypp->newpw.pw_dir = estrdup(pw->pw_dir);
|
||||
ypp->newpw.pw_shell = estrdup(pw->pw_shell);
|
||||
}
|
||||
|
||||
static int
|
||||
ypgetpwnam(const char *nam, struct passwd *pwd)
|
||||
{
|
||||
char *val;
|
||||
int reason, vallen, namlen = (int)strlen(nam);
|
||||
int flags;
|
||||
int ok;
|
||||
|
||||
flags = ok = 0;
|
||||
val = NULL;
|
||||
reason = yp_match(domain, "master.passwd.byname", nam, namlen,
|
||||
&val, &vallen);
|
||||
if (reason == YPERR_MAP) {
|
||||
reason = yp_match(domain, "passwd.byname", nam, namlen,
|
||||
&val, &vallen);
|
||||
flags = _PASSWORD_OLDFMT;
|
||||
}
|
||||
if (reason != 0)
|
||||
goto out;
|
||||
|
||||
if (pw_scan(val, pwd, &flags) == 0)
|
||||
goto out;
|
||||
|
||||
ok = 1;
|
||||
val = NULL; /* Don't free the memory, it is still in use */
|
||||
out:
|
||||
if (val)
|
||||
free(val);
|
||||
return ok;
|
||||
}
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
void
|
||||
pwyp_usage(const char *prefix)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s %s [-d nis | -y] [user]\n",
|
||||
prefix, getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
pwyp_argv0_usage(const char *prefix)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "%s %s [user]\n",
|
||||
prefix, getprogname());
|
||||
}
|
||||
|
||||
void
|
||||
pwyp_process(const char *username, int argc, char **argv)
|
||||
{
|
||||
char *master;
|
||||
int ch, r, rpcport, status;
|
||||
enum clnt_stat yr;
|
||||
struct yppasswd ypp;
|
||||
struct passwd pwb, pwb2, *pw;
|
||||
char pwbuf[1024];
|
||||
struct timeval tv;
|
||||
CLIENT *client;
|
||||
|
||||
while ((ch = getopt(argc, argv, "y")) != -1) {
|
||||
switch (ch) {
|
||||
case 'y':
|
||||
/*
|
||||
* Abosrb the -y that may have gotten us here.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* username already provided */
|
||||
break;
|
||||
case 1:
|
||||
username = argv[0];
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
if (_yp_check(NULL) == 0) {
|
||||
/* can't use YP. */
|
||||
errx(EXIT_FAILURE, "NIS not in use.");
|
||||
}
|
||||
|
||||
uid = getuid();
|
||||
|
||||
/*
|
||||
* Get local domain
|
||||
*/
|
||||
if ((r = yp_get_default_domain(&domain)) != 0)
|
||||
errx(EXIT_FAILURE, "Can't get local NIS domain (%s)",
|
||||
yperr_string(r));
|
||||
|
||||
/*
|
||||
* Find the host for the passwd map; it should be running
|
||||
* the daemon.
|
||||
*/
|
||||
if ((r = yp_master(domain, "passwd.byname", &master)) != 0)
|
||||
errx(EXIT_FAILURE, "Can't find the master NIS server (%s)",
|
||||
yperr_string(r));
|
||||
|
||||
/*
|
||||
* Ask the portmapper for the port of the daemon.
|
||||
*/
|
||||
if ((rpcport = getrpcport(master, YPPASSWDPROG,
|
||||
YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0)
|
||||
errx(EXIT_FAILURE, "Master NIS server not running yppasswd "
|
||||
"daemon");
|
||||
|
||||
/*
|
||||
* Be sure the port is privileged
|
||||
*/
|
||||
if (rpcport >= IPPORT_RESERVED)
|
||||
errx(EXIT_FAILURE, "Yppasswd daemon is on an invalid port");
|
||||
|
||||
/* Bail out if this is a local (non-yp) user, */
|
||||
/* then get user's login identity */
|
||||
if (!ypgetpwnam(username, &pwb) ||
|
||||
getpwnam_r(username, &pwb2, pwbuf, sizeof(pwbuf), &pw) ||
|
||||
pw == NULL)
|
||||
errx(EXIT_FAILURE, "NIS unknown user %s", username);
|
||||
|
||||
if (uid && uid != pwb.pw_uid) {
|
||||
errno = EACCES;
|
||||
err(EXIT_FAILURE, "You may only change your own password");
|
||||
}
|
||||
|
||||
makeypp(&ypp, &pwb);
|
||||
|
||||
client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
|
||||
if (client == NULL)
|
||||
errx(EXIT_FAILURE, "Cannot contact yppasswdd on %s (%s)",
|
||||
master, yperr_string(YPERR_YPBIND));
|
||||
|
||||
client->cl_auth = authunix_create_default();
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
yr = clnt_call(client, YPPASSWDPROC_UPDATE,
|
||||
xdr_yppasswd, &ypp, xdr_int, &status, tv);
|
||||
if (yr != RPC_SUCCESS)
|
||||
errx(EXIT_FAILURE, "RPC to yppasswdd failed (%s)",
|
||||
clnt_sperrno(yr));
|
||||
else if (status)
|
||||
printf("Couldn't change NIS password.\n");
|
||||
else
|
||||
printf("The NIS password has been changed on %s, %s\n",
|
||||
master, "the master NIS passwd server.");
|
||||
}
|
||||
|
||||
#else /* ! USE_PAM */
|
||||
|
||||
static int yflag;
|
||||
|
||||
int
|
||||
yp_init(progname)
|
||||
const char *progname;
|
||||
{
|
||||
int yppwd;
|
||||
|
||||
if (strcmp(progname, "yppasswd") == 0) {
|
||||
yppwd = 1;
|
||||
} else
|
||||
yppwd = 0;
|
||||
yflag = 0;
|
||||
if (_yp_check(NULL) == 0) {
|
||||
/* can't use YP. */
|
||||
if (yppwd)
|
||||
errx(EXIT_FAILURE, "NIS not in use");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
yp_arg(char ch, const char *arg)
|
||||
{
|
||||
switch (ch) {
|
||||
case 'y':
|
||||
yflag = 1;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
yp_arg_end(void)
|
||||
{
|
||||
if (yflag)
|
||||
return PW_USE_FORCE;
|
||||
return PW_USE;
|
||||
}
|
||||
|
||||
void
|
||||
yp_end(void)
|
||||
{
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
int
|
||||
yp_chpw(const char *username)
|
||||
{
|
||||
char *master;
|
||||
int r, rpcport, status;
|
||||
enum clnt_stat yr;
|
||||
struct yppasswd ypp;
|
||||
struct passwd *pw, pwb;
|
||||
char pwbuf[1024];
|
||||
struct timeval tv;
|
||||
CLIENT *client;
|
||||
|
||||
uid = getuid();
|
||||
|
||||
/*
|
||||
* Get local domain
|
||||
*/
|
||||
if ((r = yp_get_default_domain(&domain)) != 0)
|
||||
errx(EXIT_FAILURE, "can't get local NIS domain. Reason: %s",
|
||||
yperr_string(r));
|
||||
|
||||
/*
|
||||
* Find the host for the passwd map; it should be running
|
||||
* the daemon.
|
||||
*/
|
||||
if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
|
||||
warnx("can't find the master NIS server. Reason: %s",
|
||||
yperr_string(r));
|
||||
/* continuation */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ask the portmapper for the port of the daemon.
|
||||
*/
|
||||
if ((rpcport = getrpcport(master, YPPASSWDPROG,
|
||||
YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
|
||||
warnx("Master NIS server not running yppasswd daemon");
|
||||
/* continuation */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Be sure the port is privileged
|
||||
*/
|
||||
if (rpcport >= IPPORT_RESERVED)
|
||||
errx(EXIT_FAILURE, "Yppasswd daemon is on an invalid port");
|
||||
|
||||
/* Bail out if this is a local (non-yp) user, */
|
||||
/* then get user's login identity */
|
||||
if (!ypgetpwnam(username, pw = &pwb) ||
|
||||
getpwnam_r(username, &pwb, pwbuf, sizeof(pwbuf), &pw) ||
|
||||
pw == NULL) {
|
||||
warnx("NIS unknown user %s", username);
|
||||
/* continuation */
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uid && uid != pw->pw_uid) {
|
||||
errno = EACCES;
|
||||
err(EXIT_FAILURE, "You may only change your own password");
|
||||
}
|
||||
|
||||
makeypp(&ypp, pw);
|
||||
|
||||
client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
|
||||
if (client == NULL) {
|
||||
warnx("Cannot contact yppasswdd on %s (%s)",
|
||||
master, yperr_string(YPERR_YPBIND));
|
||||
return YPERR_YPBIND;
|
||||
}
|
||||
|
||||
client->cl_auth = authunix_create_default();
|
||||
tv.tv_sec = 2;
|
||||
tv.tv_usec = 0;
|
||||
yr = clnt_call(client, YPPASSWDPROC_UPDATE,
|
||||
xdr_yppasswd, &ypp, xdr_int, &status, tv);
|
||||
if (yr != RPC_SUCCESS)
|
||||
errx(EXIT_FAILURE, "RPC to yppasswdd failed (%s)",
|
||||
clnt_sperrno(yr));
|
||||
else if (status)
|
||||
printf("Couldn't change NIS password.\n");
|
||||
else
|
||||
printf("The NIS password has been changed on %s, %s\n",
|
||||
master, "the master NIS passwd server.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_PAM */
|
||||
|
||||
#endif /* YP */
|
48
usr.bin/passwd/yppasswd.1
Normal file
48
usr.bin/passwd/yppasswd.1
Normal file
|
@ -0,0 +1,48 @@
|
|||
.\" $NetBSD: yppasswd.1,v 1.3 2008/04/30 13:11:01 martin Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
.\" by Jason R. Thorpe.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd February 25, 2005
|
||||
.Dt YPPASSWD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm yppasswd
|
||||
.Nd modify a user's NIS password
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Ar user
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
changes the user's NIS password.
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
command is deprecated.
|
||||
See
|
||||
.Xr passwd 1
|
||||
for more information.
|
|
@ -3,7 +3,9 @@
|
|||
/* Modified for ProcFS by Alen Stojanov and David van Moolenbroek */
|
||||
|
||||
#define _MINIX 1
|
||||
#ifndef __NBSD_LIBC
|
||||
#define _POSIX_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
|
8
usr.sbin/Makefile
Normal file
8
usr.sbin/Makefile
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Makefile for usr.bin
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
# NetBSD imports
|
||||
SUBDIR= pwd_mkdb user vipw
|
||||
|
||||
.include <bsd.subdir.mk>
|
3
usr.sbin/Makefile.inc
Normal file
3
usr.sbin/Makefile.inc
Normal file
|
@ -0,0 +1,3 @@
|
|||
.include <minix.newlibc.mk>
|
||||
|
||||
BINDIR?= /usr/sbin
|
19
usr.sbin/pwd_mkdb/Makefile
Normal file
19
usr.sbin/pwd_mkdb/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
# $NetBSD: Makefile,v 1.19 2009/01/14 23:18:57 christos Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
PROG= pwd_mkdb
|
||||
MAN= pwd_mkdb.8
|
||||
.if defined(__MINIX)
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}/lib/nbsd_libc/include
|
||||
.else
|
||||
CPPFLAGS+= -I${NETBSDSRCDIR}/lib/libc/include
|
||||
.endif
|
||||
|
||||
.ifndef HOSTPROG
|
||||
LDADD+= -lutil
|
||||
DPADD+= ${LIBUTIL}
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
219
usr.sbin/pwd_mkdb/pwd_mkdb.8
Normal file
219
usr.sbin/pwd_mkdb/pwd_mkdb.8
Normal file
|
@ -0,0 +1,219 @@
|
|||
.\" $NetBSD: pwd_mkdb.8,v 1.28 2010/08/18 10:00:49 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)pwd_mkdb.8 8.2 (Berkeley) 4/27/95
|
||||
.\"
|
||||
.Dd August 18, 2010
|
||||
.Dt PWD_MKDB 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pwd_mkdb
|
||||
.Nd generate the password databases
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl BLlpsvw
|
||||
.Op Fl c Ar cachesize
|
||||
.Op Fl d Ar directory
|
||||
.Op Fl u Ar username
|
||||
.Op Fl V Ar version
|
||||
.Ar file
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
creates
|
||||
.Xr db 3
|
||||
style secure and insecure databases for the specified file.
|
||||
These databases are then installed into
|
||||
.Dq Pa /etc/spwd.db
|
||||
and
|
||||
.Dq Pa /etc/pwd.db
|
||||
respectively.
|
||||
The file is installed into
|
||||
.Dq Pa /etc/master.passwd .
|
||||
The file must be in the correct format (see
|
||||
.Xr passwd 5 ) .
|
||||
It is important to note that the format used in this system is
|
||||
different from the historic Version 7 style format.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width flag
|
||||
.It Fl B
|
||||
Store data in big-endian format (see also
|
||||
.Fl L ) .
|
||||
.It Fl c Ar cachesize
|
||||
Specify the size of the memory cache in megabytes used by the
|
||||
hashing library.
|
||||
On systems with a large user base, a small cache size can lead to
|
||||
prohibitively long database file rebuild times.
|
||||
As a rough guide, the memory usage of
|
||||
.Nm
|
||||
in megabytes will be a little bit more than twice the figure
|
||||
specified here.
|
||||
If unspecified, this value will be calculated based on the size of
|
||||
the input file up to a maximum of 8 megabytes.
|
||||
.It Fl d Ar directory
|
||||
Change the root directory of the generated files from
|
||||
.Dq Pa /
|
||||
to
|
||||
.Ar directory .
|
||||
.It Fl L
|
||||
Store data in little-endian format (see also
|
||||
.Fl B ) .
|
||||
.It Fl l
|
||||
Use
|
||||
.Xr syslog 3
|
||||
to report errors.
|
||||
.It Fl p
|
||||
Create a Version 7 style password file and install it into
|
||||
.Dq Pa /etc/passwd .
|
||||
.It Fl s
|
||||
Update the secure database only.
|
||||
This is useful when only encrypted passwords have changed.
|
||||
This option negates the effect of any
|
||||
.Fl p
|
||||
option.
|
||||
.It Fl u Ar name
|
||||
Don't re-build the database files, but instead modify or add entries
|
||||
for the specified user only.
|
||||
This option may only be used when the line number and user name in
|
||||
the password file have not changed, or when adding a new user from
|
||||
the last line in the password file.
|
||||
.It Fl V Ar version
|
||||
Upgrade or downgrade databases to the numbered version.
|
||||
Version
|
||||
.Dv 0
|
||||
is the old format (up to and including
|
||||
.Nx 5.0 )
|
||||
with the 4 byte time fields and version
|
||||
.Dv 1
|
||||
is the new format with the 8 byte time fields (greater than
|
||||
.Nx 5.0 ) .
|
||||
.Nx 5.0
|
||||
cannot read version
|
||||
.Dv 1
|
||||
databases.
|
||||
All versions above
|
||||
.Nx 5.0
|
||||
can read and write both version
|
||||
.Dv 0
|
||||
and version
|
||||
.Dv 1
|
||||
databases.
|
||||
By default the databases stay in the version they were before the command
|
||||
was run.
|
||||
.It Fl v
|
||||
Mention when a version change occurs.
|
||||
.It Fl w
|
||||
Print a warning if the system is using old style databases.
|
||||
.El
|
||||
.Pp
|
||||
The two databases differ in that the secure version contains the user's
|
||||
encrypted password and the insecure version has an asterisk
|
||||
.Pq Dq * .
|
||||
.Pp
|
||||
The databases are used by the C library password routines (see
|
||||
.Xr getpwent 3 ) .
|
||||
.Sh FILES
|
||||
.Bl -tag -width Pa -compact
|
||||
.It Pa /etc/master.passwd
|
||||
The current password file.
|
||||
.It Pa /etc/passwd
|
||||
A Version 7 format password file.
|
||||
.It Pa /etc/pwd.db
|
||||
The insecure password database file.
|
||||
.It Pa /etc/pwd.db.tmp
|
||||
A temporary file.
|
||||
.It Pa /etc/spwd.db
|
||||
The secure password database file.
|
||||
.It Pa /etc/spwd.db.tmp
|
||||
A temporary file.
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Nm
|
||||
exits zero on success, non-zero on failure.
|
||||
.Sh COMPATIBILITY
|
||||
Previous versions of the system had a program similar to
|
||||
.Nm
|
||||
which built
|
||||
.Em dbm
|
||||
style databases for the password file but depended on the calling programs
|
||||
to install them.
|
||||
The program was renamed in order that previous users of the program
|
||||
not be surprised by the changes in functionality.
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr pwhash 1 ,
|
||||
.Xr db 3 ,
|
||||
.Xr getpwent 3 ,
|
||||
.Xr pw_mkdb 3 ,
|
||||
.Xr syslog 3 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8 ,
|
||||
.Xr usermod 8 ,
|
||||
.Xr vipw 8
|
||||
.Sh BUGS
|
||||
Because of the necessity for atomic update of the password files,
|
||||
.Nm
|
||||
uses
|
||||
.Xr rename 2
|
||||
to install them.
|
||||
This, however, requires that the file specified on the command line live
|
||||
on the same file system as the
|
||||
.Dq Pa /etc
|
||||
directory.
|
||||
.Pp
|
||||
There are the obvious races with multiple people running
|
||||
.Nm
|
||||
on different password files at the same time.
|
||||
The front-ends to
|
||||
.Xr chpass 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8 ,
|
||||
.Xr usermod 8 ,
|
||||
and
|
||||
.Xr vipw 8
|
||||
handle the locking necessary to avoid this problem.
|
||||
.Pp
|
||||
The database files are copied when the
|
||||
.Fl u
|
||||
option is used.
|
||||
Real locking would make this unnecessary.
|
||||
.Pp
|
||||
Although the DB format is endian-transparent, the data stored in
|
||||
the DB is not.
|
||||
Also, the format doesn't lend itself to insertion or removal of
|
||||
records from arbitrary locations in the password file.
|
||||
This is difficult to fix without breaking compatibility.
|
||||
.Pp
|
||||
Using the
|
||||
.Fl u
|
||||
option on a system where multiple users share the same UID can have
|
||||
unexpected results.
|
1065
usr.sbin/pwd_mkdb/pwd_mkdb.c
Normal file
1065
usr.sbin/pwd_mkdb/pwd_mkdb.c
Normal file
File diff suppressed because it is too large
Load diff
81
usr.sbin/user/Makefile
Normal file
81
usr.sbin/user/Makefile
Normal file
|
@ -0,0 +1,81 @@
|
|||
# $NetBSD: Makefile,v 1.12 2009/04/22 15:23:09 lukem Exp $
|
||||
#
|
||||
|
||||
WARNS?= 1 # XXX: -Wsign-compare -Wcast-qual
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
CPPFLAGS+= -DEXTENSIONS -DPW_MKDB_ARGC=2
|
||||
|
||||
PROG= user
|
||||
SRCS+= user.c main.c
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/useradd
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/userdel
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/usermod
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/group
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/groupadd
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/groupdel
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/groupmod
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/userinfo
|
||||
LINKS+= ${BINDIR}/user ${BINDIR}/groupinfo
|
||||
LDADD+= -lutil
|
||||
DPADD+= ${LIBUTIL}
|
||||
MAN= user.8 useradd.8 userdel.8 usermod.8 userinfo.8 usermgmt.conf.5
|
||||
MAN+= group.8 groupadd.8 groupdel.8 groupmod.8 groupinfo.8
|
||||
MLINKS= useradd.8 adduser.8
|
||||
|
||||
# this target checks the built-in default group, and, if it doesn't exist,
|
||||
# creates it
|
||||
default-group:
|
||||
@ln -fs ${.OBJDIR}/user ${.OBJDIR}/group; \
|
||||
defgrp=`${.OBJDIR}/user add -D | \
|
||||
${TOOL_AWK} '/^group/ { print $$2 }'`; \
|
||||
if ${.OBJDIR}/group info -e $$defgrp; then \
|
||||
defgid=`${.OBJDIR}/group info $$defgrp | \
|
||||
${TOOL_AWK} '/^gid/ { print $$2 }'`; \
|
||||
else \
|
||||
defgid=99; \
|
||||
while [ $$defgid -gt 0 ]; do \
|
||||
${.OBJDIR}/group info -e $$defgid || break; \
|
||||
defgid=`expr $$defgid - 1`; \
|
||||
done; \
|
||||
if [ $$defgid -eq 0 ]; then \
|
||||
defgid=100; \
|
||||
while [ $$defgid -lt 60000 ]; do \
|
||||
${.OBJDIR}/group info -e $$defgid || break; \
|
||||
defgid=`expr $$defgid + 1`; \
|
||||
done; \
|
||||
if [ $$defgid -eq 60000 ]; then \
|
||||
echo "No gids left"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
fi; \
|
||||
${.OBJDIR}/group add -g $$defgid $$defgrp; \
|
||||
fi; \
|
||||
echo "Default group is $$defgrp ($$defgid):"; \
|
||||
${.OBJDIR}/group info $$defgrp
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
test: ${PROG}
|
||||
@echo "No news is good news"
|
||||
@echo "1. Adding new user"
|
||||
@rm -f useradd
|
||||
@ln -s user useradd
|
||||
-./useradd -m -g=uid test1.1
|
||||
@echo "2. Modifying new user"
|
||||
-./${PROG} mod -l test1.2 test1.1
|
||||
@echo "3. Deleting new user"
|
||||
-./${PROG} del -r test1.2
|
||||
@echo "4. Attempting to add an invalid user name - IGNORE ANY ERROR"
|
||||
-./${PROG} add -m test1%1
|
||||
@echo "5. Bad usage - IGNORE ANY ERROR"
|
||||
-./${PROG} add -m
|
||||
@echo "6. Set range defaults"
|
||||
-./${PROG} add -D -r4000..6000
|
||||
-./${PROG} add -D
|
||||
@echo "7. Get user information"
|
||||
-./${PROG} info root
|
||||
@echo "8. Bad user name - IGNORE ANY ERROR"
|
||||
-./${PROG} info test1%1 || echo "User not found"
|
||||
@echo "All tests completed"
|
59
usr.sbin/user/defs.h
Normal file
59
usr.sbin/user/defs.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* $NetBSD: defs.h,v 1.6 2005/11/25 08:00:18 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef DEFS_H_
|
||||
#define DEFS_H_
|
||||
|
||||
#define NEWARRAY(type,ptr,size,action) do { \
|
||||
if ((ptr = (type *) calloc(sizeof(type), size)) == (type *) NULL) { \
|
||||
warn("can't allocate %ld bytes", (long)(size * sizeof(type))); \
|
||||
action; \
|
||||
} \
|
||||
} while( /* CONSTCOND */ 0)
|
||||
|
||||
#define RENEW(type,ptr,size,action) do { \
|
||||
if ((ptr = (type *) realloc(ptr, sizeof(type) * size)) == (type *) NULL) { \
|
||||
warn("can't realloc %ld bytes", (long)(size * sizeof(type))); \
|
||||
action; \
|
||||
} \
|
||||
} while( /* CONSTCOND */ 0)
|
||||
|
||||
#define NEW(type, ptr, action) NEWARRAY(type, ptr, 1, action)
|
||||
|
||||
#define FREE(ptr) (void) free(ptr)
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#endif /* !DEFS_H_ */
|
89
usr.sbin/user/group.8
Normal file
89
usr.sbin/user/group.8
Normal file
|
@ -0,0 +1,89 @@
|
|||
.\" $NetBSD: group.8,v 1.17 2005/11/25 08:00:18 agc Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 7, 2005
|
||||
.Dt GROUP 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm group
|
||||
.Nd manage group information on the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm add
|
||||
.Op options
|
||||
.Ar group
|
||||
.Nm
|
||||
.Cm del
|
||||
.Op options
|
||||
.Ar group
|
||||
.Nm
|
||||
.Cm info
|
||||
.Op options
|
||||
.Ar group
|
||||
.Nm
|
||||
.Cm mod
|
||||
.Op options
|
||||
.Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility acts as a frontend to the
|
||||
.Xr groupadd 8 ,
|
||||
.Xr groupmod 8 ,
|
||||
.Xr groupinfo 8 ,
|
||||
and
|
||||
.Xr groupdel 8
|
||||
commands.
|
||||
The utilities by default are built with
|
||||
.Dv EXTENSIONS .
|
||||
This allows for further functionality.
|
||||
.Pp
|
||||
For a full explanation of the options available, please see the relevant manual page.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std group
|
||||
.Sh SEE ALSO
|
||||
.Xr group 5 ,
|
||||
.Xr groupadd 8 ,
|
||||
.Xr groupdel 8 ,
|
||||
.Xr groupinfo 8 ,
|
||||
.Xr groupmod 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
87
usr.sbin/user/groupadd.8
Normal file
87
usr.sbin/user/groupadd.8
Normal file
|
@ -0,0 +1,87 @@
|
|||
.\" $NetBSD: groupadd.8,v 1.17 2006/05/29 01:38:33 hubertf Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 7, 2005
|
||||
.Dt GROUPADD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm groupadd
|
||||
.Nd add a group to the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ov
|
||||
.Op Fl g Ar gid
|
||||
.Op Fl r Ar lowgid Ns Li .. Ns Ar highgid
|
||||
.Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility adds a group to the system.
|
||||
See
|
||||
.Xr group 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl g Ar gid
|
||||
Give the numeric group identifier to be used for the new group.
|
||||
.It Fl o
|
||||
Allow the new group to have a gid which is already in use for
|
||||
another group.
|
||||
.It Fl r Ar lowgid Ns Li .. Ns Ar highgid
|
||||
Set the low and high bounds of a gid range for new groups.
|
||||
A new group can only be created if there are gids which can be
|
||||
assigned inside the range.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl v
|
||||
Enable verbose mode - explain the commands as they are executed.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std groupadd
|
||||
.Sh SEE ALSO
|
||||
.Xr group 5 ,
|
||||
.Xr group 8 ,
|
||||
.Xr user 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
74
usr.sbin/user/groupdel.8
Normal file
74
usr.sbin/user/groupdel.8
Normal file
|
@ -0,0 +1,74 @@
|
|||
.\" $NetBSD: groupdel.8,v 1.14 2006/05/29 01:38:33 hubertf Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 7, 2005
|
||||
.Dt GROUPDEL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm groupdel
|
||||
.Nd remove a group from the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl v
|
||||
.Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility removes a group from the system.
|
||||
See
|
||||
.Xr group 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl v
|
||||
Enable verbose mode - explain the commands as they are executed.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std groupdel
|
||||
.Sh SEE ALSO
|
||||
.Xr group 5 ,
|
||||
.Xr group 8 ,
|
||||
.Xr user 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
90
usr.sbin/user/groupinfo.8
Normal file
90
usr.sbin/user/groupinfo.8
Normal file
|
@ -0,0 +1,90 @@
|
|||
.\" $NetBSD: groupinfo.8,v 1.12 2006/05/29 01:38:33 hubertf Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 7, 2005
|
||||
.Dt GROUPINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm groupinfo
|
||||
.Nd displays group information
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ev
|
||||
.Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility retrieves the group information from the system.
|
||||
The
|
||||
.Nm
|
||||
utility is only available if built with
|
||||
.Dv EXTENSIONS .
|
||||
See
|
||||
.Xr group 8
|
||||
for more information.
|
||||
.Pp
|
||||
The following command line options are recognised:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl e
|
||||
Return 0 if the group exists, and non-zero if the
|
||||
group does not exist, on the system.
|
||||
No information is displayed.
|
||||
This form of the command is useful for
|
||||
scripts which need to check whether a particular group
|
||||
name or gid is already in use on the system.
|
||||
.It Fl v
|
||||
Perform any actions in a verbose manner.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar group
|
||||
argument may either be a group's name, or a gid.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std groupinfo
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/usermgmt.conf -compact
|
||||
.It Pa /etc/usermgmt.conf
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr passwd 5 ,
|
||||
.Xr group 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
83
usr.sbin/user/groupmod.8
Normal file
83
usr.sbin/user/groupmod.8
Normal file
|
@ -0,0 +1,83 @@
|
|||
.\" $NetBSD: groupmod.8,v 1.14 2005/11/25 08:00:18 agc Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 7, 2005
|
||||
.Dt GROUPMOD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm groupmod
|
||||
.Nd modify an existing group on the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl ov
|
||||
.Op Fl g Ar gid
|
||||
.Op Fl n Ar newname
|
||||
.Ar group
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility modifies an existing group on the system.
|
||||
See
|
||||
.Xr group 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl g Ar gid
|
||||
Give the numeric group identifier to be used for the new group.
|
||||
.It Fl n Ar new-group-name
|
||||
Give the new name which the group shall have.
|
||||
.It Fl o
|
||||
Allow the new group to have a gid which is already in use for
|
||||
another group.
|
||||
.It Fl v
|
||||
Enable verbose mode - explain the commands as they are executed.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std groupmod
|
||||
.Sh SEE ALSO
|
||||
.Xr group 5 ,
|
||||
.Xr group 8 ,
|
||||
.Xr user 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
99
usr.sbin/user/main.c
Normal file
99
usr.sbin/user/main.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* $NetBSD: main.c,v 1.5 2006/10/22 21:16:58 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "usermgmt.h"
|
||||
|
||||
enum {
|
||||
MaxCmdWords = 2
|
||||
};
|
||||
|
||||
/* this struct describes a command */
|
||||
typedef struct cmd_t {
|
||||
int c_wc; /* word count */
|
||||
const char *c_word[MaxCmdWords]; /* command words */
|
||||
int (*c_func)(int, char **); /* called function */
|
||||
} cmd_t;
|
||||
|
||||
/* despatch table for commands */
|
||||
static cmd_t cmds[] = {
|
||||
{ 1, { "useradd", NULL }, useradd },
|
||||
{ 2, { "user", "add" }, useradd },
|
||||
{ 1, { "usermod", NULL }, usermod },
|
||||
{ 2, { "user", "mod" }, usermod },
|
||||
{ 1, { "userdel", NULL }, userdel },
|
||||
{ 2, { "user", "del" }, userdel },
|
||||
#ifdef EXTENSIONS
|
||||
{ 1, { "userinfo", NULL }, userinfo },
|
||||
{ 2, { "user", "info" }, userinfo },
|
||||
#endif
|
||||
{ 1, { "groupadd", NULL }, groupadd },
|
||||
{ 2, { "group", "add" }, groupadd },
|
||||
{ 1, { "groupmod", NULL }, groupmod },
|
||||
{ 2, { "group", "mod" }, groupmod },
|
||||
{ 1, { "groupdel", NULL }, groupdel },
|
||||
{ 2, { "group", "del" }, groupdel },
|
||||
#ifdef EXTENSIONS
|
||||
{ 1, { "groupinfo", NULL }, groupinfo },
|
||||
{ 2, { "group", "info" }, groupinfo },
|
||||
#endif
|
||||
{ .c_wc = 0 }
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
cmd_t *cmdp;
|
||||
int matched;
|
||||
int i;
|
||||
|
||||
for (cmdp = cmds ; cmdp->c_wc > 0 ; cmdp++) {
|
||||
for (matched = i = 0 ; i < cmdp->c_wc && i < MaxCmdWords ; i++) {
|
||||
if (argc > i) {
|
||||
if (strcmp((i == 0) ? getprogname() : argv[i],
|
||||
cmdp->c_word[i]) == 0) {
|
||||
matched += 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched == cmdp->c_wc) {
|
||||
return (*cmdp->c_func)(argc - (matched - 1), argv + (matched - 1));
|
||||
}
|
||||
}
|
||||
usermgmt_usage(getprogname());
|
||||
errx(EXIT_FAILURE, "Program `%s' not recognised", getprogname());
|
||||
/* NOTREACHED */
|
||||
}
|
17
usr.sbin/user/out
Normal file
17
usr.sbin/user/out
Normal file
|
@ -0,0 +1,17 @@
|
|||
chown: /home/test1.1/.ashrc: invalid argument
|
||||
chown: /home/test1.1/.ellepro.b1: invalid argument
|
||||
chown: /home/test1.1/.ellepro.e: invalid argument
|
||||
chown: /home/test1.1/.exrc: invalid argument
|
||||
chown: /home/test1.1/.profile: invalid argument
|
||||
chown: /home/test1.1: invalid argument
|
||||
useradd: Error running `/usr/sbin/chown -R -h 4000:4000 /home/test1.1': no such file or directory
|
||||
user: User `test1.2' doesn't own directory `/home/test1.1', not removed
|
||||
user: Can't add user `test1%1': invalid login name
|
||||
usage: useradd -D [-F] [-b base-dir] [-e expiry-time] [-f inactive-time]
|
||||
[-g gid | name | =uid] [-k skel-dir] [-L login-class]
|
||||
[-M homeperm] [-r lowuid..highuid] [-s shell]
|
||||
usage: useradd [-moSv] [-b base-dir] [-c comment] [-d home-dir] [-e expiry-time]
|
||||
[-f inactive-time] [-G secondary-group] [-g gid | name | =uid]
|
||||
[-k skeletondir] [-L login-class] [-M homeperm] [-p password]
|
||||
[-r lowuid..highuid] [-s shell] [-u uid] user
|
||||
user: Can't find user `test1%1'
|
115
usr.sbin/user/user.8
Normal file
115
usr.sbin/user/user.8
Normal file
|
@ -0,0 +1,115 @@
|
|||
.\" $NetBSD: user.8,v 1.23 2005/11/25 08:00:18 agc Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 16, 2005
|
||||
.Dt USER 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm user
|
||||
.Nd manage user login information on the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm add
|
||||
.Fl D
|
||||
.Op options
|
||||
.Nm
|
||||
.Cm add
|
||||
.Op options
|
||||
.Ar user
|
||||
.Nm
|
||||
.Cm del
|
||||
.Fl D
|
||||
.Op options
|
||||
.Nm
|
||||
.Cm del
|
||||
.Op options
|
||||
.Ar user
|
||||
.Nm
|
||||
.Cm info
|
||||
.Op options
|
||||
.Ar user
|
||||
.Nm
|
||||
.Cm mod
|
||||
.Op options
|
||||
.Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility acts as a frontend to the
|
||||
.Xr useradd 8 ,
|
||||
.Xr usermod 8 ,
|
||||
.Xr userinfo 8 ,
|
||||
and
|
||||
.Xr userdel 8
|
||||
commands.
|
||||
The utilities by default are built with
|
||||
.Dv EXTENSIONS .
|
||||
This allows for further functionality.
|
||||
.Pp
|
||||
For a full explanation of the options available, please see the relevant manual page.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std user
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/share/examples/usermgmt -compact
|
||||
.It Pa /etc/skel/.[A-z]*
|
||||
Skeleton files for new user
|
||||
.It Pa /etc/usermgmt.conf
|
||||
Configuration file for
|
||||
.Nm ,
|
||||
.Xr group 8
|
||||
and the backend commands mentioned above.
|
||||
.\" .It Pa /usr/share/examples/usermgmt
|
||||
.\" A directory containing examples for
|
||||
.\" .Nm
|
||||
.\" and
|
||||
.\" .Xr group 8 .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr group 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr usermgmt.conf 5 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8 ,
|
||||
.Xr userinfo 8 ,
|
||||
.Xr usermod 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
2561
usr.sbin/user/user.c
Normal file
2561
usr.sbin/user/user.c
Normal file
File diff suppressed because it is too large
Load diff
318
usr.sbin/user/useradd.8
Normal file
318
usr.sbin/user/useradd.8
Normal file
|
@ -0,0 +1,318 @@
|
|||
.\" $NetBSD: useradd.8,v 1.42 2009/01/14 02:18:28 reed Exp $ */
|
||||
.\"
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd January 13, 2009
|
||||
.Dt USERADD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm useradd
|
||||
.Nd add a user to the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Fl D
|
||||
.Op Fl F
|
||||
.Op Fl b Ar base-dir
|
||||
.Op Fl e Ar expiry-time
|
||||
.Op Fl f Ar inactive-time
|
||||
.Op Fl g Ar gid | name | Li =uid
|
||||
.Op Fl k Ar skel-dir
|
||||
.Op Fl L Ar login-class
|
||||
.Op Fl M Ar home-perm
|
||||
.Op Fl r Ar lowuid Ns Li .. Ns Ar highuid
|
||||
.Op Fl s Ar shell
|
||||
.Nm
|
||||
.Op Fl moSv
|
||||
.Op Fl b Ar base-dir
|
||||
.Op Fl c Ar comment
|
||||
.Op Fl d Ar home-dir
|
||||
.Op Fl e Ar expiry-time
|
||||
.Op Fl f Ar inactive-time
|
||||
.Op Fl G Ar secondary-group
|
||||
.Op Fl g Ar gid | name | Li =uid
|
||||
.Op Fl k Ar skel-dir
|
||||
.Op Fl L Ar login-class
|
||||
.Op Fl M Ar home-perm
|
||||
.Op Fl p Ar password
|
||||
.Op Fl r Ar lowuid Ns Li .. Ns Ar highuid
|
||||
.Op Fl s Ar shell
|
||||
.Op Fl u Ar uid
|
||||
.Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm useradd
|
||||
utility adds a user to the system, creating and
|
||||
populating a home directory if necessary.
|
||||
Any skeleton files will be provided
|
||||
for the new user if they exist in the
|
||||
.Ar skel-dir
|
||||
directory (see the
|
||||
.Fl k
|
||||
option).
|
||||
Default values for
|
||||
the base directory,
|
||||
the time of password expiry,
|
||||
the time of account expiry,
|
||||
primary group,
|
||||
the skeleton directory,
|
||||
the range from which the uid will be allocated,
|
||||
and default login shell
|
||||
can be provided in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file, which, if running as root, is created using the built-in defaults if
|
||||
it does not exist.
|
||||
.Pp
|
||||
The first form of the command shown above (using the
|
||||
.Fl D
|
||||
option)
|
||||
sets and displays the defaults for the
|
||||
.Nm
|
||||
utility.
|
||||
.Pp
|
||||
See
|
||||
.Xr user 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
.Bl -tag -width Ds
|
||||
.It Fl b Ar base-dir
|
||||
Set the default base directory.
|
||||
This is the directory to which the
|
||||
user directory is added, which will be created if the
|
||||
.Fl m
|
||||
option is specified and no
|
||||
.Fl d
|
||||
option is specified.
|
||||
.It Fl D
|
||||
without any further options,
|
||||
.Fl D
|
||||
will show the current defaults which
|
||||
will be used by the
|
||||
.Nm
|
||||
utility.
|
||||
Together with one of the options shown for the first version
|
||||
of the command,
|
||||
.Fl D
|
||||
will set the default to be the new value.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more information.
|
||||
.It Fl e Ar expiry-time
|
||||
Set the time at which the new user accounts will expire.
|
||||
It should be entered in the form
|
||||
.Dq month day year ,
|
||||
where month is the month name (the first three characters are
|
||||
sufficient), day is the day of the month, and year is the year.
|
||||
Time in seconds since the epoch (UTC) is also valid.
|
||||
A value of 0 can be used to disable this feature.
|
||||
.It Fl F
|
||||
Force the user to change their password upon next login.
|
||||
.It Fl f Ar inactive-time
|
||||
Set the time at which passwords for the new user accounts will
|
||||
expire.
|
||||
Also see the
|
||||
.Fl e
|
||||
option above.
|
||||
.It Fl g Ar gid | groupname | Li =uid
|
||||
Set the default group for new users.
|
||||
.It Fl k Ar skel-dir
|
||||
Set the skeleton directory in which to find files with
|
||||
which to populate new users' home directories.
|
||||
.It Fl L Ar login-class
|
||||
Set the default login class for new users.
|
||||
See
|
||||
.Xr login.conf 5
|
||||
for more information on user login classes.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl M Ar home-perm
|
||||
sets the default permissions of the newly created home directory if
|
||||
.Fl m
|
||||
is given.
|
||||
The permission is specified as an octal number, with or without a leading zero.
|
||||
.It Fl r Ar lowuid Ns Li .. Ns Ar highuid
|
||||
Set the low and high bounds of uid ranges for new users.
|
||||
A new user can only be created if there are uids which can be
|
||||
assigned from one of the free ranges.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl s Ar shell
|
||||
Set the default login shell for new users.
|
||||
.El
|
||||
.Pp
|
||||
In the second form of the command,
|
||||
after setting any defaults, and then reading values from
|
||||
.Pa /etc/usermgmt.conf ,
|
||||
the following command line options are processed:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl b Ar base-directory
|
||||
Set the base directory name, in which the user's new home
|
||||
directory will be created, should the
|
||||
.Fl m
|
||||
option be specified.
|
||||
.It Fl c Ar comment
|
||||
Set the comment field (also, for historical reasons known as the
|
||||
GECOS field) which will be added for the user, and typically will include
|
||||
the user's full name, and, perhaps, contact information for the user.
|
||||
.It Fl d Ar home-directory
|
||||
Set the home directory which will be created and populated for the user,
|
||||
should the
|
||||
.Fl m
|
||||
option be specified.
|
||||
.It Fl e Ar expiry-time
|
||||
Set the time at which the current password will expire for new
|
||||
users.
|
||||
It should be entered in the form
|
||||
.Dq month day year ,
|
||||
where month is the month name (the first three characters are
|
||||
sufficient), day is the day of the month, and year is the year.
|
||||
Time in seconds since the epoch (UTC) is also valid.
|
||||
A value of 0 can be used to disable this feature.
|
||||
See
|
||||
.Xr passwd 5
|
||||
for more details.
|
||||
.It Fl f Ar inactive-time
|
||||
Set the time at which new user accounts will expire.
|
||||
Also see the
|
||||
.Fl e
|
||||
option above.
|
||||
.It Fl G Ar secondary-group
|
||||
Add the user to the secondary group
|
||||
.Ar secondary-group
|
||||
in the
|
||||
.Pa /etc/group
|
||||
file.
|
||||
The
|
||||
.Ar secondary-group
|
||||
may be a comma-delimited list for multiple groups.
|
||||
Or the option may be repeated for multiple groups.
|
||||
(16 groups maximum.)
|
||||
.It Fl g Ar gid | name | Li =uid
|
||||
Give the group name or identifier to be used for the new user's primary group.
|
||||
If this is
|
||||
.Ql =uid ,
|
||||
then a uid and gid will be picked which are both unique
|
||||
and the same, and a line added to
|
||||
.Pa /etc/group
|
||||
to describe the new group.
|
||||
.It Fl k Ar skeleton directory
|
||||
Give the skeleton directory in which to find files
|
||||
with which to populate the new user's home directory.
|
||||
.It Fl L Ar login-class
|
||||
Set the login class for the user being created.
|
||||
See
|
||||
.Xr login.conf 5
|
||||
for more information on user login classes.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl M Ar home-perm
|
||||
sets the permissions of the newly created home directory if
|
||||
.Fl m
|
||||
is given.
|
||||
The permission is specified as an octal number, with or without a leading zero.
|
||||
.It Fl m
|
||||
Create a new home directory for the new user.
|
||||
.It Fl o
|
||||
Allow the new user to have a uid which is already in use for another user.
|
||||
.It Fl p Ar password
|
||||
Specify an already-encrypted password for the new user.
|
||||
Encrypted passwords can be generated with
|
||||
.Xr pwhash 1 .
|
||||
The password can be changed later by using
|
||||
.Xr chpass 1
|
||||
or
|
||||
.Xr passwd 1 .
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl S
|
||||
Allow samba user names with a trailing dollar sign to be
|
||||
added to the system.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl s Ar shell
|
||||
Specify the login shell for the new user.
|
||||
.It Fl u Ar uid
|
||||
Specify a uid for the new user.
|
||||
Boundaries for this value can be preset for all users
|
||||
by using the
|
||||
.Ar range
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
.It Fl v
|
||||
Enable verbose mode - explain the commands as they are executed.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Pp
|
||||
Once the information has been verified,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the user database.
|
||||
This is run in the background, and,
|
||||
at very large sites could take several minutes.
|
||||
Until this update
|
||||
is completed, the password file is unavailable for other updates
|
||||
and the new information is not available to programs.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std useradd
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/usermgmt.conf -compact
|
||||
.It Pa /etc/usermgmt.conf
|
||||
.It Pa /etc/skel/*
|
||||
.It Pa /etc/login.conf
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr pwhash 1 ,
|
||||
.Xr group 5 ,
|
||||
.Xr login.conf 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr usermgmt.conf 5 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr user 8 ,
|
||||
.Xr userdel 8 ,
|
||||
.Xr usermod 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
||||
.Pp
|
||||
Support for setting permissions of home directories was added by Hubert Feyrer.
|
168
usr.sbin/user/userdel.8
Normal file
168
usr.sbin/user/userdel.8
Normal file
|
@ -0,0 +1,168 @@
|
|||
.\" $NetBSD: userdel.8,v 1.32 2006/05/29 01:38:33 hubertf Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 16, 2005
|
||||
.Dt USERDEL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm userdel
|
||||
.Nd remove a user from the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Fl D
|
||||
.Op Fl p Ar preserve-value
|
||||
.Nm
|
||||
.Op Fl rSv
|
||||
.Op Fl p Ar preserve-value
|
||||
.Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility removes a user from the system, optionally
|
||||
removing that user's home directory and any subdirectories.
|
||||
.Pp
|
||||
Default values are taken from the information provided in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file, which, if running as root, is created using the built-in
|
||||
defaults if it does not exist.
|
||||
.Pp
|
||||
The first form of the command shown above (using the
|
||||
.Fl D
|
||||
option) sets and displays the defaults for the
|
||||
.Nm
|
||||
utility.
|
||||
.Pp
|
||||
See
|
||||
.Xr user 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
.Bl -tag -width Ds
|
||||
.It Fl D
|
||||
Without any further options,
|
||||
.Fl D
|
||||
will show the current defaults which will be used by the
|
||||
.Nm
|
||||
utility.
|
||||
Together with one of the options shown for the first version
|
||||
of the command,
|
||||
.Fl D
|
||||
will set the default to be the new value.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl p Ar preserve-value
|
||||
Set the preservation value.
|
||||
If this value is one of
|
||||
.Ql true ,
|
||||
.Ql yes ,
|
||||
or a non-zero number, then the user login information will be
|
||||
preserved.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Pp
|
||||
In the second form of the command,
|
||||
after setting any defaults, and then reading values from
|
||||
.Pa /etc/usermgmt.conf ,
|
||||
the following command line options are processed:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl p Ar preserve-value
|
||||
Preserve the user information in the password file,
|
||||
but do not allow the user to login, by switching the
|
||||
password to an
|
||||
.Dq impossible
|
||||
one, and by setting the user's shell to the
|
||||
.Xr nologin 8
|
||||
program.
|
||||
This option can be helpful in preserving a user's
|
||||
files for later use by members of that person's
|
||||
group after the user has moved on.
|
||||
This value can also be set in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file, using the
|
||||
.Ql preserve
|
||||
field.
|
||||
If the field has any of the values
|
||||
.Ql true ,
|
||||
.Ql yes ,
|
||||
or a non-zero number, then user information preservation will take
|
||||
place.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl r
|
||||
Remove the user's home directory, any subdirectories,
|
||||
and any files and other entries in them.
|
||||
.It Fl S
|
||||
Allow a samba user name (with a trailing dollar sign)
|
||||
to be deleted.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl v
|
||||
Perform any actions in a verbose manner.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Pp
|
||||
Once the information has been verified,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the user database.
|
||||
This is run in the background, and,
|
||||
at very large sites could take several minutes.
|
||||
Until this update
|
||||
is completed, the password file is unavailable for other updates
|
||||
and the new information is not available to programs.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std userdel
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/usermgmt.conf -compact
|
||||
.It Pa /etc/usermgmt.conf
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr passwd 5 ,
|
||||
.Xr usermgmt.conf 5 ,
|
||||
.Xr group 8 ,
|
||||
.Xr nologin 8 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr user 8 ,
|
||||
.Xr useradd 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
87
usr.sbin/user/userinfo.8
Normal file
87
usr.sbin/user/userinfo.8
Normal file
|
@ -0,0 +1,87 @@
|
|||
.\" $NetBSD: userinfo.8,v 1.15 2008/02/27 19:12:56 reed Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd November 16, 2005
|
||||
.Dt USERINFO 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm userinfo
|
||||
.Nd displays user information
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl e
|
||||
.Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility retrieves the user information from the system.
|
||||
The
|
||||
.Nm
|
||||
utility is only available if built with
|
||||
.Dv EXTENSIONS .
|
||||
See
|
||||
.Xr user 8
|
||||
for more information.
|
||||
.Pp
|
||||
The following command line option is recognised:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl e
|
||||
Return 0 if the user exists, and non-zero if the
|
||||
user does not exist, on the system.
|
||||
No information is displayed.
|
||||
This form of the command is useful for
|
||||
scripts which need to check whether a particular user
|
||||
name or uid is already in use on the system.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Ar user
|
||||
argument may either be a user's name, or a uid.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std userinfo
|
||||
.Sh SEE ALSO
|
||||
.Xr passwd 5 ,
|
||||
.Xr group 8 ,
|
||||
.Xr user 8 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
155
usr.sbin/user/usermgmt.conf.5
Normal file
155
usr.sbin/user/usermgmt.conf.5
Normal file
|
@ -0,0 +1,155 @@
|
|||
.\" $NetBSD: usermgmt.conf.5,v 1.7 2009/12/31 20:14:19 wiz Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This document is derived from works contributed to The NetBSD Foundation
|
||||
.\" by Grant Beattie.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd December 31, 2009
|
||||
.Dt USERMGMT.CONF 5
|
||||
.Os
|
||||
.\" turn off hyphenation
|
||||
.hym 999
|
||||
.Sh NAME
|
||||
.Nm usermgmt.conf
|
||||
.Nd user management tools configuration file
|
||||
.Sh SYNOPSIS
|
||||
.Nm usermgmt.conf
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm usermgmt.conf
|
||||
file defines the default values used by the user management tools,
|
||||
.Xr useradd 8
|
||||
and friends.
|
||||
.Pp
|
||||
Options in this file can be set by manually editing
|
||||
.Pa /etc/usermgmt.conf
|
||||
or using the
|
||||
.Fl D
|
||||
option to
|
||||
.Xr useradd 8 .
|
||||
.Pp
|
||||
.Bl -tag -width preserveX
|
||||
.It Ic base_dir
|
||||
sets the base directory name, in which new users' home directories
|
||||
are created when using the
|
||||
.Fl m
|
||||
option to
|
||||
.Xr useradd 8 .
|
||||
.It Ic class
|
||||
sets the default login class for new users.
|
||||
See
|
||||
.Xr login.conf 5
|
||||
for more information on user login classes.
|
||||
.It Ic expire
|
||||
sets the default time at which the current password expires.
|
||||
This can be used to implement password aging.
|
||||
Both the
|
||||
.Ar expire
|
||||
and
|
||||
.Ar inactive
|
||||
fields should be entered in the form
|
||||
.Dq month day year ,
|
||||
where month is the month name (the first three characters are
|
||||
sufficient), day is the day of the month, and year is the year.
|
||||
Time in seconds since the epoch (UTC) is also valid.
|
||||
A value of 0 can be used to disable this feature.
|
||||
.It Ic group
|
||||
sets the default primary group for new users.
|
||||
If this is
|
||||
.Ql =uid ,
|
||||
then a uid and gid will be picked which are both unique
|
||||
and the same, and a line will be added to
|
||||
.Pa /etc/group
|
||||
to describe the new group.
|
||||
It has the format:
|
||||
.br
|
||||
.Bd -ragged -offset indent -compact
|
||||
.Ic group
|
||||
.Ar gid | name | Li =uid
|
||||
.Ed
|
||||
.It Ic homeperm
|
||||
sets the default permissions of the newly created home directory if
|
||||
.Fl m
|
||||
is given to
|
||||
.Xr useradd 8 .
|
||||
The permission is specified as an octal number, with or without a leading zero.
|
||||
.It Ic inactive
|
||||
sets the default time at which new accounts expire.
|
||||
A value of 0 can be used to disable this feature.
|
||||
Also see the
|
||||
.Ar expire
|
||||
field.
|
||||
.It Ic password
|
||||
specifies an already-encrypted default password.
|
||||
.It Ic preserve
|
||||
If this value is one of
|
||||
.Ql true ,
|
||||
.Ql yes ,
|
||||
or a non-zero number, then the user login information will be
|
||||
preserved when removing a user with
|
||||
.Xr userdel 8 .
|
||||
.It Ic range
|
||||
specifies the uid boundaries for new users.
|
||||
If unspecified, the default is
|
||||
.Dq 1000..60000 .
|
||||
It has the format:
|
||||
.Bd -unfilled -offset indent -compact
|
||||
.Ic range Ar starting-uid Ns Li .. Ns Ar ending-uid
|
||||
.Ed
|
||||
.It Ic gid_range
|
||||
specifies the gid boundaries for new groups.
|
||||
If unspecified, the default is
|
||||
.Dq 1000..60000 .
|
||||
It has the format:
|
||||
.Bd -unfilled -offset indent -compact
|
||||
.Ic gid_range Ar starting-gid Ns Li .. Ns Ar ending-gid
|
||||
.Ed
|
||||
.It Ic shell
|
||||
sets the default login shell for new users.
|
||||
.It Ic skel_dir
|
||||
sets the default skeleton directory in which to find files
|
||||
with which to populate the new user's home directory.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/usermgmt.conf -compact
|
||||
.It Pa /etc/usermgmt.conf
|
||||
.It Pa /etc/skel/*
|
||||
.It Pa /etc/login.conf
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr login.conf 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr user 8 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8 ,
|
||||
.Xr usermod 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
configuration file first appeared in
|
||||
.Nx 1.5 .
|
47
usr.sbin/user/usermgmt.h
Normal file
47
usr.sbin/user/usermgmt.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/* $NetBSD: usermgmt.h,v 1.8 2005/11/25 08:00:18 agc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef USERMGMT_H_
|
||||
#define USERMGMT_H_
|
||||
|
||||
int useradd(int, char **);
|
||||
int usermod(int, char **);
|
||||
int userdel(int, char **);
|
||||
int groupadd(int, char **);
|
||||
int groupdel(int, char **);
|
||||
int groupmod(int, char **);
|
||||
|
||||
#ifdef EXTENSIONS
|
||||
int userinfo(int, char **);
|
||||
int groupinfo(int, char **);
|
||||
#endif
|
||||
|
||||
void usermgmt_usage(const char *);
|
||||
|
||||
#endif
|
259
usr.sbin/user/usermod.8
Normal file
259
usr.sbin/user/usermod.8
Normal file
|
@ -0,0 +1,259 @@
|
|||
.\" $NetBSD: usermod.8,v 1.32 2009/03/11 17:54:03 dyoung Exp $ */
|
||||
.\"
|
||||
.\" Copyright (c) 1999 Alistair G. Crooks. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote
|
||||
.\" products derived from this software without specific prior written
|
||||
.\" permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
.\" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\"
|
||||
.Dd January 13, 2009
|
||||
.Dt USERMOD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm usermod
|
||||
.Nd modify user login information
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl FmoSv
|
||||
.Op Fl C Ar yes/no
|
||||
.Op Fl c Ar comment
|
||||
.Op Fl d Ar home-dir
|
||||
.Op Fl e Ar expiry-time
|
||||
.Op Fl f Ar inactive-time
|
||||
.Op Fl G Ar secondary-group
|
||||
.Op Fl g Ar gid | name | Li =uid
|
||||
.Op Fl L Ar login-class
|
||||
.Op Fl l Ar new-login
|
||||
.Op Fl p Ar password
|
||||
.Op Fl s Ar shell
|
||||
.Op Fl u Ar uid
|
||||
.Ar user
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility modifies user login information on the system.
|
||||
.Pp
|
||||
Default values are taken from the information provided in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file, which, if running as root, is created using the built-in defaults if
|
||||
it does not exist.
|
||||
.Pp
|
||||
See
|
||||
.Xr user 8
|
||||
for more information about
|
||||
.Dv EXTENSIONS .
|
||||
.Pp
|
||||
After setting any defaults, and then reading values from
|
||||
.Pa /etc/usermgmt.conf ,
|
||||
the following command line options are processed:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl C Ar yes/no
|
||||
Enable user accounts to be temporary locked/closed.
|
||||
The
|
||||
.Ar yes/no
|
||||
operand can be given as
|
||||
.Dq Ar yes
|
||||
to lock the account or
|
||||
.Dq Ar no
|
||||
to unlock the account.
|
||||
.It Fl c Ar comment
|
||||
Set the comment field (also, for historical reasons known as the
|
||||
GECOS field) for the user.
|
||||
The comment field will typically include
|
||||
the user's full name and, perhaps, contact information for the user.
|
||||
.It Fl d Ar home-directory
|
||||
Set the home directory without populating it; if the
|
||||
.Fl m
|
||||
option is specified, tries to move the old home directory to
|
||||
.Ar home-directory .
|
||||
.It Fl e Ar expiry-time
|
||||
Set the time at which the account expires.
|
||||
This can be used to implement password aging.
|
||||
It should be entered in the form
|
||||
.Dq month day year ,
|
||||
where month is the month name (the first three characters are
|
||||
sufficient), day is the day of the month, and year is the year.
|
||||
Time in seconds since the epoch (UTC) is also valid.
|
||||
A value of 0 can be used to disable this feature.
|
||||
This value can be preset for all users using the
|
||||
.Ar expire
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
.It Fl F
|
||||
Force the user to change their password upon next login.
|
||||
.It Fl f Ar inactive-time
|
||||
Set the time at which the password expires.
|
||||
See the
|
||||
.Fl e
|
||||
option.
|
||||
.It Fl G Ar secondary-group
|
||||
Specify a secondary group to which the user will be added in the
|
||||
.Pa /etc/group
|
||||
file.
|
||||
The
|
||||
.Ar secondary-group
|
||||
may be a comma-delimited list for multiple groups.
|
||||
Or the option may be repeated for multiple groups.
|
||||
(16 groups maximum.)
|
||||
.It Fl g Ar gid | name | Li =uid
|
||||
Give the group name or identifier to be used for the user's primary group.
|
||||
If this is
|
||||
.Ql =uid ,
|
||||
then a uid and gid will be picked which are both unique
|
||||
and the same, and a line will be added to
|
||||
.Pa /etc/group
|
||||
to describe the new group.
|
||||
This value can be preset for all users by using the
|
||||
.Ar group
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
.It Fl L Ar login-class
|
||||
Set the login class for the user.
|
||||
See
|
||||
.Xr login.conf 5
|
||||
for more information on user login classes.
|
||||
This value can be preset for all users by using the
|
||||
.Ar class
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl l Ar new-user
|
||||
Give the new user name.
|
||||
It can consist of alphanumeric characters and the characters
|
||||
.Ql \&. ,
|
||||
.Ql \&- ,
|
||||
and
|
||||
.Ql \&_ .
|
||||
.It Fl m
|
||||
Move the home directory from its old position to the new one.
|
||||
If
|
||||
.Fl d
|
||||
is not specified, the
|
||||
.Ar new-user
|
||||
argument of the
|
||||
.Fl l
|
||||
option is used; one of
|
||||
.Fl d
|
||||
and
|
||||
.Fl l
|
||||
is needed.
|
||||
.It Fl o
|
||||
Allow duplicate uids to be given.
|
||||
.It Fl p Ar password
|
||||
Specify an already-encrypted password for the user.
|
||||
This password can then be changed by using the
|
||||
.Xr chpass 1
|
||||
utility.
|
||||
This value can be preset for all users by using the
|
||||
.Ar password
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl S
|
||||
Allow samba user names with a trailing dollar sign to be modified.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.It Fl s Ar shell
|
||||
Specify the login shell for the user.
|
||||
This value can be preset for all users by using the
|
||||
.Ar shell
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
.It Fl u Ar uid
|
||||
Specify a new uid for the user.
|
||||
Boundaries for this value can be preset for all users by using the
|
||||
.Ar range
|
||||
field in the
|
||||
.Pa /etc/usermgmt.conf
|
||||
file.
|
||||
See
|
||||
.Xr usermgmt.conf 5
|
||||
for more details.
|
||||
.It Fl v
|
||||
Enable verbose mode - explain the commands as they are executed.
|
||||
This option is included if built with
|
||||
.Dv EXTENSIONS .
|
||||
.El
|
||||
.Pp
|
||||
Once the information has been verified,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the user database.
|
||||
This is run in the background.
|
||||
At very large sites this can take several minutes.
|
||||
Until this update
|
||||
is completed, the password file is unavailable for other updates
|
||||
and the new information is not available to programs.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std usermod
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/usermgmt.conf -compact
|
||||
.It Pa /etc/usermgmt.conf
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr group 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr usermgmt.conf 5 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr user 8 ,
|
||||
.Xr useradd 8 ,
|
||||
.Xr userdel 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
utility first appeared in
|
||||
.Nx 1.5 .
|
||||
It is based on the
|
||||
.Ar addnerd
|
||||
package by the same author.
|
||||
.Sh AUTHORS
|
||||
The
|
||||
.Nm
|
||||
utility was written by
|
||||
.An Alistair G. Crooks
|
||||
.Aq agc@NetBSD.org .
|
10
usr.sbin/vipw/Makefile
Normal file
10
usr.sbin/vipw/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
# $NetBSD: Makefile,v 1.5 1996/05/15 23:23:45 jtc Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/6/93
|
||||
|
||||
PROG= vipw
|
||||
SRCS= vipw.c
|
||||
DPADD= ${LIBUTIL}
|
||||
LDADD= -lutil
|
||||
MAN= vipw.8
|
||||
|
||||
.include <bsd.prog.mk>
|
122
usr.sbin/vipw/vipw.8
Normal file
122
usr.sbin/vipw/vipw.8
Normal file
|
@ -0,0 +1,122 @@
|
|||
.\" $NetBSD: vipw.8,v 1.15 2005/09/05 03:37:15 hubertf Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)vipw.8 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.Dd September 4, 2005
|
||||
.Dt VIPW 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm vipw
|
||||
.Nd edit the password file
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Bk -words
|
||||
.Op Fl d Ar directory
|
||||
.Ek
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
edits the password file after setting the appropriate locks,
|
||||
and does any necessary processing after the password file is unlocked.
|
||||
If the password file is already locked for editing by another user,
|
||||
.Nm
|
||||
will ask you
|
||||
to try again later. The default editor for
|
||||
.Nm
|
||||
is
|
||||
.Xr vi 1 .
|
||||
.Pp
|
||||
.Nm
|
||||
performs a number of consistency checks on the password entries,
|
||||
and will not allow a password file with a
|
||||
.Dq mangled
|
||||
entry to be
|
||||
installed.
|
||||
If
|
||||
.Nm
|
||||
rejects the new password file, the user is prompted to re-enter
|
||||
the edit session.
|
||||
.Pp
|
||||
Once the information has been verified,
|
||||
.Nm
|
||||
uses
|
||||
.Xr pwd_mkdb 8
|
||||
to update the user database. This is run in the background, and,
|
||||
at very large sites could take several minutes. Until this update
|
||||
is completed, the password file is unavailable for other updates
|
||||
and the new information is not available to programs.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width flag
|
||||
.It Fl d Ar directory
|
||||
Change the root directory of the password file from
|
||||
.Dq Pa /
|
||||
to
|
||||
.Ar directory .
|
||||
.El
|
||||
.Pp
|
||||
If a
|
||||
.Nm
|
||||
session is killed it may leave
|
||||
.Dq Pa /etc/ptmp ,
|
||||
which will cause future
|
||||
.Nm
|
||||
executions to fail with
|
||||
.Dq Pa vipw: the passwd file is busy ,
|
||||
until it is removed.
|
||||
.Sh ENVIRONMENT
|
||||
If the following environment variable exists it will be used by
|
||||
.Nm :
|
||||
.Bl -tag -width EDITOR
|
||||
.It Ev EDITOR
|
||||
The editor specified by the string
|
||||
.Ev EDITOR
|
||||
will be invoked instead of the default editor
|
||||
.Xr vi 1 .
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width Pa -compact
|
||||
.It Pa /etc/master.passwd
|
||||
The current password file.
|
||||
.It Pa /etc/ptmp
|
||||
Temporary copy of the password file used while editing.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr chpass 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr pwhash 1 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr passwd.conf 5 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr user 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Bx 4.0 .
|
150
usr.sbin/vipw/vipw.c
Normal file
150
usr.sbin/vipw/vipw.c
Normal file
|
@ -0,0 +1,150 @@
|
|||
/* $NetBSD: vipw.c,v 1.14 2009/04/19 00:44:49 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__COPYRIGHT("@(#) Copyright (c) 1987, 1993, 1994\
|
||||
The Regents of the University of California. All rights reserved.");
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)vipw.c 8.3 (Berkeley) 4/2/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: vipw.c,v 1.14 2009/04/19 00:44:49 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <util.h>
|
||||
|
||||
int main __P((int, char **));
|
||||
static void copyfile __P((int, int));
|
||||
static void usage __P((void));
|
||||
|
||||
char mpwd[MAXPATHLEN], mpwdl[MAXPATHLEN];
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *prefix;
|
||||
int pfd, tfd;
|
||||
struct stat begin, end;
|
||||
int ch;
|
||||
|
||||
prefix = "";
|
||||
while ((ch = getopt(argc, argv, "d:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
prefix = optarg;
|
||||
if (pw_setprefix(prefix) < 0)
|
||||
err(1, "%s", prefix);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 0)
|
||||
usage();
|
||||
|
||||
(void)snprintf(mpwd, sizeof(mpwd), "%s%s", prefix, _PATH_MASTERPASSWD);
|
||||
(void)snprintf(mpwdl, sizeof(mpwdl), "%s%s", prefix,
|
||||
_PATH_MASTERPASSWD_LOCK);
|
||||
|
||||
pw_init();
|
||||
tfd = pw_lock(0);
|
||||
if (tfd < 0) {
|
||||
if (errno == EEXIST)
|
||||
errx(1, "the passwd file is busy.");
|
||||
else
|
||||
err(1, "%s", mpwdl);
|
||||
}
|
||||
|
||||
pfd = open(mpwd, O_RDONLY, 0);
|
||||
if (pfd < 0)
|
||||
pw_error(mpwd, 1, 1);
|
||||
copyfile(pfd, tfd);
|
||||
(void)close(tfd);
|
||||
|
||||
for (;;) {
|
||||
if (stat(mpwdl, &begin))
|
||||
pw_error(mpwdl, 1, 1);
|
||||
pw_edit(0, NULL);
|
||||
if (stat(mpwdl, &end))
|
||||
pw_error(mpwdl, 1, 1);
|
||||
if (begin.st_mtime == end.st_mtime &&
|
||||
begin.st_mtimensec == end.st_mtimensec) {
|
||||
warnx("no changes made");
|
||||
pw_error((char *)NULL, 0, 0);
|
||||
}
|
||||
if (pw_mkdb(NULL, 0) == 0)
|
||||
break;
|
||||
pw_prompt();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
copyfile(int from, int to)
|
||||
{
|
||||
int nr, nw, off;
|
||||
char buf[8*1024];
|
||||
|
||||
while ((nr = read(from, buf, sizeof(buf))) > 0)
|
||||
for (off = 0; off < nr; nr -= nw, off += nw)
|
||||
if ((nw = write(to, buf + off, nr)) < 0)
|
||||
pw_error(mpwdl, 1, 1);
|
||||
if (nr < 0)
|
||||
pw_error(mpwd, 1, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "usage: %s [-d directory]\n", getprogname());
|
||||
exit(1);
|
||||
}
|
Loading…
Reference in a new issue