コード例 #1
0
ファイル: main.c プロジェクト: bsmr-dovecot/core
static void drop_privileges(void)
{
	struct restrict_access_settings set;
	const char *error;

	/* by default we don't drop any privileges, but keep running as root. */
	restrict_access_get_env(&set);
	if (set.uid != 0) {
		/* open config connection before dropping privileges */
		struct master_service_settings_input input;
		struct master_service_settings_output output;

		memset(&input, 0, sizeof(input));
		input.module = "lmtp";
		input.service = "lmtp";
		(void)master_service_settings_read(master_service,
						   &input, &output, &error);
	}
	restrict_access_by_env(NULL, FALSE);
}
コード例 #2
0
ファイル: indexer-worker.c プロジェクト: bdraco/core
static void drop_privileges(void)
{
	struct restrict_access_settings set;
	const char *error;

	/* by default we don't drop any privileges, but keep running as root. */
	restrict_access_get_env(&set);
	if (set.uid != 0) {
		/* open config connection before dropping privileges */
		struct master_service_settings_input input;
		struct master_service_settings_output output;

		i_zero(&input);
		input.module = "mail";
		input.service = "indexer-worker";
		(void)master_service_settings_read(master_service,
						   &input, &output, &error);
	}
	restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
}
コード例 #3
0
static int
service_drop_privileges(struct mail_storage_service_user *user,
			struct mail_storage_service_privileges *priv,
			bool disallow_root, bool keep_setuid_root,
			bool setenv_only, const char **error_r)
{
	const struct mail_user_settings *set = user->user_set;
	struct restrict_access_settings rset;
	uid_t current_euid, setuid_uid = 0;
	const char *cur_chroot, *error;

	current_euid = geteuid();
	restrict_access_init(&rset);
	restrict_access_get_env(&rset);
	if (priv->uid != (uid_t)-1) {
		rset.uid = priv->uid;
		rset.uid_source = priv->uid_source;
	} else if (rset.uid == (uid_t)-1 &&
		 disallow_root && current_euid == 0) {
		*error_r = "User is missing UID (see mail_uid setting)";
		return -1;
	}
	if (priv->gid != (gid_t)-1) {
		rset.gid = priv->gid;
		rset.gid_source = priv->gid_source;
	} else if (rset.gid == (gid_t)-1 && disallow_root &&
		   set->first_valid_gid > 0 && getegid() == 0) {
		*error_r = "User is missing GID (see mail_gid setting)";
		return -1;
	}
	if (*set->mail_privileged_group != '\0') {
		if (!parse_gid(set->mail_privileged_group, &rset.privileged_gid,
			       &error)) {
			*error_r = t_strdup_printf(
				"%s (in mail_privileged_group setting)", error);
			return -1;
		}
	}
	if (*set->mail_access_groups != '\0') {
		rset.extra_groups = t_strconcat(set->mail_access_groups, ",",
						rset.extra_groups, NULL);
	}

	rset.first_valid_gid = set->first_valid_gid;
	rset.last_valid_gid = set->last_valid_gid;
	rset.chroot_dir = *priv->chroot == '\0' ? NULL : priv->chroot;
	rset.system_groups_user = user->system_groups_user;

	cur_chroot = restrict_access_get_current_chroot();
	if (cur_chroot != NULL) {
		/* we're already chrooted. make sure the chroots are equal. */
		if (rset.chroot_dir == NULL) {
			*error_r = "Process is already chrooted, "
				"can't un-chroot for this user";
			return -1;
		}
		if (strcmp(rset.chroot_dir, cur_chroot) != 0) {
			*error_r = t_strdup_printf(
				"Process is already chrooted to %s, "
				"can't chroot to %s", cur_chroot, priv->chroot);
			return -1;
		}
		/* chrooting to same directory where we're already chrooted */
		rset.chroot_dir = NULL;
	}

	if (disallow_root &&
	    (rset.uid == 0 || (rset.uid == (uid_t)-1 && current_euid == 0))) {
		*error_r = "Mail access not allowed for root";
		return -1;
	}

	if (keep_setuid_root) {
		if (current_euid != rset.uid) {
			if (current_euid != 0) {
				/* we're changing the UID,
				   switch back to root first */
				mail_storage_service_seteuid_root();
			}
			setuid_uid = rset.uid;
		}
		rset.uid = (uid_t)-1;
		disallow_root = FALSE;
	}
	if (!setenv_only) {
		restrict_access(&rset, *priv->home == '\0' ? NULL : priv->home,
				disallow_root);
	} else {
		restrict_access_set_env(&rset);
	}
	if (setuid_uid != 0 && !setenv_only) {
		if (seteuid(setuid_uid) < 0)
			i_fatal("mail-storage-service: seteuid(%s) failed: %m",
				dec2str(setuid_uid));
	}
	return 0;
}