grupd.c revision 50479
1190214Srpaulo/*- 2190214Srpaulo * Copyright (C) 1996 3190214Srpaulo * David L. Nugent. All rights reserved. 4190214Srpaulo * 5190214Srpaulo * Redistribution and use in source and binary forms, with or without 6190214Srpaulo * modification, are permitted provided that the following conditions 7190214Srpaulo * are met: 8190214Srpaulo * 1. Redistributions of source code must retain the above copyright 9190214Srpaulo * notice, this list of conditions and the following disclaimer. 10190214Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 11190214Srpaulo * notice, this list of conditions and the following disclaimer in the 12190214Srpaulo * documentation and/or other materials provided with the distribution. 13190214Srpaulo * 14190214Srpaulo * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 15190214Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16190214Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17190214Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 18190214Srpaulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19190214Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20190214Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21190214Srpaulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22190214Srpaulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23190214Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24190214Srpaulo * SUCH DAMAGE. 25190214Srpaulo */ 26190214Srpaulo 27190214Srpaulo#ifndef lint 28190214Srpaulostatic const char rcsid[] = 29190214Srpaulo "$FreeBSD: head/usr.sbin/pw/grupd.c 50479 1999-08-28 01:35:59Z peter $"; 30190214Srpaulo#endif /* not lint */ 31190214Srpaulo 32190214Srpaulo#include <stdio.h> 33190214Srpaulo#include <stdlib.h> 34190214Srpaulo#include <string.h> 35190214Srpaulo#include <unistd.h> 36190214Srpaulo#include <stdarg.h> 37190214Srpaulo#include <sys/types.h> 38190214Srpaulo#include <sys/stat.h> 39190214Srpaulo#include <sys/param.h> 40214518Srpaulo 41190214Srpaulo#include "pwupd.h" 42190214Srpaulo 43190214Srpaulostatic char * grpath = _PATH_PWD; 44190214Srpaulo 45190214Srpauloint 46190214Srpaulosetgrdir(const char * dir) 47190214Srpaulo{ 48190214Srpaulo if (dir == NULL) 49190214Srpaulo return -1; 50190214Srpaulo else { 51236167Sdelphij char * d = malloc(strlen(dir)+1); 52236167Sdelphij if (d == NULL) 53236167Sdelphij return -1; 54236167Sdelphij grpath = strcpy(d, dir); 55190214Srpaulo } 56190214Srpaulo return 0; 57236167Sdelphij} 58236167Sdelphij 59236167Sdelphijchar * 60236167Sdelphijgetgrpath(const char * file) 61236167Sdelphij{ 62236167Sdelphij static char pathbuf[MAXPATHLEN]; 63236167Sdelphij 64236167Sdelphij snprintf(pathbuf, sizeof pathbuf, "%s/%s", grpath, file); 65236167Sdelphij return pathbuf; 66236167Sdelphij} 67236167Sdelphij 68236167Sdelphijint 69236167Sdelphijgrdb(char *arg,...) 70236167Sdelphij{ 71236167Sdelphij /* 72236167Sdelphij * This is a stub for now, but maybe eventually be functional 73236167Sdelphij * if ever an indexed version of /etc/groups is implemented. 74236167Sdelphij */ 75190214Srpaulo arg=arg; 76190214Srpaulo return 0; 77190214Srpaulo} 78190214Srpaulo 79190214Srpauloint 80190214Srpaulofmtgrentry(char **buf, int * buflen, struct group * grp, int type) 81190214Srpaulo{ 82190214Srpaulo int i, l; 83190214Srpaulo 84190214Srpaulo /* 85190214Srpaulo * Since a group line is of arbitrary length, 86190214Srpaulo * we need to calculate up-front just how long 87190214Srpaulo * it will need to be... 88190214Srpaulo */ 89190214Srpaulo /* groupname : password : gid : */ 90190214Srpaulo l = strlen(grp->gr_name) + 1 + strlen(grp->gr_passwd) + 1 + 5 + 1; 91190214Srpaulo /* group members + comma separator */ 92190214Srpaulo for (i = 0; grp->gr_mem[i] != NULL; i++) { 93236167Sdelphij l += strlen(grp->gr_mem[i]) + 1; 94236167Sdelphij } 95236167Sdelphij l += 2; /* For newline & NUL */ 96190214Srpaulo if (extendline(buf, buflen, l) == -1) 97190214Srpaulo l = -1; 98190214Srpaulo else{ 99190214Srpaulo /* 100190214Srpaulo * Now we can safely format 101190214Srpaulo */ 102190214Srpaulo if (type == PWF_STANDARD) 103190214Srpaulo l = sprintf(*buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid); 104190214Srpaulo else 105190214Srpaulo l = sprintf(*buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid); 106190214Srpaulo 107190214Srpaulo /* 108190214Srpaulo * List members 109190214Srpaulo */ 110190214Srpaulo for (i = 0; grp->gr_mem[i] != NULL; i++) { 111190214Srpaulo l += sprintf(*buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]); 112190214Srpaulo } 113236167Sdelphij 114190214Srpaulo (*buf)[l++] = '\n'; 115190214Srpaulo (*buf)[l] = '\0'; 116190214Srpaulo } 117190214Srpaulo return l; 118190214Srpaulo} 119190214Srpaulo 120190214Srpaulo 121190214Srpauloint 122236167Sdelphijfmtgrent(char **buf, int * buflen, struct group * grp) 123236167Sdelphij{ 124236167Sdelphij return fmtgrentry(buf, buflen, grp, PWF_STANDARD); 125236167Sdelphij} 126236167Sdelphij 127236167Sdelphij 128190214Srpaulostatic int 129190214Srpaulogr_update(struct group * grp, char const * group, int mode) 130190214Srpaulo{ 131190214Srpaulo int l; 132190214Srpaulo char pfx[64]; 133190214Srpaulo int grbuflen = 0; 134190214Srpaulo char *grbuf = NULL; 135190214Srpaulo 136190214Srpaulo ENDGRENT(); 137190214Srpaulo l = snprintf(pfx, sizeof pfx, "%s:", group); 138190214Srpaulo 139190214Srpaulo /* 140190214Srpaulo * Update the group file 141190214Srpaulo */ 142190214Srpaulo if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1) 143190214Srpaulo l = -1; 144190214Srpaulo else { 145190214Srpaulo if ((l = fileupdate(getgrpath(_GROUP), 0644, grbuf, pfx, l, mode)) != 0) 146190214Srpaulo l = grdb(NULL) == 0; 147190214Srpaulo } 148190214Srpaulo if (grbuf != NULL) 149190214Srpaulo free(grbuf); 150190214Srpaulo return l; 151190214Srpaulo} 152190214Srpaulo 153190214Srpaulo 154190214Srpauloint 155190214Srpauloaddgrent(struct group * grp) 156190214Srpaulo{ 157190214Srpaulo return gr_update(grp, grp->gr_name, UPD_CREATE); 158190214Srpaulo} 159190214Srpaulo 160190214Srpauloint 161190214Srpaulochggrent(char const * login, struct group * grp) 162190214Srpaulo{ 163190214Srpaulo return gr_update(grp, login, UPD_REPLACE); 164190214Srpaulo} 165190214Srpaulo 166190214Srpauloint 167190214Srpaulodelgrent(struct group * grp) 168190214Srpaulo{ 169190214Srpaulo return gr_update(NULL, grp->gr_name, UPD_DELETE); 170190214Srpaulo} 171190214Srpaulo