Select Git revision
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
main.c 3.90 KiB
// Copyright © 2019 Lars Seipel <ls@slrz.net>
//
// Derived from autofs (modules/lookup_sss.c, v5.1.6)
//
// Copyright 2012 Ian Kent <raven@themaw.net>
// Copyright 2012 Red Hat, Inc.
//
// GNU General Public License v2.0+ (https://www.gnu.org/licenses/gpl-2.0.txt)
#include <bsd/stdlib.h>
#include <dlfcn.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include "arg.h"
#include "log.h"
#include "time.h"
#define SSS_SO_NAME "libsss_autofs"
#ifndef SSS_LIB_DIR
#define SSS_LIB_DIR "/usr/lib64/sssd/modules"
#endif
int _sss_setautomntent(const char *, void **);
int _sss_getautomntent_r(char **, char **, void *);
int _sss_getautomntbyname_r(char *, char **, void *);
int _sss_endautomntent(void **);
typedef int (*setautomntent_t)(const char *, void **);
typedef int (*getautomntent_t)(char **, char **, void *);
typedef int (*getautomntbyname_t)(char *, char **, void *);
typedef int (*endautomntent_t)(void **);
struct libsss_autofs {
void *dlhandle;
setautomntent_t setautomntent;
getautomntent_t getautomntent_r;
getautomntbyname_t getautomntbyname_r;
endautomntent_t endautomntent;
};
static int
libsss_autofs_open(struct libsss_autofs *ctxt)
{
char dlbuf[PATH_MAX];
char *estr;
void *dh;
size_t size;
size = snprintf(dlbuf, sizeof(dlbuf), "%s/%s.so", SSS_LIB_DIR,
SSS_SO_NAME);
if (size >= sizeof(dlbuf)) {
errorf("sss library path too long");
return 1;
}
dh = dlopen(dlbuf, RTLD_LAZY);
if (!dh)
return 1;
ctxt->dlhandle = dh;
ctxt->setautomntent = (setautomntent_t)dlsym(dh, "_sss_setautomntent");
if (!ctxt->setautomntent)
goto lib_names_fail;
ctxt->getautomntent_r =
(getautomntent_t)dlsym(dh, "_sss_getautomntent_r");
if (!ctxt->getautomntent_r)
goto lib_names_fail;
ctxt->getautomntbyname_r =
(getautomntbyname_t)dlsym(dh, "_sss_getautomntbyname_r");
if (!ctxt->getautomntbyname_r)
goto lib_names_fail;
ctxt->endautomntent = (endautomntent_t)dlsym(dh, "_sss_endautomntent");
if (!ctxt->setautomntent)
goto lib_names_fail;
return 0;
lib_names_fail:
if ((estr = dlerror()) == NULL)
errorf("failed to locate sss library entry points");
else
errorf("dlsym: %s", estr);
dlclose(dh);
return 1;
}
static int
libsss_autofs_close(struct libsss_autofs *ctxt)
{
int r;
if (r = dlclose(ctxt->dlhandle))
errorf("dlclose: %s", dlerror() ?: "<null>");
return r;
}
char *argv0;
static void
usage(int status)
{
fprintf(stderr,
"Usage: %s [options]\n"
" -h: show this help text\n"
" -v: be verbose\n",
argv0);
exit(status);
}
static const int64_t base_delay = 100 * Millisecond;
static const int64_t max_delay = 2 * Second;
int
main(int argc, char **argv)
{
const char *mapname = "auto.master";
int vflag = 0;
char fmtbuf[16];
ARGBEGIN
{
case 'h':
usage(0);
break;
case 'v':
vflag++;
break;
default:
usage(2);
}
ARGEND
if (*argv)
mapname = *argv;
struct libsss_autofs sss_autofs;
void *ctx = NULL;
int r = libsss_autofs_open(&sss_autofs);
if (r)
fatalf("libsss_autofs_open: %d", r);
int64_t delay = base_delay;
for (int i = 0; i < 1000; i++) {
r = sss_autofs.setautomntent(mapname, &ctx);
if (r == 0)
break;
ctx = NULL;
int64_t backoff_nsec = delay + arc4random_uniform(delay / 2);
struct timespec ts = totimespec(backoff_nsec);
warnf("setautomntent: %d (retry in %s)", r,
fmtduration(fmtbuf, sizeof fmtbuf, backoff_nsec));
nanosleep(&ts, NULL);
delay <<= 1;
if (delay > max_delay)
delay = max_delay;
}
if (!ctx)
goto Out;
char *key = NULL, *value = NULL;
while ((r = sss_autofs.getautomntent_r(&key, &value, ctx)) == 0) {
if (vflag)
printf("%s → %s\n", key ?: "<null>", value ?: "<null>");
free(key);
free(value);
key = value = NULL;
}
r = 0;
Out:
if (ctx)
sss_autofs.endautomntent(&ctx);
libsss_autofs_close(&sss_autofs);
return r;
}