grupd.c revision 50479
120253Sjoerg/*- 220302Sjoerg * Copyright (C) 1996 320302Sjoerg * David L. Nugent. All rights reserved. 420253Sjoerg * 520253Sjoerg * Redistribution and use in source and binary forms, with or without 620253Sjoerg * modification, are permitted provided that the following conditions 720253Sjoerg * are met: 820253Sjoerg * 1. Redistributions of source code must retain the above copyright 920302Sjoerg * notice, this list of conditions and the following disclaimer. 1020253Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1120253Sjoerg * notice, this list of conditions and the following disclaimer in the 1220253Sjoerg * documentation and/or other materials provided with the distribution. 1320253Sjoerg * 1420302Sjoerg * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 1520253Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1620253Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1720302Sjoerg * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 1820253Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1920253Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2020253Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2120253Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2220253Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2320253Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2420253Sjoerg * SUCH DAMAGE. 2520253Sjoerg */ 2620253Sjoerg 2730259Scharnier#ifndef lint 2830259Scharnierstatic const char rcsid[] = 2950479Speter "$FreeBSD: head/usr.sbin/pw/grupd.c 50479 1999-08-28 01:35:59Z peter $"; 3030259Scharnier#endif /* not lint */ 3130259Scharnier 3220253Sjoerg#include <stdio.h> 3320253Sjoerg#include <stdlib.h> 3420253Sjoerg#include <string.h> 3520253Sjoerg#include <unistd.h> 3620253Sjoerg#include <stdarg.h> 3720253Sjoerg#include <sys/types.h> 3820253Sjoerg#include <sys/stat.h> 3944229Sdavidn#include <sys/param.h> 4020253Sjoerg 4120253Sjoerg#include "pwupd.h" 4220253Sjoerg 4344229Sdavidnstatic char * grpath = _PATH_PWD; 4444229Sdavidn 4520253Sjoergint 4644229Sdavidnsetgrdir(const char * dir) 4744229Sdavidn{ 4844229Sdavidn if (dir == NULL) 4944229Sdavidn return -1; 5044229Sdavidn else { 5144229Sdavidn char * d = malloc(strlen(dir)+1); 5244229Sdavidn if (d == NULL) 5344229Sdavidn return -1; 5444229Sdavidn grpath = strcpy(d, dir); 5544229Sdavidn } 5644229Sdavidn return 0; 5744229Sdavidn} 5844229Sdavidn 5944229Sdavidnchar * 6044229Sdavidngetgrpath(const char * file) 6144229Sdavidn{ 6244229Sdavidn static char pathbuf[MAXPATHLEN]; 6344229Sdavidn 6444229Sdavidn snprintf(pathbuf, sizeof pathbuf, "%s/%s", grpath, file); 6544229Sdavidn return pathbuf; 6644229Sdavidn} 6744229Sdavidn 6844229Sdavidnint 6944229Sdavidngrdb(char *arg,...) 7044229Sdavidn{ 7144229Sdavidn /* 7244229Sdavidn * This is a stub for now, but maybe eventually be functional 7344229Sdavidn * if ever an indexed version of /etc/groups is implemented. 7444229Sdavidn */ 7544229Sdavidn arg=arg; 7644229Sdavidn return 0; 7744229Sdavidn} 7844229Sdavidn 7944229Sdavidnint 8020747Sdavidnfmtgrentry(char **buf, int * buflen, struct group * grp, int type) 8120253Sjoerg{ 8220253Sjoerg int i, l; 8320253Sjoerg 8420253Sjoerg /* 8520747Sdavidn * Since a group line is of arbitrary length, 8620747Sdavidn * we need to calculate up-front just how long 8720747Sdavidn * it will need to be... 8820253Sjoerg */ 8920747Sdavidn /* groupname : password : gid : */ 9020747Sdavidn l = strlen(grp->gr_name) + 1 + strlen(grp->gr_passwd) + 1 + 5 + 1; 9120747Sdavidn /* group members + comma separator */ 9220747Sdavidn for (i = 0; grp->gr_mem[i] != NULL; i++) { 9320747Sdavidn l += strlen(grp->gr_mem[i]) + 1; 9420747Sdavidn } 9520747Sdavidn l += 2; /* For newline & NUL */ 9620747Sdavidn if (extendline(buf, buflen, l) == -1) 9720747Sdavidn l = -1; 9820747Sdavidn else{ 9920747Sdavidn /* 10020747Sdavidn * Now we can safely format 10120747Sdavidn */ 10220747Sdavidn if (type == PWF_STANDARD) 10320747Sdavidn l = sprintf(*buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid); 10420747Sdavidn else 10520747Sdavidn l = sprintf(*buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid); 10620747Sdavidn 10720747Sdavidn /* 10820747Sdavidn * List members 10920747Sdavidn */ 11020747Sdavidn for (i = 0; grp->gr_mem[i] != NULL; i++) { 11120747Sdavidn l += sprintf(*buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]); 11220747Sdavidn } 11320747Sdavidn 11420747Sdavidn (*buf)[l++] = '\n'; 11520747Sdavidn (*buf)[l] = '\0'; 11620747Sdavidn } 11720253Sjoerg return l; 11820253Sjoerg} 11920253Sjoerg 12020253Sjoerg 12120253Sjoergint 12220747Sdavidnfmtgrent(char **buf, int * buflen, struct group * grp) 12320253Sjoerg{ 12420747Sdavidn return fmtgrentry(buf, buflen, grp, PWF_STANDARD); 12520253Sjoerg} 12620253Sjoerg 12720253Sjoerg 12820253Sjoergstatic int 12920253Sjoerggr_update(struct group * grp, char const * group, int mode) 13020253Sjoerg{ 13120253Sjoerg int l; 13220747Sdavidn char pfx[64]; 13320747Sdavidn int grbuflen = 0; 13420747Sdavidn char *grbuf = NULL; 13520253Sjoerg 13644229Sdavidn ENDGRENT(); 13720747Sdavidn l = snprintf(pfx, sizeof pfx, "%s:", group); 13820253Sjoerg 13920253Sjoerg /* 14020253Sjoerg * Update the group file 14120253Sjoerg */ 14220747Sdavidn if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1) 14320747Sdavidn l = -1; 14444229Sdavidn else { 14544229Sdavidn if ((l = fileupdate(getgrpath(_GROUP), 0644, grbuf, pfx, l, mode)) != 0) 14644229Sdavidn l = grdb(NULL) == 0; 14744229Sdavidn } 14820747Sdavidn if (grbuf != NULL) 14920747Sdavidn free(grbuf); 15020747Sdavidn return l; 15120253Sjoerg} 15220253Sjoerg 15320253Sjoerg 15420253Sjoergint 15520253Sjoergaddgrent(struct group * grp) 15620253Sjoerg{ 15720253Sjoerg return gr_update(grp, grp->gr_name, UPD_CREATE); 15820253Sjoerg} 15920253Sjoerg 16020253Sjoergint 16120253Sjoergchggrent(char const * login, struct group * grp) 16220253Sjoerg{ 16320253Sjoerg return gr_update(grp, login, UPD_REPLACE); 16420253Sjoerg} 16520253Sjoerg 16620253Sjoergint 16720253Sjoergdelgrent(struct group * grp) 16820253Sjoerg{ 16920253Sjoerg return gr_update(NULL, grp->gr_name, UPD_DELETE); 17020253Sjoerg} 171