From: Pieter Lexis Date: Wed, 14 Feb 2018 15:42:49 +0000 (+0100) Subject: ixfrdist: Implement priv-dropping X-Git-Tag: dnsdist-1.3.0~100^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6f8cb809d6ec441a05882d1f1cacaed1d4e9f24e;p=thirdparty%2Fpdns.git ixfrdist: Implement priv-dropping Closes #6265 --- diff --git a/docs/manpages/ixfrdist.1.rst b/docs/manpages/ixfrdist.1.rst index 4f19d920d6..7b7136f2d4 100644 --- a/docs/manpages/ixfrdist.1.rst +++ b/docs/manpages/ixfrdist.1.rst @@ -17,6 +17,8 @@ When a SOA query comes in on the address(es) set with **--listen-address**, :pro This query can be followed up with an IXFR or AXFR query, which will then be served. Should an IXFR be served, :program:`ixfrdist` will condense the diff into the IXFR. +When using **--uid** or **--gid** the **--work-dir** directory will be accessed (and potentially created) as the proved user/group. + Options ------- @@ -34,6 +36,8 @@ Options By default, this is the current working directory. --keep Keep at most *NUM* versions of any zone. By default, 20 versions are kept. +--uid Drop effective user-id to *UID* after binding the listen sockets +--gid Drop effective group-id to *GID* after binding the listen sockets See also -------- diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index a0465633e7..aaaa216485 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -23,6 +23,9 @@ #include "config.h" #endif #include +#include +#include +#include #include #include #include @@ -702,6 +705,8 @@ int main(int argc, char** argv) { ("version", "Display the version of ixfrdist") ("verbose", "Be verbose") ("debug", "Be even more verbose") + ("uid", po::value(), "Drop privileges to this user after binding the listen sockets") + ("gid", po::value(), "Drop privileges to this group after binding the listen sockets") ("listen-address", po::value< vector< string>>(), "IP Address(es) to listen on") ("acl", po::value>(), "IP Address masks that are allowed access, by default only loopback addresses are allowed") ("server-address", po::value()->default_value("127.0.0.1:5300"), "server address") @@ -828,6 +833,64 @@ int main(int argc, char** argv) { g_workdir = g_vm["work-dir"].as(); + int newgid = 0; + + if (g_vm.count("gid") > 0) { + string gid = g_vm["gid"].as(); + if (!(newgid = atoi(gid.c_str()))) { + struct group *gr = getgrnam(gid.c_str()); + if (gr == nullptr) { + cerr<<"[ERROR] Can not determine group-id for gid "<gr_gid; + } + } + if(g_verbose) { + cerr<<"[INFO] Dropping effective group-id to "< 0) { + string uid = g_vm["uid"].as(); + if (!(newuid = atoi(uid.c_str()))) { + struct passwd *pw = getpwnam(uid.c_str()); + if (pw == nullptr) { + cerr<<"[ERROR] Can not determine user-id for uid "<pw_uid; + } + } + + struct passwd *pw = getpwuid(newuid); + if (pw == nullptr) { + if (setgroups(0, nullptr) < 0) { + cerr<<"[ERROR] Unable to drop supplementary gids: "<pw_name, newgid) < 0) { + cerr<<"[ERROR] Unable to set supplementary groups: "<pw_uid) < 0) { + cerr<<"[ERROR] Could not set user id to "<