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