summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jaildaemon.c37
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 );
55static int check_for_jail( int jid ); 56static int check_for_jail( int jid );
56static int copy_daemontask( daemon_task ** out, daemon_task * const in ); 57static int copy_daemontask( daemon_task ** out, daemon_task * const in );
57static int add_task_to_kqueue( int kq, daemon_task * task_in ); 58static int add_task_to_kqueue( int kq, daemon_task * task_in );
58static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ); 59static pid_t fork_and_jail( int jid, uid_t uid, gid_t gid, char * proctitle );
59static void fork_and_execve( int kq, daemon_task * task ); 60static void fork_and_execve( int kq, daemon_task * task );
60static int fork_fork_slave( ); 61static int fork_fork_slave( );
61static void exerr( char * message, ... ); 62static void exerr( char * message, ... );
@@ -95,7 +96,7 @@ static void exerr( char * message, ... ) {
95static void usage( char * cmd ) { 96static 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
199static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) { 201static 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 */
407int main( int argc, char **argv ) { 413int 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 ) ||