1 /* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <errno.h> 7 #include <getopt.h> 8 #include <grp.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <unistd.h> 13 14 #include <OS.h> 15 16 #include <RegistrarDefs.h> 17 #include <user_group.h> 18 #include <util/KMessage.h> 19 20 #include "multiuser_utils.h" 21 22 23 extern const char *__progname; 24 25 26 static const char* kUsage = 27 "Usage: %s [ <options> ] <group name>\n" 28 "Creates a new group <group name>.\n" 29 "\n" 30 "Options:\n" 31 " -h, --help\n" 32 " Print usage info.\n" 33 ; 34 35 static void 36 print_usage_and_exit(bool error) 37 { 38 fprintf(error ? stderr : stdout, kUsage, __progname); 39 exit(error ? 1 : 0); 40 } 41 42 43 int 44 main(int argc, const char* const* argv) 45 { 46 while (true) { 47 static struct option sLongOptions[] = { 48 { "help", no_argument, 0, 'h' }, 49 { 0, 0, 0, 0 } 50 }; 51 52 opterr = 0; // don't print errors 53 int c = getopt_long(argc, (char**)argv, "h", sLongOptions, NULL); 54 if (c == -1) 55 break; 56 57 58 switch (c) { 59 case 'h': 60 print_usage_and_exit(false); 61 break; 62 63 default: 64 print_usage_and_exit(true); 65 break; 66 } 67 } 68 69 if (optind != argc - 1) 70 print_usage_and_exit(true); 71 72 const char* group = argv[optind]; 73 74 if (geteuid() != 0) { 75 fprintf(stderr, "Error: Only root may add groups.\n"); 76 exit(1); 77 } 78 79 // check, if group already exists 80 if (getgrnam(group) != NULL) { 81 fprintf(stderr, "Error: Group \"%s\" already exists.\n", group); 82 exit(1); 83 } 84 85 // find an unused GID 86 gid_t gid = 100; 87 while (getgrgid(gid) != NULL) 88 gid++; 89 90 // prepare request for the registrar 91 KMessage message(BPrivate::B_REG_UPDATE_GROUP); 92 if (message.AddInt32("gid", gid) != B_OK 93 || message.AddString("name", group) != B_OK 94 || message.AddString("password", "x") != B_OK 95 || message.AddBool("add group", true) != B_OK) { 96 fprintf(stderr, "Error: Out of memory!\n"); 97 exit(1); 98 } 99 100 // send the request 101 KMessage reply; 102 status_t error = send_authentication_request_to_registrar(message, reply); 103 if (error != B_OK) { 104 fprintf(stderr, "Error: Failed to create group: %s\n", strerror(error)); 105 exit(1); 106 } 107 108 return 0; 109 } 110