xref: /illumos-gate/usr/src/lib/libfsmgt/common/fs_shares.c (revision edd580643f2cf1434e252cd7779e83182ea84945)
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
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 *
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 **
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 **
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 *
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