summaryrefslogtreecommitdiff
path: root/src/nsssd/nsssd-switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsssd/nsssd-switch.c')
-rw-r--r--src/nsssd/nsssd-switch.c292
1 files changed, 292 insertions, 0 deletions
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) ;
+}