summaryrefslogtreecommitdiffstats
path: root/usbmuxd/main.c
diff options
context:
space:
mode:
authorGravatar Hector Martin2009-08-19 01:35:31 +0200
committerGravatar Hector Martin2009-08-19 01:35:31 +0200
commit00928c2127234a085f37be45ef59b9347f453145 (patch)
treee01f64df2283e2260c8fff6234821ea5975ff962 /usbmuxd/main.c
parentd23a2142685b943c4a944ae28d6658c4f562e79e (diff)
downloadusbmuxd-00928c2127234a085f37be45ef59b9347f453145.tar.gz
usbmuxd-00928c2127234a085f37be45ef59b9347f453145.tar.bz2
Change privilege dropping
- make it use a specific user (for usb access) - swap around -u and -d command line flags to be more in line with other apps (-u==--user) - improve privilege dropping and make sure we get additional group access
Diffstat (limited to 'usbmuxd/main.c')
-rw-r--r--usbmuxd/main.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/usbmuxd/main.c b/usbmuxd/main.c
index ec52ce0..f1aa1cc 100644
--- a/usbmuxd/main.c
+++ b/usbmuxd/main.c
@@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36#include <sys/fcntl.h> 36#include <sys/fcntl.h>
37#include <getopt.h> 37#include <getopt.h>
38#include <pwd.h> 38#include <pwd.h>
39#include <grp.h>
39 40
40#include "log.h" 41#include "log.h"
41#include "usb.h" 42#include "usb.h"
@@ -50,6 +51,7 @@ int should_exit;
50static int verbose = 0; 51static int verbose = 0;
51static int foreground = 0; 52static int foreground = 0;
52static int drop_privileges = 0; 53static int drop_privileges = 0;
54static const char *drop_user = "usbmux";
53static int opt_udev = 0; 55static int opt_udev = 0;
54static int opt_exit = 0; 56static int opt_exit = 0;
55static int exit_signal = 0; 57static int exit_signal = 0;
@@ -236,8 +238,9 @@ static void usage()
236 printf("\t-h|--help Print this message.\n"); 238 printf("\t-h|--help Print this message.\n");
237 printf("\t-v|--verbose Be verbose (use twice or more to increase).\n"); 239 printf("\t-v|--verbose Be verbose (use twice or more to increase).\n");
238 printf("\t-f|--foreground Do not daemonize (implies one -v).\n"); 240 printf("\t-f|--foreground Do not daemonize (implies one -v).\n");
239 printf("\t-d|--drop-privileges Drop privileges after startup.\n"); 241 printf("\t-u|--user[=USER] Change to this user after startup (needs usb privileges).\n");
240 printf("\t-u|--udev Run in udev operation mode.\n"); 242 printf("\t If USER is not specified, defaults to usbmux.\n");
243 printf("\t-d|--udev Run in udev operation mode.\n");
241 printf("\t-x|--exit Tell a running instance to exit.\n"); 244 printf("\t-x|--exit Tell a running instance to exit.\n");
242 printf("\t-X|--force-exit Tell a running instance to exit, even if\n"); 245 printf("\t-X|--force-exit Tell a running instance to exit, even if\n");
243 printf("\t there are still devices connected.\n"); 246 printf("\t there are still devices connected.\n");
@@ -250,8 +253,8 @@ static void parse_opts(int argc, char **argv)
250 {"help", 0, NULL, 'h'}, 253 {"help", 0, NULL, 'h'},
251 {"foreground", 0, NULL, 'f'}, 254 {"foreground", 0, NULL, 'f'},
252 {"verbose", 0, NULL, 'v'}, 255 {"verbose", 0, NULL, 'v'},
253 {"drop-privileges", 0, NULL, 'd'}, 256 {"user", 2, NULL, 'u'},
254 {"udev", 0, NULL, 'u'}, 257 {"udev", 0, NULL, 'd'},
255 {"exit", 0, NULL, 'x'}, 258 {"exit", 0, NULL, 'x'},
256 {"force-exit", 0, NULL, 'X'}, 259 {"force-exit", 0, NULL, 'X'},
257 {NULL, 0, NULL, 0} 260 {NULL, 0, NULL, 0}
@@ -259,7 +262,7 @@ static void parse_opts(int argc, char **argv)
259 int c; 262 int c;
260 263
261 while (1) { 264 while (1) {
262 c = getopt_long(argc, argv, "hfvduxX", longopts, (int *) 0); 265 c = getopt_long(argc, argv, "hfvdu::xX", longopts, (int *) 0);
263 if (c == -1) { 266 if (c == -1) {
264 break; 267 break;
265 } 268 }
@@ -274,10 +277,12 @@ static void parse_opts(int argc, char **argv)
274 case 'v': 277 case 'v':
275 ++verbose; 278 ++verbose;
276 break; 279 break;
277 case 'd': 280 case 'u':
278 drop_privileges = 1; 281 drop_privileges = 1;
282 if(optarg)
283 drop_user = optarg;
279 break; 284 break;
280 case 'u': 285 case 'd':
281 opt_udev = 1; 286 opt_udev = 1;
282 break; 287 break;
283 case 'x': 288 case 'x':
@@ -403,23 +408,38 @@ int main(int argc, char *argv[])
403 408
404 // drop elevated privileges 409 // drop elevated privileges
405 if (drop_privileges && (getuid() == 0 || geteuid() == 0)) { 410 if (drop_privileges && (getuid() == 0 || geteuid() == 0)) {
406 struct passwd *pw = getpwnam("nobody"); 411 struct passwd *pw = getpwnam(drop_user);
407 if (pw) { 412 if (!pw) {
408 setuid(pw->pw_uid); 413 usbmuxd_log(LL_FATAL, "Dropping privileges failed, check if user '%s' exists!", drop_user);
409 } else { 414 res = 1;
410 usbmuxd_log(LL_ERROR, 415 goto terminate;
411 "ERROR: Dropping privileges failed, check if user 'nobody' exists! Will now terminate."); 416 }
412 log_disable_syslog(); 417
413 exit(EXIT_FAILURE); 418 if ((res = initgroups(drop_user, pw->pw_gid)) < 0) {
419 usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set supplementary groups)");
420 goto terminate;
421 }
422 if ((res = setgid(pw->pw_gid)) < 0) {
423 usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set group ID to %d)", pw->pw_gid);
424 goto terminate;
425 }
426 if ((res = setuid(pw->pw_uid)) < 0) {
427 usbmuxd_log(LL_FATAL, "Failed to drop privileges (cannot set user ID to %d)", pw->pw_uid);
428 goto terminate;
414 } 429 }
415 430
416 // security check 431 // security check
417 if (setuid(0) != -1) { 432 if (setuid(0) != -1) {
418 usbmuxd_log(LL_ERROR, "ERROR: Failed to drop privileges properly!"); 433 usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!");
419 log_disable_syslog(); 434 res = 1;
420 exit(EXIT_FAILURE); 435 goto terminate;
436 }
437 if (getuid() != pw->pw_uid || getgid() != pw->pw_gid) {
438 usbmuxd_log(LL_FATAL, "Failed to drop privileges properly!");
439 res = 1;
440 goto terminate;
421 } 441 }
422 usbmuxd_log(LL_NOTICE, "Successfully dropped privileges"); 442 usbmuxd_log(LL_NOTICE, "Successfully dropped privileges to '%s'", drop_user);
423 } 443 }
424 444
425 res = main_loop(listenfd); 445 res = main_loop(listenfd);