summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2018-03-09 11:48:27 +0100
committerSimon Rettberg2018-03-09 11:48:27 +0100
commit9b33230f3c6235990335fa73c071ff53e89dcfd8 (patch)
treeb8402ad0a60d5ceda5408302a215623685d4647a
parent[pam-slx-plug] Handle sssd.conf generation (diff)
downloadmltk-9b33230f3c6235990335fa73c071ff53e89dcfd8.tar.gz
mltk-9b33230f3c6235990335fa73c071ff53e89dcfd8.tar.xz
mltk-9b33230f3c6235990335fa73c071ff53e89dcfd8.zip
[run-virt] pwdaemon now drops privs, no more su hack; support pam-slx-plug
If usage of pam-slx-plug is detected, we'll use the approprivate environment variables to detect the mount domain, not the global /opt/openslx/inc/shares
-rwxr-xr-xcore/modules/run-virt/compile5
-rw-r--r--core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials64
-rw-r--r--core/modules/run-virt/pw_daemon.c40
3 files changed, 78 insertions, 31 deletions
diff --git a/core/modules/run-virt/compile b/core/modules/run-virt/compile
deleted file mode 100755
index 4db15686..00000000
--- a/core/modules/run-virt/compile
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-rm -- winres.exe
-i686-w64-mingw32-gcc -std=c99 -Os -Wl,--subsystem,windows -o winres.exe winres.c -lole32 -luuid -lgdi32 #-lws2_32
-strip winres.exe && echo "Successfully created winres.exe"
diff --git a/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials
index 941f0047..211f780e 100644
--- a/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials
+++ b/core/modules/run-virt/data/opt/openslx/scripts/pam_script_auth.d/99-run_virt_credentials
@@ -12,38 +12,60 @@ if [ -n "$TEMP_HOME_DIR" ]; then
echo "${PERSISTENT_NETPATH}" > "${TEMP_HOME_DIR}/.home"
chmod 0644 "${TEMP_HOME_DIR}/.home"
fi
+
# pwdaemon
+
# Figure out username
XUSER="${REAL_ACCOUNT}"
[ -z "$XUSER" ] && XUSER="${PAM_USER}"
# Figure out domain
XDOMAIN=
- # Take explicitly configured domain
- if [ -s "/opt/openslx/inc/shares" ]; then
- . /opt/openslx/inc/shares
- XDOMAIN="${SHARE_DOMAIN}"
- fi
- if [ "x$XDOMAIN" != "x#" ]; then
- # Guess domain
- if [ -z "$XDOMAIN" ] && [ -n "$PERSISTENT_HOME_DIR" ]; then
- XDOMAIN=$(grep -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | grep -m1 -F 'domain=' | sed -r 's/^.*[ ,]domain=([^ ,]*)[ ,].*$/\1/g')
- fi
- if [ -z "$XDOMAIN" ]; then
- XDOMAIN=$(<"/etc/ldap.conf" grep -m1 -i '^BASE\s.*DC=' | grep -o -E -i 'DC=([^,;]+)' | head -n 1 | cut -c 4-)
+
+ if [ -d "/opt/openslx/pam/slx-ldap.d" ]; then
+ # New pretty approach - modular with multiple auth sources
+ if [ -n "$LDAP_DOMAIN_OVERRIDE" ]; then
+ [ "x$LDAP_DOMAIN_OVERRIDE" != "x#" ] && XDOMAIN="$LDAP_DOMAIN_OVERRIDE"
+ else
+ if [ -z "$XDOMAIN" ] && [ -n "$PERSISTENT_HOME_DIR" ]; then
+ XDOMAIN=$(grep -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | grep -m1 -F 'domain=' | sed -r 's/^.*[ ,]domain=([^ ,]*)[ ,].*$/\1/g')
+ fi
+ if [ -z "$XDOMAIN" ] && [ -n "$USER_DN" ]; then
+ XDOMAIN=$(echo "$USER_DN" | grep -o -E -i 'DC=([^,;]+)' | head -n 1 | cut -c 4-)
+ fi
+ if [ -z "$XDOMAIN" ] && [ -n "$LDAP_BASE" ]; then
+ XDOMAIN=$(echo "$LDAP_BASE" | grep -o -E -i 'DC=([^,;]+)' | head -n 1 | cut -c 4-)
+ fi
+ if [ -z "$XDOMAIN" ]; then
+ XDOMAIN="WORKGROUP"
+ fi
fi
- if [ -z "$XDOMAIN" ]; then
- XDOMAIN=$(<"/etc/sssd/sssd.conf" grep -m1 -i '^ldap_search_base\s*=.*DC=' | grep -o -E -i 'DC=[^,;]+' | head -n 1 | cut -c 4-)
+ else
+ # Old approach - just one global config
+ # Take explicitly configured domain
+ if [ -s "/opt/openslx/inc/shares" ]; then
+ . /opt/openslx/inc/shares
+ XDOMAIN="${SHARE_DOMAIN}"
fi
- if [ -n "$XDOMAIN" ]; then
- XDOMAIN=$(echo "$XDOMAIN" | tr '[a-z]' '[A-Z]')
+ if [ "x$XDOMAIN" = "x#" ]; then
+ XDOMAIN=
else
- XDOMAIN="WORKGROUP"
+ # Guess domain
+ if [ -z "$XDOMAIN" ] && [ -n "$PERSISTENT_HOME_DIR" ]; then
+ XDOMAIN=$(grep -F " ${PERSISTENT_HOME_DIR} " "/proc/mounts" | grep -m1 -F 'domain=' | sed -r 's/^.*[ ,]domain=([^ ,]*)[ ,].*$/\1/g')
+ fi
+ if [ -z "$XDOMAIN" ]; then
+ XDOMAIN=$(<"/etc/ldap.conf" grep -m1 -i '^BASE\s.*DC=' | grep -o -E -i 'DC=([^,;]+)' | head -n 1 | cut -c 4-)
+ fi
+ if [ -z "$XDOMAIN" ]; then
+ XDOMAIN=$(<"/etc/sssd/sssd.conf" grep -m1 -i '^ldap_search_base\s*=.*DC=' | grep -o -E -i 'DC=[^,;]+' | head -n 1 | cut -c 4-)
+ fi
+ if [ -z "$XDOMAIN" ]; then
+ XDOMAIN="WORKGROUP"
+ fi
fi
- XDOMAIN="${XDOMAIN}\\"
- else
- XDOMAIN=
fi
- USERNAME="${XDOMAIN}${XUSER}" PASSWORD="$PAM_AUTHTOK" PWSOCKET="${TEMP_HOME_DIR}/.pwsocket" su -c 'pwdaemon --daemon &' "${PAM_USER}" &
+ [ -n "$XDOMAIN" ] && XDOMAIN="$(echo "$XDOMAIN" | tr '[a-z]' '[A-Z]')\\"
+ USERNAME="${XDOMAIN}${XUSER}" PASSWORD="$PAM_AUTHTOK" PWSOCKET="${TEMP_HOME_DIR}/.pwsocket" pwdaemon --daemon "${USER_UID}"
unset XUSER XDOMAIN
fi
fi
diff --git a/core/modules/run-virt/pw_daemon.c b/core/modules/run-virt/pw_daemon.c
index 768a5b00..46a380d7 100644
--- a/core/modules/run-virt/pw_daemon.c
+++ b/core/modules/run-virt/pw_daemon.c
@@ -15,6 +15,7 @@
#include <sys/socket.h>
#include <sys/prctl.h>
#include <sys/un.h>
+#include <grp.h>
static const ssize_t KEYLEN = 16;
@@ -25,7 +26,7 @@ static size_t passwordLen = 0;
static uint8_t *key1 = NULL, *key2 = NULL;
static char *key1s = NULL, *key2s = NULL;
-static int mode_daemon();
+static int mode_daemon(const uid_t uidNumber);
static int mode_query(const char *socketPath);
static void sig_handler(int sig);
static int setup_vars(const char *envuser, const char *envpass);
@@ -36,12 +37,18 @@ static int init_udp();
int main(int argc, char **argv)
{
- if (argc > 1 && strcmp(argv[1], "--daemon") == 0) {
- return mode_daemon();
+ if (argc > 2 && strcmp(argv[1], "--daemon") == 0) {
+ char *end = NULL;
+ uid_t uid = (uid_t)strtoul(argv[2], &end, 10);
+ if (argv[2][0] == '\0' || *end != '\0') {
+ fprintf(stderr, "Invalid uidNumber\n");
+ return 1;
+ }
+ return mode_daemon(uid);
} else if (argc > 2 && strcmp(argv[1], "--query") == 0) {
return mode_query(argv[2]);
}
- fprintf(stderr, "Invalid call. Use --daemon or --query\n");
+ fprintf(stderr, "Invalid call. Use --daemon [uidNumber] or --query [unixSocket]\n");
return 1;
}
@@ -90,7 +97,7 @@ static int mode_query(const char *socketPath)
return 0;
}
-static int mode_daemon()
+static int mode_daemon(const uid_t uidNumber)
{
int listenFd, udpPort = -1;
struct sockaddr_un addr;
@@ -98,6 +105,7 @@ static int mode_daemon()
const char *envuser = getenv("USERNAME");
const char *envpass = getenv("PASSWORD");
const char *pwsocket = getenv("PWSOCKET");
+ gid_t gidNumber = 65534;
memset(&addr, 0, sizeof(addr));
memset(&sig, 0, sizeof(sig));
if (envuser == NULL) {
@@ -116,6 +124,26 @@ static int mode_daemon()
fprintf(stderr, "Error setting up variables\n");
return 1;
}
+ // Drop privs
+ setgroups(1, &gidNumber);
+ if (setregid(gidNumber, gidNumber) == -1) {
+ fprintf(stderr, "Warn: Could not switch to group 'nogroup'\n");
+ }
+ if (setreuid(uidNumber, uidNumber) == -1) {
+ fprintf(stderr, "Warn: Could not switch to user %d\n", (int)uidNumber);
+ }
+ // Only bail out if we're not running as the user requested
+ setuid(0);
+ setgid(0);
+ if (getuid() != uidNumber || geteuid() != uidNumber) {
+ fprintf(stderr, "Fatal: Currently running as user %d\n", (int)getuid());
+ return 1;
+ }
+ if (getgid() == 0 || getegid() == 0) {
+ fprintf(stderr, "Fatal: Current process gid is 0 (root)\n");
+ return 1;
+ }
+ // Create unix socket
listenFd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (listenFd == -1) {
perror("Could not create unix socket");
@@ -138,6 +166,8 @@ static int mode_daemon()
perror("Cannot listen on unix socket");
return 1;
}
+ // Daemon
+ daemon( 0, 0 );
// Mainloop
sig.sa_handler = &sig_handler;
sigaction(SIGCHLD, &sig, NULL);