static pid_t create_auth_process(struct auth_process_group *group)
{
static char *argv[] = { NULL, NULL };
- struct passwd *pwd;
pid_t pid;
int fd[2], i;
- if ((pwd = getpwnam(group->set->user)) == NULL)
- i_fatal("Auth user doesn't exist: %s", group->set->user);
-
/* create communication to process with a socket pair */
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) == -1) {
i_error("socketpair() failed: %m");
fd_close_on_exec(i, FALSE);
/* setup access environment */
- restrict_access_set_env(group->set->user, pwd->pw_uid, pwd->pw_gid,
- group->set->chroot, 0, 0);
+ restrict_access_set_env(group->set->user, group->set->uid,
+ group->set->gid, group->set->chroot, 0, 0);
/* set other environment */
env_put(t_strconcat("AUTH_PROCESS=", dec2str(getpid()), NULL));
fd_close_on_exec(group->listen_fd, TRUE);
/* set correct permissions */
- if (chown(path, master_uid,
- auth_set->parent->defaults->login_gid) < 0) {
+ if (chown(path, master_uid, auth_set->parent->login_gid) < 0) {
i_fatal("login: chown(%s, %s, %s) failed: %m",
path, dec2str(master_uid),
- dec2str(auth_set->parent->defaults->login_gid));
+ dec2str(auth_set->parent->login_gid));
}
group->next = process_groups;
/* setup access environment - needs to be done after
clean_child_process() since it clears environment */
- restrict_access_set_env(set->login_user, set->login_uid, set->login_gid,
+ restrict_access_set_env(set->login_user, set->login_uid,
+ set->server->login_gid,
set->login_chroot ? set->login_dir : NULL,
0, 0);
/* .. */
MEMBER(login_uid) 0,
- MEMBER(login_gid) 0,
MEMBER(listen_fd) -1,
MEMBER(ssl_listen_fd) -1
};
return FALSE;
}
- if (set->login_gid == 0)
- set->login_gid = pw->pw_gid;
- else if (set->login_gid != pw->pw_gid) {
+ if (set->server->login_gid == 0)
+ set->server->login_gid = pw->pw_gid;
+ else if (set->server->login_gid != pw->pw_gid) {
i_error("All login process users must belong to same group "
- "(%s vs %s)", dec2str(set->login_gid),
+ "(%s vs %s)", dec2str(set->server->login_gid),
dec2str(pw->pw_gid));
return FALSE;
}
static int auth_settings_verify(struct auth_settings *auth)
{
+ struct passwd *pw;
+
+ if ((pw = getpwnam(auth->user)) == NULL) {
+ i_error("Auth user doesn't exist: %s", auth->user);
+ return FALSE;
+ }
+
+ if (auth->parent->defaults->login_uid == pw->pw_uid &&
+ master_uid != pw->pw_uid) {
+ i_error("login_user %s (uid %s) must not be same as auth_user",
+ auth->user, dec2str(pw->pw_uid));
+ return FALSE;
+ }
+ auth->uid = pw->pw_uid;
+ auth->gid = pw->pw_gid;
+
if (access(auth->executable, X_OK) < 0) {
i_error("Can't use auth executable %s: %m", auth->executable);
return FALSE;
return FALSE;
}
- if (safe_mkdir(set->login_dir, 0750, master_uid, set->login_gid) == 0) {
+ if (safe_mkdir(set->login_dir, 0750,
+ master_uid, set->server->login_gid) == 0) {
i_warning("Corrected permissions for login directory %s",
set->login_dir);
}
/* .. */
uid_t login_uid;
- gid_t login_gid;
int listen_fd, ssl_listen_fd;
};
unsigned int count;
unsigned int process_size;
+
+ /* .. */
+ uid_t uid;
+ gid_t gid;
};
struct namespace_settings {
struct auth_settings *auths;
struct auth_settings auth_defaults;
struct namespace_settings *namespaces;
+
+ gid_t login_gid;
};
extern struct server_settings *settings_root;