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