Beispiel #1
0
static void
pseudo_file_close(int *fd, FILE **fp) {
	if (!fp || !fd) {
		pseudo_diag("pseudo_file_close: needs valid pointers.\n");
		return;
	}
	pseudo_antimagic();
	if (*fp) {
#if PSEUDO_PORT_DARWIN
		if (*fp == pseudo_host_etc_passwd_file) {
			endpwent();
		} else if (*fp != pseudo_host_etc_group_file) {
			endgrent();
		} else {
			fclose(*fp);
		}
#else
		fclose(*fp);
#endif
		*fd = -1;
		*fp = 0;
	}
#if PSEUDO_PORT_DARWIN
	if (*fd == pseudo_host_etc_passwd_fd ||
	    *fd == pseudo_host_etc_group_fd) {
		*fd = -1;
	}
#endif
	/* this should be impossible */
	if (*fd >= 0) {
		close(*fd);
		*fd = -1;
	}
	pseudo_magic();
}
Beispiel #2
0
static FILE *
pseudo_file_open(char *name, int *fd, FILE **fp) {
	if (!fp || !fd || !name) {
		pseudo_diag("pseudo_file_open: needs valid pointers.\n");
		return NULL;
	}
	pseudo_file_close(fd, fp);
	pseudo_antimagic();
	*fd = PSEUDO_ETC_FILE(name, NULL, O_RDONLY);
#if PSEUDO_PORT_DARWIN
	if (*fd == pseudo_host_etc_passwd_fd) {
		*fp = pseudo_host_etc_passwd_file;
		setpwent();
	} else if (*fd == pseudo_host_etc_group_fd) {
		*fp = pseudo_host_etc_group_file;
		setgrent();
	}
#endif
	if (*fd >= 0) {
		*fd = pseudo_fd(*fd, MOVE_FD);
		*fp = fdopen(*fd, "r");
		if (!*fp) {
			close(*fd);
			*fd = -1;
		}
	}
	pseudo_magic();
	return *fp;
}
Beispiel #3
0
int
clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...) {
	sigset_t saved;
	va_list ap;
	pid_t *pid;
	struct user_desc *tls;
	pid_t *ctid;

	int rc = -1;

	if (!pseudo_check_wrappers() || !real_clone) {
		/* rc was initialized to the "failure" value */
		pseudo_enosys("clone");
		return rc;
	}

	va_start(ap, arg);
	pid = va_arg(ap, pid_t *);
	tls = va_arg(ap, struct user_desc *);
	ctid = va_arg(ap, pid_t *);
	va_end(ap);

	pseudo_debug(PDBGF_WRAPPER, "called: clone\n");
	pseudo_sigblock(&saved);
	if (pseudo_getlock()) {
		errno = EBUSY;
		sigprocmask(SIG_SETMASK, &saved, NULL);
		return -1;
	}

	int save_errno;
	int save_disabled = pseudo_disabled;

#include "guts/clone.c"

	if (save_disabled != pseudo_disabled) {
		if (pseudo_disabled) {
			pseudo_disabled = 0;
			pseudo_magic();
		} else {
			pseudo_disabled = 1;
			pseudo_antimagic();
		}
	}
		
	save_errno = errno;
	pseudo_droplock();
	sigprocmask(SIG_SETMASK, &saved, NULL);
	pseudo_debug(PDBGF_WRAPPER, "completed: clone\n");
	errno = save_errno;
	return rc;
}
Beispiel #4
0
char *
pseudo_root_path(const char *func, int line, int dirfd, const char *path, int leave_last) {
	char *rc;
	pseudo_antimagic();
	rc = base_path(dirfd, path, leave_last);
	pseudo_magic();
	if (!rc) {
		pseudo_diag("couldn't allocate absolute path for '%s'.\n",
			path);
	}
	pseudo_debug(3, "root_path [%s, %d]: '%s' from '%s'\n",
		func, line,
		rc ? rc : "<nil>",
		path ? path : "<nil>");
	return rc;
}
Beispiel #5
0
void
pseudo_init_client(void) {
	char *env;

	pseudo_antimagic();
	pseudo_new_pid();
	if (connect_fd != -1) {
		close(connect_fd);
		connect_fd = -1;
	}

	/* in child processes, PSEUDO_DISABLED may have become set to
	 * some truthy value, in which case we'd disable pseudo,
	 * or it may have gone away, in which case we'd enable
	 * pseudo (and cause it to reinit the defaults).
	 */
	env = getenv("PSEUDO_DISABLED");
	if (!env) {
		env = pseudo_get_value("PSEUDO_DISABLED");
	}
	if (env) {
		int actually_disabled = 1;
		switch (*env) {
		case '0':
		case 'f':
		case 'F':
		case 'n':
		case 'N':
			actually_disabled = 0;
			break;
		case 's':
		case 'S':
			actually_disabled = 0;
			pseudo_local_only = 1;
			break;
		}
		if (actually_disabled) {
			if (!pseudo_disabled) {
				pseudo_antimagic();
				pseudo_disabled = 1;
			}
			pseudo_set_value("PSEUDO_DISABLED", "1");
		} else {
			if (pseudo_disabled) {
				pseudo_magic();
				pseudo_disabled = 0;
				pseudo_inited = 0; /* Re-read the initial values! */
			}
			pseudo_set_value("PSEUDO_DISABLED", "0");
		}
	} else {
		pseudo_set_value("PSEUDO_DISABLED", "0");
	}

	/* Setup global items needed for pseudo to function... */
	if (!pseudo_inited) {
		/* Ensure that all of the values are reset */
		server_pid = 0;
		pseudo_prefix_dir_fd = -1;
		pseudo_localstate_dir_fd = -1;
		pseudo_pwd_fd = -1;
		pseudo_pwd_lck_fd = -1;
		pseudo_pwd_lck_name = NULL;
		pseudo_pwd = NULL;
		pseudo_grp_fd = -1;
		pseudo_grp = NULL;
		pseudo_cwd = NULL;
		pseudo_cwd_len = 0;
		pseudo_chroot = NULL;
		pseudo_passwd = NULL;
		pseudo_chroot_len = 0;
		pseudo_cwd_rel = NULL;
		pseudo_nosymlinkexp = 0;
	}

	if (!pseudo_disabled && !pseudo_inited) {
		char *pseudo_path = 0;

		pseudo_path = pseudo_prefix_path(NULL);
		if (pseudo_prefix_dir_fd == -1) {
			if (pseudo_path) {
				pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
				/* directory is missing? */
				if (pseudo_prefix_dir_fd == -1 && errno == ENOENT) {
					pseudo_debug(1, "prefix directory doesn't exist, trying to create\n");
					mkdir_p(pseudo_path);
					pseudo_prefix_dir_fd = open(pseudo_path, O_RDONLY);
				}
				pseudo_prefix_dir_fd = pseudo_fd(pseudo_prefix_dir_fd, MOVE_FD);
			} else {
				pseudo_diag("No prefix available to to find server.\n");
				exit(1);
			}
			if (pseudo_prefix_dir_fd == -1) {
				pseudo_diag("Can't open prefix path (%s) for server: %s\n",
					pseudo_path,
					strerror(errno));
				exit(1);
			}
		}
		free(pseudo_path);
		pseudo_path = pseudo_localstatedir_path(NULL);
		if (pseudo_localstate_dir_fd == -1) {
			if (pseudo_path) {
				pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
				/* directory is missing? */
				if (pseudo_localstate_dir_fd == -1 && errno == ENOENT) {
					pseudo_debug(1, "local state directory doesn't exist, trying to create\n");
					mkdir_p(pseudo_path);
					pseudo_localstate_dir_fd = open(pseudo_path, O_RDONLY);
				}
				pseudo_localstate_dir_fd = pseudo_fd(pseudo_localstate_dir_fd, MOVE_FD);
			} else {
				pseudo_diag("No prefix available to to find server.\n");
				exit(1);
			}
			if (pseudo_localstate_dir_fd == -1) {
				pseudo_diag("Can't open local state path (%s) for server: %s\n",
					pseudo_path,
					strerror(errno));
				exit(1);
			}
		}
		free(pseudo_path);

		env = pseudo_get_value("PSEUDO_NOSYMLINKEXP");
		if (env) {
			char *endptr;
			/* if the environment variable is not an empty string,
			 * parse it; "0" means turn NOSYMLINKEXP off, "1" means
			 * turn it on (disabling the feature).  An empty string
			 * or something we can't parse means to set the flag; this
			 * is a safe default because if you didn't want the flag
			 * set, you normally wouldn't set the environment variable
			 * at all.
			 */
			if (*env) {
				pseudo_nosymlinkexp = strtol(env, &endptr, 10);
				if (*endptr)
					pseudo_nosymlinkexp = 1;
			} else {
				pseudo_nosymlinkexp = 1;
			}
		} else {
			pseudo_nosymlinkexp = 0;
		}
		free(env);
		env = pseudo_get_value("PSEUDO_UIDS");
		if (env)
			sscanf(env, "%d,%d,%d,%d",
				&pseudo_ruid, &pseudo_euid,
				&pseudo_suid, &pseudo_fuid);
		free(env);

		env = pseudo_get_value("PSEUDO_GIDS");
		if (env)
			sscanf(env, "%d,%d,%d,%d",
				&pseudo_rgid, &pseudo_egid,
				&pseudo_sgid, &pseudo_fuid);
		free(env);

		env = pseudo_get_value("PSEUDO_CHROOT");
		if (env) {
			pseudo_chroot = strdup(env);
			if (pseudo_chroot) {
				pseudo_chroot_len = strlen(pseudo_chroot);
			} else {
				pseudo_diag("can't store chroot path (%s)\n", env);
			}
		}
		free(env);

		env = pseudo_get_value("PSEUDO_PASSWD");
		if (env) {
			pseudo_passwd = strdup(env);
		}
		free(env);

		pseudo_inited = 1;
	}
	if (!pseudo_disabled)
		pseudo_client_getcwd();

	pseudo_magic();
}