grupd.c revision 30259
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[] = 2930259Scharnier "$Id$"; 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> 3920253Sjoerg 4020253Sjoerg#include "pwupd.h" 4120253Sjoerg 4220253Sjoergint 4320747Sdavidnfmtgrentry(char **buf, int * buflen, struct group * grp, int type) 4420253Sjoerg{ 4520253Sjoerg int i, l; 4620253Sjoerg 4720253Sjoerg /* 4820747Sdavidn * Since a group line is of arbitrary length, 4920747Sdavidn * we need to calculate up-front just how long 5020747Sdavidn * it will need to be... 5120253Sjoerg */ 5220747Sdavidn /* groupname : password : gid : */ 5320747Sdavidn l = strlen(grp->gr_name) + 1 + strlen(grp->gr_passwd) + 1 + 5 + 1; 5420747Sdavidn /* group members + comma separator */ 5520747Sdavidn for (i = 0; grp->gr_mem[i] != NULL; i++) { 5620747Sdavidn l += strlen(grp->gr_mem[i]) + 1; 5720747Sdavidn } 5820747Sdavidn l += 2; /* For newline & NUL */ 5920747Sdavidn if (extendline(buf, buflen, l) == -1) 6020747Sdavidn l = -1; 6120747Sdavidn else{ 6220747Sdavidn /* 6320747Sdavidn * Now we can safely format 6420747Sdavidn */ 6520747Sdavidn if (type == PWF_STANDARD) 6620747Sdavidn l = sprintf(*buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid); 6720747Sdavidn else 6820747Sdavidn l = sprintf(*buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid); 6920747Sdavidn 7020747Sdavidn /* 7120747Sdavidn * List members 7220747Sdavidn */ 7320747Sdavidn for (i = 0; grp->gr_mem[i] != NULL; i++) { 7420747Sdavidn l += sprintf(*buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]); 7520747Sdavidn } 7620747Sdavidn 7720747Sdavidn (*buf)[l++] = '\n'; 7820747Sdavidn (*buf)[l] = '\0'; 7920747Sdavidn } 8020253Sjoerg return l; 8120253Sjoerg} 8220253Sjoerg 8320253Sjoerg 8420253Sjoergint 8520747Sdavidnfmtgrent(char **buf, int * buflen, struct group * grp) 8620253Sjoerg{ 8720747Sdavidn return fmtgrentry(buf, buflen, grp, PWF_STANDARD); 8820253Sjoerg} 8920253Sjoerg 9020253Sjoerg 9120253Sjoergstatic int 9220253Sjoerggr_update(struct group * grp, char const * group, int mode) 9320253Sjoerg{ 9420253Sjoerg int l; 9520747Sdavidn char pfx[64]; 9620747Sdavidn int grbuflen = 0; 9720747Sdavidn char *grbuf = NULL; 9820253Sjoerg 9920253Sjoerg endgrent(); 10020747Sdavidn l = snprintf(pfx, sizeof pfx, "%s:", group); 10120253Sjoerg 10220253Sjoerg /* 10320253Sjoerg * Update the group file 10420253Sjoerg */ 10520747Sdavidn if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1) 10620747Sdavidn l = -1; 10720253Sjoerg else 10820747Sdavidn l = fileupdate(_PATH_GROUP, 0644, grbuf, pfx, l, mode); 10920747Sdavidn if (grbuf != NULL) 11020747Sdavidn free(grbuf); 11120747Sdavidn return l; 11220253Sjoerg} 11320253Sjoerg 11420253Sjoerg 11520253Sjoergint 11620253Sjoergaddgrent(struct group * grp) 11720253Sjoerg{ 11820253Sjoerg return gr_update(grp, grp->gr_name, UPD_CREATE); 11920253Sjoerg} 12020253Sjoerg 12120253Sjoergint 12220253Sjoergchggrent(char const * login, struct group * grp) 12320253Sjoerg{ 12420253Sjoerg return gr_update(grp, login, UPD_REPLACE); 12520253Sjoerg} 12620253Sjoerg 12720253Sjoergint 12820253Sjoergdelgrent(struct group * grp) 12920253Sjoerg{ 13020253Sjoerg return gr_update(NULL, grp->gr_name, UPD_DELETE); 13120253Sjoerg} 132