#include <sys/file.h>
#include <sys/resource.h>
#include <orbit/orb-core/corba-defs.h>
+#include "captive/client.h"
#ifdef HAVE_ORBIT_LINK
char *link_get_tmpdir(void);
fatal("Unsuccessful setrlimit(%s)",resource_string);
}
-static gchar *chrooted_orbit_dir;
+static void sandbox_server_mkdir_p(const gchar *dirpathname)
+{
+gchar *pathname=(/* de-const */ gchar *)captive_strdup_alloca(dirpathname);
+gchar *gs,*gs2;
+
+ /* Missing mkdir(2) of the last component path is intentional: */
+ for (gs=pathname;(gs2=strchr(gs,'/'));gs=gs2) {
+ *gs2='\0';
+ if (*pathname && mkdir(pathname,S_ISVTX|0777)) {
+ if (errno!=EEXIST)
+ fatal("Failed to mkdir(\"%s\"): %m",pathname);
+ }
+ *gs2++='/';
+ }
+}
+
+static const gchar *chrooted_orbit_dir;
static void chroot_setup(gboolean fragile)
{
g_get_home_dir();
g_get_tmp_dir();
+ /* Pre-resolve "link_get_tmpdir" symbol to prevent its later failed
+ * resolving in chroot(2) mode in Debian dynamic build.
+ */
+#ifdef HAVE_ORBIT_LINK
+ g_free(link_get_tmpdir()); /* returns g_strdup()ed string */
+#else
+ g_free(linc_get_tmpdir()); /* returns g_strdup()ed string */
+#endif
+
if (fragile && !optarg_chroot)
fatal("Fragile setuid/root environment but no --chroot set");
if (optarg_chroot) {
}
g_rand_free(grand);
*s=0;
- if (geteuid()==0) /* Not 'fragile' as we can be native 'root'. */
+ if (geteuid()==0) { /* Not 'fragile' as we can be native 'root'. */
chrooted_cleanuplockeddirs(optarg_chroot,"s-");
+ chrooted_cleanuplockeddirs(captive_printf_alloca("%s/tmp",optarg_chroot),"captive-orbit-");
+ }
chroot_pid_dir=captive_printf_alloca("%s/s-%d",optarg_chroot,(int)getpid());
chrooted_createdir(chroot_pid_dir,(!optarg_setuid ? (uid_t)-1 : want_uid),(!optarg_setgid ? (gid_t)-1 : want_gid),
TRUE); /* lock */
/* Prepare /t for /t/o-$PID directories for ORBit2
* and also for parent's hardlink to its /t/o-$pid directory. */
if (optarg_chroot) {
-gchar *chrooted_orbit_dir_old,*gs,*gs2;
+gchar *chrooted_orbit_dir_old;
if (mkdir("/t",S_ISVTX|0777)) {
if (errno!=EEXIST)
}
g_assert(chroot_pid_hashkey_dir!=NULL);
chrooted_orbit_dir=g_strdup_printf("%s/t/o-%d",chroot_pid_hashkey_dir,getpid());
- /* Missing mkdir(2) of the last component path is intentional: */
- for (gs=chrooted_orbit_dir;(gs2=strchr(gs,'/'));gs=gs2) {
- *gs2='\0';
- if (*chrooted_orbit_dir && mkdir(chrooted_orbit_dir,S_ISVTX|0777)) {
- if (errno!=EEXIST)
- fatal("Failed to mkdir(\"%s\"): %m",chrooted_orbit_dir);
- }
- *gs2++='/';
- }
- /* Prepare '/tmp' for the initial CORBA_ORB_init() default path: */
- if (mkdir("/tmp",S_ISVTX|0777)) {
- if (errno!=EEXIST)
- fatal("Failed to mkdir(\"%s\"): %m","/tmp");
- }
+ /* Last pathname component is not created: */
+ sandbox_server_mkdir_p(chrooted_orbit_dir);
+ /* Prepare '/tmp' for the initial CORBA_ORB_init() default path.
+ * Workaround sandbox_server_mkdir_p() does not create last component.
+ * Do not use '/tmp' directly as some distributions may set custom
+ * tmpdir pathname by $ENV{"TMPDIR"} etc.
+ */
+ sandbox_server_mkdir_p(captive_printf_alloca("%s/",g_get_tmp_dir()));
/* Set '0700' to prevent: Wrong permissions for ...
* by linc-1.0.1-1/src/linc-protocols.c/make_local_tmpdir()
*/
NULL};
CORBA_exception_init(&ev);
- orb=CORBA_ORB_init(&orb_argc,orb_argv,"orbit-local-orb",&ev);
+ /* libcaptive is single-threaded only, caller must lock it.
+ * If thread A spawned the sandbox while currently doing its own work
+ * and thread B calls the sandbox thread B waits on ORB_run()
+ * while the sandbox waits for the response of thread A ORB. Deadlock.
+ * "orbit-local-non-threaded-orb" requests thread unaware ORB.
+ */
+ orb=CORBA_ORB_init(&orb_argc,orb_argv,"orbit-local-non-threaded-orb",&ev);
if (orb==CORBA_OBJECT_NIL)
fatal("Cannot initialize CORBA ORB (CORBA_OBJECT_NIL): %m");
if (ev._major!=CORBA_NO_EXCEPTION)
|G_LOG_LEVEL_DEBUG
));
+ /* Do not do it later than chroot_setup() as it requires it.
+ * On the other hand it is SETUID-fragile this way.
+ */
+ captive_standalone_init();
+
fatal_argv0=argv[0];
fragile=(getuid()!=geteuid() || getuid()==0 || geteuid()==0);
chroot_setup(TRUE);
#endif /* MAINTAINER_MODE */
- /* Initialize the i18n stuff */
- setlocale(LC_ALL,"");
- bindtextdomain(PACKAGE,LOCALEDIR);
- textdomain(PACKAGE);
-
- /* Initialize GObject subsystem of GLib. */
- g_type_init();
-
captive_options_init(&options);
captive_options=&options; /* for parsing by 'CAPTIVE_POPT_INCLUDE' */