362
static const struct var_expand_table *
363
get_var_expand_table(struct master_service *service,
364
struct mail_storage_service_input *input,
365
struct mail_storage_service_privileges *priv)
367
static struct var_expand_table static_tab[] = {
368
{ 'u', NULL, "user" },
369
{ 'n', NULL, "username" },
370
{ 'd', NULL, "domain" },
371
{ 's', NULL, "service" },
372
{ 'l', NULL, "lip" },
373
{ 'r', NULL, "rip" },
374
{ 'p', NULL, "pid" },
375
{ 'i', NULL, "uid" },
376
{ '\0', NULL, "gid" },
377
{ '\0', NULL, "session" },
380
struct var_expand_table *tab;
382
tab = t_malloc(sizeof(static_tab));
383
memcpy(tab, static_tab, sizeof(static_tab));
385
tab[0].value = input->username;
386
tab[1].value = t_strcut(input->username, '@');
387
tab[2].value = strchr(input->username, '@');
388
if (tab[2].value != NULL) tab[2].value++;
389
tab[3].value = service->name;
390
tab[4].value = net_ip2addr(&input->local_ip);
391
tab[5].value = net_ip2addr(&input->remote_ip);
392
tab[6].value = my_pid;
393
tab[7].value = dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
394
tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
395
tab[9].value = input->session_id;
399
const struct var_expand_table *
400
mail_storage_service_get_var_expand_table(struct mail_storage_service_ctx *ctx,
401
struct mail_storage_service_input *input)
403
struct mail_storage_service_privileges priv;
405
memset(&priv, 0, sizeof(priv));
406
priv.uid = (uid_t)-1;
407
priv.gid = (gid_t)-1;
408
return get_var_expand_table(ctx->service, input, &priv);
412
user_expand_varstr(struct master_service *service,
413
struct mail_storage_service_input *input,
414
struct mail_storage_service_privileges *priv,
419
if (*str == SETTING_STRVAR_EXPANDED[0])
422
i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
424
ret = t_str_new(256);
425
var_expand(ret, str + 1, get_var_expand_table(service, input, priv));
430
service_parse_privileges(struct mail_storage_service_ctx *ctx,
431
struct mail_storage_service_user *user,
432
struct mail_storage_service_privileges *priv_r,
433
const char **error_r)
435
const struct mail_user_settings *set = user->user_set;
436
uid_t uid = (uid_t)-1;
437
gid_t gid = (gid_t)-1;
439
memset(priv_r, 0, sizeof(*priv_r));
440
if (*set->mail_uid != '\0') {
441
if (!parse_uid(set->mail_uid, &uid, error_r)) {
442
*error_r = t_strdup_printf("%s (from %s)", *error_r,
446
if (uid < (uid_t)set->first_valid_uid ||
447
(set->last_valid_uid != 0 &&
448
uid > (uid_t)set->last_valid_uid)) {
449
*error_r = t_strdup_printf(
450
"Mail access for users with UID %s not permitted "
451
"(see first_valid_uid in config file, uid from %s).",
452
dec2str(uid), user->uid_source);
457
priv_r->uid_source = user->uid_source;
459
if (*set->mail_gid != '\0') {
460
if (!parse_gid(set->mail_gid, &gid, error_r)) {
461
*error_r = t_strdup_printf("%s (from %s)", *error_r,
465
if (gid < (gid_t)set->first_valid_gid ||
466
(set->last_valid_gid != 0 &&
467
gid > (gid_t)set->last_valid_gid)) {
468
*error_r = t_strdup_printf(
469
"Mail access for users with GID %s not permitted "
470
"(see first_valid_gid in config file, gid from %s).",
471
dec2str(gid), user->gid_source);
476
priv_r->gid_source = user->gid_source;
478
/* variable strings are expanded in mail_user_init(),
479
but we need the home and chroot sooner so do them separately here. */
480
priv_r->home = user_expand_varstr(ctx->service, &user->input, priv_r,
481
user->user_set->mail_home);
482
priv_r->chroot = user_expand_varstr(ctx->service, &user->input, priv_r,
483
user->user_set->mail_chroot);
341
488
service_drop_privileges(struct mail_storage_service_user *user,
342
const struct mail_user_settings *set,
343
const char *home, const char *chroot,
489
struct mail_storage_service_privileges *priv,
344
490
bool disallow_root, bool keep_setuid_root,
345
491
bool setenv_only, const char **error_r)
493
const struct mail_user_settings *set = user->user_set;
347
494
struct restrict_access_settings rset;
348
495
uid_t current_euid, setuid_uid = 0;
349
496
const char *cur_chroot, *error;
351
498
current_euid = geteuid();
352
499
restrict_access_init(&rset);
353
500
restrict_access_get_env(&rset);
354
if (*set->mail_uid != '\0') {
355
if (!parse_uid(set->mail_uid, &rset.uid, &error)) {
356
*error_r = t_strdup_printf("%s (from %s)", error,
360
if (rset.uid < (uid_t)set->first_valid_uid ||
361
(set->last_valid_uid != 0 &&
362
rset.uid > (uid_t)set->last_valid_uid)) {
363
*error_r = t_strdup_printf(
364
"Mail access for users with UID %s not permitted "
365
"(see first_valid_uid in config file, uid from %s).",
366
dec2str(rset.uid), user->uid_source);
369
rset.uid_source = user->uid_source;
501
if (priv->uid != (uid_t)-1) {
502
rset.uid = priv->uid;
503
rset.uid_source = priv->uid_source;
370
504
} else if (rset.uid == (uid_t)-1 &&
371
disallow_root && current_euid == 0) {
505
disallow_root && current_euid == 0) {
372
506
*error_r = "User is missing UID (see mail_uid setting)";
375
if (*set->mail_gid != '\0') {
376
if (!parse_gid(set->mail_gid, &rset.gid, &error)) {
377
*error_r = t_strdup_printf("%s (from %s)", error,
381
if (rset.gid < (gid_t)set->first_valid_gid ||
382
(set->last_valid_gid != 0 &&
383
rset.gid > (gid_t)set->last_valid_gid)) {
384
*error_r = t_strdup_printf(
385
"Mail access for users with GID %s not permitted "
386
"(see first_valid_gid in config file, gid from %s).",
387
dec2str(rset.gid), user->gid_source);
390
rset.gid_source = user->gid_source;
509
if (priv->gid != (gid_t)-1) {
510
rset.gid = priv->gid;
511
rset.gid_source = priv->gid_source;
391
512
} else if (rset.gid == (gid_t)-1 && disallow_root &&
392
513
set->first_valid_gid > 0 && getegid() == 0) {
393
514
*error_r = "User is missing GID (see mail_gid setting)";
465
586
mail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
466
587
struct mail_storage_service_user *user,
467
const char *home, struct mail_user **mail_user_r,
588
struct mail_storage_service_privileges *priv,
589
struct mail_user **mail_user_r,
468
590
const char **error_r)
470
592
const struct mail_storage_settings *mail_set;
593
const char *home = priv->home;
471
594
struct mail_user *mail_user;
473
596
mail_user = mail_user_alloc(user->input.username, user->user_info,
475
598
mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
476
mail_user_set_vars(mail_user, geteuid(), ctx->service->name,
599
mail_user_set_vars(mail_user, ctx->service->name,
477
600
&user->input.local_ip, &user->input.remote_ip);
601
mail_user->uid = priv->uid == (uid_t)-1 ? geteuid() : priv->uid;
602
mail_user->gid = priv->gid == (gid_t)-1 ? getegid() : priv->gid;
479
604
mail_set = mail_user_set_get_storage_set(mail_user);
481
606
if (mail_set->mail_debug) {
482
i_debug("Effective uid=%s, gid=%s, home=%s",
483
dec2str(geteuid()), dec2str(getegid()), home);
607
string_t *str = t_str_new(64);
609
str_printfa(str, "Effective uid=%s, gid=%s, home=%s",
610
dec2str(geteuid()), dec2str(getegid()), home);
611
if (*priv->chroot != '\0')
612
str_printfa(str, ", chroot=%s", priv->chroot);
613
i_debug("%s", str_c(str));
486
616
if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0 &&
520
static const struct var_expand_table *
521
get_var_expand_table(struct master_service *service,
522
struct mail_storage_service_input *input)
650
static void mail_storage_service_io_activate(void *context)
524
static struct var_expand_table static_tab[] = {
525
{ 'u', NULL, "user" },
526
{ 'n', NULL, "username" },
527
{ 'd', NULL, "domain" },
528
{ 's', NULL, "service" },
529
{ 'l', NULL, "lip" },
530
{ 'r', NULL, "rip" },
531
{ 'p', NULL, "pid" },
532
{ 'i', NULL, "uid" },
535
struct var_expand_table *tab;
537
tab = t_malloc(sizeof(static_tab));
538
memcpy(tab, static_tab, sizeof(static_tab));
540
tab[0].value = input->username;
541
tab[1].value = t_strcut(input->username, '@');
542
tab[2].value = strchr(input->username, '@');
543
if (tab[2].value != NULL) tab[2].value++;
544
tab[3].value = service->name;
545
tab[4].value = net_ip2addr(&input->local_ip);
546
tab[5].value = net_ip2addr(&input->remote_ip);
547
tab[6].value = my_pid;
548
tab[7].value = dec2str(geteuid());
652
struct mail_storage_service_user *user = context;
654
i_set_failure_prefix(user->log_prefix);
553
user_expand_varstr(struct master_service *service,
554
struct mail_storage_service_input *input, const char *str)
657
static void mail_storage_service_io_deactivate(void *context)
558
if (*str == SETTING_STRVAR_EXPANDED[0])
561
i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
563
ret = t_str_new(256);
564
var_expand(ret, str + 1, get_var_expand_table(service, input));
659
struct mail_storage_service_user *user = context;
661
i_set_failure_prefix(user->service_ctx->default_log_prefix);
569
665
mail_storage_service_init_log(struct mail_storage_service_ctx *ctx,
570
struct mail_storage_service_user *user)
666
struct mail_storage_service_user *user,
667
struct mail_storage_service_privileges *priv)
572
669
ctx->log_initialized = TRUE;
575
struct ioloop_log *log;
577
673
str = t_str_new(256);
578
674
var_expand(str, user->user_set->mail_log_prefix,
579
get_var_expand_table(ctx->service, &user->input));
580
master_service_init_log(ctx->service, str_c(str));
582
log = io_loop_log_new(current_ioloop);
583
io_loop_log_set_prefix(log, str_c(str));
584
io_loop_log_unref(&log);
675
get_var_expand_table(ctx->service, &user->input, priv));
676
user->log_prefix = p_strdup(user->pool, str_c(str));
679
master_service_init_log(ctx->service, user->log_prefix);
681
if (master_service_get_client_limit(master_service) == 1)
682
i_set_failure_send_prefix(user->log_prefix);
683
user->ioloop_ctx = io_loop_context_new(current_ioloop);
684
io_loop_context_add_callbacks(user->ioloop_ctx,
685
mail_storage_service_io_activate,
686
mail_storage_service_io_deactivate,
588
690
static void mail_storage_service_time_moved(time_t old_time, time_t new_time)
929
1047
(user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
930
1048
bool use_chroot;
932
/* variable strings are expanded in mail_user_init(),
933
but we need the home and chroot sooner so do them separately here. */
934
home = user_expand_varstr(ctx->service, &user->input,
935
user_set->mail_home);
936
chroot = user_expand_varstr(ctx->service, &user->input,
937
user_set->mail_chroot);
1050
if (service_parse_privileges(ctx, user, &priv, &error) < 0) {
1051
i_error("user %s: %s", user->input.username, error);
939
if (*home != '/' && *home != '\0') {
1055
if (*priv.home != '/' && *priv.home != '\0') {
940
1056
i_error("user %s: "
941
1057
"Relative home directory paths not supported: %s",
942
user->input.username, home);
1058
user->input.username, priv.home);
950
1066
use_chroot = !temp_priv_drop ||
951
1067
restrict_access_get_current_chroot() != NULL;
953
len = strlen(chroot);
954
if (len > 2 && strcmp(chroot + len - 2, "/.") == 0 &&
955
strncmp(home, chroot, len - 2) == 0) {
1069
len = strlen(priv.chroot);
1070
if (len > 2 && strcmp(priv.chroot + len - 2, "/.") == 0 &&
1071
strncmp(priv.home, priv.chroot, len - 2) == 0) {
956
1072
/* mail_chroot = /chroot/. means that the home dir already
957
1073
contains the chroot dir. remove it from home. */
958
1074
if (use_chroot) {
962
chroot = t_strndup(chroot, len - 2);
1075
priv.home += len - 2;
1076
if (*priv.home == '\0')
1078
priv.chroot = t_strndup(priv.chroot, len - 2);
964
set_keyval(ctx, user, "mail_home", home);
965
set_keyval(ctx, user, "mail_chroot", chroot);
1080
set_keyval(ctx, user, "mail_home", priv.home);
1081
set_keyval(ctx, user, "mail_chroot", priv.chroot);
967
1083
} else if (len > 0 && !use_chroot) {
968
1084
/* we're not going to chroot. fix home directory so we can
970
if (*home == '\0' || strcmp(home, "/") == 0)
1086
if (*priv.home == '\0' || strcmp(priv.home, "/") == 0)
1087
priv.home = priv.chroot;
973
home = t_strconcat(chroot, home, NULL);
975
set_keyval(ctx, user, "mail_home", home);
1089
priv.home = t_strconcat(priv.chroot, priv.home, NULL);
1091
set_keyval(ctx, user, "mail_home", priv.home);
978
1094
if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT) == 0)
979
mail_storage_service_init_log(ctx, user);
1095
mail_storage_service_init_log(ctx, user, &priv);
981
1097
if ((user->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
982
if (service_drop_privileges(user, user_set, home, chroot,
1098
if (service_drop_privileges(user, &priv,
983
1099
disallow_root, temp_priv_drop,
984
1100
FALSE, &error) < 0) {
985
1101
i_error("user %s: Couldn't drop privileges: %s",
1007
1123
void mail_storage_service_restrict_setenv(struct mail_storage_service_ctx *ctx,
1008
1124
struct mail_storage_service_user *user)
1010
const struct mail_user_settings *user_set = user->user_set;
1011
const char *home, *chroot, *error;
1013
home = user_expand_varstr(ctx->service, &user->input,
1014
user_set->mail_home);
1015
chroot = user_expand_varstr(ctx->service, &user->input,
1016
user_set->mail_chroot);
1018
if (service_drop_privileges(user, user_set, home, chroot,
1021
i_fatal("%s", error);
1126
struct mail_storage_service_privileges priv;
1129
if (service_parse_privileges(ctx, user, &priv, &error) < 0)
1130
i_fatal("user %s: %s", user->input.username, error);
1131
if (service_drop_privileges(user, &priv,
1132
FALSE, FALSE, TRUE, &error) < 0)
1133
i_fatal("user %s: %s", user->input.username, error);
1024
1136
int mail_storage_service_lookup_next(struct mail_storage_service_ctx *ctx,