diff options
author | Stefan Grundmann <sg2342@googlemail.com> | 2017-05-31 22:55:00 +0000 |
---|---|---|
committer | erdgeist <erdgeist@bauklotz.intern> | 2017-06-01 12:35:14 +0200 |
commit | 2e02e531588c28bf907b9676c8e8d085771f2ea6 (patch) | |
tree | 50f249d705f654fc29decf23b5b272f89ce081f7 | |
parent | 5384ac7db63368ab04e3d97abbe5a4e9c3bbeccf (diff) |
introduce -g switch; because -u alone will not work if security.bsd.see_other_gids=0
-rw-r--r-- | jaildaemon.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/jaildaemon.c b/jaildaemon.c index 46e14af..089b16e 100644 --- a/jaildaemon.c +++ b/jaildaemon.c | |||
@@ -44,6 +44,7 @@ typedef struct { | |||
44 | int m_jid; | 44 | int m_jid; |
45 | int m_flags; | 45 | int m_flags; |
46 | uid_t m_uid; | 46 | uid_t m_uid; |
47 | gid_t m_gid; | ||
47 | char *m_commandline; | 48 | char *m_commandline; |
48 | char *m_proctitle; | 49 | char *m_proctitle; |
49 | } daemon_task; | 50 | } daemon_task; |
@@ -55,7 +56,7 @@ static void remove_files( void ); | |||
55 | static int check_for_jail( int jid ); | 56 | static int check_for_jail( int jid ); |
56 | static int copy_daemontask( daemon_task ** out, daemon_task * const in ); | 57 | static int copy_daemontask( daemon_task ** out, daemon_task * const in ); |
57 | static int add_task_to_kqueue( int kq, daemon_task * task_in ); | 58 | static int add_task_to_kqueue( int kq, daemon_task * task_in ); |
58 | static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ); | 59 | static pid_t fork_and_jail( int jid, uid_t uid, gid_t gid, char * proctitle ); |
59 | static void fork_and_execve( int kq, daemon_task * task ); | 60 | static void fork_and_execve( int kq, daemon_task * task ); |
60 | static int fork_fork_slave( ); | 61 | static int fork_fork_slave( ); |
61 | static void exerr( char * message, ... ); | 62 | static void exerr( char * message, ... ); |
@@ -95,7 +96,7 @@ static void exerr( char * message, ... ) { | |||
95 | static void usage( char * cmd ) { | 96 | static void usage( char * cmd ) { |
96 | fprintf( stderr, | 97 | fprintf( stderr, |
97 | "%s -D [-p pidfile] [-f ipcsockpath]\n" | 98 | "%s -D [-p pidfile] [-f ipcsockpath]\n" |
98 | "%s -c command -j jid [-t proctitle] [-rR] [-u uid]" | 99 | "%s -c command -j jid [-t proctitle] [-rR] [-u uid] [-g gid]" |
99 | " [-f ipcsockpath]\n", | 100 | " [-f ipcsockpath]\n", |
100 | cmd, cmd ); | 101 | cmd, cmd ); |
101 | exit( 1 ); | 102 | exit( 1 ); |
@@ -130,7 +131,8 @@ static void fork_slave( int master_fd ) { | |||
130 | /* Decode packet and throw a forked child */ | 131 | /* Decode packet and throw a forked child */ |
131 | *(pid_t*)g_ipc_packet = fork_and_jail( | 132 | *(pid_t*)g_ipc_packet = fork_and_jail( |
132 | g_ipc_packet_int[0], (uid_t)g_ipc_packet_int[1], | 133 | g_ipc_packet_int[0], (uid_t)g_ipc_packet_int[1], |
133 | g_ipc_packet + 2 * sizeof(int) ); | 134 | (gid_t)g_ipc_packet_int[2], |
135 | g_ipc_packet + 3 * sizeof(int) ); | ||
134 | if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != | 136 | if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != |
135 | sizeof(pid_t) ) | 137 | sizeof(pid_t) ) |
136 | exerr( "Error: Can not reply to master." ); | 138 | exerr( "Error: Can not reply to master." ); |
@@ -196,7 +198,7 @@ static int check_for_jail( int jid ) { | |||
196 | return -1; | 198 | return -1; |
197 | } | 199 | } |
198 | 200 | ||
199 | static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { | 201 | static pid_t fork_and_jail( int jid, uid_t uid, gid_t gid, char * proctitle ) { |
200 | int sig; | 202 | int sig; |
201 | pid_t pid = fork(); | 203 | pid_t pid = fork(); |
202 | if( !pid ) { | 204 | if( !pid ) { |
@@ -213,6 +215,7 @@ static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { | |||
213 | exerr( "Error: Can not attach process to jail %d.", jid ); | 215 | exerr( "Error: Can not attach process to jail %d.", jid ); |
214 | 216 | ||
215 | /* If we're supposed to drop privileges, do it now */ | 217 | /* If we're supposed to drop privileges, do it now */ |
218 | setgid( gid ); | ||
216 | setuid( uid ); | 219 | setuid( uid ); |
217 | 220 | ||
218 | /* wait for SIGHUP */ | 221 | /* wait for SIGHUP */ |
@@ -235,6 +238,7 @@ static int copy_daemontask( daemon_task ** out, daemon_task * const in ) { | |||
235 | t->m_jid = in->m_jid; | 238 | t->m_jid = in->m_jid; |
236 | t->m_flags = in->m_flags; | 239 | t->m_flags = in->m_flags; |
237 | t->m_uid = in->m_uid; | 240 | t->m_uid = in->m_uid; |
241 | t->m_gid = in->m_gid; | ||
238 | t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; | 242 | t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; |
239 | t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; | 243 | t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; |
240 | 244 | ||
@@ -342,9 +346,10 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { | |||
342 | memset( g_ipc_packet, 0, IPC_PACKETSIZE ); | 346 | memset( g_ipc_packet, 0, IPC_PACKETSIZE ); |
343 | g_ipc_packet_int[0] = t->m_jid; | 347 | g_ipc_packet_int[0] = t->m_jid; |
344 | g_ipc_packet_int[1] = t->m_uid; | 348 | g_ipc_packet_int[1] = t->m_uid; |
349 | g_ipc_packet_int[2] = t->m_gid; | ||
345 | if( t->m_proctitle ) | 350 | if( t->m_proctitle ) |
346 | strncpy( g_ipc_packet + 2 * sizeof(int), t->m_proctitle, | 351 | strncpy( g_ipc_packet + 3 * sizeof(int), t->m_proctitle, |
347 | IPC_PACKETSIZE - 2 * sizeof(int) ); | 352 | IPC_PACKETSIZE - 3 * sizeof(int) ); |
348 | if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != | 353 | if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != |
349 | IPC_PACKETSIZE ) | 354 | IPC_PACKETSIZE ) |
350 | exerr( "Error: Can not send task to fork slave." ); | 355 | exerr( "Error: Can not send task to fork slave." ); |
@@ -402,7 +407,8 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) { | |||
402 | } | 407 | } |
403 | 408 | ||
404 | /* jaildaemon -D [-ppidfile] [-fipcsockpath] | 409 | /* jaildaemon -D [-ppidfile] [-fipcsockpath] |
405 | jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-fipsockpath] | 410 | jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-g gid] |
411 | [-fipsockpath] | ||
406 | */ | 412 | */ |
407 | int main( int argc, char **argv ) { | 413 | int main( int argc, char **argv ) { |
408 | pid_t second_pid; | 414 | pid_t second_pid; |
@@ -411,6 +417,7 @@ int main( int argc, char **argv ) { | |||
411 | int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; | 417 | int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; |
412 | char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; | 418 | char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; |
413 | uid_t o_uid = 0; | 419 | uid_t o_uid = 0; |
420 | gid_t o_gid = 0; | ||
414 | struct kevent ke; | 421 | struct kevent ke; |
415 | struct sockaddr_un addr; | 422 | struct sockaddr_un addr; |
416 | struct sigaction sa; | 423 | struct sigaction sa; |
@@ -423,7 +430,7 @@ int main( int argc, char **argv ) { | |||
423 | 430 | ||
424 | i=1; | 431 | i=1; |
425 | while(i) { | 432 | while(i) { |
426 | switch( getopt( argc, argv, "DFrRt:c:j:p:u:f:" ) ) { | 433 | switch( getopt( argc, argv, "DFrRt:c:j:p:u:g:f:" ) ) { |
427 | case -1: i=0; break; | 434 | case -1: i=0; break; |
428 | case 'D': o_daemonize = 1; break; | 435 | case 'D': o_daemonize = 1; break; |
429 | case 'r': o_respawn = TASK_RESPAWN; break; | 436 | case 'r': o_respawn = TASK_RESPAWN; break; |
@@ -432,6 +439,7 @@ int main( int argc, char **argv ) { | |||
432 | case 'c': o_command = optarg; break; | 439 | case 'c': o_command = optarg; break; |
433 | case 'j': o_jid = jail_getid(optarg); break; | 440 | case 'j': o_jid = jail_getid(optarg); break; |
434 | case 'u': o_uid = strtol( optarg, 0, 0 ); break; | 441 | case 'u': o_uid = strtol( optarg, 0, 0 ); break; |
442 | case 'g': o_gid = strtol( optarg, 0, 0 ); break; | ||
435 | case 'p': o_pidfile = optarg; break; | 443 | case 'p': o_pidfile = optarg; break; |
436 | case 'f': g_uds_path = optarg; break; | 444 | case 'f': g_uds_path = optarg; break; |
437 | case 'F': o_force_daemon = 1; break; | 445 | case 'F': o_force_daemon = 1; break; |
@@ -463,6 +471,7 @@ int main( int argc, char **argv ) { | |||
463 | int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING | 471 | int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING |
464 | int m_jid | 472 | int m_jid |
465 | int m_uid | 473 | int m_uid |
474 | int m_gid | ||
466 | int m_commandline_length | 475 | int m_commandline_length |
467 | int m_proctitle_length | 476 | int m_proctitle_length |
468 | char[] command_line \0 | 477 | char[] command_line \0 |
@@ -470,7 +479,7 @@ int main( int argc, char **argv ) { | |||
470 | */ | 479 | */ |
471 | size_t o_command_len = strlen(o_command); | 480 | size_t o_command_len = strlen(o_command); |
472 | size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; | 481 | size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; |
473 | char *text_off = (char*)(g_ipc_packet_int + 5); | 482 | char *text_off = (char*)(g_ipc_packet_int + 6); |
474 | 483 | ||
475 | if( text_off + 2 + o_command_len + o_proctitle_len > | 484 | if( text_off + 2 + o_command_len + o_proctitle_len > |
476 | g_ipc_packet + IPC_PACKETSIZE ) | 485 | g_ipc_packet + IPC_PACKETSIZE ) |
@@ -479,8 +488,9 @@ int main( int argc, char **argv ) { | |||
479 | g_ipc_packet_int[0] = o_respawn; | 488 | g_ipc_packet_int[0] = o_respawn; |
480 | g_ipc_packet_int[1] = o_jid; | 489 | g_ipc_packet_int[1] = o_jid; |
481 | g_ipc_packet_int[2] = o_uid; | 490 | g_ipc_packet_int[2] = o_uid; |
482 | g_ipc_packet_int[3] = o_command_len; | 491 | g_ipc_packet_int[3] = o_gid; |
483 | g_ipc_packet_int[4] = o_proctitle_len; | 492 | g_ipc_packet_int[4] = o_command_len; |
493 | g_ipc_packet_int[5] = o_proctitle_len; | ||
484 | memcpy( text_off, o_command, o_command_len + 1 ); | 494 | memcpy( text_off, o_command, o_command_len + 1 ); |
485 | if( o_proctitle_len ) { | 495 | if( o_proctitle_len ) { |
486 | text_off += o_command_len + 1; | 496 | text_off += o_command_len + 1; |
@@ -640,7 +650,7 @@ int main( int argc, char **argv ) { | |||
640 | break; | 650 | break; |
641 | case EVFILT_READ: | 651 | case EVFILT_READ: |
642 | if( (int)ke.ident == g_uds ) { | 652 | if( (int)ke.ident == g_uds ) { |
643 | char *text_off = (char*)(g_ipc_packet_int + 5); | 653 | char *text_off = (char*)(g_ipc_packet_int + 6); |
644 | socklen_t fromlen; | 654 | socklen_t fromlen; |
645 | daemon_task task; | 655 | daemon_task task; |
646 | 656 | ||
@@ -659,8 +669,9 @@ int main( int argc, char **argv ) { | |||
659 | task.m_flags = g_ipc_packet_int[0]; | 669 | task.m_flags = g_ipc_packet_int[0]; |
660 | task.m_jid = g_ipc_packet_int[1]; | 670 | task.m_jid = g_ipc_packet_int[1]; |
661 | task.m_uid = g_ipc_packet_int[2]; | 671 | task.m_uid = g_ipc_packet_int[2]; |
672 | task.m_gid = g_ipc_packet_int[3]; | ||
662 | task.m_commandline = text_off; | 673 | task.m_commandline = text_off; |
663 | text_off += g_ipc_packet_int[3]; | 674 | text_off += g_ipc_packet_int[4]; |
664 | 675 | ||
665 | /* Sanity check on string length, expect terminator */ | 676 | /* Sanity check on string length, expect terminator */ |
666 | if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || | 677 | if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || |