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 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <sys/stat.h> 32 #include <project.h> 33 #include <unistd.h> 34 #include <userdefs.h> 35 #include <errno.h> 36 #include <nss_dbdefs.h> 37 #include "users.h" 38 #include "messages.h" 39 40 int 41 edit_project(char *login, char *new_login, projid_t projids[], int overwrite) 42 { 43 char **memptr; 44 char t_name[] = "/etc/projtmp.XXXXXX"; 45 FILE *e_fptr, *t_fptr; 46 struct project *p_ptr; 47 struct project p_work; 48 char workbuf[NSS_LINELEN_PROJECT]; 49 int i, modified = 0; 50 struct stat sbuf; 51 int p_length; 52 char p_string[NSS_LINELEN_PROJECT]; 53 long p_curr = 0; 54 int exist; 55 int fd; 56 57 if ((e_fptr = fopen(PROJF_PATH, "r")) == NULL) { 58 return (EX_UPDATE); 59 } 60 61 if (fstat(fileno(e_fptr), &sbuf) != 0) 62 return (EX_UPDATE); 63 64 if ((fd = mkstemp(t_name)) < 0) { 65 return (EX_UPDATE); 66 } 67 68 if ((t_fptr = fdopen(fd, "w+")) == NULL) { 69 (void) close(fd); 70 (void) unlink(t_name); 71 return (EX_UPDATE); 72 } 73 74 /* 75 * Get ownership and permissions correct 76 */ 77 78 if (fchmod(fd, sbuf.st_mode) != 0 || 79 fchown(fd, sbuf.st_uid, sbuf.st_gid) != 0) { 80 (void) fclose(t_fptr); 81 (void) unlink(t_name); 82 return (EX_UPDATE); 83 } 84 85 p_curr = ftell(e_fptr); 86 87 /* Make TMP file look like we want project file to look */ 88 89 while (fgets(p_string, NSS_LINELEN_PROJECT - 1, e_fptr)) { 90 /* While there is another group string */ 91 92 p_length = strlen(p_string); 93 (void) fseek(e_fptr, p_curr, SEEK_SET); 94 p_ptr = fgetprojent(e_fptr, &p_work, &workbuf, 95 sizeof (workbuf)); 96 p_curr = ftell(e_fptr); 97 98 if (p_ptr == NULL) { 99 /* 100 * tried to parse a proj string over 101 * NSS_LINELEN_PROJECT chars 102 */ 103 errmsg(M_PROJ_ENTRY_OVF, NSS_LINELEN_PROJECT); 104 modified = 0; /* bad project file: cannot rebuild */ 105 break; 106 } 107 108 /* first delete the login from the project, if it's there */ 109 if (overwrite || !projids) { 110 if (p_ptr->pj_users != NULL) { 111 for (memptr = p_ptr->pj_users; *memptr; 112 memptr++) { 113 if (strcmp(*memptr, login) == 0) { 114 /* Delete this one */ 115 char **from = memptr + 1; 116 p_length -= (strlen(*memptr)+1); 117 do { 118 *(from - 1) = *from; 119 } while (*from++); 120 121 modified++; 122 break; 123 } 124 } 125 } 126 } 127 128 /* now check to see if project is one to add to */ 129 if (projids) { 130 for (i = 0; projids[i] != -1; i++) { 131 if (p_ptr->pj_projid == projids[i]) { 132 /* Scan for dups */ 133 exist = 0; 134 for (memptr = p_ptr->pj_users; *memptr; 135 memptr++) { 136 if (strncmp(*memptr, new_login ? 137 new_login : login, 138 strlen(*memptr)) == 0) 139 exist++; 140 } 141 p_length += strlen(new_login ? 142 new_login : login) + 1; 143 144 if (p_length >= 145 NSS_LINELEN_PROJECT - 1) { 146 errmsg(M_PROJ_ENTRY_OVF, 147 NSS_LINELEN_PROJECT); 148 break; 149 } else { 150 if (!exist) { 151 *memptr++ = new_login ? 152 new_login : login; 153 *memptr = NULL; 154 modified++; 155 } 156 } 157 } 158 } 159 } 160 putprojent(p_ptr, t_fptr); 161 } 162 163 (void) fclose(e_fptr); 164 (void) fclose(t_fptr); 165 166 /* Now, update project file, if it was modified */ 167 if (modified && rename(t_name, PROJF_PATH) < 0) { 168 (void) unlink(t_name); 169 return (EX_UPDATE); 170 } 171 172 (void) unlink(t_name); 173 return (EX_SUCCESS); 174 } 175