From 9b9d6ab15090fdb97e0c9759082676358accac05 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 12 Jan 2016 17:50:25 +0100 Subject: [PATCH] privops: add support for privileged DNS_Name2IPAddress() --- nameserv_async.c | 3 ++- privops.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ privops.h | 6 +++++ stubs.c | 3 ++- 4 files changed, 78 insertions(+), 2 deletions(-) diff --git a/nameserv_async.c b/nameserv_async.c index 89954d6..0175cc2 100644 --- a/nameserv_async.c +++ b/nameserv_async.c @@ -31,6 +31,7 @@ #include "nameserv_async.h" #include "logging.h" #include "memory.h" +#include "privops.h" #include "sched.h" #include "util.h" @@ -59,7 +60,7 @@ start_resolving(void *anything) { struct DNS_Async_Instance *inst = (struct DNS_Async_Instance *)anything; - inst->status = DNS_Name2IPAddress(inst->name, inst->addresses, DNS_MAX_ADDRESSES); + inst->status = PRV_Name2IPAddress(inst->name, inst->addresses, DNS_MAX_ADDRESSES); /* Notify the main thread that the result is ready */ if (write(inst->pipe[1], "", 1) < 0) diff --git a/privops.c b/privops.c index d7ac1fc..9b4094a 100644 --- a/privops.c +++ b/privops.c @@ -29,6 +29,7 @@ #include "sysincl.h" #include "conf.h" +#include "nameserv.h" #include "logging.h" #include "privops.h" #include "util.h" @@ -37,6 +38,7 @@ #define OP_ADJUSTTIMEX 1025 #define OP_SETTIME 1026 #define OP_BINDSOCKET 1027 +#define OP_NAME2IPADDRESS 1028 #define OP_QUIT 1099 union sockaddr_in46 { @@ -69,6 +71,10 @@ typedef struct { union sockaddr_in46 sa; } ReqBindSocket; +typedef struct { + char name[256]; +} ReqName2IPAddress; + typedef struct { int op; union { @@ -78,6 +84,9 @@ typedef struct { #endif ReqSetTime set_time; ReqBindSocket bind_socket; +#ifdef PRIVOPS_NAME2IPADDRESS + ReqName2IPAddress name_to_ipaddress; +#endif } data; } PrvRequest; @@ -93,6 +102,10 @@ typedef struct { } ResAdjustTimex; #endif +typedef struct { + IPAddr addresses[DNS_MAX_ADDRESSES]; +} ResName2IPAddress; + typedef struct { char msg[256]; } ResFatalMsg; @@ -106,6 +119,9 @@ typedef struct { ResAdjustTime adjust_time; #ifdef PRIVOPS_ADJUSTTIMEX ResAdjustTimex adjust_timex; +#endif +#ifdef PRIVOPS_NAME2IPADDRESS + ResName2IPAddress name_to_ipaddress; #endif } data; } PrvResponse; @@ -267,6 +283,21 @@ do_bind_socket(ReqBindSocket *req, PrvResponse *res) /* ======================================================================= */ +/* HELPER - perform DNS_Name2IPAddress() */ + +#ifdef PRIVOPS_NAME2IPADDRESS +static void +do_name_to_ipaddress(ReqName2IPAddress *req, PrvResponse *res) +{ + /* make sure the string is terminated */ + req->name[sizeof (req->name) - 1] = '\0'; + res->rc = DNS_Name2IPAddress(req->name, res->data.name_to_ipaddress.addresses, + DNS_MAX_ADDRESSES); +} +#endif + +/* ======================================================================= */ + /* HELPER - main loop - action requests from the daemon */ static void @@ -303,6 +334,11 @@ helper_main(int fd) case OP_BINDSOCKET: do_bind_socket(&req.data.bind_socket, &res); break; +#endif +#ifdef PRIVOPS_NAME2IPADDRESS + case OP_NAME2IPADDRESS: + do_name_to_ipaddress(&req.data.name_to_ipaddress, &res); + break; #endif case OP_QUIT: quit = 1; @@ -541,6 +577,38 @@ PRV_BindSocket(int sock, struct sockaddr *address, socklen_t address_len) /* ======================================================================= */ +/* DAEMON - request DNS_Name2IPAddress() */ + +#ifdef PRIVOPS_NAME2IPADDRESS +int +PRV_Name2IPAddress(const char *name, IPAddr *ip_addrs, int max_addrs) +{ + PrvRequest req; + PrvResponse res; + int i; + + if (!have_helper()) + return DNS_Name2IPAddress(name, ip_addrs, max_addrs); + + memset(&req, 0, sizeof (req)); + req.op = OP_NAME2IPADDRESS; + if (snprintf(req.data.name_to_ipaddress.name, sizeof (req.data.name_to_ipaddress.name), + "%s", name) >= sizeof (req.data.name_to_ipaddress.name)) { + DEBUG_LOG(LOGF_PrivOps, "Name too long"); + return DNS_Failure; + } + + submit_request(&req, &res); + + for (i = 0; i < max_addrs && i < DNS_MAX_ADDRESSES; i++) + ip_addrs[i] = res.data.name_to_ipaddress.addresses[i]; + + return res.rc; +} +#endif + +/* ======================================================================= */ + void PRV_Initialise(void) { diff --git a/privops.h b/privops.h index ee0cb8f..77cdde7 100644 --- a/privops.h +++ b/privops.h @@ -52,6 +52,12 @@ int PRV_BindSocket(int sock, struct sockaddr *address, socklen_t address_len); #define PRV_BindSocket bind #endif +#ifdef PRIVOPS_NAME2IPADDRESS +int PRV_Name2IPAddress(const char *name, IPAddr *ip_addrs, int max_addrs); +#else +#define PRV_Name2IPAddress DNS_Name2IPAddress +#endif + #ifdef PRIVOPS_HELPER void PRV_Initialise(void); void PRV_StartHelper(void); diff --git a/stubs.c b/stubs.c index 0c7414c..ac337e8 100644 --- a/stubs.c +++ b/stubs.c @@ -38,6 +38,7 @@ #include "ntp_core.h" #include "ntp_io.h" #include "ntp_sources.h" +#include "privops.h" #include "refclock.h" #include "sched.h" @@ -60,7 +61,7 @@ resolve_name(void *anything) int i; inst = (struct DNS_Async_Instance *)anything; - status = DNS_Name2IPAddress(inst->name, addrs, DNS_MAX_ADDRESSES); + status = PRV_Name2IPAddress(inst->name, addrs, DNS_MAX_ADDRESSES); for (i = 0; status == DNS_Success && i < DNS_MAX_ADDRESSES && addrs[i].family != IPADDR_UNSPEC; i++)