xref: /haiku/src/add-ons/kernel/file_systems/netfs/netfs_server_prefs/NetFSServerPrefs.cpp (revision 610f99c838cb661ff85377789ffd3ad4ff672a08)
1 // NetFSServerPrefs.cpp
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 
7 #include <Application.h>
8 #include <Message.h>
9 
10 #include "NetFSServerRoster.h"
11 #include "Permissions.h"
12 
13 // simplified permissions
14 static const uint32 kMountPermission = MOUNT_SHARE_PERMISSION;
15 static const uint32 kQueryPermission = QUERY_SHARE_PERMISSION;
16 static const uint32 kReadPermission
17 	= READ_PERMISSION | READ_DIR_PERMISSION | RESOLVE_DIR_ENTRY_PERMISSION;
18 static const uint32 kWritePermission
19 	= WRITE_PERMISSION | WRITE_DIR_PERMISSION;
20 
21 // usage
22 static const char* kUsage =
23 "Usage: netfs_server_prefs -h | --help\n"
24 "       netfs_server_prefs <command>\n"
25 "options:\n"
26 "  -h, --help        - print this text\n"
27 "\n"
28 "commands:\n"
29 "  launch\n"
30 "      launches the server\n"
31 "  terminate\n"
32 "      terminates the server\n"
33 "  save\n"
34 "      saves the server settings\n"
35 "  l, list\n"
36 "      list all users and all shares\n"
37 "  add share <name> <path>\n"
38 "      add a new share with the name <name> and path <path>\n"
39 "  remove share <name>\n"
40 "      remove the share named <name>\n"
41 "  add user <name> [ <password> ]\n"
42 "      add a new user with the name <name> and, if supplied, \n"
43 "      password <password>\n"
44 "  remove user <name>\n"
45 "      remove the user named <name>\n"
46 "  permissions <user> <share> [ m ] [ r ] [ w ] [ q ]\n"
47 "      set the permissions of user <user> for share <share> to m(ount),\n"
48 "      r(ead), w(rite), and/or q(uery).\n"
49 ;
50 
51 // print_usage
52 static
53 void
54 print_usage(bool error)
55 {
56 	fputs(kUsage, (error ? stderr : stdout));
57 }
58 
59 // print_usage_and_exit
60 static
61 void
62 print_usage_and_exit(bool error)
63 {
64 	print_usage(error);
65 	exit(error ? 1 : 0);
66 }
67 
68 // get_permissions_string
69 static
70 void
71 get_permissions_string(uint32 permissions, char* str)
72 {
73 	str[0] = (permissions & kMountPermission ? 'm' : '-');
74 	str[1] = (permissions & kReadPermission ? 'r' : '-');
75 	str[2] = (permissions & kWritePermission ? 'w' : '-');
76 	str[3] = (permissions & kQueryPermission ? 'q' : '-');
77 	str[4] = '\0';
78 }
79 
80 // get_permissions
81 static
82 bool
83 get_permissions(const char* str, uint32* permissions)
84 {
85 	*permissions = 0;
86 
87 	if (!str)
88 		return true;
89 
90 	while (*str) {
91 		switch (*str) {
92 			case 'm':
93 				*permissions |= kMountPermission;
94 				break;
95 			case 'r':
96 				*permissions |= kReadPermission;
97 				break;
98 			case 'w':
99 				*permissions |= kWritePermission;
100 				break;
101 			case 'q':
102 				*permissions |= kQueryPermission;
103 				break;
104 			default:
105 				return false;
106 		}
107 		str++;
108 	}
109 
110 	return true;
111 }
112 
113 // assert_server_running
114 static
115 void
116 assert_server_running()
117 {
118 	// check, if the server is running
119 	NetFSServerRoster roster;
120 	if (!roster.IsServerRunning()) {
121 		fprintf(stderr, "Server is not running.\n");
122 		exit(1);
123 	}
124 }
125 
126 // list
127 static
128 void
129 list()
130 {
131 	assert_server_running();
132 
133 	NetFSServerRoster roster;
134 
135 	// get the users
136 	BMessage users;
137 	status_t error = roster.GetUsers(&users);
138 	if (error == B_OK) {
139 		// list the users
140 		printf("users\n");
141 		printf("-----\n");
142 		const char* user;
143 		for (int32 i = 0; users.FindString("users", i, &user) == B_OK; i++)
144 			printf("%s\n", user);
145 		printf("\n");
146 	} else
147 		fprintf(stderr, "Failed to get users: %s\n", strerror(error));
148 
149 	// get the shares
150 	BMessage shares;
151 	error = roster.GetShares(&shares);
152 	if (error == B_OK) {
153 		// list the shares
154 		printf("shares\n");
155 		printf("------\n");
156 		const char* share;
157 		for (int32 i = 0; shares.FindString("shares", i, &share) == B_OK; i++) {
158 			// get path
159 			const char* path;
160 			if (shares.FindString("paths", i, &path) != B_OK)
161 				path = "<invalid path>\n";
162 
163 			// get share users
164 			BMessage shareUsers;
165 			roster.GetShareUsers(share, &shareUsers);
166 
167 			// get statistics
168 			BMessage statistics;
169 			roster.GetShareStatistics(share, &statistics);
170 
171 			printf("%s:\n", share);
172 			printf("  path:         %s\n", path);
173 
174 			// print permitted users
175 			printf("  mountable by: ");
176 			const char* user;
177 			for (int32 k = 0;
178 				 shareUsers.FindString("users", k, &user) == B_OK;
179 				 k++) {
180 				if (k > 0)
181 					printf(", ");
182 				printf("%s", user);
183 
184 				// print permissions
185 				uint32 permissions = 0;
186 				roster.GetUserPermissions(share, user, &permissions);
187 				char permissionsString[8];
188 				get_permissions_string(permissions, permissionsString);
189 				printf(" (%s)", permissionsString);
190 			}
191 			printf("\n");
192 
193 			// print current users
194 			printf("  mounted by:   ");
195 			for (int32 k = 0;
196 				 statistics.FindString("mounted by", k, &user) == B_OK;
197 				 k++) {
198 				if (k > 0)
199 					printf(", ");
200 				printf("%s", user);
201 			}
202 			printf("\n");
203 
204 			printf("\n");
205 		}
206 	} else
207 		fprintf(stderr, "Failed to get users: %s\n", strerror(error));
208 }
209 
210 // add_share
211 static
212 void
213 add_share(const char* name, const char* path)
214 {
215 	assert_server_running();
216 
217 	NetFSServerRoster roster;
218 
219 	// check whether a share with the given name already exists
220 	BMessage statistics;
221 	if (roster.GetShareStatistics(name, &statistics) == B_OK) {
222 		fprintf(stderr, "A share `%s' does already exist.\n", name);
223 		exit(1);
224 	}
225 
226 	// add the share
227 	status_t error = roster.AddShare(name, path);
228 	if (error != B_OK) {
229 		fprintf(stderr, "Failed to add share: %s\n", strerror(error));
230 		exit(1);
231 	}
232 }
233 
234 // remove_share
235 static
236 void
237 remove_share(const char* name)
238 {
239 	assert_server_running();
240 
241 	NetFSServerRoster roster;
242 
243 	// check whether a share with the given name exists
244 	BMessage statistics;
245 	if (roster.GetShareStatistics(name, &statistics) != B_OK) {
246 		fprintf(stderr, "A share `%s' does not exist.\n", name);
247 		exit(1);
248 	}
249 
250 	// remove the share
251 	status_t error = roster.RemoveShare(name);
252 	if (error != B_OK) {
253 		fprintf(stderr, "Failed to remove share: %s\n", strerror(error));
254 		exit(1);
255 	}
256 }
257 
258 // add_user
259 static
260 void
261 add_user(const char* name, const char* password)
262 {
263 	assert_server_running();
264 
265 	NetFSServerRoster roster;
266 
267 	// check whether a user with the given name already exists
268 	BMessage statistics;
269 	if (roster.GetUserStatistics(name, &statistics) == B_OK) {
270 		fprintf(stderr, "A user `%s' does already exist.\n", name);
271 		exit(1);
272 	}
273 
274 	// add the user
275 	status_t error = roster.AddUser(name, password);
276 	if (error != B_OK) {
277 		fprintf(stderr, "Failed to add user: %s\n", strerror(error));
278 		exit(1);
279 	}
280 }
281 
282 // remove_user
283 static
284 void
285 remove_user(const char* name)
286 {
287 	assert_server_running();
288 
289 	NetFSServerRoster roster;
290 
291 	// check whether a user with the given name exists
292 	BMessage statistics;
293 	if (roster.GetUserStatistics(name, &statistics) != B_OK) {
294 		fprintf(stderr, "A user `%s' does not exist.\n", name);
295 		exit(1);
296 	}
297 
298 	// remove the user
299 	status_t error = roster.RemoveUser(name);
300 	if (error != B_OK) {
301 		fprintf(stderr, "Failed to remove user: %s\n", strerror(error));
302 		exit(1);
303 	}
304 }
305 
306 // set_user_permissions
307 static
308 void
309 set_user_permissions(const char* user, const char* share, uint32 permissions)
310 {
311 	assert_server_running();
312 
313 	NetFSServerRoster roster;
314 
315 	// check whether a user with the given name exists
316 	BMessage statistics;
317 	if (roster.GetUserStatistics(user, &statistics) != B_OK) {
318 		fprintf(stderr, "A user `%s' does not exist.\n", user);
319 		exit(1);
320 	}
321 
322 	// check whether a share with the given name exists
323 	if (roster.GetShareStatistics(share, &statistics) != B_OK) {
324 		fprintf(stderr, "A share `%s' does not exist.\n", share);
325 		exit(1);
326 	}
327 
328 	// set the permissions
329 	status_t error = roster.SetUserPermissions(share, user, permissions);
330 	if (error != B_OK) {
331 		fprintf(stderr, "Failed to set permissions: %s\n", strerror(error));
332 		exit(1);
333 	}
334 }
335 
336 // launch_server
337 static
338 void
339 launch_server()
340 {
341 	NetFSServerRoster roster;
342 
343 	if (roster.IsServerRunning()) {
344 		fprintf(stderr, "Server is already running.\n");
345 		exit(1);
346 	}
347 
348 	status_t error = roster.LaunchServer();
349 	if (error != B_OK) {
350 		fprintf(stderr, "Failed to launch server: %s\n", strerror(error));
351 		exit(1);
352 	}
353 }
354 
355 // terminate_server
356 static
357 void
358 terminate_server()
359 {
360 	assert_server_running();
361 
362 	NetFSServerRoster roster;
363 
364 	status_t error = roster.TerminateServer();
365 	if (error != B_OK) {
366 		fprintf(stderr, "Failed to terminate server: %s\n", strerror(error));
367 		exit(1);
368 	}
369 }
370 
371 // save_server_setttings
372 static
373 void
374 save_server_setttings()
375 {
376 	assert_server_running();
377 
378 	NetFSServerRoster roster;
379 
380 	status_t error = roster.SaveServerSettings();
381 	if (error != B_OK) {
382 		fprintf(stderr, "Failed to save settings: %s\n", strerror(error));
383 		exit(1);
384 	}
385 }
386 
387 // next_arg
388 static
389 const char*
390 next_arg(int argc, char** argv, int& argi, bool dontFail = false)
391 {
392 	if (argi >= argc) {
393 		if (dontFail)
394 			return NULL;
395 		print_usage_and_exit(true);
396 	}
397 
398 	return argv[argi++];
399 }
400 
401 // no_more_args
402 static
403 void
404 no_more_args(int argc, int argi)
405 {
406 	if (argi < argc)
407 		print_usage_and_exit(true);
408 }
409 
410 // main
411 int
412 main(int argc, char** argv)
413 {
414 	BApplication app("application/x-vnd.haiku-netfs_server_prefs");
415 
416 	// parse first argument
417 	int argi = 1;
418 	const char* arg = next_arg(argc, argv, argi);
419 	if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0)
420 		print_usage_and_exit(false);
421 
422 	if (strcmp(arg, "launch") == 0) {
423 		// launch
424 		no_more_args(argc, argi);
425 		launch_server();
426 	} else if (strcmp(arg, "terminate") == 0) {
427 		// terminate
428 		no_more_args(argc, argi);
429 		terminate_server();
430 	} else if (strcmp(arg, "save") == 0) {
431 		// save
432 		no_more_args(argc, argi);
433 		save_server_setttings();
434 	} else if (strcmp(arg, "l") == 0 || strcmp(arg, "list") == 0) {
435 		// list
436 		no_more_args(argc, argi);
437 		list();
438 	} else if (strcmp(arg, "add") == 0) {
439 		// add
440 		arg = next_arg(argc, argv, argi);
441 		if (strcmp(arg, "share") == 0) {
442 			// share
443 			const char* name = next_arg(argc, argv, argi);
444 			const char* path = next_arg(argc, argv, argi);
445 			no_more_args(argc, argi);
446 			add_share(name, path);
447 		} else if (strcmp(arg, "user") == 0) {
448 			// user
449 			const char* name = next_arg(argc, argv, argi);
450 			const char* password = next_arg(argc, argv, argi, true);
451 			no_more_args(argc, argi);
452 			add_user(name, password);
453 		} else
454 			print_usage_and_exit(true);
455 	} else if (strcmp(arg, "remove") == 0) {
456 		// remove
457 		arg = next_arg(argc, argv, argi);
458 		if (strcmp(arg, "share") == 0) {
459 			// share
460 			const char* name = next_arg(argc, argv, argi);
461 			no_more_args(argc, argi);
462 			remove_share(name);
463 		} else if (strcmp(arg, "user") == 0) {
464 			// user
465 			const char* name = next_arg(argc, argv, argi);
466 			no_more_args(argc, argi);
467 			remove_user(name);
468 		} else
469 			print_usage_and_exit(true);
470 	} else if (strcmp(arg, "permissions") == 0) {
471 		// permissions
472 		const char* user = next_arg(argc, argv, argi);
473 		const char* share = next_arg(argc, argv, argi);
474 		uint32 permissions = 0;
475 		while (argi < argc) {
476 			uint32 perms = 0;
477 			arg = next_arg(argc, argv, argi);
478 			if (!get_permissions(arg, &perms))
479 				print_usage_and_exit(true);
480 			permissions |= perms;
481 		}
482 		set_user_permissions(user, share, permissions);
483 	} else {
484 		print_usage_and_exit(true);
485 	}
486 
487 	return 0;
488 }
489