+static const gchar *sandbox_parent_own_orbit_dir;
+static const gchar *sandbox_parent_own_orbit_socket;
+
+gchar *sandbox_parent_read_ior(int Vfs_IOR_fd_read,gchar **child_chroot_pid_hashkey_dirp)
+{
+gchar *data;
+gsize data_size;
+GHashTable *hash;
+gchar *ior,*child_chroot_pid_hashkey_dir;
+int errint;
+gchar *s,*sd,*se;
+gboolean errbool;
+
+ /* Initialize /tmp/orbit-$username directory for linking IOR socket. */
+ errbool=corba_init("captive-sandbox-parent",&captive_corba_ev,&captive_corba_orb,&captive_corba_poa);
+ g_assert(errbool==TRUE);
+
+ /* FIXME: Security: Duplicate giop_tmpdir_init() here. */
+ if (!sandbox_parent_own_orbit_dir) {
+ sandbox_parent_own_orbit_dir=captive_printf_alloca("/tmp/captive-orbit-%d",getpid());
+ if (mkdir(sandbox_parent_own_orbit_dir,0700)) {
+DIR *dir;
+struct dirent *dirent;
+ g_assert(errno==EEXIST);
+
+ dir=opendir(sandbox_parent_own_orbit_dir);
+ g_assert(dir!=NULL);
+
+ while (errno=0,(dirent=readdir(dir))) {
+gchar *pathname;
+ if (!strcmp(dirent->d_name,".") || !strcmp(dirent->d_name,".."))
+ continue;
+ pathname=g_strdup_printf("%s/%s",sandbox_parent_own_orbit_dir,dirent->d_name);
+ errint=unlink(pathname);
+ g_assert(errint==0);
+ g_free(pathname);
+ }
+ g_assert(errno==0);
+ errint=closedir(dir);
+ g_assert(errint==0);
+ }
+ linc_set_tmpdir(sandbox_parent_own_orbit_dir);
+ }
+
+ data=captive_rtl_file_read(Vfs_IOR_fd_read,&data_size); /* data_fd_read */
+ errint=close(Vfs_IOR_fd_read);
+ g_assert(errint==0);
+ g_assert(data!=NULL);
+ g_assert(data_size>=1);
+ g_assert(data[data_size-1]=='\n');
+
+ hash=g_hash_table_new(g_str_hash,g_str_equal);
+
+ for (s=data;s<data+data_size;s=se+1) {
+ se=strchr(s,'\n');
+ g_assert(se!=NULL);
+ *se=0;
+ sd=strchr(s,'=');
+ g_assert(sd!=NULL);
+ *sd=0;
+ g_hash_table_insert(hash,s,sd+1);
+ }
+ g_assert(s==data+data_size);
+
+ if ((child_chroot_pid_hashkey_dir=g_hash_table_lookup(hash,"chroot_pid_hashkey_dir"))) {
+const gchar *socketname,*socketpathname_src,*socketpathname_dest;
+const gchar *chrooted_orbit_dir;
+
+ /* IOR contains the full pathname with the setuid username encoded. */
+ chrooted_orbit_dir=g_hash_table_lookup(hash,"chrooted_orbit_dir");
+ g_assert(chrooted_orbit_dir!=NULL);
+ if (mkdir(chrooted_orbit_dir,S_ISVTX|0777)) {
+ g_assert(errno==EEXIST);
+ }
+
+ socketname=g_hash_table_lookup(hash,"socketname");
+ g_assert(socketname!=NULL);
+
+ socketpathname_src=captive_printf_alloca("%s/%s/%s",child_chroot_pid_hashkey_dir,chrooted_orbit_dir,socketname);
+ socketpathname_dest=captive_printf_alloca("%s/%s",chrooted_orbit_dir,socketname);
+ errint=link(socketpathname_src,socketpathname_dest);
+ g_assert(errint==0);
+ }
+ if (child_chroot_pid_hashkey_dirp)
+ *child_chroot_pid_hashkey_dirp=g_strdup(child_chroot_pid_hashkey_dir);
+
+ ior=g_hash_table_lookup(hash,"ior");
+ g_assert(ior!=NULL);
+ ior=g_strdup(ior);
+ g_free(data);
+
+ g_hash_table_destroy(hash);
+
+ return ior;
+}
+
+
+static void sandbox_parent(const gchar *Vfs_IOR,const gchar *child_chroot_pid_hashkey_dir,
+ struct captive_options *options_captive,Captive_Vfs *corba_Vfs_object_return,