diff options
author | bapt <bapt@FreeBSD.org> | 2011-12-15 22:07:36 +0000 |
---|---|---|
committer | bapt <bapt@FreeBSD.org> | 2011-12-15 22:07:36 +0000 |
commit | b5cd6ab67fdbb336e943f41df3595dcfa1394853 (patch) | |
tree | 1a8609290b50e06da3f03030f56fa0c994016a31 /lib/libutil/pw_util.c | |
parent | 8d73b322faab5ab431948b0b7bc89ede6c808e8e (diff) | |
download | FreeBSD-src-b5cd6ab67fdbb336e943f41df3595dcfa1394853.zip FreeBSD-src-b5cd6ab67fdbb336e943f41df3595dcfa1394853.tar.gz |
Modify pw_copy:
- if pw is NULL and oldpw is not NULL then the oldpw is deleted
- if pw->pw_name != oldpw->pw_name but pw->pw_uid == oldpw->pw_uid
then it renames the user
add new gr_* functions so now gr_util API is similar to pw_util API,
this allow to manipulate groups in a safe way.
Reviewed by: des
Approved by: des
MFC after: 1 month
Diffstat (limited to 'lib/libutil/pw_util.c')
-rw-r--r-- | lib/libutil/pw_util.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/lib/libutil/pw_util.c b/lib/libutil/pw_util.c index 5eae280..1068eff 100644 --- a/lib/libutil/pw_util.c +++ b/lib/libutil/pw_util.c @@ -410,18 +410,25 @@ pw_make(const struct passwd *pw) } /* - * Copy password file from one descriptor to another, replacing or adding - * a single record on the way. + * Copy password file from one descriptor to another, replacing, deleting + * or adding a single record on the way. */ int pw_copy(int ffd, int tfd, const struct passwd *pw, struct passwd *old_pw) { char buf[8192], *end, *line, *p, *q, *r, t; struct passwd *fpw; + const struct passwd *spw; size_t len; int eof, readlen; - if ((line = pw_make(pw)) == NULL) + spw = pw; + if (pw == NULL) { + line = NULL; + if (old_pw == NULL) + return (-1); + spw = old_pw; + } else if ((line = pw_make(pw)) == NULL) return (-1); eof = 0; @@ -489,7 +496,7 @@ pw_copy(int ffd, int tfd, const struct passwd *pw, struct passwd *old_pw) */ *q = t; - if (fpw == NULL || strcmp(fpw->pw_name, pw->pw_name) != 0) { + if (fpw == NULL || fpw->pw_uid != spw->pw_uid) { /* nope */ if (fpw != NULL) free(fpw); @@ -506,11 +513,15 @@ pw_copy(int ffd, int tfd, const struct passwd *pw, struct passwd *old_pw) } free(fpw); - /* it is, replace it */ - len = strlen(line); - if (write(tfd, line, len) != (int)len) - goto err; - + /* it is, replace or remove it */ + if (line != NULL) { + len = strlen(line); + if (write(tfd, line, len) != (int)len) + goto err; + } else { + /* when removed, avoid the \n */ + q++; + } /* we're done, just copy the rest over */ for (;;) { if (write(tfd, q, end - q) != end - q) @@ -528,16 +539,22 @@ pw_copy(int ffd, int tfd, const struct passwd *pw, struct passwd *old_pw) goto done; } - /* if we got here, we have a new entry */ + /* if we got here, we didn't find the old entry */ + if (line == NULL) { + errno = ENOENT; + goto err; + } len = strlen(line); if ((size_t)write(tfd, line, len) != len || write(tfd, "\n", 1) != 1) goto err; done: - free(line); + if (line != NULL) + free(line); return (0); err: - free(line); + if (line != NULL) + free(line); return (-1); } |