xref: /illumos-gate/usr/src/cmd/oamuser/group/add_group.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28 /*	All Rights Reserved	*/
29 
30 
31 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.3 */
32 
33 #include	<sys/types.h>
34 #include	<sys/stat.h>
35 #include	<stdio.h>
36 #include	<unistd.h>
37 #include	<userdefs.h>
38 
39 #define	GRPTMP		"/etc/gtmp"
40 #define	GRPBUFSIZ	5120
41 
42 int
43 add_group(group, gid)
44 char *group;	/* name of group to add */
45 gid_t gid;		/* gid of group to add */
46 {
47 	FILE *etcgrp;		/* /etc/group file */
48 	FILE *etctmp;		/* temp file */
49 	int o_mask;		/* old umask value */
50 	int newdone = 0;	/* set true when new entry done */
51 	struct stat sb;		/* stat buf to copy modes */
52 	char buf[GRPBUFSIZ];
53 
54 	if ((etcgrp = fopen(GROUP, "r")) == NULL) {
55 		return (EX_UPDATE);
56 	}
57 
58 	if (fstat(fileno(etcgrp), &sb) < 0) {
59 		/* If we can't get mode, take a default */
60 		sb.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
61 	}
62 
63 	o_mask = umask(077);
64 	etctmp = fopen(GRPTMP, "w+");
65 	(void) umask(o_mask);
66 
67 	if (etctmp == NULL) {
68 		fclose(etcgrp);
69 		return (EX_UPDATE);
70 	}
71 
72 	if (fchmod(fileno(etctmp), sb.st_mode) != 0 ||
73 	    fchown(fileno(etctmp), sb.st_uid, sb.st_gid) != 0 ||
74 	    lockf(fileno(etctmp), F_LOCK, 0) != 0) {
75 		fclose(etcgrp);
76 		fclose(etctmp);
77 		unlink(GRPTMP);
78 		return (EX_UPDATE);
79 	}
80 
81 	while (fgets(buf, GRPBUFSIZ, etcgrp) != NULL) {
82 		/* Check for NameService reference */
83 		if (!newdone && (buf[0] == '+' || buf[0] == '-')) {
84 			(void) fprintf(etctmp, "%s::%ld:\n", group, gid);
85 			newdone = 1;
86 		}
87 
88 		fputs(buf, etctmp);
89 	}
90 
91 
92 	(void) fclose(etcgrp);
93 
94 	if (!newdone) {
95 		(void) fprintf(etctmp, "%s::%ld:\n", group, gid);
96 	}
97 
98 	if (rename(GRPTMP, GROUP) < 0) {
99 		fclose(etctmp);
100 		unlink(GRPTMP);
101 		return (EX_UPDATE);
102 	}
103 
104 	(void) fclose(etctmp);
105 
106 
107 	return (EX_SUCCESS);
108 }
109