pwupd.c revision 20302
1139804Simp/*- 2185435Sbz * Copyright (C) 1996 3185435Sbz * David L. Nugent. All rights reserved. 4191673Sjamie * 5185435Sbz * Redistribution and use in source and binary forms, with or without 6190466Sjamie * modification, are permitted provided that the following conditions 7185404Sbz * are met: 8185404Sbz * 1. Redistributions of source code must retain the above copyright 9185404Sbz * notice, this list of conditions and the following disclaimer. 10185404Sbz * 2. Redistributions in binary form must reproduce the above copyright 11185404Sbz * notice, this list of conditions and the following disclaimer in the 12185404Sbz * documentation and/or other materials provided with the distribution. 13185404Sbz * 14185404Sbz * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 15185404Sbz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16185404Sbz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17185404Sbz * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 18185404Sbz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19185404Sbz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20185404Sbz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21185404Sbz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22185404Sbz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23185404Sbz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24185404Sbz * SUCH DAMAGE. 25185404Sbz * 26185404Sbz * $Id: pwupd.c,v 1.1.1.2 1996/12/09 23:55:27 joerg Exp $ 2746197Sphk */ 2846155Sphk 29116182Sobrien#include <stdio.h> 30116182Sobrien#include <stdlib.h> 31116182Sobrien#include <string.h> 32193066Sjamie#include <unistd.h> 33185435Sbz#include <stdarg.h> 34185435Sbz#include <errno.h> 35185435Sbz#include <sys/types.h> 36131177Spjd#include <sys/stat.h> 3746155Sphk#include <sys/wait.h> 3846155Sphk#include <stdarg.h> 3946155Sphk 4046155Sphk#include "pwupd.h" 4146155Sphk 4246155Sphk#define HAVE_PWDB_C 1 4346155Sphk 44192895Sjamiestatic int 45164032Srwatsonpwdb(char *arg,...) 4646155Sphk{ 47124882Srwatson int i = 0; 48177785Skib pid_t pid; 4946155Sphk va_list ap; 5087275Srwatson char *args[8]; 5187275Srwatson 52220137Strasz args[i++] = _PATH_PWD_MKDB; 53221362Strasz va_start(ap, arg); 54168401Spjd while (i < 6 && arg != NULL) { 55193066Sjamie args[i++] = arg; 56113275Smike arg = va_arg(ap, char *); 57147185Spjd } 58113275Smike args[i++] = _PATH_MASTERPASSWD; 5946155Sphk args[i] = NULL; 60113275Smike 6157163Srwatson if ((pid = fork()) == -1) /* Error (errno set) */ 62113275Smike i = -1; 63196019Srwatson else if (pid == 0) { /* Child */ 6446155Sphk execv(args[0], args); 65196019Srwatson _exit(1); 66196019Srwatson } else { /* Parent */ 6746155Sphk waitpid(pid, &i, 0); 68196019Srwatson if ((i = WEXITSTATUS(i)) != 0) 69185435Sbz errno = EIO; /* set SOMETHING */ 70185435Sbz } 71185435Sbz return i; 72185435Sbz} 73185435Sbz 74185435Sbzint 7546155Sphkfmtpwentry(char *buf, struct passwd * pwd, int type) 76163606Srwatson{ 77163606Srwatson int l; 78195944Sjamie char *pw; 79195944Sjamie 8046155Sphk pw = (pwd->pw_passwd == NULL || !*pwd->pw_passwd) ? "" : (type == PWF_MASTER) ? pwd->pw_passwd : "*"; 81227293Sed 8246155Sphk if (type == PWF_PASSWD) 83202468Sbz l = sprintf(buf, "%s:*:%ld:%ld:%s:%s:%s\n", 84202468Sbz pwd->pw_name, (long) pwd->pw_uid, (long) pwd->pw_gid, 85202468Sbz pwd->pw_gecos ? pwd->pw_gecos : "User &", 86202468Sbz pwd->pw_dir, pwd->pw_shell); 87202468Sbz else 88202468Sbz l = sprintf(buf, "%s:%s:%ld:%ld:%s:%lu:%lu:%s:%s:%s\n", 89202468Sbz pwd->pw_name, pw, (long) pwd->pw_uid, (long) pwd->pw_gid, 90202468Sbz pwd->pw_class ? pwd->pw_class : "", 91202468Sbz (unsigned long) pwd->pw_change, 92202468Sbz (unsigned long) pwd->pw_expire, 93202468Sbz pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); 94202468Sbz return l; 95202468Sbz} 96202468Sbz 97202468Sbz 98192895Sjamieint 99192895Sjamiefmtpwent(char *buf, struct passwd * pwd) 100192895Sjamie{ 101192895Sjamie return fmtpwentry(buf, pwd, PWF_STANDARD); 102192895Sjamie} 103192895Sjamie 104192895Sjamiestatic int 105192895Sjamiepw_update(struct passwd * pwd, char const * user, int mode) 106231267Smm{ 107194762Sjamie int rc = 0; 108195944Sjamie 109201145Santoine endpwent(); 110196176Sbz 111202468Sbz /* 112196176Sbz * First, let's check the see if the database is alright 113202468Sbz * Note: -c is only available in FreeBSD 2.2 and above 114196176Sbz */ 115192895Sjamie#ifdef HAVE_PWDB_C 116192895Sjamie if (pwdb("-c", NULL) == 0) { /* Check only */ 117192895Sjamie#else 11857163Srwatson { /* No -c */ 119221362Strasz#endif 120168401Spjd char pfx[32]; 121191673Sjamie char pwbuf[MAXPWLINE]; 122191673Sjamie int l = sprintf(pfx, "%s:", user); 123221362Strasz 124179881Sdelphij /* 125113275Smike * Update the passwd file first 126191673Sjamie */ 127190466Sjamie if (pwd == NULL) 128191673Sjamie *pwbuf = '\0'; 129192895Sjamie else 130192895Sjamie fmtpwentry(pwbuf, pwd, PWF_PASSWD); 131221362Strasz if ((rc = fileupdate(_PATH_PASSWD, 0644, pwbuf, pfx, l, mode)) != 0) { 132221362Strasz 133232598Strasz /* 134221362Strasz * Then the master.passwd file 135221362Strasz */ 136185435Sbz if (pwd != NULL) 137190466Sjamie fmtpwentry(pwbuf, pwd, PWF_MASTER); 138192895Sjamie if ((rc = fileupdate(_PATH_MASTERPASSWD, 0644, pwbuf, pfx, l, mode)) != 0) 139185435Sbz rc = pwdb(NULL) == 0; 140185435Sbz } 141190466Sjamie } 142192895Sjamie return rc; 143185435Sbz} 144113275Smike 145191673Sjamieint 146191673Sjamieaddpwent(struct passwd * pwd) 147191673Sjamie{ 148191673Sjamie return pw_update(pwd, pwd->pw_name, UPD_CREATE); 149191673Sjamie} 150191673Sjamie 151113275Smikeint 152192895Sjamiechgpwent(char const * login, struct passwd * pwd) 153216861Sbz{ 154216861Sbz return pw_update(pwd, login, UPD_REPLACE); 155216861Sbz} 156192895Sjamie 157192895Sjamieint 158192895Sjamiedelpwent(struct passwd * pwd) 159202468Sbz{ 160202468Sbz return pw_update(NULL, pwd->pw_name, UPD_DELETE); 161202468Sbz} 162202468Sbz