static char locked_str[] = "*LOCKED*";
static int delete_user(struct userconf *cnf, struct passwd *pwd,
- struct carg *a_name, int delete, int mode);
-static int print_user(struct passwd * pwd, int pretty, int v7);
-static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args);
-static uid_t pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer);
+ char *name, int delete, int mode);
+static int print_user(struct passwd * pwd);
+static uid_t pw_uidpolicy(struct userconf * cnf, long id);
+static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer);
static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args);
static time_t pw_exppolicy(struct userconf * cnf, struct cargs * args);
static char *pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user);
static void rmopie(char const * name);
static void
-create_and_populate_homedir(int mode, struct cargs *args, struct passwd *pwd,
- struct userconf *cnf)
+create_and_populate_homedir(int mode, struct passwd *pwd)
{
char *homedir, *dotdir;
- struct carg *arg;
+ struct userconf *cnf = conf.userconf;
homedir = dotdir = NULL;
- if ((arg = getarg(args, 'R'))) {
- asprintf(&homedir, "%s/%s", arg->val, pwd->pw_dir);
+ if (conf.rootdir[0] != '\0') {
+ asprintf(&homedir, "%s/%s", conf.rootdir, pwd->pw_dir);
if (homedir == NULL)
errx(EX_OSERR, "out of memory");
- asprintf(&dotdir, "%s/%s", arg->val, cnf->dotdir);
+ asprintf(&dotdir, "%s/%s", conf.rootdir, cnf->dotdir);
}
copymkdir(homedir ? homedir : pwd->pw_dir, dotdir ? dotdir: cnf->dotdir,
*/
int
-pw_user(struct userconf * cnf, int mode, struct cargs * args)
+pw_user(int mode, char *name, long id, struct cargs * args)
{
int rc, edited = 0;
char *p = NULL;
char *passtmp;
- struct carg *a_name;
- struct carg *a_uid;
struct carg *arg;
struct passwd *pwd = NULL;
struct group *grp;
struct stat st;
+ struct userconf *cnf;
char line[_PASSWORD_LEN+1];
char path[MAXPATHLEN];
FILE *fp;
#endif
};
+ cnf = conf.userconf;
/*
* With M_NEXT, we only need to return the
* next uid to stdout
*/
- if (mode == M_NEXT)
- {
- uid_t next = pw_uidpolicy(cnf, args);
- if (getarg(args, 'q'))
- return next;
- printf("%u:", next);
- pw_group(cnf, mode, args);
- return EXIT_SUCCESS;
+ if (mode == M_NEXT) {
+ printf("%u:", pw_uidpolicy(cnf, id));
+ pw_group(mode, name, -1, args);
+ return (EXIT_SUCCESS);
}
/*
if ((arg = getarg(args, 'w')) != NULL)
cnf->default_password = boolean_val(arg->val, cnf->default_password);
if (mode == M_ADD && getarg(args, 'D')) {
- if (getarg(args, 'n') != NULL)
+ if (name != NULL)
errx(EX_DATAERR, "can't combine `-D' with `-n name'");
if ((arg = getarg(args, 'u')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) {
if ((cnf->min_uid = (uid_t) atoi(p)) == 0)
cnf->max_gid = 32000;
}
- arg = getarg(args, 'C');
- if (write_userconfig(arg ? arg->val : NULL))
- return EXIT_SUCCESS;
+ if (write_userconfig(conf.config))
+ return (EXIT_SUCCESS);
err(EX_IOERR, "config udpate");
}
if (mode == M_PRINT && getarg(args, 'a')) {
- int pretty = getarg(args, 'P') != NULL;
- int v7 = getarg(args, '7') != NULL;
SETPWENT();
while ((pwd = GETPWENT()) != NULL)
- print_user(pwd, pretty, v7);
+ print_user(pwd);
ENDPWENT();
return EXIT_SUCCESS;
}
- if ((a_name = getarg(args, 'n')) != NULL)
- pwd = GETPWNAM(pw_checkname(a_name->val, 0));
- a_uid = getarg(args, 'u');
+ if (name != NULL)
+ pwd = GETPWNAM(pw_checkname(name, 0));
- if (a_uid == NULL) {
- if (a_name == NULL)
- errx(EX_DATAERR, "user name or id required");
-
- /*
- * Determine whether 'n' switch is name or uid - we don't
- * really don't really care which we have, but we need to
- * know.
- */
- if (mode != M_ADD && pwd == NULL
- && strspn(a_name->val, "0123456789") == strlen(a_name->val)
- && *a_name->val) {
- (a_uid = a_name)->ch = 'u';
- a_name = NULL;
- }
- } else {
- if (strspn(a_uid->val, "0123456789") != strlen(a_uid->val))
- errx(EX_USAGE, "-u expects a number");
- }
+ if (id < 0 && name == NULL)
+ errx(EX_DATAERR, "user name or id required");
/*
* Update, delete & print require that the user exists
if (mode == M_UPDATE || mode == M_DELETE ||
mode == M_PRINT || mode == M_LOCK || mode == M_UNLOCK) {
- if (a_name == NULL && pwd == NULL) /* Try harder */
- pwd = GETPWUID(atoi(a_uid->val));
+ if (name == NULL && pwd == NULL) /* Try harder */
+ pwd = GETPWUID(id);
if (pwd == NULL) {
if (mode == M_PRINT && getarg(args, 'F')) {
- fakeuser.pw_name = a_name ? a_name->val : "nouser";
- fakeuser.pw_uid = a_uid ? (uid_t) atol(a_uid->val) : (uid_t) -1;
- return print_user(&fakeuser,
- getarg(args, 'P') != NULL,
- getarg(args, '7') != NULL);
+ fakeuser.pw_name = name ? name : "nouser";
+ fakeuser.pw_uid = (uid_t) id;
+ return print_user(&fakeuser);
}
- if (a_name == NULL)
- errx(EX_NOUSER, "no such uid `%s'", a_uid->val);
- errx(EX_NOUSER, "no such user `%s'", a_name->val);
+ if (name == NULL)
+ errx(EX_NOUSER, "no such uid `%ld'", id);
+ errx(EX_NOUSER, "no such user `%s'", name);
}
- if (a_name == NULL) /* May be needed later */
- a_name = addarg(args, 'n', newstr(pwd->pw_name));
+ if (name == NULL)
+ name = pwd->pw_name;
/*
* The M_LOCK and M_UNLOCK functions simply add or remove
pwd->pw_passwd += sizeof(locked_str)-1;
edited = 1;
} else if (mode == M_DELETE)
- return (delete_user(cnf, pwd, a_name,
+ return (delete_user(cnf, pwd, name,
getarg(args, 'r') != NULL, mode));
else if (mode == M_PRINT)
- return print_user(pwd,
- getarg(args, 'P') != NULL,
- getarg(args, '7') != NULL);
+ return print_user(pwd);
/*
* The rest is edit code
*/
- if ((arg = getarg(args, 'l')) != NULL) {
+ if (conf.newname != NULL) {
if (strcmp(pwd->pw_name, "root") == 0)
errx(EX_DATAERR, "can't rename `root' account");
- pwd->pw_name = pw_checkname(arg->val, 0);
+ pwd->pw_name = pw_checkname(conf.newname, 0);
edited = 1;
}
- if ((arg = getarg(args, 'u')) != NULL && isdigit((unsigned char)*arg->val)) {
- pwd->pw_uid = (uid_t) atol(arg->val);
+ if (id > 0 && isdigit((unsigned char)*arg->val)) {
+ pwd->pw_uid = (uid_t)id;
edited = 1;
if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0)
errx(EX_DATAERR, "can't change uid of `root' account");
* Add code
*/
- if (a_name == NULL) /* Required */
+ if (name == NULL) /* Required */
errx(EX_DATAERR, "login name required");
- else if ((pwd = GETPWNAM(a_name->val)) != NULL) /* Exists */
- errx(EX_DATAERR, "login name `%s' already exists", a_name->val);
+ else if ((pwd = GETPWNAM(name)) != NULL) /* Exists */
+ errx(EX_DATAERR, "login name `%s' already exists", name);
/*
* Now, set up defaults for a new user
*/
pwd = &fakeuser;
- pwd->pw_name = a_name->val;
+ pwd->pw_name = name;
pwd->pw_class = cnf->default_class ? cnf->default_class : "";
- pwd->pw_uid = pw_uidpolicy(cnf, args);
- pwd->pw_gid = pw_gidpolicy(cnf, args, pwd->pw_name, (gid_t) pwd->pw_uid);
+ pwd->pw_uid = pw_uidpolicy(cnf, id);
+ pwd->pw_gid = pw_gidpolicy(args, pwd->pw_name, (gid_t) pwd->pw_uid);
pwd->pw_change = pw_pwdpolicy(cnf, args);
pwd->pw_expire = pw_exppolicy(cnf, args);
pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name);
/*
* Special case: -N only displays & exits
*/
- if (getarg(args, 'N') != NULL)
- return print_user(pwd,
- getarg(args, 'P') != NULL,
- getarg(args, '7') != NULL);
+ if (conf.dryrun)
+ return print_user(pwd);
if (mode == M_ADD) {
edited = 1; /* Always */
}
} else if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) {
if (edited) { /* Only updated this if required */
- rc = chgpwent(a_name->val, pwd);
+ rc = chgpwent(name, pwd);
if (rc == -1)
errx(EX_IOERR, "user '%s' does not exist (NIS?)", pwd->pw_name);
else if (rc != 0)
err(EX_IOERR, "passwd file update");
if ( cnf->nispasswd && *cnf->nispasswd=='/') {
- rc = chgnispwent(cnf->nispasswd, a_name->val, pwd);
+ rc = chgnispwent(cnf->nispasswd, name, pwd);
if (rc == -1)
warn("User '%s' not found in NIS passwd", pwd->pw_name);
else
/* go get a current version of pwd */
- pwd = GETPWNAM(a_name->val);
+ pwd = GETPWNAM(name);
if (pwd == NULL) {
/* This will fail when we rename, so special case that */
- if (mode == M_UPDATE && (arg = getarg(args, 'l')) != NULL) {
- a_name->val = arg->val; /* update new name */
- pwd = GETPWNAM(a_name->val); /* refetch renamed rec */
+ if (mode == M_UPDATE && conf.newname != NULL) {
+ name = conf.newname; /* update new name */
+ pwd = GETPWNAM(name); /* refetch renamed rec */
}
}
if (pwd == NULL) /* can't go on without this */
- errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val);
+ errx(EX_NOUSER, "user '%s' disappeared during update", name);
grp = GETGRGID(pwd->pw_gid);
pw_log(cnf, mode, W_USER, "%s(%u):%s(%u):%s:%s:%s",
*/
if (PWALTDIR() != PWF_ALT && getarg(args, 'm') != NULL && pwd->pw_dir &&
*pwd->pw_dir == '/' && pwd->pw_dir[1])
- create_and_populate_homedir(mode, args, pwd, cnf);
+ create_and_populate_homedir(mode, pwd);
/*
* Finally, send mail to the new user as well, if we are asked to
static uid_t
-pw_uidpolicy(struct userconf * cnf, struct cargs * args)
+pw_uidpolicy(struct userconf * cnf, long id)
{
struct passwd *pwd;
uid_t uid = (uid_t) - 1;
- struct carg *a_uid = getarg(args, 'u');
/*
* Check the given uid, if any
*/
- if (a_uid != NULL) {
- uid = (uid_t) atol(a_uid->val);
+ if (id > 0) {
+ uid = (uid_t) id;
- if ((pwd = GETPWUID(uid)) != NULL && getarg(args, 'o') == NULL)
+ if ((pwd = GETPWUID(uid)) != NULL && conf.checkduplicate)
errx(EX_DATAERR, "uid `%u' has already been allocated", pwd->pw_uid);
} else {
struct bitmap bm;
static uid_t
-pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer)
+pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer)
{
struct group *grp;
gid_t gid = (uid_t) - 1;
struct carg *a_gid = getarg(args, 'g');
+ struct userconf *cnf = conf.userconf;
/*
* If no arg given, see if default can help out
char tmp[32];
LIST_INIT(&grpargs);
- addarg(&grpargs, 'n', nam);
/*
* We need to auto-create a group with the user's name. We
snprintf(tmp, sizeof(tmp), "%u", prefer);
addarg(&grpargs, 'g', tmp);
}
- if (getarg(args, 'N'))
- {
- addarg(&grpargs, 'N', NULL);
+ if (conf.dryrun) {
addarg(&grpargs, 'q', NULL);
- gid = pw_group(cnf, M_NEXT, &grpargs);
+ gid = pw_group(M_NEXT, nam, -1, &grpargs);
}
else
{
- pw_group(cnf, M_ADD, &grpargs);
+ pw_group(M_ADD, nam, -1, &grpargs);
if ((grp = GETGRNAM(nam)) != NULL)
gid = grp->gr_gid;
}
* We give this information back to the user
*/
if (getarg(args, 'h') == NULL && getarg(args, 'H') == NULL &&
- getarg(args, 'N') == NULL) {
+ !conf.dryrun) {
if (isatty(STDOUT_FILENO))
printf("Password for '%s' is: ", user);
printf("%s\n", pwbuf);
}
static int
-delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name,
+delete_user(struct userconf *cnf, struct passwd *pwd, char *name,
int delete, int mode)
{
char file[MAXPATHLEN];
err(EX_IOERR, "passwd update");
if (cnf->nispasswd && *cnf->nispasswd=='/') {
- rc = delnispwent(cnf->nispasswd, a_name->val);
+ rc = delnispwent(cnf->nispasswd, name);
if (rc == -1)
warnx("WARNING: user '%s' does not exist in NIS passwd", pwd->pw_name);
else if (rc != 0)
/* non-fatal */
}
- grp = GETGRNAM(a_name->val);
+ grp = GETGRNAM(name);
if (grp != NULL &&
(grp->gr_mem == NULL || *grp->gr_mem == NULL) &&
- strcmp(a_name->val, grname) == 0)
- delgrent(GETGRNAM(a_name->val));
+ strcmp(name, grname) == 0)
+ delgrent(GETGRNAM(name));
SETGRENT();
while ((grp = GETGRENT()) != NULL) {
int i, j;
continue;
for (i = 0; grp->gr_mem[i] != NULL; i++) {
- if (strcmp(grp->gr_mem[i], a_name->val))
+ if (strcmp(grp->gr_mem[i], name) != 0)
continue;
for (j = i; grp->gr_mem[j] != NULL; j++)
}
ENDGRENT();
- pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid);
+ pw_log(cnf, mode, W_USER, "%s(%u) account removed", name, uid);
- if (PWALTDIR()) {
+ if (!PWALTDIR()) {
/*
* Remove mail file
*/
stat(home, &st) != -1) {
rm_r(home, uid);
pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved",
- a_name->val, uid, home,
+ name, uid, home,
stat(home, &st) == -1 ? "" : "not completely ");
}
}
}
static int
-print_user(struct passwd * pwd, int pretty, int v7)
+print_user(struct passwd * pwd)
{
- if (!pretty) {
+ if (!conf.pretty) {
char *buf;
- if (!v7)
- pwd->pw_passwd = (pwd->pw_passwd == NULL) ? "" : "*";
-
- buf = v7 ? pw_make_v7(pwd) : pw_make(pwd);
+ buf = conf.v7 ? pw_make_v7(pwd) : pw_make(pwd);
printf("%s\n", buf);
free(buf);
} else {