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