diff options
author | davidn <davidn@FreeBSD.org> | 1999-02-23 07:15:11 +0000 |
---|---|---|
committer | davidn <davidn@FreeBSD.org> | 1999-02-23 07:15:11 +0000 |
commit | aea1f6bc3cb4963dbd48dcd9f051919520f70f2b (patch) | |
tree | b3bd7501edb165799eda61bf2ac5d8202c789a5d /usr.sbin/pw/pw_user.c | |
parent | f6416f79a6b9a2eb5c485e8af421d3d570a95d25 (diff) | |
download | FreeBSD-src-aea1f6bc3cb4963dbd48dcd9f051919520f70f2b.zip FreeBSD-src-aea1f6bc3cb4963dbd48dcd9f051919520f70f2b.tar.gz |
1) Do not blindly ignore file update errors which may occur due to concurrent
updating
2) Add -V <etcdir>, which allows maintaining user/group database in alternate
locations other than /etc.
Diffstat (limited to 'usr.sbin/pw/pw_user.c')
-rw-r--r-- | usr.sbin/pw/pw_user.c | 172 |
1 files changed, 89 insertions, 83 deletions
diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index d339381..635b530 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -22,11 +22,12 @@ * 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 lint static const char rcsid[] = - "$Id: pw_user.c,v 1.25 1999/01/04 14:07:53 billf Exp $"; + "$Id: pw_user.c,v 1.26 1999/02/08 21:26:44 des Exp $"; #endif /* not lint */ #include <ctype.h> @@ -46,7 +47,6 @@ static const char rcsid[] = #endif #include "pw.h" #include "bitmap.h" -#include "pwupd.h" #if (MAXLOGNAME-1) > UT_NAMESIZE #define LOGNAMESIZE UT_NAMESIZE @@ -215,8 +215,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if ((arg = getarg(args, 'g')) != NULL) { p = arg->val; - if ((grp = getgrnam(p)) == NULL) { - if (!isdigit(*p) || (grp = getgrgid((gid_t) atoi(p))) == NULL) + if ((grp = GETGRNAM(p)) == NULL) { + if (!isdigit(*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL) errx(EX_NOUSER, "group `%s' does not exist", p); } cnf->default_group = newstr(grp->gr_name); @@ -228,8 +228,8 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) int i = 0; for (p = strtok(arg->val, ", \t"); p != NULL; p = strtok(NULL, ", \t")) { - if ((grp = getgrnam(p)) == NULL) { - if (!isdigit(*p) || (grp = getgrgid((gid_t) atoi(p))) == NULL) + if ((grp = GETGRNAM(p)) == NULL) { + if (!isdigit(*p) || (grp = GETGRGID((gid_t) atoi(p))) == NULL) errx(EX_NOUSER, "group `%s' does not exist", p); } if (extendarray(&cnf->groups, &cnf->numgroups, i + 2) != -1) @@ -272,14 +272,14 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_PRINT && getarg(args, 'a')) { int pretty = getarg(args, 'P') != NULL; - setpwent(); - while ((pwd = getpwent()) != NULL) + SETPWENT(); + while ((pwd = GETPWENT()) != NULL) print_user(pwd, pretty); - endpwent(); + ENDPWENT(); return EXIT_SUCCESS; } if ((a_name = getarg(args, 'n')) != NULL) - pwd = getpwnam(pw_checkname((u_char *)a_name->val, 0)); + pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, 0)); a_uid = getarg(args, 'u'); if (a_uid == NULL) { @@ -303,7 +303,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ if (mode == M_UPDATE || mode == M_DELETE || mode == M_PRINT) { if (a_name == NULL && pwd == NULL) /* Try harder */ - pwd = getpwuid(atoi(a_uid->val)); + pwd = GETPWUID(atoi(a_uid->val)); if (pwd == NULL) { if (mode == M_PRINT && getarg(args, 'F')) { @@ -329,19 +329,21 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "cannot remove user 'root'"); - /* - * Remove skey record from /etc/skeykeys - */ + if (!PWALTDIR()) { + /* + * Remove skey record from /etc/skeykeys + */ - rmskey(pwd->pw_name); + rmskey(pwd->pw_name); - /* - * Remove crontabs - */ - sprintf(file, "/var/cron/tabs/%s", pwd->pw_name); - if (access(file, F_OK) == 0) { - sprintf(file, "crontab -u %s -r", pwd->pw_name); - system(file); + /* + * Remove crontabs + */ + sprintf(file, "/var/cron/tabs/%s", pwd->pw_name); + if (access(file, F_OK) == 0) { + sprintf(file, "crontab -u %s -r", pwd->pw_name); + system(file); + } } /* * Save these for later, since contents of pwd may be @@ -361,26 +363,28 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) pw_log(cnf, mode, W_USER, "%s(%ld) account removed", a_name->val, (long) uid); - /* - * Remove mail file - */ - remove(file); - - /* - * Remove at jobs - */ - if (getpwuid(uid) == NULL) - rmat(uid); - - /* - * Remove home directory and contents - */ - if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) { - if (stat(home, &st) != -1) { - rm_r(home, uid); - pw_log(cnf, mode, W_USER, "%s(%ld) home '%s' %sremoved", - a_name->val, (long) uid, home, - stat(home, &st) == -1 ? "" : "not completely "); + if (!PWALTDIR()) { + /* + * Remove mail file + */ + remove(file); + + /* + * Remove at jobs + */ + if (getpwuid(uid) == NULL) + rmat(uid); + + /* + * Remove home directory and contents + */ + if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) { + if (stat(home, &st) != -1) { + rm_r(home, uid); + pw_log(cnf, mode, W_USER, "%s(%ld) home '%s' %sremoved", + a_name->val, (long) uid, home, + stat(home, &st) == -1 ? "" : "not completely "); + } } } return EXIT_SUCCESS; @@ -403,7 +407,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) warnx("WARNING: account `%s' will have a uid of 0 (superuser access!)", pwd->pw_name); } if ((arg = getarg(args, 'g')) != NULL && pwd->pw_uid != 0) /* Already checked this */ - pwd->pw_gid = (gid_t) getgrnam(cnf->default_group)->gr_gid; + pwd->pw_gid = (gid_t) GETGRNAM(cnf->default_group)->gr_gid; if ((arg = getarg(args, 'p')) != NULL) { if (*arg->val == '\0' || strcmp(arg->val, "0") == 0) @@ -449,7 +453,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) } else { if (a_name == NULL) /* Required */ errx(EX_DATAERR, "login name required"); - else if ((pwd = getpwnam(a_name->val)) != NULL) /* Exists */ + else if ((pwd = GETPWNAM(a_name->val)) != NULL) /* Exists */ errx(EX_DATAERR, "login name `%s' already exists", a_name->val); /* @@ -550,10 +554,10 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) editgroups(pwd->pw_name, cnf->groups); /* pwd may have been invalidated */ - if ((pwd = getpwnam(a_name->val)) == NULL) + if ((pwd = GETPWNAM(a_name->val)) == NULL) errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val); - grp = getgrgid(pwd->pw_gid); + grp = GETGRGID(pwd->pw_gid); pw_log(cnf, mode, W_USER, "%s(%ld):%s(%d):%s:%s:%s", pwd->pw_name, (long) pwd->pw_uid, grp ? grp->gr_name : "unknown", (long) (grp ? grp->gr_gid : -1), @@ -567,30 +571,32 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (mode == M_ADD) { FILE *fp; - sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name); - close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents & - * mtime */ - chown(line, pwd->pw_uid, pwd->pw_gid); + if (!PWALTDIR()) { + sprintf(line, "%s/%s", _PATH_MAILDIR, pwd->pw_name); + close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents & + * mtime */ + chown(line, pwd->pw_uid, pwd->pw_gid); - /* - * Send mail to the new user as well, if we are asked to - */ - if (cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) { - FILE *pfp = popen(_PATH_SENDMAIL " -t", "w"); + /* + * Send mail to the new user as well, if we are asked to + */ + if (cnf->newmail && *cnf->newmail && (fp = fopen(cnf->newmail, "r")) != NULL) { + FILE *pfp = popen(_PATH_SENDMAIL " -t", "w"); - if (pfp == NULL) - warn("sendmail"); - else { - fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name); - while (fgets(line, sizeof(line), fp) != NULL) { - /* Do substitutions? */ - fputs(line, pfp); + if (pfp == NULL) + warn("sendmail"); + else { + fprintf(pfp, "From: root\n" "To: %s\n" "Subject: Welcome!\n\n", pwd->pw_name); + while (fgets(line, sizeof(line), fp) != NULL) { + /* Do substitutions? */ + fputs(line, pfp); + } + pclose(pfp); + pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent", + pwd->pw_name, (long) pwd->pw_uid); } - pclose(pfp); - pw_log(cnf, mode, W_USER, "%s(%ld) new user mail sent", - pwd->pw_name, (long) pwd->pw_uid); + fclose(fp); } - fclose(fp); } } /* @@ -598,7 +604,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * that this also `works' for editing users if -m is used, but * existing files will *not* be overwritten. */ - if (getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) { + if (!PWALTDIR() && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) { copymkdir(pwd->pw_dir, cnf->dotdir, 0755, pwd->pw_uid, pwd->pw_gid); pw_log(cnf, mode, W_USER, "%s(%ld) home %s made", pwd->pw_name, (long) pwd->pw_uid, pwd->pw_dir); @@ -620,7 +626,7 @@ pw_uidpolicy(struct userconf * cnf, struct cargs * args) if (a_uid != NULL) { uid = (uid_t) atol(a_uid->val); - if ((pwd = getpwuid(uid)) != NULL && getarg(args, 'o') == NULL) + if ((pwd = GETPWUID(uid)) != NULL && getarg(args, 'o') == NULL) errx(EX_DATAERR, "uid `%ld' has already been allocated", (long) pwd->pw_uid); } else { struct bitmap bm; @@ -640,11 +646,11 @@ pw_uidpolicy(struct userconf * cnf, struct cargs * args) /* * Now, let's fill the bitmap from the password file */ - setpwent(); - while ((pwd = getpwent()) != NULL) - if (pwd->pw_uid >= (int) cnf->min_uid && pwd->pw_uid <= (int) cnf->max_uid) + SETPWENT(); + while ((pwd = GETPWENT()) != NULL) + if (pwd->pw_uid >= (uid_t) cnf->min_uid && pwd->pw_uid <= (uid_t) cnf->max_uid) bm_setbit(&bm, pwd->pw_uid - cnf->min_uid); - endpwent(); + ENDPWENT(); /* * Then apply the policy, with fallback to reuse if necessary @@ -679,15 +685,15 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer /* * Check the given gid, if any */ - setgrent(); + SETGRENT(); if (a_gid != NULL) { - if ((grp = getgrnam(a_gid->val)) == NULL) { + if ((grp = GETGRNAM(a_gid->val)) == NULL) { gid = (gid_t) atol(a_gid->val); - if ((gid == 0 && !isdigit(*a_gid->val)) || (grp = getgrgid(gid)) == NULL) + if ((gid == 0 && !isdigit(*a_gid->val)) || (grp = GETGRGID(gid)) == NULL) errx(EX_NOUSER, "group `%s' is not defined", a_gid->val); } gid = grp->gr_gid; - } else if ((grp = getgrnam(nam)) != NULL && grp->gr_mem[0] == NULL) { + } else if ((grp = GETGRNAM(nam)) != NULL && grp->gr_mem[0] == NULL) { gid = grp->gr_gid; /* Already created? Use it anyway... */ } else { struct cargs grpargs; @@ -705,7 +711,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer * user's name dups an existing group, then the group add * function will happily handle that case for us and exit. */ - if (getgrgid(prefer) == NULL) { + if (GETGRGID(prefer) == NULL) { sprintf(tmp, "%lu", (unsigned long) prefer); addarg(&grpargs, 'g', tmp); } @@ -718,7 +724,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer else { pw_group(cnf, M_ADD, &grpargs); - if ((grp = getgrnam(nam)) != NULL) + if ((grp = GETGRNAM(nam)) != NULL) gid = grp->gr_gid; } a_gid = grpargs.lh_first; @@ -728,7 +734,7 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer a_gid = t; } } - endgrent(); + ENDGRENT(); return gid; } @@ -968,7 +974,7 @@ print_user(struct passwd * pwd, int pretty) } else { int j; char *p; - struct group *grp = getgrgid(pwd->pw_gid); + struct group *grp = GETGRGID(pwd->pw_gid); char uname[60] = "User &", office[60] = "[None]", wphone[60] = "[None]", hphone[60] = "[None]"; char acexpire[32] = "[None]", pwexpire[32] = "[None]"; @@ -1016,9 +1022,9 @@ print_user(struct passwd * pwd, int pretty) uname, pwd->pw_dir, pwd->pw_class, pwd->pw_shell, office, wphone, hphone, acexpire, pwexpire); - setgrent(); + SETGRENT(); j = 0; - while ((grp=getgrent()) != NULL) + while ((grp=GETGRENT()) != NULL) { int i = 0; while (grp->gr_mem[i] != NULL) @@ -1031,7 +1037,7 @@ print_user(struct passwd * pwd, int pretty) ++i; } } - endgrent(); + ENDGRENT(); printf("%s\n", j ? "\n" : ""); } return EXIT_SUCCESS; |