X-Git-Url: https://git.cameronkatri.com/pw-darwin.git/blobdiff_plain/5cc3dcbb4b1ff86e884ca90d654447e83c91ac8f..bf6355bb3cc93e6db08f51886034f025350ae7f2:/pw/pwupd.c diff --git a/pw/pwupd.c b/pw/pwupd.c index 05fb087..87c3c99 100644 --- a/pw/pwupd.c +++ b/pw/pwupd.c @@ -29,166 +29,124 @@ static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ +#include + +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include #include "pwupd.h" -#define HAVE_PWDB_C 1 - -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; + snprintf(pathbuf, sizeof pathbuf, "%s/%s", conf.etcpath, file); + + return (pathbuf); } -int -pwdb(char *arg,...) +static int +pwdb_check(void) { int i = 0; pid_t pid; - va_list ap; char *args[10]; args[i++] = _PATH_PWD_MKDB; - va_start(ap, arg); - while (i < 6 && arg != NULL) { - args[i++] = arg; - arg = va_arg(ap, char *); - } - if (pwpath != pathpwd) { + args[i++] = "-C"; + + if (strcmp(conf.etcpath, _PATH_PWD) != 0) { args[i++] = "-d"; - args[i++] = pwpath; + args[i++] = conf.etcpath; } 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; -} -int -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 : "*"; - - if (type == PWF_PASSWD) - l = sprintf(buf, "%s:*:%ld:%ld:%s:%s:%s\n", - pwd->pw_name, (long) pwd->pw_uid, (long) pwd->pw_gid, - pwd->pw_gecos ? pwd->pw_gecos : "User &", - pwd->pw_dir, pwd->pw_shell); - else - l = sprintf(buf, "%s:%s:%ld:%ld:%s:%lu:%lu:%s:%s:%s\n", - pwd->pw_name, pw, (long) pwd->pw_uid, (long) pwd->pw_gid, - pwd->pw_class ? pwd->pw_class : "", - (unsigned long) pwd->pw_change, - (unsigned long) pwd->pw_expire, - pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); - return l; -} - - -int -fmtpwent(char *buf, struct passwd * pwd) -{ - return fmtpwentry(buf, pwd, PWF_STANDARD); + return (i); } static int -pw_update(struct passwd * pwd, char const * user, int mode) +pw_update(struct passwd * pwd, char const * user) { - int rc = 0; + struct passwd *pw = NULL; + struct passwd *old_pw = NULL; + int rc, pfd, tfd; + + if ((rc = pwdb_check()) != 0) + return (rc); - ENDPWENT(); + if (pwd != NULL) + pw = pw_dup(pwd); + if (user != NULL) + old_pw = GETPWNAM(user); + + if (pw_init(conf.etcpath, NULL)) + err(1, "pw_init()"); + if ((pfd = pw_lock()) == -1) { + pw_fini(); + err(1, "pw_lock()"); + } + if ((tfd = pw_tmp(-1)) == -1) { + pw_fini(); + err(1, "pw_tmp()"); + } + if (pw_copy(pfd, tfd, pw, old_pw) == -1) { + pw_fini(); + close(tfd); + err(1, "pw_copy()"); + } + fsync(tfd); + close(tfd); /* - * First, let's check the see if the database is alright - * Note: -C is only available in FreeBSD 2.2 and above + * in case of deletion of a user, the whole database + * needs to be regenerated */ -#ifdef HAVE_PWDB_C - if (pwdb("-C", NULL) == 0) { /* Check only */ -#else - { /* No -C */ -#endif - char pfx[32]; - char pwbuf[PWBUFSZ]; - int l = sprintf(pfx, "%s:", user); - - /* - * Update the passwd file first - */ - if (pwd == NULL) - *pwbuf = '\0'; - else - fmtpwentry(pwbuf, pwd, PWF_PASSWD); - if ((rc = fileupdate(getpwpath(_PASSWD), 0644, pwbuf, pfx, l, mode)) != 0) { - - /* - * Then the master.passwd file - */ - if (pwd != NULL) - fmtpwentry(pwbuf, pwd, PWF_MASTER); - if ((rc = fileupdate(getpwpath(_MASTERPASSWD), 0644, pwbuf, pfx, l, mode)) != 0) - rc = pwdb(NULL) == 0; - } + if (pw_mkdb(pw != NULL ? pw->pw_name : NULL) == -1) { + pw_fini(); + err(1, "pw_mkdb()"); } - return rc; + free(pw); + pw_fini(); + + return (0); } int addpwent(struct passwd * pwd) { - return pw_update(pwd, pwd->pw_name, UPD_CREATE); + + return (pw_update(pwd, NULL)); } int chgpwent(char const * login, struct passwd * pwd) { - return pw_update(pwd, login, UPD_REPLACE); + + return (pw_update(pwd, login)); } int delpwent(struct passwd * pwd) { - return pw_update(NULL, pwd->pw_name, UPD_DELETE); + + return (pw_update(NULL, pwd->pw_name)); }