Mercurial > dropbear
comparison dbutil.c @ 482:7ad49f34a122
- Add run_shell_command() function to run a "sh -c" command, handling
lots of the work that exechild did (and can be shared by client -J option)
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 15 Sep 2008 14:04:55 +0000 |
parents | 357a2e2e9bcc |
children | effb4a25b1ae |
comparison
equal
deleted
inserted
replaced
481:357a2e2e9bcc | 482:7ad49f34a122 |
---|---|
391 | 391 |
392 /* Sets up a pipe for a, returning three non-blocking file descriptors | 392 /* Sets up a pipe for a, returning three non-blocking file descriptors |
393 * and the pid. exec_fn is the function that will actually execute the child process, | 393 * and the pid. exec_fn is the function that will actually execute the child process, |
394 * it will be run after the child has fork()ed, and is passed exec_data. */ | 394 * it will be run after the child has fork()ed, and is passed exec_data. */ |
395 int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, | 395 int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, |
396 int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) | 396 int *ret_writefd, int *ret_readfd, int *ret_errfd, pid_t *ret_pid) { |
397 { | |
398 int infds[2]; | 397 int infds[2]; |
399 int outfds[2]; | 398 int outfds[2]; |
400 int errfds[2]; | 399 int errfds[2]; |
401 pid_t pid; | 400 pid_t pid; |
402 | 401 |
462 *ret_writefd = infds[FDOUT]; | 461 *ret_writefd = infds[FDOUT]; |
463 *ret_readfd = outfds[FDIN]; | 462 *ret_readfd = outfds[FDIN]; |
464 *ret_errfd = errfds[FDIN]; | 463 *ret_errfd = errfds[FDIN]; |
465 return DROPBEAR_SUCCESS; | 464 return DROPBEAR_SUCCESS; |
466 } | 465 } |
466 } | |
467 | |
468 /* Runs a command with "sh -c". Will close FDs (except stdin/stdout/stderr) and | |
469 * re-enabled SIGPIPE. If cmd is NULL, will run a login shell. | |
470 */ | |
471 void run_shell_command(const char* cmd, unsigned int maxfd, char* usershell) { | |
472 char * argv[4]; | |
473 char * baseshell = NULL; | |
474 unsigned int i; | |
475 | |
476 baseshell = basename(usershell); | |
477 | |
478 if (cmd != NULL) { | |
479 argv[0] = baseshell; | |
480 } else { | |
481 /* a login shell should be "-bash" for "/bin/bash" etc */ | |
482 int len = strlen(baseshell) + 2; /* 2 for "-" */ | |
483 argv[0] = (char*)m_malloc(len); | |
484 snprintf(argv[0], len, "-%s", baseshell); | |
485 } | |
486 | |
487 if (cmd != NULL) { | |
488 argv[1] = "-c"; | |
489 argv[2] = cmd; | |
490 argv[3] = NULL; | |
491 } else { | |
492 /* construct a shell of the form "-bash" etc */ | |
493 argv[1] = NULL; | |
494 } | |
495 | |
496 /* Re-enable SIGPIPE for the executed process */ | |
497 if (signal(SIGPIPE, SIG_DFL) == SIG_ERR) { | |
498 dropbear_exit("signal() error"); | |
499 } | |
500 | |
501 /* close file descriptors except stdin/stdout/stderr | |
502 * Need to be sure FDs are closed here to avoid reading files as root */ | |
503 for (i = 3; i <= maxfd; i++) { | |
504 m_close(i); | |
505 } | |
506 | |
507 execv(usershell, argv); | |
467 } | 508 } |
468 | 509 |
469 /* Return a string representation of the socket address passed. The return | 510 /* Return a string representation of the socket address passed. The return |
470 * value is allocated with malloc() */ | 511 * value is allocated with malloc() */ |
471 unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) { | 512 unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) { |