summaryrefslogtreecommitdiffstats
path: root/usr.sbin/radiusd/radiusd_module.c
diff options
context:
space:
mode:
authoryasuoka <yasuoka@openbsd.org>2015-07-27 08:58:09 +0000
committeryasuoka <yasuoka@openbsd.org>2015-07-27 08:58:09 +0000
commit3d3cf35c34048a9033acbb73a64e5c0b8e4dfa9a (patch)
tree4240133ff571da15e077a8dec4942cb40ab464ec /usr.sbin/radiusd/radiusd_module.c
parentMake -q suppress ambiguous option warnings too, from Cam Hutchison. (diff)
downloadwireguard-openbsd-3d3cf35c34048a9033acbb73a64e5c0b8e4dfa9a.tar.xz
wireguard-openbsd-3d3cf35c34048a9033acbb73a64e5c0b8e4dfa9a.zip
Drop the privilege from modules. "radiusd_radius" could simply run
without root. "radiusd_bsdauth" uses some functions which needs root. So separate its process into a privileged process and a non-privileged process.
Diffstat (limited to 'usr.sbin/radiusd/radiusd_module.c')
-rw-r--r--usr.sbin/radiusd/radiusd_module.c45
1 files changed, 40 insertions, 5 deletions
diff --git a/usr.sbin/radiusd/radiusd_module.c b/usr.sbin/radiusd/radiusd_module.c
index c99df5c7228..3e932577ff4 100644
--- a/usr.sbin/radiusd/radiusd_module.c
+++ b/usr.sbin/radiusd/radiusd_module.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd_module.c,v 1.1 2015/07/21 04:06:04 yasuoka Exp $ */
+/* $OpenBSD: radiusd_module.c,v 1.2 2015/07/27 08:58:09 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -33,6 +33,7 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+#include <pwd.h>
#include "radiusd.h"
#include "radiusd_module.h"
@@ -50,10 +51,11 @@ static void (*module_access_request) (void *, u_int, const u_char *,
struct module_base {
void *ctx;
struct imsgbuf ibuf;
+ bool priv_dropped;
/* Buffer for receiving the RADIUS packet */
u_char *radpkt;
- int radpktsiz;
+ int radpktsiz;
int radpktoff;
#ifdef USE_LIBEVENT
@@ -76,7 +78,7 @@ static void module_reset_event(struct module_base *);
struct module_base *
module_create(int sock, void *ctx, struct module_handlers *handler)
{
- struct module_base *base;
+ struct module_base *base;
if ((base = calloc(1, sizeof(struct module_base))) == NULL)
return (NULL);
@@ -140,6 +142,28 @@ module_load(struct module_base *base)
imsg_flush(&base->ibuf);
}
+void
+module_drop_privilege(struct module_base *base)
+{
+ struct passwd *pw;
+
+ /* Drop the privilege */
+ if ((pw = getpwnam(RADIUSD_USER)) == NULL)
+ goto on_fail;
+ if (chroot(pw->pw_dir) == -1)
+ goto on_fail;
+ if (chdir("/") == -1)
+ goto on_fail;
+ if (setgroups(1, &pw->pw_gid) ||
+ setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
+ setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
+ goto on_fail;
+ base->priv_dropped = true;
+
+on_fail:
+ return;
+}
+
int
module_notify_secret(struct module_base *base, const char *secret)
{
@@ -336,10 +360,21 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
break;
}
case IMSG_RADIUSD_MODULE_START:
- if (module_start_module != NULL)
+ if (module_start_module != NULL) {
module_start_module(base->ctx);
- else
+ if (!base->priv_dropped) {
+ syslog(LOG_ERR, "Module tried to start with "
+ "root priviledge");
+ abort();
+ }
+ } else {
+ if (!base->priv_dropped) {
+ syslog(LOG_ERR, "Module tried to start with "
+ "root priviledge");
+ abort();
+ }
module_send_message(base, IMSG_OK, NULL);
+ }
break;
case IMSG_RADIUSD_MODULE_STOP:
if (module_stop_module != NULL)