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