summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-03-10 23:37:29 +0100
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2021-04-28 00:40:36 +0200
commitbe31ef213f118abe5fc68732f5492b6b16d28b87 (patch)
tree0363e292a492e62f663b68efed6b697cda65b13f
parentb05dc3573f4cd476482374b0ac0393153d344338 (diff)
downloadexim4-be31ef213f118abe5fc68732f5492b6b16d28b87.tar.gz
Add priv.c: reworked version of priv dropping code
(cherry picked from commit 82b545236e6dc82b7af34528c532811bfc74ea19)
-rw-r--r--src/OS/Makefile-Base3
-rwxr-xr-xsrc/scripts/MakeLinks2
-rw-r--r--src/src/dbfn.c62
-rw-r--r--src/src/functions.h2
-rw-r--r--src/src/priv.c76
-rw-r--r--test/stderr/02751
-rw-r--r--test/stderr/02781
-rw-r--r--test/stderr/03861
-rw-r--r--test/stderr/03881
-rw-r--r--test/stderr/04021
-rw-r--r--test/stderr/04031
-rw-r--r--test/stderr/04041
-rw-r--r--test/stderr/04081
-rw-r--r--test/stderr/04871
14 files changed, 81 insertions, 73 deletions
diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base
index 9eed7b0b9..c7bb116ab 100644
--- a/src/OS/Makefile-Base
+++ b/src/OS/Makefile-Base
@@ -486,7 +486,7 @@ OBJ_EXIM = acl.o base64.o child.o crypt16.o daemon.o dbfn.o debug.o deliver.o \
directory.o dns.o drtables.o enq.o exim.o expand.o filter.o \
filtertest.o globals.o dkim.o dkim_transport.o hash.o \
header.o host.o ip.o log.o lss.o match.o md5.o moan.o \
- os.o parse.o queue.o \
+ os.o parse.o priv.o queue.o \
rda.o readconf.o receive.o retry.o rewrite.o rfc2047.o \
route.o search.o sieve.o smtp_in.o smtp_out.o spool_in.o spool_out.o \
std-crypto.o store.o string.o tls.o tod.o transport.o tree.o verify.o \
@@ -792,6 +792,7 @@ md5.o: $(HDRS) md5.c
moan.o: $(HDRS) moan.c
os.o: $(HDRS) $(OS_C_INCLUDES) os.c
parse.o: $(HDRS) parse.c
+priv.o: $(HDRS) priv.c
queue.o: $(HDRS) queue.c
rda.o: $(HDRS) rda.c
readconf.o: $(HDRS) readconf.c
diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks
index 784247d99..0bc7bb2a8 100755
--- a/src/scripts/MakeLinks
+++ b/src/scripts/MakeLinks
@@ -103,7 +103,7 @@ for f in blob.h dbfunctions.h dbstuff.h exim.h functions.h globals.h \
deliver.c directory.c dns.c drtables.c dummies.c enq.c exim.c \
exim_dbmbuild.c exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c \
globals.c hash.c header.c host.c ip.c log.c lss.c match.c md5.c moan.c \
- parse.c perl.c queue.c rda.c readconf.c receive.c retry.c rewrite.c \
+ parse.c perl.c priv.c queue.c rda.c readconf.c receive.c retry.c rewrite.c \
rfc2047.c route.c search.c setenv.c environment.c \
sieve.c smtp_in.c smtp_out.c spool_in.c spool_out.c std-crypto.c store.c \
string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-cipher-stdname.c \
diff --git a/src/src/dbfn.c b/src/src/dbfn.c
index dceb5f140..e9a0fc27c 100644
--- a/src/src/dbfn.c
+++ b/src/src/dbfn.c
@@ -58,68 +58,6 @@ log_write(0, LOG_MAIN, "Berkeley DB error: %s", msg);
#endif
-
-
-static enum {
- PRIV_DROPPING, PRIV_DROPPED,
- PRIV_RESTORING, PRIV_RESTORED
-} priv_state = PRIV_RESTORED;
-
-static uid_t priv_euid;
-static gid_t priv_egid;
-static gid_t priv_groups[EXIM_GROUPLIST_SIZE + 1];
-static int priv_ngroups;
-
-/* Inspired by OpenSSH's temporarily_use_uid(). Thanks! */
-
-static void
-priv_drop_temp(const uid_t temp_uid, const gid_t temp_gid)
-{
-if (priv_state != PRIV_RESTORED) _exit(EXIT_FAILURE);
-priv_state = PRIV_DROPPING;
-
-priv_euid = geteuid();
-if (priv_euid == root_uid)
- {
- priv_egid = getegid();
- priv_ngroups = getgroups(nelem(priv_groups), priv_groups);
- if (priv_ngroups < 0) _exit(EXIT_FAILURE);
-
- if (priv_ngroups > 0 && setgroups(1, &temp_gid) != 0) _exit(EXIT_FAILURE);
- if (setegid(temp_gid) != 0) _exit(EXIT_FAILURE);
- if (seteuid(temp_uid) != 0) _exit(EXIT_FAILURE);
-
- if (geteuid() != temp_uid) _exit(EXIT_FAILURE);
- if (getegid() != temp_gid) _exit(EXIT_FAILURE);
- }
-
-priv_state = PRIV_DROPPED;
-}
-
-/* Inspired by OpenSSH's restore_uid(). Thanks! */
-
-static void
-priv_restore(void)
-{
-if (priv_state != PRIV_DROPPED) _exit(EXIT_FAILURE);
-priv_state = PRIV_RESTORING;
-
-if (priv_euid == root_uid)
- {
- if (seteuid(priv_euid) != 0) _exit(EXIT_FAILURE);
- if (setegid(priv_egid) != 0) _exit(EXIT_FAILURE);
- if (priv_ngroups > 0 && setgroups(priv_ngroups, priv_groups) != 0) _exit(EXIT_FAILURE);
-
- if (geteuid() != priv_euid) _exit(EXIT_FAILURE);
- if (getegid() != priv_egid) _exit(EXIT_FAILURE);
- }
-
-priv_state = PRIV_RESTORED;
-}
-
-
-
-
/*************************************************
* Open and lock a database file *
*************************************************/
diff --git a/src/src/functions.h b/src/src/functions.h
index 4ce0f093d..fc4e0444d 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -370,6 +370,8 @@ extern const uschar *parse_fix_phrase(const uschar *, int);
extern const uschar *parse_message_id(const uschar *, uschar **, uschar **);
extern const uschar *parse_quote_2047(const uschar *, int, uschar *, BOOL);
extern const uschar *parse_date_time(const uschar *str, time_t *t);
+extern void priv_drop_temp(const uid_t, const gid_t);
+extern void priv_restore(void);
extern int vaguely_random_number(int);
#ifndef DISABLE_TLS
extern int vaguely_random_number_fallback(int);
diff --git a/src/src/priv.c b/src/src/priv.c
new file mode 100644
index 000000000..94d425401
--- /dev/null
+++ b/src/src/priv.c
@@ -0,0 +1,76 @@
+#include "exim.h"
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+
+static enum {
+ PRIV_DROPPING, PRIV_DROPPED,
+ PRIV_RESTORING, PRIV_RESTORED
+} priv_state = PRIV_RESTORED;
+
+
+static uid_t priv_euid;
+static gid_t priv_egid;
+static gid_t priv_groups[EXIM_GROUPLIST_SIZE + 1];
+static int priv_ngroups;
+
+/* Inspired by OpenSSH's temporarily_use_uid(). Thanks! */
+
+void
+priv_drop_temp(const uid_t temp_uid, const gid_t temp_gid)
+{
+if (priv_state != PRIV_RESTORED)
+ log_write(0, LOG_PANIC_DIE, "priv_drop_temp: unexpected priv_state %d != %d", priv_state, PRIV_RESTORED);
+
+priv_state = PRIV_DROPPING;
+
+priv_euid = geteuid();
+if (priv_euid == root_uid)
+ {
+ priv_egid = getegid();
+ priv_ngroups = getgroups(nelem(priv_groups), priv_groups);
+ if (priv_ngroups < 0)
+ log_write(0, LOG_PANIC_DIE, "getgroups: %s", strerror(errno));
+
+ if (priv_ngroups > 0 && setgroups(1, &temp_gid) != 0)
+ log_write(0, LOG_PANIC_DIE, "setgroups: %s", strerror(errno));
+ if (setegid(temp_gid) != 0)
+ log_write(0, LOG_PANIC_DIE, "setegid(%d): %s", temp_gid, strerror(errno));
+ if (seteuid(temp_uid) != 0)
+ log_write(0, LOG_PANIC_DIE, "seteuid(%d): %s", temp_uid, strerror(errno));
+
+ if (geteuid() != temp_uid)
+ log_write(0, LOG_PANIC_DIE, "getdeuid() != %d", temp_uid);
+ if (getegid() != temp_gid)
+ log_write(0, LOG_PANIC_DIE, "getegid() != %d", temp_gid);
+ }
+
+priv_state = PRIV_DROPPED;
+}
+
+/* Inspired by OpenSSH's restore_uid(). Thanks! */
+
+void
+priv_restore(void)
+{
+if (priv_state != PRIV_DROPPED)
+ log_write(0, LOG_PANIC_DIE, "priv_restore: unexpected priv_state %d != %d", priv_state, PRIV_DROPPED);
+priv_state = PRIV_RESTORING;
+
+if (priv_euid == root_uid)
+ {
+ if (seteuid(priv_euid) != 0)
+ log_write(0, LOG_PANIC_DIE, "seteuid(%d): %s", priv_euid, strerror(errno));
+ if (setegid(priv_egid) != 0)
+ log_write(0, LOG_PANIC_DIE, "setegid(%d): %s", priv_egid, strerror(errno));
+ if (priv_ngroups > 0 && setgroups(priv_ngroups, priv_groups) != 0)
+ log_write(0, LOG_PANIC_DIE, "setgroups: %s", strerror(errno));
+
+ if (geteuid() != priv_euid)
+ log_write(0, LOG_PANIC_DIE, "getdeuid() != %d", priv_euid);
+ if (getegid() != priv_egid)
+ log_write(0, LOG_PANIC_DIE, "getdegid() != %d", priv_egid);
+ }
+
+priv_state = PRIV_RESTORED;
+}
diff --git a/test/stderr/0275 b/test/stderr/0275
index 47c9c9e28..1d85b56c1 100644
--- a/test/stderr/0275
+++ b/test/stderr/0275
@@ -171,7 +171,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0278 b/test/stderr/0278
index c09920b94..5e9428da0 100644
--- a/test/stderr/0278
+++ b/test/stderr/0278
@@ -130,7 +130,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0386 b/test/stderr/0386
index 7bc56d9b7..608aa0402 100644
--- a/test/stderr/0386
+++ b/test/stderr/0386
@@ -272,7 +272,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0388 b/test/stderr/0388
index 7819fe907..91fcf830b 100644
--- a/test/stderr/0388
+++ b/test/stderr/0388
@@ -10,7 +10,6 @@ set_process_info: pppp delivering 10HmaX-0005vi-00
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0402 b/test/stderr/0402
index ec4b9ea72..e4ffc0ee5 100644
--- a/test/stderr/0402
+++ b/test/stderr/0402
@@ -213,7 +213,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0403 b/test/stderr/0403
index 9d759694c..5eeb2df0d 100644
--- a/test/stderr/0403
+++ b/test/stderr/0403
@@ -70,7 +70,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0404 b/test/stderr/0404
index f0c1c355b..f945de9b8 100644
--- a/test/stderr/0404
+++ b/test/stderr/0404
@@ -171,7 +171,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0408 b/test/stderr/0408
index 50b853183..48fc0aee1 100644
--- a/test/stderr/0408
+++ b/test/stderr/0408
@@ -70,7 +70,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/test/stderr/0487 b/test/stderr/0487
index 579b1bd5b..834f4daf1 100644
--- a/test/stderr/0487
+++ b/test/stderr/0487
@@ -98,7 +98,6 @@ Delivery address list:
locked TESTSUITE/spool/db/retry.lockfile
EXIM_DBOPEN: file <TESTSUITE/spool/db/retry> dir <TESTSUITE/spool/db> flags=O_RDONLY
returned from EXIM_DBOPEN: (nil)
- ensuring TESTSUITE/spool/db/retry.lockfile is owned by exim
failed to open DB file TESTSUITE/spool/db/retry: No such file or directory
no retry data available
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>