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