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
fs_free_share_list(fs_sharelist_t * headp)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 *
fs_get_share_list(int * errp)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 **
fs_parse_opts_for_sec_modes(char * cmd,int * count,int * error)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 **
fs_create_array_from_accesslist(char * access_list,int * count,int * err)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 *
create_sharelist_entry(struct share * sharetab_entry,int * errp)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