xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
2*0Sstevel@tonic-gate 
3*0Sstevel@tonic-gate /****************************************************************************
4*0Sstevel@tonic-gate 
5*0Sstevel@tonic-gate    Copyright (c) 1999,2000 WU-FTPD Development Group.
6*0Sstevel@tonic-gate    All rights reserved.
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate    Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
9*0Sstevel@tonic-gate    The Regents of the University of California.  Portions Copyright (c)
10*0Sstevel@tonic-gate    1993, 1994 Washington University in Saint Louis.  Portions Copyright
11*0Sstevel@tonic-gate    (c) 1996, 1998 Berkeley Software Design, Inc.  Portions Copyright (c)
12*0Sstevel@tonic-gate    1998 Sendmail, Inc.  Portions Copyright (c) 1983, 1995, 1996, 1997 Eric
13*0Sstevel@tonic-gate    P. Allman.  Portions Copyright (c) 1989 Massachusetts Institute of
14*0Sstevel@tonic-gate    Technology.  Portions Copyright (c) 1997 by Stan Barber.  Portions
15*0Sstevel@tonic-gate    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free Software
16*0Sstevel@tonic-gate    Foundation, Inc.  Portions Copyright (c) 1997 by Kent Landfield.
17*0Sstevel@tonic-gate 
18*0Sstevel@tonic-gate    Use and distribution of this software and its source code are governed
19*0Sstevel@tonic-gate    by the terms and conditions of the WU-FTPD Software License ("LICENSE").
20*0Sstevel@tonic-gate 
21*0Sstevel@tonic-gate    $Id: privatepw.c,v 1.10 2000/07/01 18:43:59 wuftpd Exp $
22*0Sstevel@tonic-gate 
23*0Sstevel@tonic-gate ****************************************************************************/
24*0Sstevel@tonic-gate /*
25*0Sstevel@tonic-gate    Subsystem:  WU-FTPD FTP Server
26*0Sstevel@tonic-gate    Purpose:    Change WU-FTPD Guest Passwords
27*0Sstevel@tonic-gate    File Name:  privatepw.c
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate    usage: privatepw [-c] [-f passwordfile] [-g group] accessgroup
30*0Sstevel@tonic-gate    privatepw [-d] [-f passwordfile] accessgroup
31*0Sstevel@tonic-gate    privatepw [-l] [-f passwordfile]
32*0Sstevel@tonic-gate    -c:           creates a new file.
33*0Sstevel@tonic-gate    -d:           deletes specified accessgroup.
34*0Sstevel@tonic-gate    -l:           list contents of ftpgroups file.
35*0Sstevel@tonic-gate    -f ftpgroups: updates the specified file.
36*0Sstevel@tonic-gate    -g group:     set real group to the specified group.
37*0Sstevel@tonic-gate 
38*0Sstevel@tonic-gate    This software was initially written by Kent Landfield (kent@landfield.com)
39*0Sstevel@tonic-gate  */
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate #include <sys/types.h>
42*0Sstevel@tonic-gate #include <sys/signal.h>
43*0Sstevel@tonic-gate #include <sys/stat.h>
44*0Sstevel@tonic-gate #include <string.h>
45*0Sstevel@tonic-gate #include <stdio.h>
46*0Sstevel@tonic-gate #include <stdlib.h>
47*0Sstevel@tonic-gate #include <time.h>
48*0Sstevel@tonic-gate #include <grp.h>
49*0Sstevel@tonic-gate #include <unistd.h>
50*0Sstevel@tonic-gate #include "config.h"
51*0Sstevel@tonic-gate #include "pathnames.h"
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #define BUFLEN 256
54*0Sstevel@tonic-gate #define GROUPLEN 8
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate char *tmp;
57*0Sstevel@tonic-gate char line[BUFLEN];
58*0Sstevel@tonic-gate FILE *fp;
59*0Sstevel@tonic-gate int verbose = 0;
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate static unsigned char itoa64[] =	/* 0 ... 63 => ascii - 64 */
62*0Sstevel@tonic-gate "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate void print_copyright(void);
65*0Sstevel@tonic-gate 
usage(void)66*0Sstevel@tonic-gate static void usage(void)
67*0Sstevel@tonic-gate {
68*0Sstevel@tonic-gate     fprintf(stderr, "usage: privatepw [-c] [-f ftpgroups] [-g group] accessgroup\n");
69*0Sstevel@tonic-gate     fprintf(stderr, "       privatepw [-d] [-f ftpgroups] accessgroup\n");
70*0Sstevel@tonic-gate     fprintf(stderr, "       privatepw [-l] [-f ftpgroups]\n");
71*0Sstevel@tonic-gate     fprintf(stderr, "\t\t-c:           creates a new file.\n");
72*0Sstevel@tonic-gate     fprintf(stderr, "\t\t-d:           deletes specified accessgroup.\n");
73*0Sstevel@tonic-gate     fprintf(stderr, "\t\t-l:           list contents of ftpgroups file.\n");
74*0Sstevel@tonic-gate     fprintf(stderr, "\t\t-f ftpgroups: updates the specified file.\n");
75*0Sstevel@tonic-gate     fprintf(stderr, "\t\t-g group:     set real group to the specified group.\n");
76*0Sstevel@tonic-gate     exit(1);
77*0Sstevel@tonic-gate }
78*0Sstevel@tonic-gate 
to64(register char * s,register long v,register int n)79*0Sstevel@tonic-gate static void to64(register char *s, register long v, register int n)
80*0Sstevel@tonic-gate {
81*0Sstevel@tonic-gate     while (--n >= 0) {
82*0Sstevel@tonic-gate 	*s++ = itoa64[v & 0x3f];
83*0Sstevel@tonic-gate 	v >>= 6;
84*0Sstevel@tonic-gate     }
85*0Sstevel@tonic-gate }
86*0Sstevel@tonic-gate 
terminate(void)87*0Sstevel@tonic-gate static void terminate(void)
88*0Sstevel@tonic-gate {
89*0Sstevel@tonic-gate     if (tmp)
90*0Sstevel@tonic-gate 	unlink(tmp);
91*0Sstevel@tonic-gate     exit(1);
92*0Sstevel@tonic-gate }
93*0Sstevel@tonic-gate 
catchintr(void)94*0Sstevel@tonic-gate static void catchintr(void)
95*0Sstevel@tonic-gate {
96*0Sstevel@tonic-gate     fprintf(stderr, "Interrupted.\n");
97*0Sstevel@tonic-gate     terminate();
98*0Sstevel@tonic-gate }
99*0Sstevel@tonic-gate 
savit(char * s)100*0Sstevel@tonic-gate static char *savit(char *s)
101*0Sstevel@tonic-gate {
102*0Sstevel@tonic-gate     char *d;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate     if ((d = (char *) malloc(strlen(s) + 1)) == NULL) {
105*0Sstevel@tonic-gate 	fprintf(stderr, "Whoa... Malloc failed.\n");
106*0Sstevel@tonic-gate 	terminate();
107*0Sstevel@tonic-gate     }
108*0Sstevel@tonic-gate     strcpy(d, s);
109*0Sstevel@tonic-gate     return (d);
110*0Sstevel@tonic-gate }
111*0Sstevel@tonic-gate 
confirmed(char * accessgroup)112*0Sstevel@tonic-gate static int confirmed(char *accessgroup)
113*0Sstevel@tonic-gate {
114*0Sstevel@tonic-gate     register int ch;
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate     printf("Delete %s: Are your sure ? (y/n) ", accessgroup);
117*0Sstevel@tonic-gate     ch = getc(stdin);
118*0Sstevel@tonic-gate     if (ch == 'y')
119*0Sstevel@tonic-gate 	return (1);
120*0Sstevel@tonic-gate     return (0);
121*0Sstevel@tonic-gate }
122*0Sstevel@tonic-gate 
getgroup(char * msg)123*0Sstevel@tonic-gate static char *getgroup(char *msg)
124*0Sstevel@tonic-gate {
125*0Sstevel@tonic-gate     register int ch;
126*0Sstevel@tonic-gate     register char *p;
127*0Sstevel@tonic-gate     static char buf[GROUPLEN + 1];
128*0Sstevel@tonic-gate 
129*0Sstevel@tonic-gate     fputs(msg, stderr);
130*0Sstevel@tonic-gate     rewind(stderr);		/* implied flush */
131*0Sstevel@tonic-gate     for (p = buf; (ch = getc(stdin)) != EOF && ch != '\n';)
132*0Sstevel@tonic-gate 	if (p < buf + GROUPLEN)
133*0Sstevel@tonic-gate 	    *p++ = ch;
134*0Sstevel@tonic-gate     *p = '\0';
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate     if (getgrnam(buf) == NULL) {
137*0Sstevel@tonic-gate 	fprintf(stderr, "Invalid group \'%s\' specified\n", buf);
138*0Sstevel@tonic-gate 	terminate();
139*0Sstevel@tonic-gate     }
140*0Sstevel@tonic-gate     return (buf);
141*0Sstevel@tonic-gate }
142*0Sstevel@tonic-gate 
addrecord(char * accessgroup,char * sysgroup,char * msg,FILE * f)143*0Sstevel@tonic-gate static void addrecord(char *accessgroup, char *sysgroup, char *msg, FILE *f)
144*0Sstevel@tonic-gate {
145*0Sstevel@tonic-gate     char *pw, *cpw, salt[3];
146*0Sstevel@tonic-gate #ifndef NO_CRYPT_PROTO
147*0Sstevel@tonic-gate     extern char *crypt(const char *, const char *);
148*0Sstevel@tonic-gate #endif
149*0Sstevel@tonic-gate     char *getpass(const char *prompt);
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate     printf("%s %s\n", msg, accessgroup);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate     if (sysgroup[0] == '\0')
154*0Sstevel@tonic-gate 	strcpy(sysgroup, getgroup("Real System Group to use: "));
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate     pw = savit((char *) getpass("New password: "));
157*0Sstevel@tonic-gate     if (strcmp(pw, (char *) getpass("Re-type new password: "))) {
158*0Sstevel@tonic-gate 	fprintf(stderr, "They don't match, sorry.\n");
159*0Sstevel@tonic-gate 	if (tmp)
160*0Sstevel@tonic-gate 	    unlink(tmp);
161*0Sstevel@tonic-gate 	exit(1);
162*0Sstevel@tonic-gate     }
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate     srand((int) time((time_t *) NULL));
165*0Sstevel@tonic-gate     to64(&salt[0], rand(), 2);
166*0Sstevel@tonic-gate     cpw = crypt(pw, salt);
167*0Sstevel@tonic-gate     free(pw);
168*0Sstevel@tonic-gate     fprintf(f, "%s:%s:%s\n", accessgroup, cpw, sysgroup);
169*0Sstevel@tonic-gate }
170*0Sstevel@tonic-gate 
list_privatefile(char * privatefile)171*0Sstevel@tonic-gate static void list_privatefile(char *privatefile)
172*0Sstevel@tonic-gate {
173*0Sstevel@tonic-gate     if (verbose)
174*0Sstevel@tonic-gate 	fprintf(stderr, "Private File: %s file.\n", privatefile);
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate     if ((fp = fopen(privatefile, "r")) == NULL) {
177*0Sstevel@tonic-gate 	fprintf(stderr, "Could not open %s file.\n", privatefile);
178*0Sstevel@tonic-gate 	exit(1);
179*0Sstevel@tonic-gate     }
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate     printf("\nWU-FTPD Private file: %s\n", privatefile);
182*0Sstevel@tonic-gate     printf("accessgroup : password : system group\n");
183*0Sstevel@tonic-gate     printf("-------\n");
184*0Sstevel@tonic-gate 
185*0Sstevel@tonic-gate     while (fgets(line, BUFLEN, fp) != NULL)
186*0Sstevel@tonic-gate 	fputs(line, stdout);
187*0Sstevel@tonic-gate     printf("-------\n");
188*0Sstevel@tonic-gate }
189*0Sstevel@tonic-gate 
main(int argc,char ** argv)190*0Sstevel@tonic-gate int main(int argc, char **argv)
191*0Sstevel@tonic-gate {
192*0Sstevel@tonic-gate     extern void (*signal(int sig, void (*disp) (int))) (int);
193*0Sstevel@tonic-gate     extern int getopt(int argc, char *const *argv, const char *optstring);
194*0Sstevel@tonic-gate     extern char *optarg;
195*0Sstevel@tonic-gate     extern int optind;
196*0Sstevel@tonic-gate     extern int opterr;
197*0Sstevel@tonic-gate 
198*0Sstevel@tonic-gate     struct stat stbuf;
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate     char realgroup[BUFLEN];
201*0Sstevel@tonic-gate     char *passwdpath;
202*0Sstevel@tonic-gate     char *cp;
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate     char accessgroup[BUFLEN];
205*0Sstevel@tonic-gate     char w[BUFLEN];
206*0Sstevel@tonic-gate     char command[BUFLEN];
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate     int create;
209*0Sstevel@tonic-gate     int delete;
210*0Sstevel@tonic-gate     int list;
211*0Sstevel@tonic-gate     int found;
212*0Sstevel@tonic-gate     int lineno;
213*0Sstevel@tonic-gate     int c;
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate     FILE *tfp;
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate #ifdef HAVE_MKSTEMP
218*0Sstevel@tonic-gate     char tmpname[BUFLEN];
219*0Sstevel@tonic-gate     int tfd;
220*0Sstevel@tonic-gate #endif
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate     opterr = 0;
223*0Sstevel@tonic-gate     create = 0;
224*0Sstevel@tonic-gate     delete = 0;
225*0Sstevel@tonic-gate     list = 0;
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate     tmp = NULL;
228*0Sstevel@tonic-gate     realgroup[0] = '\0';
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate     passwdpath = _PATH_PRIVATE;
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate     if (argc == 1)
233*0Sstevel@tonic-gate 	usage();
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate     while ((c = getopt(argc, argv, "Vvcdf:g:l")) != EOF) {
236*0Sstevel@tonic-gate 	switch (c) {
237*0Sstevel@tonic-gate 	case 'd':
238*0Sstevel@tonic-gate 	    delete++;
239*0Sstevel@tonic-gate 	    break;
240*0Sstevel@tonic-gate 	case 'c':
241*0Sstevel@tonic-gate 	    create++;
242*0Sstevel@tonic-gate 	    break;
243*0Sstevel@tonic-gate 	case 'f':
244*0Sstevel@tonic-gate 	    passwdpath = optarg;
245*0Sstevel@tonic-gate 	    break;
246*0Sstevel@tonic-gate 	case 'g':
247*0Sstevel@tonic-gate 	    strcpy(realgroup, optarg);
248*0Sstevel@tonic-gate 	    if (getgrnam(realgroup) == NULL) {
249*0Sstevel@tonic-gate 		fprintf(stderr, "Invalid group \'%s\' specified\n", realgroup);
250*0Sstevel@tonic-gate 		return (1);
251*0Sstevel@tonic-gate 	    }
252*0Sstevel@tonic-gate 	    break;
253*0Sstevel@tonic-gate 	case 'l':
254*0Sstevel@tonic-gate 	    list++;
255*0Sstevel@tonic-gate 	    break;
256*0Sstevel@tonic-gate 	case 'v':
257*0Sstevel@tonic-gate 	    verbose++;
258*0Sstevel@tonic-gate 	    break;
259*0Sstevel@tonic-gate 	case 'V':
260*0Sstevel@tonic-gate 	    print_copyright();
261*0Sstevel@tonic-gate 	    return (0);
262*0Sstevel@tonic-gate 	    /* NOTREACHED */
263*0Sstevel@tonic-gate 	default:
264*0Sstevel@tonic-gate 	    usage();
265*0Sstevel@tonic-gate 	}
266*0Sstevel@tonic-gate     }
267*0Sstevel@tonic-gate 
268*0Sstevel@tonic-gate     if (list) {
269*0Sstevel@tonic-gate 	list_privatefile(passwdpath);
270*0Sstevel@tonic-gate 	return (0);
271*0Sstevel@tonic-gate     }
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate     if (optind >= argc) {
274*0Sstevel@tonic-gate 	fprintf(stderr, "Need to specify an accessgroup name.\n");
275*0Sstevel@tonic-gate 	usage();
276*0Sstevel@tonic-gate     }
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate     signal(SIGINT, (void (*)()) catchintr);
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate     strcpy(accessgroup, argv[optind]);
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate     if (create) {
283*0Sstevel@tonic-gate 	if (stat(passwdpath, &stbuf) == 0) {
284*0Sstevel@tonic-gate 	    fprintf(stderr, "%s exists, cannot create it.\n", passwdpath);
285*0Sstevel@tonic-gate 	    fprintf(stderr, "Remove -c option or use the -f option to specify another.\n");
286*0Sstevel@tonic-gate 	    return (1);
287*0Sstevel@tonic-gate 	}
288*0Sstevel@tonic-gate 
289*0Sstevel@tonic-gate 	if ((tfp = fopen(passwdpath, "w")) == NULL) {
290*0Sstevel@tonic-gate 	    fprintf(stderr, "Could not open \"%s\" for writing.\n", passwdpath);
291*0Sstevel@tonic-gate 	    perror("fopen");
292*0Sstevel@tonic-gate 	    return (1);
293*0Sstevel@tonic-gate 	}
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 	tmp = passwdpath;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 	printf("Creating WU-FTPD Private file: %s\n", passwdpath);
298*0Sstevel@tonic-gate 	addrecord(accessgroup, realgroup, "Adding accessgroup", tfp);
299*0Sstevel@tonic-gate 
300*0Sstevel@tonic-gate 	fclose(tfp);
301*0Sstevel@tonic-gate 	return (0);
302*0Sstevel@tonic-gate     }
303*0Sstevel@tonic-gate 
304*0Sstevel@tonic-gate #ifdef HAVE_MKSTEMP
305*0Sstevel@tonic-gate     strcpy (tmpname, "/tmp/privatepwXXXXXX");
306*0Sstevel@tonic-gate     tmp = tmpname;
307*0Sstevel@tonic-gate     if ((tfd = mkstemp(tmp)) < 0) {
308*0Sstevel@tonic-gate 	fprintf(stderr, "Could not open temp file.\n");
309*0Sstevel@tonic-gate 	return (1);
310*0Sstevel@tonic-gate     }
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate     if ((tfp = fdopen(tfd, "w")) == NULL) {
313*0Sstevel@tonic-gate 	unlink(tmp);
314*0Sstevel@tonic-gate 	fprintf(stderr, "Could not open temp file.\n");
315*0Sstevel@tonic-gate 	return (1);
316*0Sstevel@tonic-gate     }
317*0Sstevel@tonic-gate #else
318*0Sstevel@tonic-gate     tmp = tmpnam(NULL);
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate     if ((tfp = fopen(tmp, "w")) == NULL) {
321*0Sstevel@tonic-gate 	fprintf(stderr, "Could not open temp file.\n");
322*0Sstevel@tonic-gate 	return (1);
323*0Sstevel@tonic-gate     }
324*0Sstevel@tonic-gate #endif
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate     if ((fp = fopen(passwdpath, "r")) == NULL) {
327*0Sstevel@tonic-gate 	fprintf(stderr, "Could not open %s file.\n", passwdpath);
328*0Sstevel@tonic-gate 	fprintf(stderr, "Use -c option to create new one.\n");
329*0Sstevel@tonic-gate 	return (1);
330*0Sstevel@tonic-gate     }
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate     lineno = 0;
333*0Sstevel@tonic-gate     found = 0;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate     while (fgets(line, BUFLEN, fp) != NULL) {
336*0Sstevel@tonic-gate 	lineno++;
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 	if (found || (line[0] == '#') || (!line[0])) {
339*0Sstevel@tonic-gate 	    fputs(line, tfp);
340*0Sstevel@tonic-gate 	    continue;
341*0Sstevel@tonic-gate 	}
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate 	strcpy(w, line);
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	if ((cp = strchr(w, ':')) == NULL) {
346*0Sstevel@tonic-gate 	    fprintf(stderr, "%s: line %d: invalid record format.\n", passwdpath, lineno);
347*0Sstevel@tonic-gate 	    continue;
348*0Sstevel@tonic-gate 	}
349*0Sstevel@tonic-gate 	*cp++ = '\0';
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	if ((cp = strchr(cp, ':')) == NULL) {
352*0Sstevel@tonic-gate 	    fprintf(stderr, "%s: line %d: invalid record format.\n", passwdpath, lineno);
353*0Sstevel@tonic-gate 	    continue;
354*0Sstevel@tonic-gate 	}
355*0Sstevel@tonic-gate 	*cp++ = '\0';
356*0Sstevel@tonic-gate 
357*0Sstevel@tonic-gate 	if (strcmp(accessgroup, w)) {
358*0Sstevel@tonic-gate 	    fputs(line, tfp);
359*0Sstevel@tonic-gate 	    continue;
360*0Sstevel@tonic-gate 	}
361*0Sstevel@tonic-gate 	else {
362*0Sstevel@tonic-gate 	    if (delete) {
363*0Sstevel@tonic-gate 		if (!confirmed(accessgroup))
364*0Sstevel@tonic-gate 		    terminate();
365*0Sstevel@tonic-gate 	    }
366*0Sstevel@tonic-gate 	    else {
367*0Sstevel@tonic-gate 		if (realgroup[0] == '\0') {
368*0Sstevel@tonic-gate 		    strcpy(realgroup, cp);
369*0Sstevel@tonic-gate 		    if ((cp = strchr(realgroup, '\n')) != NULL)
370*0Sstevel@tonic-gate 			*cp = '\0';
371*0Sstevel@tonic-gate 		}
372*0Sstevel@tonic-gate 		addrecord(accessgroup, realgroup, "Updating accessgroup", tfp);
373*0Sstevel@tonic-gate 	    }
374*0Sstevel@tonic-gate 	    found = 1;
375*0Sstevel@tonic-gate 	}
376*0Sstevel@tonic-gate     }
377*0Sstevel@tonic-gate 
378*0Sstevel@tonic-gate     if (!found && !delete)
379*0Sstevel@tonic-gate 	addrecord(accessgroup, realgroup, "Adding accessgroup", tfp);
380*0Sstevel@tonic-gate     else if (!found && delete) {
381*0Sstevel@tonic-gate 	fprintf(stderr, "%s not found in %s.\n", accessgroup, passwdpath);
382*0Sstevel@tonic-gate 	terminate();
383*0Sstevel@tonic-gate     }
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate     fclose(fp);
386*0Sstevel@tonic-gate     fclose(tfp);
387*0Sstevel@tonic-gate 
388*0Sstevel@tonic-gate     sprintf(command, "cp %s %s", tmp, passwdpath);
389*0Sstevel@tonic-gate     system(command);
390*0Sstevel@tonic-gate     unlink(tmp);
391*0Sstevel@tonic-gate     return (0);
392*0Sstevel@tonic-gate }
393