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