* 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$
*/
+#ifndef lint
+static const char rcsid[] =
+ "$FreeBSD$";
+#endif /* not lint */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/param.h>
#include <sys/wait.h>
#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);
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;
}
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",
{
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
*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;