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