Hello I have a problem when combining --background and --chroot options of start-stop-daemon. The program I try to start fails immediately. I looked at the source and discovered why, the background code is done after the chroot code, and so the openning of /dev/null for stdin, stdout and stderr fails because the /dev/null is not in the jail. So instead of forcing people to create de /dev/null in the jail I think it better to reoder the code. This is what I have done in the attached patch. I have not check that this patch works in every situation but it woks for me and it is very light so it should not disturbe many things except that went background option is used, more potential errors are hidden. I also miss a chdir option to start-stop-deamon, so I added it in the same patch. It is easy to remove it if you do not want it. This patch is for version 1.9.21 of dpkg source package. Bye. -- Loic "heaven is not a place, it's a feeling"
diff -r -u dpkg-1.9.21.orig/utils/start-stop-daemon.c dpkg-1.9.21/utils/start-stop-daemon.c --- dpkg-1.9.21.orig/utils/start-stop-daemon.c Mon May 14 00:01:28 2001 +++ dpkg-1.9.21/utils/start-stop-daemon.c Mon Jun 10 23:56:41 2002 @@ -98,6 +98,7 @@ static char *changeuser = NULL; static const char *changegroup = NULL; static char *changeroot = NULL; +static char *changedir = NULL; static const char *cmdname = NULL; static char *execname = NULL; static char *startas = NULL; @@ -453,12 +454,13 @@ { "background", 0, NULL, 'b'}, { "make-pidfile", 0, NULL, 'm'}, { "retry", 1, NULL, 'R'}, + { "chdir", 1, NULL, 'd'}, { NULL, 0, NULL, 0} }; int c; for (;;) { - c = getopt_long(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:N:bmR:", + c = getopt_long(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:N:bmR:d:", longopts, (int *) 0); if (c == -1) break; @@ -527,6 +529,9 @@ case 'R': /* --retry <schedule>|<timeout> */ schedule_str = optarg; break; + case 'd': /* --chdir /new/dir */ + changedir = optarg; + break; default: badusage(NULL); /* message printed by getopt */ } @@ -1108,20 +1113,6 @@ if (quietmode < 0) printf("Starting %s...\n", startas); *--argv = startas; - if (changeroot != NULL) { - if (chdir(changeroot) < 0) - fatal("Unable to chdir() to %s", changeroot); - if (chroot(changeroot) < 0) - fatal("Unable to chroot() to %s", changeroot); - } - if (changeuser != NULL) { - if (setgid(runas_gid)) - fatal("Unable to set gid to %d", runas_gid); - if (initgroups(changeuser, runas_gid)) - fatal("Unable to set initgroups() with gid %d", runas_gid); - if (setuid(runas_uid)) - fatal("Unable to set uid to %s", changeuser); - } if (background) { /* ok, we need to detach this process */ int i, fd; @@ -1149,6 +1140,24 @@ fd=open("/dev/null", O_RDWR); /* stdin */ dup(fd); /* stdout */ dup(fd); /* stderr */ + } + if (changeroot != NULL) { + if (chdir(changeroot) < 0) + fatal("Unable to chdir() to %s", changeroot); + if (chroot(changeroot) < 0) + fatal("Unable to chroot() to %s", changeroot); + } + if (changedir != NULL) { + if (chdir(changedir) < 0) + fatal("Unable to chdir() to %s", changedir); + } + if (changeuser != NULL) { + if (setgid(runas_gid)) + fatal("Unable to set gid to %d", runas_gid); + if (initgroups(changeuser, runas_gid)) + fatal("Unable to set initgroups() with gid %d", runas_gid); + if (setuid(runas_uid)) + fatal("Unable to set uid to %s", changeuser); } if (nicelevel) { if (nice(nicelevel))
Attachment:
pgpjOYTbab2cM.pgp
Description: PGP signature