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) {