307
312
ret = file_dotlock_create(set, fname, 0, &mbox->mbox_dotlock);
309
314
mbox->mbox_used_privileges = TRUE;
315
else if (ret < 0 && errno == EACCES) {
317
eacces_error_get_creating("file_dotlock_create",
319
mail_storage_set_critical(&mbox->storage->storage,
322
mbox_set_syscall_error(mbox, "file_dotlock_create()");
311
325
case MBOX_DOTLOCK_OP_UNLOCK:
312
326
/* we're now privileged - avoid doing as much as possible */
313
327
ret = file_dotlock_delete(&mbox->mbox_dotlock);
329
mbox_set_syscall_error(mbox, "file_dotlock_delete()");
314
330
mbox->mbox_used_privileges = FALSE;
316
332
case MBOX_DOTLOCK_OP_TOUCH:
317
if (!file_dotlock_is_locked(mbox->mbox_dotlock)) {
318
file_dotlock_delete(&mbox->mbox_dotlock);
319
mbox->mbox_used_privileges = TRUE;
322
ret = file_dotlock_touch(mbox->mbox_dotlock);
333
ret = file_dotlock_touch(mbox->mbox_dotlock);
335
mbox_set_syscall_error(mbox, "file_dotlock_touch()");
327
340
restrict_access_drop_priv_gid();
329
if (fchdir(orig_dir_fd) < 0)
330
i_error("fchdir() failed: %m");
342
if (fchdir(orig_dir_fd) < 0) {
343
mail_storage_set_critical(&mbox->storage->storage,
344
"fchdir() failed: %m");
331
346
(void)close(orig_dir_fd);
352
mbox_dotlock_log_eacces_error(struct mbox_mailbox *mbox, const char *path)
354
const char *dir, *errmsg;
356
const struct group *group;
357
int orig_errno = errno;
359
errmsg = eacces_error_get_creating("file_dotlock_create", path);
360
dir = strrchr(path, '/');
361
dir = dir == NULL ? "." : t_strdup_until(path, dir);
362
if (strcmp(mbox->ibox.box.name, "INBOX") != 0) {
363
mail_storage_set_critical(&mbox->storage->storage,
364
"%s (not INBOX -> no privileged locking)", errmsg);
365
} else if (!mbox->mbox_privileged_locking) {
366
dir = mailbox_list_get_path(mbox->storage->storage.list, NULL,
367
MAILBOX_LIST_PATH_TYPE_DIR);
368
mail_storage_set_critical(&mbox->storage->storage,
369
"%s (under root dir %s -> no privileged locking)",
371
} else if (stat(dir, &st) == 0 &&
372
(st.st_mode & 02) == 0 && /* not world-writable */
373
(st.st_mode & 020) != 0) { /* group-writable */
374
group = getgrgid(st.st_gid);
375
mail_storage_set_critical(&mbox->storage->storage,
376
"%s (set mail_privileged_group=%s)", errmsg,
377
group == NULL ? dec2str(st.st_gid) : group->gr_name);
379
mail_storage_set_critical(&mbox->storage->storage,
380
"%s (nonstandard permissions in %s)", errmsg, dir);
336
386
mbox_lock_dotlock_int(struct mbox_lock_context *ctx, int lock_type, bool try)
343
393
if (!mbox->mbox_dotlocked)
346
if (!mbox->mbox_used_privileges)
347
ret = file_dotlock_delete(&mbox->mbox_dotlock);
396
if (!mbox->mbox_used_privileges) {
397
if (file_dotlock_delete(&mbox->mbox_dotlock) <= 0) {
398
mbox_set_syscall_error(mbox,
399
"file_dotlock_delete()");
349
402
ctx->using_privileges = TRUE;
350
ret = mbox_dotlock_privileged_op(mbox, NULL,
351
MBOX_DOTLOCK_OP_UNLOCK);
403
(void)mbox_dotlock_privileged_op(mbox, NULL,
404
MBOX_DOTLOCK_OP_UNLOCK);
352
405
ctx->using_privileges = FALSE;
355
mbox_set_syscall_error(mbox, "file_dotlock_delete()");
358
407
mbox->mbox_dotlocked = FALSE;
375
424
set.context = ctx;
377
426
ret = file_dotlock_create(&set, mbox->path, 0, &mbox->mbox_dotlock);
378
if (ret < 0 && errno == EACCES && restrict_access_have_priv_gid() &&
379
mbox->mbox_privileged_locking) {
428
/* success / timeout */
429
} else if (errno == EACCES && restrict_access_have_priv_gid() &&
430
mbox->mbox_privileged_locking) {
380
431
/* try again, this time with extra privileges */
381
432
ret = mbox_dotlock_privileged_op(mbox, &set,
382
433
MBOX_DOTLOCK_OP_LOCK);
434
} else if (errno == EACCES)
435
mbox_dotlock_log_eacces_error(mbox, mbox->path);
437
mbox_set_syscall_error(mbox, "file_dotlock_create()");
386
440
if ((ENOSPACE(errno) || errno == EACCES) && try)
389
mbox_set_syscall_error(mbox, "file_lock_dotlock()");
433
486
lock_type = LOCK_UN;
488
if (max_wait_time == 0) {
489
/* usually we're waiting here, but if we came from
490
mbox_lock_dotlock(), we just want to try locking */
491
lock_type |= LOCK_NB;
494
if (now >= max_wait_time)
497
alarm(I_MIN(max_wait_time - now, 5));
436
while (flock(ctx->mbox->mbox_fd, lock_type | LOCK_NB) < 0) {
437
if (errno != EWOULDBLOCK) {
501
while (flock(ctx->mbox->mbox_fd, lock_type) < 0) {
502
if (errno != EINTR) {
503
if (errno == EWOULDBLOCK && max_wait_time == 0) {
504
/* non-blocking lock trying failed */
438
508
mbox_set_syscall_error(ctx->mbox, "flock()");
442
512
now = time(NULL);
443
if (now >= max_wait_time)
513
if (now >= max_wait_time) {
446
if (now != last_notify) {
447
index_storage_lock_notify(&ctx->mbox->ibox,
448
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
449
max_wait_time - now);
452
usleep(LOCK_RANDOM_USLEEP_TIME);
518
/* notify locks once every 5 seconds.
519
try to use rounded values. */
520
next_alarm = (max_wait_time - now) % 5;
525
index_storage_lock_notify(&ctx->mbox->ibox,
526
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
527
max_wait_time - now);
468
545
if (lock_type == F_UNLCK && ctx->mbox->mbox_fd == -1)
471
if (lock_type != F_UNLCK)
548
if (lock_type == F_UNLCK)
550
else if (max_wait_time == 0) {
551
/* usually we're waiting here, but if we came from
552
mbox_lock_dotlock(), we just want to try locking */
472
553
lock_type = F_TLOCK;
556
if (now >= max_wait_time)
559
alarm(I_MIN(max_wait_time - now, 5));
477
564
while (lockf(ctx->mbox->mbox_fd, lock_type, 0) < 0) {
478
if (errno != EAGAIN) {
565
if (errno != EINTR) {
566
if ((errno == EACCES || errno == EAGAIN) &&
567
max_wait_time == 0) {
568
/* non-blocking lock trying failed */
479
572
mbox_set_syscall_error(ctx->mbox, "lockf()");
483
576
now = time(NULL);
484
if (now >= max_wait_time)
577
if (now >= max_wait_time) {
487
if (now != last_notify) {
488
index_storage_lock_notify(&ctx->mbox->ibox,
489
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
490
max_wait_time - now);
493
usleep(LOCK_RANDOM_USLEEP_TIME);
582
/* notify locks once every 5 seconds.
583
try to use rounded values. */
584
next_alarm = (max_wait_time - now) % 5;
589
index_storage_lock_notify(&ctx->mbox->ibox,
590
MAILBOX_LOCK_NOTIFY_MAILBOX_ABORT,
591
max_wait_time - now);