summaryrefslogtreecommitdiff
path: root/src/nsssd
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-09-09 19:58:12 +0000
committerLaurent Bercot <ska@appnovation.com>2021-09-09 19:58:12 +0000
commit6fdb4834cdb5557d9bd7562f61984da8bd0d9c80 (patch)
treec9ac0c6bc512beed2e550b9aba09eb2af090e6a7 /src/nsssd
parent1f213b642deb1d8e6139d2b7daac8f639c8717e7 (diff)
downloadnsss-6fdb4834cdb5557d9bd7562f61984da8bd0d9c80.tar.xz
Prepare for 0.2.0.0, lots of changes.
- Make _r functions completely thread-safe. - Save a lot of forking by having a persistent nsss_switch_query - Introduce a timeout to make the server expire - Start writing nsss-switch, not working yet. Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/nsssd')
-rw-r--r--src/nsssd/deps-exe/nsssd-switch5
-rw-r--r--src/nsssd/deps-exe/nsssd-unix2
-rw-r--r--src/nsssd/nsssd-nslcd.c9
-rw-r--r--src/nsssd/nsssd-switch.c292
-rw-r--r--src/nsssd/nsssd-unix.c9
-rw-r--r--src/nsssd/nsssd_main.c41
6 files changed, 341 insertions, 17 deletions
diff --git a/src/nsssd/deps-exe/nsssd-switch b/src/nsssd/deps-exe/nsssd-switch
new file mode 100644
index 0000000..81b2820
--- /dev/null
+++ b/src/nsssd/deps-exe/nsssd-switch
@@ -0,0 +1,5 @@
+${LIBNSSSD}
+${LIBNSSS}
+-lskarnet
+${SOCKET_LIB}
+${SYSCLOCK_LIB}
diff --git a/src/nsssd/deps-exe/nsssd-unix b/src/nsssd/deps-exe/nsssd-unix
index deff087..5958e7a 100644
--- a/src/nsssd/deps-exe/nsssd-unix
+++ b/src/nsssd/deps-exe/nsssd-unix
@@ -1,3 +1,3 @@
-${LIBNSSS}
${LIBNSSSD}
+${LIBNSSS}
-lskarnet
diff --git a/src/nsssd/nsssd-nslcd.c b/src/nsssd/nsssd-nslcd.c
index 75df846..b8e4b00 100644
--- a/src/nsssd/nsssd-nslcd.c
+++ b/src/nsssd/nsssd-nslcd.c
@@ -56,7 +56,7 @@ void *nsssd_handle_init (void)
return &a ;
}
-int nsssd_handle_start (void *handle, char const *const *argv, char const *const *envp)
+int nsssd_handle_start (void *handle, char const *const *argv)
{
nslcd_handle_t *a = handle ;
if (!argv[0]) strerr_dieusage(100, USAGE) ;
@@ -339,6 +339,7 @@ int nsssd_pwd_getbyname (void *handle, struct passwd *pw, char const *name)
void nsssd_pwd_end (void *handle)
{
+ (void)handle ;
}
int nsssd_grp_start (void *handle)
@@ -480,6 +481,7 @@ int nsssd_grp_getlist (void *handle, char const *user, gid_t *gids, size_t n, si
void nsssd_grp_end (void *handle)
{
+ (void)handle ;
}
int nsssd_shadow_start (void *handle)
@@ -571,9 +573,10 @@ int nsssd_shadow_getbyname (void *handle, struct spwd *sp, char const *name)
void nsssd_shadow_end (void *handle)
{
+ (void)handle ;
}
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
PROG = "nsssd-nslcd" ;
{
@@ -593,5 +596,5 @@ int main (int argc, char const *const *argv, char const *const *envp)
if (t) tain_from_millisecs(&tto, t) ;
}
- return nsssd_main(argv, envp) ;
+ return nsssd_main(argv) ;
}
diff --git a/src/nsssd/nsssd-switch.c b/src/nsssd/nsssd-switch.c
new file mode 100644
index 0000000..91eb1ce
--- /dev/null
+++ b/src/nsssd/nsssd-switch.c
@@ -0,0 +1,292 @@
+/* ISC license. */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/tai.h>
+
+#include <nsss/nsssd.h>
+#include <nsss/nsss-switch.h>
+#include <nsss/nsss-unix.h>
+
+#define USAGE "nsssd-switch flag1 backend1... \"\" flag2 backend2... \"\""
+#define dieusage() strerr_dieusage(100, USAGE)
+
+#define MAX_BACKENDS 16
+
+static tain tto = TAIN_INFINITE_RELATIVE ;
+
+
+ /* We cannot depend on execline so we duplicate functions here */
+
+static unsigned int el_getstrict (void)
+{
+ static unsigned int strict = 0 ;
+ static int first = 1 ;
+ if (first)
+ {
+ char const *x = getenv("EXECLINE_STRICT") ;
+ first = 0 ;
+ if (x) uint0_scan(x, &strict) ;
+ }
+ return strict ;
+}
+
+static int el_semicolon (char const **argv)
+{
+ static unsigned int nblock = 0 ;
+ int argc1 = 0 ;
+ nblock++ ;
+ for (;; argc1++, argv++)
+ {
+ char const *arg = *argv ;
+ if (!arg) return argc1 + 1 ;
+ if (!arg[0]) return argc1 ;
+ else if (arg[0] == ' ') ++*argv ;
+ else
+ {
+ unsigned int strict = el_getstrict() ;
+ if (strict)
+ {
+ char fmt1[UINT_FMT] ;
+ char fmt2[UINT_FMT] ;
+ fmt1[uint_fmt(fmt1, nblock)] = 0 ;
+ fmt2[uint_fmt(fmt2, (unsigned int)argc1)] = 0 ;
+ if (strict >= 2)
+ strerr_dief6x(100, "unquoted argument ", arg, " at block ", fmt1, " position ", fmt2) ;
+ else
+ strerr_warnw6x("unquoted argument ", arg, " at block ", fmt1, " position ", fmt2) ;
+ }
+ }
+ }
+}
+
+
+ /* Real code here */
+
+typedef struct backend_s backend_t, *backend_t_ref ;
+struct backend_s
+{
+ char const *const *argv ;
+ nsss_switch_t handle ;
+ uint8_t flags ;
+} ;
+
+typedef struct handle_s handle_t, *handle_t_ref ;
+struct handle_s
+{
+ backend_t tab[MAX_BACKENDS] ;
+ unsigned int n ;
+} ;
+
+void *nsssd_handle_init (void)
+{
+ static handle_t a = { .n = 0 } ;
+ return &a ;
+}
+
+int nsssd_handle_start (void *handle, char const *const *argv)
+{
+ static nsss_switch_t const nsss_switch_zero = NSSS_SWITCH_ZERO ;
+ handle_t *a = handle ;
+ char const **args = (char const **)argv ;
+ unsigned int argc = 0 ;
+ while (args[argc])
+ {
+ backend_t *be = &a->tab[a->n] ;
+ int argc1 ;
+ unsigned int flags ;
+ if (!uint0_scan(args[argc++], &flags)) dieusage() ;
+ if (!args[argc]) strerr_dief1x(100, "missing block") ;
+ argc1 = el_semicolon(args + argc) ;
+ if (!argc1) strerr_dief1x(100, "empty block") ;
+ if (!args[argc + argc1]) strerr_dief1x(100, "unterminated block") ;
+ args[argc + argc1] = 0 ;
+ if (a->n++ >= MAX_BACKENDS) strerr_dief1x(100, "too many defined backends") ;
+ be->flags = flags & 0x7 ;
+ be->argv = args + argc ;
+ be->handle = nsss_switch_zero ;
+ argc += argc1 ;
+ }
+ if (!a->n) strerr_dief1x(100, "no defined backends") ;
+ return 1 ;
+}
+
+void nsssd_handle_end (void *handle)
+{
+ handle_t *a = handle ;
+ for (unsigned int i = 0 ; i < a->n ; i++)
+ nsss_switch_end(&a->tab[i].handle, NSSS_SWITCH_PWD | NSSS_SWITCH_GRP | NSSS_SWITCH_SHADOW) ;
+ a->n = 0 ;
+}
+
+int nsssd_pwd_start (void *handle)
+{
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_pwd_rewind (void *handle)
+{
+ nsss_unix_setpwent() ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_pwd_get (void *handle, struct passwd *pw)
+{
+ struct passwd *pw2 = nsss_unix_getpwent() ;
+ if (!pw2) return 0 ;
+ *pw = *pw2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_pwd_getbyuid (void *handle, struct passwd *pw, uid_t uid)
+{
+ struct passwd *pw2 = nsss_unix_getpwuid(uid) ;
+ if (!pw2) return 0 ;
+ *pw = *pw2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_pwd_getbyname (void *handle, struct passwd *pw, char const *name)
+{
+ struct passwd *pw2 = nsss_unix_getpwnam(name) ;
+ if (!pw2) return 0 ;
+ *pw = *pw2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+void nsssd_pwd_end (void *handle)
+{
+ nsss_unix_endpwent() ;
+ (void)handle ;
+}
+
+void nsssd_grp_handle_init (void *handle)
+{
+ (void)handle ;
+}
+
+int nsssd_grp_start (void *handle)
+{
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_grp_rewind (void *handle)
+{
+ nsss_unix_setgrent() ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_grp_get (void *handle, struct group *gr)
+{
+ struct group *gr2 = nsss_unix_getgrent() ;
+ if (!gr2) return 0 ;
+ *gr = *gr2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_grp_getbygid (void *handle, struct group *gr, gid_t gid)
+{
+ struct group *gr2 = nsss_unix_getgrgid(gid) ;
+ if (!gr2) return 0 ;
+ *gr = *gr2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_grp_getbyname (void *handle, struct group *gr, char const *name)
+{
+ struct group *gr2 = nsss_unix_getgrnam(name) ;
+ if (!gr2) return 0 ;
+ *gr = *gr2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_grp_getlist (void *handle, char const *user, gid_t *gids, size_t n, size_t *r)
+{
+ (void)handle ;
+ return nsss_unix_getgrouplist_preadjust(user, gids, n, r) ;
+}
+
+void nsssd_grp_end (void *handle)
+{
+ nsss_unix_endgrent() ;
+ (void)handle ;
+}
+
+void nsssd_shadow_handle_init (void *handle)
+{
+ (void)handle ;
+}
+
+int nsssd_shadow_start (void *handle)
+{
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_shadow_rewind (void *handle)
+{
+ nsss_unix_setspent() ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_shadow_get (void *handle, struct spwd *sp)
+{
+ struct spwd *sp2 = nsss_unix_getspent() ;
+ if (!sp2) return 0 ;
+ *sp = *sp2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+int nsssd_shadow_getbyname (void *handle, struct spwd *sp, char const *name)
+{
+ struct spwd *sp2 = nsss_unix_getspnam(name) ;
+ if (!sp2) return 0 ;
+ *sp = *sp2 ;
+ (void)handle ;
+ return 1 ;
+}
+
+void nsssd_shadow_end (void *handle)
+{
+ nsss_unix_endspent() ;
+ (void)handle ;
+}
+
+int main (int argc, char const *const *argv)
+{
+ PROG = "nsssd-switch" ;
+ {
+ subgetopt l = SUBGETOPT_ZERO ;
+ unsigned int t = 0 ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "t:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ if (t) tain_from_millisecs(&tto, t) ;
+ }
+ return nsssd_main(argv) ;
+}
diff --git a/src/nsssd/nsssd-unix.c b/src/nsssd/nsssd-unix.c
index 6cbb3f2..3974cb5 100644
--- a/src/nsssd/nsssd-unix.c
+++ b/src/nsssd/nsssd-unix.c
@@ -1,6 +1,7 @@
/* ISC license. */
#include <skalibs/strerr2.h>
+
#include <nsss/pwd-unix.h>
#include <nsss/grp-unix.h>
#include <nsss/shadow-unix.h>
@@ -11,11 +12,10 @@ void *nsssd_handle_init (void)
return 0 ;
}
-int nsssd_handle_start (void *handle, char const *const *argv, char const *const *envp)
+int nsssd_handle_start (void *handle, char const *const *argv)
{
(void)handle ;
(void)argv ;
- (void)envp ;
return 1 ;
}
@@ -169,8 +169,9 @@ void nsssd_shadow_end (void *handle)
(void)handle ;
}
-int main (int argc, char const *const *argv, char const *const *envp)
+int main (int argc, char const *const *argv)
{
PROG = "nsssd-unix" ;
- return nsssd_main(argv+1, envp) ;
+ (void)argc ;
+ return nsssd_main(argv+1) ;
}
diff --git a/src/nsssd/nsssd_main.c b/src/nsssd/nsssd_main.c
index 9dbc27c..ba23e05 100644
--- a/src/nsssd/nsssd_main.c
+++ b/src/nsssd/nsssd_main.c
@@ -1,5 +1,6 @@
/* ISC license. */
+#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
@@ -23,12 +24,13 @@
#include <nsss/nsssd.h>
static unsigned int initted = 0 ;
+static tain tto = TAIN_INFINITE_RELATIVE ;
+static tain outertto = TAIN_INFINITE_RELATIVE ;
static void get0 (char *s, size_t n)
{
tain deadline ;
- tain_ulong(&deadline, 30) ;
- tain_add_g(&deadline, &deadline) ;
+ tain_add_g(&deadline, &tto) ;
if (buffer_timed_get_g(buffer_0small, s, n, &deadline) < n)
strerr_diefu1sys(111, "read from stdin") ;
}
@@ -37,8 +39,7 @@ static void put1 (char const *s, size_t n)
{
size_t w = 0 ;
tain deadline ;
- tain_ulong(&deadline, 30) ;
- tain_add_g(&deadline, &deadline) ;
+ tain_add_g(&deadline, &tto) ;
while (!buffer_putall(buffer_1, s, n, &w))
{
if (!buffer_timed_flush_g(buffer_1, &deadline))
@@ -49,8 +50,7 @@ static void put1 (char const *s, size_t n)
static void flush1 (void)
{
tain deadline ;
- tain_ulong(&deadline, 2) ;
- tain_add_g(&deadline, &deadline) ;
+ tain_add_g(&deadline, &tto) ;
if (!buffer_timed_flush_g(buffer_1, &deadline))
strerr_diefu1sys(111, "write to stdout") ;
}
@@ -131,6 +131,16 @@ static inline void print_sp (struct spwd const *sp)
flush1() ;
}
+static inline void do_set_timeout (void)
+{
+ uint32_t t ;
+ char buf[4] ;
+ get0(buf, 4) ;
+ uint32_unpack_big(buf, &t) ;
+ if (t) tain_from_millisecs(&outertto, t) ;
+ else outertto = tain_infinite_relative ;
+ answer(0) ;
+}
static inline void do_pwend (void *a)
{
@@ -402,6 +412,7 @@ static inline void do_spget (void *a)
}
print_sp(&sp) ;
}
+
static inline void do_spnam (void *a)
{
struct spwd sp ;
@@ -432,7 +443,7 @@ static inline void do_spnam (void *a)
}
-int nsssd_main (char const *const *argv, char const *const *envp)
+int nsssd_main (char const *const *argv)
{
void *a ;
@@ -452,22 +463,34 @@ int nsssd_main (char const *const *argv, char const *const *envp)
if (setuid(uid) == -1) strerr_diefu2sys(111, "setuid to ", x) ;
}
+ {
+ char const *x = getenv("NSSSD_TIMEOUT") ;
+ if (x)
+ {
+ uint32_t t ;
+ if (!uint320_scan(x, &t))
+ strerr_dief1x(100, "invalid NSSSD_TIMEOUT") ;
+ if (t) tain_from_millisecs(&tto, t) ;
+ }
+ }
+
tain_now_set_stopwatch_g() ;
a = nsssd_handle_init() ;
if (ndelay_on(0) < 0) strerr_diefu1sys(111, "set stdin non-blocking") ;
tain_now_g() ;
- if (!nsssd_handle_start(a, argv, envp))
+ if (!nsssd_handle_start(a, argv))
strerr_diefu1sys(111, "nsssd_handle_start") ;
for (;;)
{
tain deadline ;
char c ;
- tain_add_g(&deadline, &tain_infinite_relative) ;
+ tain_add_g(&deadline, &outertto) ;
if (!buffer_timed_get_g(buffer_0small, &c, 1, &deadline)) break ;
errno = 0 ;
switch (c)
{
+ case NSSS_SWITCH_SET_TIMEOUT : do_set_timeout() ; break ;
case NSSS_SWITCH_PWD_END : do_pwend(a) ; break ;
case NSSS_SWITCH_PWD_REWIND : do_pwrewind(a) ; break ;
case NSSS_SWITCH_PWD_GET : do_pwget(a) ; break ;