Commit Diff
Diff:
bc1f044a51c739dfa28356a28b4d54397121dcbd
20ce9f5cb4f6382cd9aa93f8eaccc3438ab4bc0e
Commit:
20ce9f5cb4f6382cd9aa93f8eaccc3438ab4bc0e
Tree:
4f0856a22cca5bb8855a48b1e0c1b165f9b54620
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Wed Nov 6 05:18:06 2019 UTC
Message:
move a pledge down beyond parse_db() in dddctl configtest move drop_privs() to parse.y fork and conduct a privsepped and pledged getting of any missing rzones. I'd much rather have no pledge around parse_db() than no pledge around the network facing process of getting a zone file. This is the best I can think of this. tested on OpenBSD
blob - 0337feb2549f35632db3e9854bf3d077115e6e02
blob + 797f97b0a443cda4736b84bf4bec5afbbd18dcd9
--- dddctl.c
+++ dddctl.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: dddctl.c,v 1.85 2019/11/05 07:52:27 pjp Exp $
+ * $Id: dddctl.c,v 1.86 2019/11/06 05:18:06 pjp Exp $
*/
#include <sys/param.h>
@@ -7054,12 +7054,6 @@ configtest(int argc, char *argv[])
if (argc)
zonefile = argv[0];
-#if __OpenBSD__
- if (pledge("stdio rpath wpath cpath chown inet getpw", NULL) < 0) {
- perror("pledge");
- exit(1);
- }
-#endif
@@ -7076,6 +7070,14 @@ configtest(int argc, char *argv[])
dolog(LOG_INFO, "parsing config file failed\n");
return 1;
}
+
+#if __OpenBSD__
+ /* better late than never */
+ if (pledge("stdio", NULL) < 0) {
+ perror("pledge");
+ exit(1);
+ }
+#endif
if (count)
count_db(db);
blob - 969fc030d713e84cd4616691edefdf6cca49c4ed
blob + c24be3223fe3bea108a26f55cf76a8b454391b49
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.80 2019/11/04 12:10:49 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.81 2019/11/06 05:18:06 pjp Exp $
*/
@@ -162,12 +162,12 @@ extern struct rrset * find_rr(struct rbtree *rbt, u_in
extern int add_rr(struct rbtree *, char *, int, u_int16_t, void *);
extern int display_rr(struct rrset *rrset);
extern int notifysource(struct question *, struct sockaddr_storage *);
+extern int drop_privs(char *, struct passwd *);
struct question *convert_question(struct parsequestion *);
void build_reply(struct sreply *, int, char *, int, struct question *, struct sockaddr *, socklen_t, struct rbtree *, struct rbtree *, u_int8_t, int, int, void *, char *);
int compress_label(u_char *, u_int16_t, int);
-int drop_privs(char *, struct passwd *);
struct rbtree * get_soa(ddDB *, struct question *);
struct rbtree * get_ns(ddDB *, struct rbtree *, int *);
void mainloop(struct cfg *, struct imsgbuf **);
@@ -3645,55 +3645,4 @@ setup_unixsocket(char *socketpath, struct imsgbuf *ibu
} /* for (;;) */
/* NOTREACHED */
-}
-
-int
-drop_privs(char *chrootpath, struct passwd *pw)
-{
- /* chroot to the drop priv user home directory */
- if (chroot(chrootpath) < 0) {
- dolog(LOG_INFO, "chroot: %s\n", strerror(errno));
- return -1;
- }
-
- if (unveil("/", "rwc") < 0) {
- dolog(LOG_INFO, "unveil: %s\n", strerror(errno));
- return -1;
- }
-
- if (chdir("/") < 0) {
- dolog(LOG_INFO, "chdir: %s\n", strerror(errno));
- return -1;
- }
-
- /* set groups */
-
- if (setgroups(1, &pw->pw_gid) < 0) {
- dolog(LOG_INFO, "setgroups: %s\n", strerror(errno));
- return -1;
- }
-
-#if defined __OpenBSD__ || defined __FreeBSD__
- if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) {
- dolog(LOG_INFO, "setresgid: %s\n", strerror(errno));
- return -1;
- }
-
- if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) {
- dolog(LOG_INFO, "setresuid: %s\n", strerror(errno));
- return -1;
- }
-
-#else
- if (setgid(pw->pw_gid) < 0) {
- dolog(LOG_INFO, "setgid: %s\n", strerror(errno));
- return -1;
- }
- if (setuid(pw->pw_uid) < 0) {
- dolog(LOG_INFO, "setuid: %s\n", strerror(errno));
- return -1;
- }
-#endif
-
- return 0;
}
blob - 034e9f110829326ab9b0840bc2a40095d1a9380b
blob + eb13adf3b052f7cecd65212e4f1d7b153b057167
--- parse.y
+++ parse.y
@@ -21,7 +21,7 @@
*/
/*
- * $Id: parse.y,v 1.82 2019/11/05 16:33:41 pjp Exp $
+ * $Id: parse.y,v 1.83 2019/11/06 05:18:06 pjp Exp $
*/
%{
@@ -29,6 +29,7 @@
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -97,7 +98,6 @@ extern int display_rr(struct rrset *rrset);
extern void flag_rr(struct rbtree *);
extern int pull_rzone(struct rzone *, time_t, int);
-
extern int whitelist;
extern int tsig;
extern int notify;
@@ -229,6 +229,7 @@ static struct rzone * add_rzone(void);
static struct mzone * add_mzone(void);
static int pull_remote_zone(struct rzone *);
int notifysource(struct question *, struct sockaddr_storage *);
+int drop_privs(char *, struct passwd *);
%}
@@ -3746,37 +3747,42 @@ static int
pull_remote_zone(struct rzone *lrz)
{
struct passwd *pw;
- int ret;
- char *current;
+ int status;
+ pid_t pid;
- current = getcwd(NULL, PATH_MAX);
- if (current == NULL) {
- dolog(LOG_INFO, "pull_remote_zone getcwd: %s\n", strerror(errno));
+ switch (pid = fork()) {
+ case -1:
+ dolog(LOG_ERR, "can't fork: %s\n", strerror(errno));
return -1;
- }
+ case 0:
+ pw = getpwnam(DEFAULT_PRIVILEGE);
+ if (pw == NULL) {
+ dolog(LOG_INFO, "getpwnam: %s\n", strerror(errno));
+ exit(1);
+ }
- if (chdir(DELPHINUS_RZONE_PATH) < 0) {
- dolog(LOG_INFO, "pull_remote_zone chdir: %s\n", strerror(errno));
- return -1;
- }
+ if (drop_privs(DELPHINUS_RZONE_PATH, pw) < 0) {
+ dolog(LOG_INFO, "can't drop privileges\n");
+ exit(1);
+ }
- ret = pull_rzone(lrz, time(NULL), 0);
-
- pw = getpwnam(DEFAULT_PRIVILEGE);
- if (pw == NULL) {
- unlink(lrz->filename);
- return -1;
+ if (pledge("stdio rpath wpath cpath chown inet getpw", NULL) < 0) {
+ dolog(LOG_INFO, "pledge: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (pull_rzone(lrz, time(NULL), 0) < 0)
+ exit(1);
+
+ exit(0);
+ default:
+ if (waitpid(pid, &status, 0) < 0) {
+ return -1;
+ }
+ break;
}
- if (chown(lrz->filename, pw->pw_uid, pw->pw_gid) < 0) {
- unlink(lrz->filename);
- return -1;
- }
-
- chdir(current);
- free(current);
-
- return (ret);
+ return (0);
}
/*
@@ -3884,6 +3890,57 @@ notifysource(struct question *q, struct sockaddr_stora
} /* if havetsig */
} /* SLIST_FOREACH */
+
+ return 0;
+}
+
+int
+drop_privs(char *chrootpath, struct passwd *pw)
+{
+ /* chroot to the drop priv user home directory */
+ if (chroot(chrootpath) < 0) {
+ dolog(LOG_INFO, "chroot: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (unveil("/", "rwc") < 0) {
+ dolog(LOG_INFO, "unveil: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (chdir("/") < 0) {
+ dolog(LOG_INFO, "chdir: %s\n", strerror(errno));
+ return -1;
+ }
+
+ /* set groups */
+
+ if (setgroups(1, &pw->pw_gid) < 0) {
+ dolog(LOG_INFO, "setgroups: %s\n", strerror(errno));
+ return -1;
+ }
+
+#if defined __OpenBSD__ || defined __FreeBSD__
+ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) {
+ dolog(LOG_INFO, "setresgid: %s\n", strerror(errno));
+ return -1;
+ }
+
+ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) {
+ dolog(LOG_INFO, "setresuid: %s\n", strerror(errno));
+ return -1;
+ }
+
+#else
+ if (setgid(pw->pw_gid) < 0) {
+ dolog(LOG_INFO, "setgid: %s\n", strerror(errno));
+ return -1;
+ }
+ if (setuid(pw->pw_uid) < 0) {
+ dolog(LOG_INFO, "setuid: %s\n", strerror(errno));
+ return -1;
+ }
+#endif
return 0;
}
repomaster@centroid.eu