X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/9267b33e5ec61946f68b0c8333bca3bceb33385c..6a151c16645f90b21f171a44661b109f06e9097e:/pw/pwupd.c diff --git a/pw/pwupd.c b/pw/pwupd.c index 29ee0bb..84226a9 100644 --- a/pw/pwupd.c +++ b/pw/pwupd.c @@ -22,10 +22,13 @@ * 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. - * - * $Id: pwupd.c,v 1.2 1996/12/21 15:35:44 davidn Exp $ */ +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + #include #include #include @@ -34,19 +37,47 @@ #include #include #include +#include #include #include "pwupd.h" #define HAVE_PWDB_C 1 +#define HAVE_PWDB_U 1 -static int +static char pathpwd[] = _PATH_PWD; +static char * pwpath = pathpwd; + +int +setpwdir(const char * dir) +{ + if (dir == NULL) + return -1; + else { + char * d = malloc(strlen(dir)+1); + if (d == NULL) + return -1; + pwpath = strcpy(d, dir); + } + return 0; +} + +char * +getpwpath(char const * file) +{ + static char pathbuf[MAXPATHLEN]; + + snprintf(pathbuf, sizeof pathbuf, "%s/%s", pwpath, file); + return pathbuf; +} + +int pwdb(char *arg,...) { int i = 0; pid_t pid; va_list ap; - char *args[8]; + char *args[10]; args[i++] = _PATH_PWD_MKDB; va_start(ap, arg); @@ -54,18 +85,22 @@ pwdb(char *arg,...) args[i++] = arg; arg = va_arg(ap, char *); } - args[i++] = _PATH_MASTERPASSWD; + if (pwpath != pathpwd) { + args[i++] = "-d"; + args[i++] = pwpath; + } + args[i++] = getpwpath(_MASTERPASSWD); args[i] = NULL; if ((pid = fork()) == -1) /* Error (errno set) */ - i = -1; + i = errno; else if (pid == 0) { /* Child */ execv(args[0], args); _exit(1); } else { /* Parent */ waitpid(pid, &i, 0); - if ((i = WEXITSTATUS(i)) != 0) - errno = EIO; /* set SOMETHING */ + if (WEXITSTATUS(i)) + i = EIO; } return i; } @@ -76,7 +111,8 @@ fmtpwentry(char *buf, struct passwd * pwd, int type) int l; char *pw; - pw = (pwd->pw_passwd == NULL || !*pwd->pw_passwd) ? "" : (type == PWF_MASTER) ? pwd->pw_passwd : "*"; + pw = (type == PWF_MASTER) ? + ((pwd->pw_passwd == NULL) ? "" : pwd->pw_passwd) : "*"; if (type == PWF_PASSWD) l = sprintf(buf, "%s:*:%ld:%ld:%s:%s:%s\n", @@ -105,20 +141,23 @@ pw_update(struct passwd * pwd, char const * user, int mode) { int rc = 0; - endpwent(); + ENDPWENT(); /* * First, let's check the see if the database is alright - * Note: -c is only available in FreeBSD 2.2 and above + * Note: -C is only available in FreeBSD 2.2 and above */ #ifdef HAVE_PWDB_C - if (pwdb("-c", NULL) == 0) { /* Check only */ + if (pwdb("-C", NULL) == 0) { /* Check only */ #else - { /* No -c */ + { /* No -C */ #endif - char pfx[32]; + char pfx[PWBUFSZ]; char pwbuf[PWBUFSZ]; - int l = sprintf(pfx, "%s:", user); + int l = snprintf(pfx, PWBUFSZ, "%s:", user); +#ifdef HAVE_PWDB_U + int isrename = pwd!=NULL && strcmp(user, pwd->pw_name); +#endif /* * Update the passwd file first @@ -127,15 +166,28 @@ pw_update(struct passwd * pwd, char const * user, int mode) *pwbuf = '\0'; else fmtpwentry(pwbuf, pwd, PWF_PASSWD); - if ((rc = fileupdate(_PATH_PASSWD, 0644, pwbuf, pfx, l, mode)) != 0) { + + if (l < 0) + l = 0; + rc = fileupdate(getpwpath(_PASSWD), 0644, pwbuf, pfx, l, mode); + if (rc == 0) { /* * Then the master.passwd file */ if (pwd != NULL) fmtpwentry(pwbuf, pwd, PWF_MASTER); - if ((rc = fileupdate(_PATH_MASTERPASSWD, 0644, pwbuf, pfx, l, mode)) != 0) - rc = pwdb(NULL) == 0; + rc = fileupdate(getpwpath(_MASTERPASSWD), 0600, pwbuf, pfx, l, mode); + if (rc == 0) { +#ifdef HAVE_PWDB_U + if (mode == UPD_DELETE || isrename) +#endif + rc = pwdb(NULL); +#ifdef HAVE_PWDB_U + else + rc = pwdb("-u", user, NULL); +#endif + } } } return rc;