1
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
10
#include "restrict-access.h"
11
#include "auth-client.h"
12
#include "auth-master.h"
20
static bool parse_uid(const char *str, uid_t *uid_r)
25
if (*str >= '0' && *str <= '9') {
26
*uid_r = (uid_t)strtoul(str, &p, 10);
39
static bool parse_gid(const char *str, gid_t *gid_r)
44
if (*str >= '0' && *str <= '9') {
45
*gid_r = (gid_t)strtoul(str, &p, 10);
58
static int set_env(struct auth_user_reply *reply,
59
const char *user, uid_t euid)
61
const char *extra_groups;
64
if (reply->uid == 0) {
65
i_error("userdb(%s) returned 0 as uid", user);
67
} else if (reply->uid == (uid_t)-1) {
68
if (getenv("MAIL_UID") != NULL) {
69
if (!parse_uid(getenv("MAIL_UID"), &reply->uid) ||
71
i_error("mail_uid setting is invalid");
75
i_error("User %s is missing UID (set mail_uid)", user);
79
if (reply->gid == 0) {
80
i_error("userdb(%s) returned 0 as gid", user);
82
} else if (reply->gid == (gid_t)-1) {
83
if (getenv("MAIL_GID") != NULL) {
84
if (!parse_gid(getenv("MAIL_GID"), &reply->gid) ||
86
i_error("mail_gid setting is invalid");
90
i_error("User %s is missing GID (set mail_gid)", user);
95
if (euid != reply->uid) {
96
env_put(t_strconcat("RESTRICT_SETUID=",
97
dec2str(reply->uid), NULL));
99
if (euid == 0 || getegid() != reply->gid) {
100
env_put(t_strconcat("RESTRICT_SETGID=",
101
dec2str(reply->gid), NULL));
104
if (reply->chroot == NULL)
105
reply->chroot = getenv("MAIL_CHROOT");
106
if (reply->chroot != NULL) {
107
len = strlen(reply->chroot);
108
if (len > 2 && strcmp(reply->chroot + len - 2, "/.") == 0 &&
109
reply->home != NULL &&
110
strncmp(reply->home, reply->chroot, len - 2) == 0) {
111
/* strip chroot dir from home dir */
112
reply->home += len - 2;
114
env_put(t_strconcat("RESTRICT_CHROOT=", reply->chroot, NULL));
116
if (reply->home != NULL)
117
env_put(t_strconcat("HOME=", reply->home, NULL));
119
extra_groups = getenv("MAIL_ACCESS_GROUPS");
120
if (extra_groups != NULL) {
121
env_put(t_strconcat("RESTRICT_SETEXTRAGROUPS=",
122
extra_groups, NULL));
127
int auth_client_lookup_and_restrict(const char *auth_socket,
128
const char **user, uid_t euid, pool_t pool,
129
ARRAY_TYPE(const_string) *extra_fields_r)
131
struct auth_master_connection *conn;
132
struct auth_user_reply reply;
133
bool debug = getenv("DEBUG") != NULL;
134
int ret = EX_TEMPFAIL;
136
conn = auth_master_init(auth_socket, debug);
137
switch (auth_master_user_lookup(conn, *user, "deliver", pool, &reply)) {
142
if (set_env(&reply, *user, euid) == 0) {
143
*user = p_strdup(pool, reply.user);
144
restrict_access_by_env(TRUE);
150
*extra_fields_r = reply.extra_fields;
151
auth_master_deinit(&conn);