diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2021-09-09 19:58:12 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2021-09-09 19:58:12 +0000 |
commit | 6fdb4834cdb5557d9bd7562f61984da8bd0d9c80 (patch) | |
tree | c9ac0c6bc512beed2e550b9aba09eb2af090e6a7 /src/nsssd | |
parent | 1f213b642deb1d8e6139d2b7daac8f639c8717e7 (diff) | |
download | nsss-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-switch | 5 | ||||
-rw-r--r-- | src/nsssd/deps-exe/nsssd-unix | 2 | ||||
-rw-r--r-- | src/nsssd/nsssd-nslcd.c | 9 | ||||
-rw-r--r-- | src/nsssd/nsssd-switch.c | 292 | ||||
-rw-r--r-- | src/nsssd/nsssd-unix.c | 9 | ||||
-rw-r--r-- | src/nsssd/nsssd_main.c | 41 |
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 ; |