Index: contrib/dma/dma-mbox-create.c =================================================================== --- contrib/dma/dma-mbox-create.c +++ contrib/dma/dma-mbox-create.c @@ -39,15 +39,19 @@ */ #include +#include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include "dma.h" @@ -84,6 +88,7 @@ int main(int argc, char **argv) { + cap_rights_t rights; const char *user; struct passwd *pw; struct group *gr; @@ -91,9 +96,12 @@ gid_t mail_gid; int error; char fn[PATH_MAX+1]; - int f; + int f, maildirfd; - openlog("dma-mbox-create", 0, LOG_MAIL); + /* + * Open log fd now for capability sandbox. + */ + openlog("dma-mbox-create", LOG_NDELAY, LOG_MAIL); errno = 0; gr = getgrnam(DMA_GROUP); @@ -131,6 +139,30 @@ if (!pw) logfail(EX_NOUSER, "cannot find user `%s'", user); + maildirfd = open(_PATH_MAILDIR, O_RDONLY); + if (maildirfd < 0) + logfail(EX_NOINPUT, "cannot open maildir %s", _PATH_MAILDIR); + + cap_rights_init(&rights, CAP_CREATE, CAP_FCHMOD, CAP_FCHOWN, + CAP_LOOKUP, CAP_READ); + if (cap_rights_limit(maildirfd, &rights) < 0 && errno != ENOSYS) + err(EX_OSERR, "can't limit maildirfd rights"); + + /* + * Cache NLS data, for strerror, for err(3), before entering capability + * mode. + */ + (void)catopen("libc", NL_CAT_LOCALE); + + /* + * Cache local time before entering Capsicum capability sandbox. + */ + tzset(); + + /* Enter Capsicum capability sandbox */ + if (cap_enter() < 0 && errno != ENOSYS) + err(EX_OSERR, "cap_enter"); + user_uid = pw->pw_uid; error = snprintf(fn, sizeof(fn), "%s/%s", _PATH_MAILDIR, user); @@ -142,7 +174,7 @@ logfail(EX_CANTCREAT, "cannot build mbox path for `%s/%s'", _PATH_MAILDIR, user); } - f = open(fn, O_RDONLY|O_CREAT|O_NOFOLLOW, 0600); + f = openat(maildirfd, user, O_RDONLY|O_CREAT|O_NOFOLLOW, 0600); if (f < 0) logfail(EX_NOINPUT, "cannt open mbox `%s'", fn);