#define LOCK_MAX_TRIES 30
+gid_t rgid, egid, sgid;
+
+void
+save_gids(void)
+{
+ getresgid(&rgid, &egid, &sgid);
+}
+
+static void
+drop_gid(void)
+{
+ setresgid(rgid, rgid, egid);
+}
+
+static void
+raise_gid(void)
+{
+ setresgid(rgid, sgid, sgid);
+}
+
static void
random_sleep(unsigned int about, unsigned int offset)
{
int fd;
int res = -1;
char* lockfile = cat(path, ".lock");
-
+
for (i = 0; i < LOCK_MAX_TRIES; i++){
if ((fd = open(lockfile, O_WRONLY | O_EXCL | O_CREAT, 0))
>= 0) {
{
char* lockfile = cat(path, ".lock");
+ raise_gid();
unlink(lockfile);
-
+ drop_gid();
free(lockfile);
}
-int
-open_mailbox(char* path, int use_default_mailbox)
+static int
+do_open_mailbox(char* path, int is_default_mailbox)
{
int fd;
/* if OK, try to open the file:
either we are saving to default mailbox (no problem here)
or we are saving somewhere else (no need to be privileged)
- */
- if (use_default_mailbox){
- /* get our preciousss out of pocket */
- gid_t ruid, euid, suid;
- getresgid(&ruid, &euid, &suid);
- setresgid(ruid, suid, suid);
-
- /* we are not going to create default mailbox */
- fd = open(path, O_RDWR);
- if (fd < 0){
- dot_unlock(path);
- return -1;
- }
-
- /* hide it again */
- setresgid(ruid, ruid, suid);
- } else {
- fd = open(path, O_RDWR);
- if (fd < 0 && errno == ENOENT){
- fd = open(path, O_RDWR | O_CREAT | O_EXCL,
- S_IRUSR | S_IWUSR);
- if (fd < 0){
- dot_unlock(path);
- return -1;
- }
-
- } else if (fd < 0){
- dot_unlock(path);
- return -1;
- }
+ */
+ int perms = S_IRUSR | S_IWUSR;
+ if (is_default_mailbox)
+ perms |= (S_IRGRP | S_IWGRP);
+
+ mode_t oldmask = umask(0);
+ fd = open(path, O_RDWR | O_CREAT, perms);
+ umask(oldmask);
+ if (fd < 0){
+ dot_unlock(path);
+ return -1;
}
/* fcntl then */
return fd;
}
-void
-close_mailbox(int fd, char* path)
+static void
+do_close_mailbox(int fd, char* path)
{
struct flock mb_lock;
memset(&mb_lock, 0, sizeof(struct flock));
dot_unlock(path);
}
+void
+close_mailbox(int fd, char* path, int is_default_mailbox)
+{
+ if (is_default_mailbox)
+ raise_gid();
+ do_close_mailbox(fd, path);
+ if (is_default_mailbox)
+ drop_gid();
+}
+
+int
+open_mailbox(char* path, int is_default_mailbox)
+{
+ int fd;
+
+ if (is_default_mailbox)
+ raise_gid();
+ fd = do_open_mailbox(path, is_default_mailbox);
+ if (is_default_mailbox)
+ drop_gid();
+
+ return fd;
+}
+
int
main(int argc, char** argv)
{
/* FIXME: move somewhere */
int fd;
- gid_t ruid, euid, suid;
- if (argc < 2)
+ if (argc < 3)
return 1;
- char* mb = argv[1];
- getresgid(&ruid, &euid, &suid);
- setresgid(ruid, ruid, euid);
- fd = open_mailbox(mb, 0);
+ char* mb = argv[1];
+ int is_default_mailbox = atoi(argv[2]);
+ save_gids();
+ drop_gid();
+ fd = open_mailbox(mb, is_default_mailbox);
printf("%d\n", fd);
if (fd < 0)
return 1;
- close_mailbox(fd, mb);
+ close_mailbox(fd, mb, is_default_mailbox);
return 0;
}