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); }
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); }
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; }