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 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Traverses /etc/dfs/sharetab in order to find shared file systems 29 */ 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 #include <errno.h> 35 #include <thread.h> 36 #include <synch.h> 37 #include "libfsmgt.h" 38 #include <sharefs/share.h> 39 #include "sharetab.h" 40 41 #define SECMODES 5 42 43 /* 44 * Private variables 45 */ 46 static mutex_t sharetab_lock = DEFAULTMUTEX; 47 48 /* 49 * Private method declarations 50 */ 51 fs_sharelist_t *create_sharelist_entry(struct share *sharetab_entry, 52 int *errp); 53 54 /* 55 * Public methods 56 */ 57 58 void 59 fs_free_share_list(fs_sharelist_t *headp) 60 { 61 fs_sharelist_t *tmp; 62 63 while (headp != NULL) { 64 tmp = headp->next; 65 free(headp->path); 66 free(headp->resource); 67 free(headp->fstype); 68 free(headp->options); 69 free(headp->description); 70 headp->next = NULL; 71 free(headp); 72 73 headp = tmp; 74 } 75 } 76 77 /* 78 * Get a linked list of all the shares on the system from /etc/dfs/dfstab 79 */ 80 fs_sharelist_t * 81 fs_get_share_list(int *errp) 82 { 83 fs_sharelist_t *newp; 84 fs_sharelist_t *headp; 85 fs_sharelist_t *tailp; 86 FILE *fp; 87 88 headp = NULL; 89 tailp = NULL; 90 91 if ((fp = fopen(SHARETAB, "r")) != NULL) { 92 struct share *sharetab_entry; 93 94 (void) mutex_lock(&sharetab_lock); 95 while (getshare(fp, &sharetab_entry) > 0) { 96 97 newp = create_sharelist_entry(sharetab_entry, errp); 98 if (newp == NULL) { 99 /* 100 * Out of memory 101 */ 102 fs_free_share_list(headp); 103 (void) mutex_unlock(&sharetab_lock); 104 (void) fclose(fp); 105 return (NULL); 106 } 107 108 if (headp == NULL) { 109 headp = newp; 110 tailp = newp; 111 } else { 112 tailp->next = newp; 113 tailp = newp; 114 } 115 116 } /* while (getshare(fp, &sharetab_entry) != 0) */ 117 (void) mutex_unlock(&sharetab_lock); 118 (void) fclose(fp); 119 } else { 120 *errp = errno; 121 } /* if ((fp = fopen(SHARETAB, "r")) != NULL) */ 122 123 /* 124 * Caller must free the mount list 125 */ 126 return (headp); 127 } /* fs_get_share_list */ 128 129 130 /* 131 * fs_parse_opts_for_sec_modes 132 * Get an array of strings of all the security modes of the option string. 133 * 134 * char *cmd - The option string from the share command. 135 * int *count - pointer to the number of elements in the returned array. 136 * int *error - error pointer for returning any errors. 137 */ 138 char ** 139 fs_parse_opts_for_sec_modes(char *cmd, int *count, int *error) 140 { 141 char *temp_str; 142 char **secstringarray; 143 char *strptr; 144 145 *count = 0; 146 strptr = strdup(cmd); 147 if (strptr == NULL) { 148 *error = ENOMEM; 149 return (NULL); 150 } 151 152 temp_str = strptr; 153 154 secstringarray = 155 (char **)calloc((size_t)SECMODES, (size_t)(sizeof (char *))); 156 if (secstringarray == NULL) { 157 *error = ENOMEM; 158 return (NULL); 159 } 160 161 if (strstr(strptr, "sec=") != NULL) { 162 char *next_str; 163 next_str = strptr; 164 165 while (next_str != NULL) { 166 next_str = strstr(strptr, "sec="); 167 if (next_str != NULL) { 168 if (strncmp(strptr, "sec=", 4) != 0) { 169 *(next_str - 1) = '\0'; 170 } 171 strptr = next_str; 172 next_str = strstr(strptr + 4, "sec="); 173 if (next_str != NULL) { 174 *(next_str - 1) = '\0'; 175 } 176 secstringarray[*count] = strdup(strptr); 177 if (secstringarray[*count] == NULL) { 178 *error = ENOMEM; 179 if (*count > 0) { 180 fileutil_free_string_array( 181 secstringarray, *count); 182 } else { 183 free(secstringarray); 184 } 185 free(temp_str); 186 return (NULL); 187 } 188 strptr = next_str; 189 (*count)++; 190 } 191 } 192 } else { 193 secstringarray[*count] = strdup(temp_str); 194 if (secstringarray[*count] == NULL) { 195 *error = ENOMEM; 196 if (*count > 0) { 197 fileutil_free_string_array( 198 secstringarray, *count); 199 } else { 200 free(secstringarray); 201 } 202 free(temp_str); 203 return (NULL); 204 } 205 (*count)++; 206 } 207 free(temp_str); 208 return (secstringarray); 209 } 210 211 /* 212 * fs_create_array_from_accesslist 213 * Takes the colon seperated access list parses the list into an array 214 * containing all the elements of the list. The array created is returned 215 * and count is set to the number of elements in the array. 216 * 217 * char *access_list - The string containing the colon sperated access list. 218 * int *count - Will contain the number of elements in the array. 219 * int *err - any errors encountered. 220 */ 221 char ** 222 fs_create_array_from_accesslist(char *access_list, int *count, int *err) 223 { 224 char *delimiter = ":"; 225 char *server_string; 226 char **list_array = NULL; 227 char *list_copy; 228 229 *count = 0; 230 if (access_list != NULL) { 231 list_copy = strdup(access_list); 232 if (list_copy != NULL) { 233 server_string = strtok(list_copy, delimiter); 234 if (server_string != NULL) { 235 while (server_string != NULL) { 236 if (!fileutil_add_string_to_array( 237 &list_array, server_string, count, 238 err)) { 239 fileutil_free_string_array( 240 list_array, *count); 241 free(list_copy); 242 goto return_err; 243 } 244 server_string = 245 strtok(NULL, delimiter); 246 } 247 } else { 248 list_array = 249 (char **)calloc(((*count) + 1), 250 sizeof (char *)); 251 if (list_array == NULL) { 252 *err = ENOMEM; 253 free(list_copy); 254 goto return_err; 255 } 256 list_array[*count] = strdup(access_list); 257 if (list_array[*count] == NULL) { 258 *err = ENOMEM; 259 free(list_array); 260 list_array = NULL; 261 goto return_err; 262 } 263 (*count)++; 264 } 265 free(list_copy); 266 } else { 267 *err = ENOMEM; 268 } 269 } 270 return_err: 271 return (list_array); 272 } /* fs_create_array_from_accesslist */ 273 274 275 /* 276 * Private Methods 277 */ 278 279 fs_sharelist_t * 280 create_sharelist_entry(struct share *sharetab_entry, int *errp) 281 { 282 283 fs_sharelist_t *newp; 284 285 newp = (fs_sharelist_t *)calloc((size_t)1, 286 (size_t)sizeof (fs_sharelist_t)); 287 288 if (newp == NULL) { 289 /* 290 * Out of memory 291 */ 292 *errp = errno; 293 return (NULL); 294 } 295 296 newp->path = strdup(sharetab_entry->sh_path); 297 if (newp->path == NULL) { 298 /* 299 * Out of memory 300 */ 301 *errp = errno; 302 fs_free_share_list(newp); 303 return (NULL); 304 } 305 306 newp->resource = strdup(sharetab_entry->sh_res); 307 if (newp->path == NULL) { 308 /* 309 * Out of memory 310 */ 311 *errp = errno; 312 fs_free_share_list(newp); 313 return (NULL); 314 } 315 316 newp->fstype = strdup(sharetab_entry->sh_fstype); 317 if (newp->fstype == NULL) { 318 /* 319 * Out of memory 320 */ 321 *errp = errno; 322 fs_free_share_list(newp); 323 return (NULL); 324 } 325 326 newp->options = strdup(sharetab_entry->sh_opts); 327 if (newp->options == NULL) { 328 /* 329 * Out of memory 330 */ 331 *errp = errno; 332 fs_free_share_list(newp); 333 return (NULL); 334 } 335 336 newp->description = strdup(sharetab_entry->sh_descr); 337 if (newp->description == NULL) { 338 /* 339 * Out of memory 340 */ 341 *errp = errno; 342 fs_free_share_list(newp); 343 return (NULL); 344 } 345 newp->next = NULL; 346 347 return (newp); 348 } /* create_sharelist_entry */ 349