pwupd.c revision 81977
116125Swpaul/*- 216125Swpaul * Copyright (C) 1996 316125Swpaul * David L. Nugent. All rights reserved. 416125Swpaul * 516125Swpaul * Redistribution and use in source and binary forms, with or without 616125Swpaul * modification, are permitted provided that the following conditions 716125Swpaul * are met: 816125Swpaul * 1. Redistributions of source code must retain the above copyright 916125Swpaul * notice, this list of conditions and the following disclaimer. 1016125Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1116125Swpaul * notice, this list of conditions and the following disclaimer in the 1216125Swpaul * documentation and/or other materials provided with the distribution. 1316125Swpaul * 1416125Swpaul * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 1516125Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1616125Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1716125Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 1816125Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1916125Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2016125Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2116125Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2216125Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2316125Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2416125Swpaul * SUCH DAMAGE. 2516125Swpaul */ 2616125Swpaul 2716125Swpaul#ifndef lint 2816125Swpaulstatic const char rcsid[] = 2916125Swpaul "$FreeBSD: head/usr.sbin/pw/pwupd.c 81977 2001-08-20 13:24:39Z brian $"; 3016125Swpaul#endif /* not lint */ 3116125Swpaul 3216125Swpaul#include <stdio.h> 3330378Scharnier#include <stdlib.h> 3430378Scharnier#include <string.h> 3550479Speter#include <unistd.h> 3630378Scharnier#include <stdarg.h> 3730378Scharnier#include <errno.h> 3816125Swpaul#include <sys/types.h> 3930378Scharnier#include <sys/stat.h> 4030378Scharnier#include <sys/param.h> 4169793Sobrien#include <sys/wait.h> 4216125Swpaul 4316125Swpaul#include "pwupd.h" 4423716Speter 4516125Swpaul#define HAVE_PWDB_C 1 4616125Swpaul#define HAVE_PWDB_U 1 4716125Swpaul 4816125Swpaulstatic char pathpwd[] = _PATH_PWD; 4916125Swpaulstatic char * pwpath = pathpwd; 5016125Swpaul 5116125Swpaulint 5216125Swpaulsetpwdir(const char * dir) 5316125Swpaul{ 5416125Swpaul if (dir == NULL) 5516125Swpaul return -1; 5616125Swpaul else { 5716125Swpaul char * d = malloc(strlen(dir)+1); 5816125Swpaul if (d == NULL) 5916125Swpaul return -1; 6016125Swpaul pwpath = strcpy(d, dir); 6116125Swpaul } 6216125Swpaul return 0; 6316125Swpaul} 6416125Swpaul 6516125Swpaulchar * 6616125Swpaulgetpwpath(char const * file) 6716125Swpaul{ 6816125Swpaul static char pathbuf[MAXPATHLEN]; 6916125Swpaul 7016125Swpaul snprintf(pathbuf, sizeof pathbuf, "%s/%s", pwpath, file); 7116125Swpaul return pathbuf; 7216125Swpaul} 7316125Swpaul 7416125Swpaulint 7516125Swpaulpwdb(char *arg,...) 7616125Swpaul{ 7716125Swpaul int i = 0; 7816125Swpaul pid_t pid; 7916125Swpaul va_list ap; 8016125Swpaul char *args[10]; 8116125Swpaul 8216125Swpaul args[i++] = _PATH_PWD_MKDB; 8316125Swpaul va_start(ap, arg); 8416125Swpaul while (i < 6 && arg != NULL) { 8516125Swpaul args[i++] = arg; 8616125Swpaul arg = va_arg(ap, char *); 8716125Swpaul } 8862989Skris if (pwpath != pathpwd) { 8916125Swpaul args[i++] = "-d"; 9030378Scharnier args[i++] = pwpath; 9116125Swpaul } 9262989Skris args[i++] = getpwpath(_MASTERPASSWD); 9316125Swpaul args[i] = NULL; 9416125Swpaul 9516125Swpaul if ((pid = fork()) == -1) /* Error (errno set) */ 9616125Swpaul i = errno; 9716125Swpaul else if (pid == 0) { /* Child */ 9816125Swpaul execv(args[0], args); 9916125Swpaul _exit(1); 10016125Swpaul } else { /* Parent */ 10116125Swpaul waitpid(pid, &i, 0); 10216125Swpaul if (WEXITSTATUS(i)) 10316125Swpaul i = EIO; 10416125Swpaul } 10516125Swpaul return i; 10616125Swpaul} 10716125Swpaul 10816125Swpaulint 10916125Swpaulfmtpwentry(char *buf, struct passwd * pwd, int type) 11016125Swpaul{ 11116125Swpaul int l; 11216125Swpaul char *pw; 11316125Swpaul 11416125Swpaul pw = (pwd->pw_passwd == NULL || !*pwd->pw_passwd) ? "" : (type == PWF_MASTER) ? pwd->pw_passwd : "*"; 11516125Swpaul 11616125Swpaul if (type == PWF_PASSWD) 11716125Swpaul l = sprintf(buf, "%s:*:%ld:%ld:%s:%s:%s\n", 11816125Swpaul pwd->pw_name, (long) pwd->pw_uid, (long) pwd->pw_gid, 11916125Swpaul pwd->pw_gecos ? pwd->pw_gecos : "User &", 12016125Swpaul pwd->pw_dir, pwd->pw_shell); 12116125Swpaul else 12216125Swpaul l = sprintf(buf, "%s:%s:%ld:%ld:%s:%lu:%lu:%s:%s:%s\n", 12316125Swpaul pwd->pw_name, pw, (long) pwd->pw_uid, (long) pwd->pw_gid, 12416125Swpaul pwd->pw_class ? pwd->pw_class : "", 12516125Swpaul (unsigned long) pwd->pw_change, 12616125Swpaul (unsigned long) pwd->pw_expire, 12716125Swpaul pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); 12816125Swpaul return l; 12916125Swpaul} 13016125Swpaul 13116125Swpaul 13216125Swpaulint 13316125Swpaulfmtpwent(char *buf, struct passwd * pwd) 13416125Swpaul{ 13516125Swpaul return fmtpwentry(buf, pwd, PWF_STANDARD); 13616125Swpaul} 13716125Swpaul 13816125Swpaulstatic int 13916125Swpaulpw_update(struct passwd * pwd, char const * user, int mode) 14016125Swpaul{ 14116125Swpaul int rc = 0; 14216125Swpaul 14316125Swpaul ENDPWENT(); 14416125Swpaul 14516125Swpaul /* 14616125Swpaul * First, let's check the see if the database is alright 14716125Swpaul * Note: -C is only available in FreeBSD 2.2 and above 14816125Swpaul */ 14916125Swpaul#ifdef HAVE_PWDB_C 15030378Scharnier if (pwdb("-C", NULL) == 0) { /* Check only */ 15116125Swpaul#else 15216125Swpaul { /* No -C */ 15316125Swpaul#endif 15416125Swpaul char pfx[PWBUFSZ]; 15516125Swpaul char pwbuf[PWBUFSZ]; 15616125Swpaul int l = snprintf(pfx, PWBUFSZ, "%s:", user); 15716125Swpaul#ifdef HAVE_PWDB_U 15816125Swpaul int isrename = pwd!=NULL && strcmp(user, pwd->pw_name); 15916125Swpaul#endif 16016125Swpaul 16116125Swpaul /* 16216125Swpaul * Update the passwd file first 16316125Swpaul */ 16416125Swpaul if (pwd == NULL) 16536642Swpaul *pwbuf = '\0'; 16636642Swpaul else 16716125Swpaul fmtpwentry(pwbuf, pwd, PWF_PASSWD); 16836642Swpaul 16936642Swpaul if (l == -1) 17016125Swpaul l = 0; 17116125Swpaul rc = fileupdate(getpwpath(_PASSWD), 0644, pwbuf, pfx, l, mode); 17236642Swpaul if (rc == 0) { 17316125Swpaul 17416125Swpaul /* 17516125Swpaul * Then the master.passwd file 17616125Swpaul */ 17716125Swpaul if (pwd != NULL) 17816125Swpaul fmtpwentry(pwbuf, pwd, PWF_MASTER); 17916125Swpaul rc = fileupdate(getpwpath(_MASTERPASSWD), 0644, pwbuf, pfx, l, mode); 18016125Swpaul if (rc == 0) { 18116125Swpaul#ifdef HAVE_PWDB_U 18216125Swpaul if (mode == UPD_DELETE || isrename) 18336642Swpaul#endif 18436642Swpaul rc = pwdb(NULL); 18536642Swpaul#ifdef HAVE_PWDB_U 18616125Swpaul else 18716125Swpaul rc = pwdb("-u", user, NULL); 18816125Swpaul#endif 18916125Swpaul } 19030378Scharnier } 19116125Swpaul } 19216125Swpaul return rc; 19316125Swpaul} 19430378Scharnier 19516125Swpaulint 19616125Swpauladdpwent(struct passwd * pwd) 19716125Swpaul{ 19816125Swpaul return pw_update(pwd, pwd->pw_name, UPD_CREATE); 19930378Scharnier} 20016125Swpaul 20130378Scharnierint 20216125Swpaulchgpwent(char const * login, struct passwd * pwd) 20316125Swpaul{ 20416125Swpaul return pw_update(pwd, login, UPD_REPLACE); 20516125Swpaul} 20624428Simp 20790297Sdesint 20816125Swpauldelpwent(struct passwd * pwd) 20916125Swpaul{ 21016125Swpaul return pw_update(NULL, pwd->pw_name, UPD_DELETE); 21116125Swpaul} 21216125Swpaul