summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jaildaemon.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/jaildaemon.c b/jaildaemon.c
index a4e2d8d..62dcc51 100644
--- a/jaildaemon.c
+++ b/jaildaemon.c
@@ -42,6 +42,7 @@ static size_t g_probes_size;
42typedef struct { 42typedef struct {
43 int m_jid; 43 int m_jid;
44 int m_flags; 44 int m_flags;
45 uid_t m_uid;
45 char *m_commandline; 46 char *m_commandline;
46 char *m_proctitle; 47 char *m_proctitle;
47} daemon_task; 48} daemon_task;
@@ -53,7 +54,7 @@ static void remove_files( void );
53static int check_for_jail( int jid ); 54static int check_for_jail( int jid );
54static int copy_daemontask( daemon_task ** out, daemon_task * const in ); 55static int copy_daemontask( daemon_task ** out, daemon_task * const in );
55static int add_task_to_kqueue( int kq, daemon_task * task_in ); 56static int add_task_to_kqueue( int kq, daemon_task * task_in );
56static pid_t fork_and_jail( int jid, char * proctitle ); 57static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle );
57static void fork_and_execve( int kq, daemon_task * task ); 58static void fork_and_execve( int kq, daemon_task * task );
58static int fork_fork_slave( ); 59static int fork_fork_slave( );
59static void exerr( char * message, ... ); 60static void exerr( char * message, ... );
@@ -92,8 +93,9 @@ static void exerr( char * message, ... ) {
92/* Report syntax of command line arguments to the user */ 93/* Report syntax of command line arguments to the user */
93static void usage( char * cmd ) { 94static void usage( char * cmd ) {
94 fprintf( stderr, 95 fprintf( stderr,
95 "%s -D [-ppidfile] [-fipcsockpath]\n" 96 "%s -D [-p pidfile] [-f ipcsockpath]\n"
96 "%s -c command -j jid [-t proctitle] [-rR] [-fipcsockpath]\n", 97 "%s -c command -j jid [-t proctitle] [-rR] [-u uid] -f ipcsockpath]"
98 "\n",
97 cmd, cmd ); 99 cmd, cmd );
98 exit( 1 ); 100 exit( 1 );
99} 101}
@@ -122,7 +124,8 @@ static void fork_slave( int master_fd ) {
122 case IPC_PACKETSIZE: 124 case IPC_PACKETSIZE:
123 /* Decode packet and throw a forked child */ 125 /* Decode packet and throw a forked child */
124 *(pid_t*)g_ipc_packet = fork_and_jail( 126 *(pid_t*)g_ipc_packet = fork_and_jail(
125 g_ipc_packet_int[0], g_ipc_packet + sizeof(int) ); 127 g_ipc_packet_int[0], (uid_t)g_ipc_packet_int[1],
128 g_ipc_packet + 2 * sizeof(int) );
126 if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) != 129 if( write( master_fd, g_ipc_packet, sizeof(pid_t) ) !=
127 sizeof(pid_t) ) 130 sizeof(pid_t) )
128 exerr( "Error: Can not reply to master." ); 131 exerr( "Error: Can not reply to master." );
@@ -188,7 +191,7 @@ static int check_for_jail( int jid ) {
188 return -1; 191 return -1;
189} 192}
190 193
191static pid_t fork_and_jail( int jid, char * proctitle ) { 194static pid_t fork_and_jail( int jid, uid_t uid, char * proctitle ) {
192 int sig; 195 int sig;
193 pid_t pid = fork(); 196 pid_t pid = fork();
194 if( !pid ) { 197 if( !pid ) {
@@ -204,6 +207,9 @@ static pid_t fork_and_jail( int jid, char * proctitle ) {
204 if( jail_attach( jid ) ) 207 if( jail_attach( jid ) )
205 exerr( "Error: Can not attach process to jail %d.", jid ); 208 exerr( "Error: Can not attach process to jail %d.", jid );
206 209
210 /* If we're supposed to drop privileges, do it now */
211 setuid( uid );
212
207 /* wait for SIGHUP */ 213 /* wait for SIGHUP */
208 sigemptyset(&sigset); 214 sigemptyset(&sigset);
209 sigaddset(&sigset, SIGHUP); 215 sigaddset(&sigset, SIGHUP);
@@ -223,6 +229,7 @@ static int copy_daemontask( daemon_task ** out, daemon_task * const in ) {
223 229
224 t->m_jid = in->m_jid; 230 t->m_jid = in->m_jid;
225 t->m_flags = in->m_flags; 231 t->m_flags = in->m_flags;
232 t->m_uid = in->m_uid;
226 t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0; 233 t->m_commandline = in->m_commandline ? strdup( in->m_commandline ): 0;
227 t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0; 234 t->m_proctitle = in->m_proctitle ? strdup( in->m_proctitle ) : 0;
228 235
@@ -329,9 +336,10 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) {
329 /* Forge a command packet for fork slave and send it via control socket */ 336 /* Forge a command packet for fork slave and send it via control socket */
330 memset( g_ipc_packet, 0, IPC_PACKETSIZE ); 337 memset( g_ipc_packet, 0, IPC_PACKETSIZE );
331 g_ipc_packet_int[0] = t->m_jid; 338 g_ipc_packet_int[0] = t->m_jid;
339 g_ipc_packet_int[1] = t->m_uid;
332 if( t->m_proctitle ) 340 if( t->m_proctitle )
333 strncpy( g_ipc_packet + sizeof(int), t->m_proctitle, 341 strncpy( g_ipc_packet + 2 * sizeof(int), t->m_proctitle,
334 IPC_PACKETSIZE - sizeof(int) ); 342 IPC_PACKETSIZE - 2 * sizeof(int) );
335 if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) != 343 if( write( g_fork_slave_fd, g_ipc_packet, IPC_PACKETSIZE ) !=
336 IPC_PACKETSIZE ) 344 IPC_PACKETSIZE )
337 exerr( "Error: Can not send task to fork slave." ); 345 exerr( "Error: Can not send task to fork slave." );
@@ -389,7 +397,7 @@ static int add_task_to_kqueue( int kq, daemon_task * t_in ) {
389} 397}
390 398
391/* jaildaemon -D [-ppidfile] [-fipcsockpath] 399/* jaildaemon -D [-ppidfile] [-fipcsockpath]
392 jaildaemon -c command -j jid -t proctitle [-rR] [-fipsockpath] 400 jaildaemon -c command -j jid [-t proctitle] [-rR] [-u uid] [-fipsockpath]
393 */ 401 */
394int main( int argc, char **argv ) { 402int main( int argc, char **argv ) {
395 pid_t second_pid; 403 pid_t second_pid;
@@ -397,6 +405,7 @@ int main( int argc, char **argv ) {
397 int o_force_daemon = 0; 405 int o_force_daemon = 0;
398 int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT; 406 int o_daemonize = 0, o_jid = -1, o_respawn = TASK_SINGLESHOT;
399 char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL; 407 char *o_command = NULL, *o_pidfile = NULL, *o_proctitle = NULL;
408 uid_t o_uid = 0;
400 struct kevent ke; 409 struct kevent ke;
401 struct sockaddr_un addr; 410 struct sockaddr_un addr;
402 struct sigaction sa; 411 struct sigaction sa;
@@ -409,7 +418,7 @@ int main( int argc, char **argv ) {
409 418
410 i=1; 419 i=1;
411 while(i) { 420 while(i) {
412 switch( getopt( argc, argv, "DFrRt:c:j:p:f:" ) ) { 421 switch( getopt( argc, argv, "DFrRt:c:j:p:u:f:" ) ) {
413 case -1: i=0; break; 422 case -1: i=0; break;
414 case 'D': o_daemonize = 1; break; 423 case 'D': o_daemonize = 1; break;
415 case 'r': o_respawn = TASK_RESPAWN; break; 424 case 'r': o_respawn = TASK_RESPAWN; break;
@@ -417,6 +426,7 @@ int main( int argc, char **argv ) {
417 case 't': o_proctitle = optarg; break; 426 case 't': o_proctitle = optarg; break;
418 case 'c': o_command = optarg; break; 427 case 'c': o_command = optarg; break;
419 case 'j': o_jid = strtol( optarg, 0, 0 ); break; 428 case 'j': o_jid = strtol( optarg, 0, 0 ); break;
429 case 'u': o_uid = strtol( optarg, 0, 0 ); break;
420 case 'p': o_pidfile = optarg; break; 430 case 'p': o_pidfile = optarg; break;
421 case 'f': g_uds_path = optarg; break; 431 case 'f': g_uds_path = optarg; break;
422 case 'F': o_force_daemon = 1; break; 432 case 'F': o_force_daemon = 1; break;
@@ -447,6 +457,7 @@ int main( int argc, char **argv ) {
447 Packed packet format: 457 Packed packet format:
448 int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING 458 int m_flags: SINGLESHOT, RESPAWN, RESPAWN_IMMEDIATE, RESPAWNING
449 int m_jid 459 int m_jid
460 int m_uid
450 int m_commandline_length 461 int m_commandline_length
451 int m_proctitle_length 462 int m_proctitle_length
452 char[] command_line \0 463 char[] command_line \0
@@ -454,7 +465,7 @@ int main( int argc, char **argv ) {
454 */ 465 */
455 size_t o_command_len = strlen(o_command); 466 size_t o_command_len = strlen(o_command);
456 size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0; 467 size_t o_proctitle_len = o_proctitle ? strlen( o_proctitle ) : 0;
457 char *text_off = (char*)(g_ipc_packet_int + 4); 468 char *text_off = (char*)(g_ipc_packet_int + 5);
458 469
459 if( text_off + 2 + o_command_len + o_proctitle_len > 470 if( text_off + 2 + o_command_len + o_proctitle_len >
460 g_ipc_packet + IPC_PACKETSIZE ) 471 g_ipc_packet + IPC_PACKETSIZE )
@@ -462,8 +473,9 @@ int main( int argc, char **argv ) {
462 473
463 g_ipc_packet_int[0] = o_respawn; 474 g_ipc_packet_int[0] = o_respawn;
464 g_ipc_packet_int[1] = o_jid; 475 g_ipc_packet_int[1] = o_jid;
465 g_ipc_packet_int[2] = o_command_len; 476 g_ipc_packet_int[2] = o_uid;
466 g_ipc_packet_int[3] = o_proctitle_len; 477 g_ipc_packet_int[3] = o_command_len;
478 g_ipc_packet_int[4] = o_proctitle_len;
467 memcpy( text_off, o_command, o_command_len + 1 ); 479 memcpy( text_off, o_command, o_command_len + 1 );
468 if( o_proctitle_len ) { 480 if( o_proctitle_len ) {
469 text_off += o_command_len + 1; 481 text_off += o_command_len + 1;
@@ -623,7 +635,7 @@ int main( int argc, char **argv ) {
623 break; 635 break;
624 case EVFILT_READ: 636 case EVFILT_READ:
625 if( (int)ke.ident == g_uds ) { 637 if( (int)ke.ident == g_uds ) {
626 char *text_off = (char*)(g_ipc_packet_int + 4); 638 char *text_off = (char*)(g_ipc_packet_int + 5);
627 socklen_t fromlen; 639 socklen_t fromlen;
628 daemon_task task; 640 daemon_task task;
629 641
@@ -641,8 +653,9 @@ int main( int argc, char **argv ) {
641 653
642 task.m_flags = g_ipc_packet_int[0]; 654 task.m_flags = g_ipc_packet_int[0];
643 task.m_jid = g_ipc_packet_int[1]; 655 task.m_jid = g_ipc_packet_int[1];
656 task.m_uid = g_ipc_packet_int[2];
644 task.m_commandline = text_off; 657 task.m_commandline = text_off;
645 text_off += g_ipc_packet_int[2]; 658 text_off += g_ipc_packet_int[3];
646 659
647 /* Sanity check on string length, expect terminator */ 660 /* Sanity check on string length, expect terminator */
648 if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) || 661 if( text_off > (char *)( g_ipc_packet + IPC_PACKETSIZE ) ||
@@ -651,8 +664,8 @@ int main( int argc, char **argv ) {
651 continue; 664 continue;
652 } 665 }
653 666
654 task.m_proctitle = g_ipc_packet_int[3] ? ++text_off : 0; 667 task.m_proctitle = g_ipc_packet_int[4] ? ++text_off : 0;
655 text_off += g_ipc_packet_int[3]; 668 text_off += g_ipc_packet_int[4];
656 669
657 /* Sanity check on string length, expect terminator */ 670 /* Sanity check on string length, expect terminator */
658 if( text_off > (char *)(g_ipc_packet + IPC_PACKETSIZE) || 671 if( text_off > (char *)(g_ipc_packet + IPC_PACKETSIZE) ||