|
Packit |
8480eb |
/* ----------------------------------------------------------------------- *
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* lookup_multi.c - module for Linux automount to seek multiple lookup
|
|
Packit |
8480eb |
* methods in succession
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* Copyright 1999 Transmeta Corporation - All Rights Reserved
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8480eb |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8480eb |
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Packit |
8480eb |
* USA; either version 2 of the License, or (at your option) any later
|
|
Packit |
8480eb |
* version; incorporated herein by reference.
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* ----------------------------------------------------------------------- */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#include <ctype.h>
|
|
Packit |
8480eb |
#include <limits.h>
|
|
Packit |
8480eb |
#include <malloc.h>
|
|
Packit |
8480eb |
#include <stdio.h>
|
|
Packit |
8480eb |
#include <string.h>
|
|
Packit |
8480eb |
#include <sys/stat.h>
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#define MODULE_LOOKUP
|
|
Packit |
8480eb |
#include "automount.h"
|
|
Packit |
8480eb |
#include "nsswitch.h"
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#define MAX_MAP_TYPE_STRING 20
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#define MODPREFIX "lookup(multi): "
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct module_info {
|
|
Packit |
8480eb |
int argc;
|
|
Packit |
8480eb |
const char **argv;
|
|
Packit |
8480eb |
struct lookup_mod *mod;
|
|
Packit |
8480eb |
};
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct lookup_context {
|
|
Packit |
8480eb |
int n;
|
|
Packit |
8480eb |
const char **argl;
|
|
Packit |
8480eb |
struct module_info *m;
|
|
Packit |
8480eb |
};
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static int free_multi_context(struct lookup_context *);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static struct lookup_context *alloc_context(const char *format,
|
|
Packit |
8480eb |
int argc, const char *const *argv)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF];
|
|
Packit |
8480eb |
char **args;
|
|
Packit |
8480eb |
int i, an;
|
|
Packit |
8480eb |
char *estr;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
ctxt = malloc(sizeof(struct lookup_context));
|
|
Packit |
8480eb |
if (!ctxt)
|
|
Packit |
8480eb |
goto nomem;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
memset(ctxt, 0, sizeof(struct lookup_context));
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (argc < 1) {
|
|
Packit |
8480eb |
logerr(MODPREFIX "No map list");
|
|
Packit |
8480eb |
goto error_out;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
ctxt->n = 1; /* Always at least one map */
|
|
Packit |
8480eb |
for (i = 0; i < argc; i++) {
|
|
Packit |
8480eb |
if (!strcmp(argv[i], "--")) /* -- separates maps */
|
|
Packit |
8480eb |
ctxt->n++;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) ||
|
|
Packit |
8480eb |
!(ctxt->argl = malloc((argc + 1) * sizeof(const char *))))
|
|
Packit |
8480eb |
goto nomem;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info));
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *));
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
args = NULL;
|
|
Packit |
8480eb |
for (i = an = 0; ctxt->argl[an]; an++) {
|
|
Packit |
8480eb |
if (ctxt->m[i].argc == 0)
|
|
Packit |
8480eb |
args = (char **) &ctxt->argl[an];
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (strcmp(ctxt->argl[an], "--"))
|
|
Packit |
8480eb |
ctxt->m[i].argc++;
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
ctxt->argl[an] = NULL;
|
|
Packit |
8480eb |
if (!args) {
|
|
Packit |
8480eb |
logerr(MODPREFIX "error assigning map args");
|
|
Packit |
8480eb |
goto error_out;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
ctxt->m[i].argv = copy_argv(ctxt->m[i].argc,
|
|
Packit |
8480eb |
(const char **) args);
|
|
Packit |
8480eb |
if (!ctxt->m[i].argv)
|
|
Packit |
8480eb |
goto nomem;
|
|
Packit |
8480eb |
args = NULL;
|
|
Packit |
8480eb |
i++;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* catch the last one */
|
|
Packit |
8480eb |
if (args) {
|
|
Packit |
8480eb |
ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args);
|
|
Packit |
8480eb |
if (!ctxt->m[i].argv)
|
|
Packit |
8480eb |
goto nomem;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return ctxt;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
nomem:
|
|
Packit |
8480eb |
estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr(MODPREFIX "error: %s", estr);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
error_out:
|
|
Packit |
8480eb |
free_multi_context(ctxt);
|
|
Packit |
8480eb |
free(ctxt);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static int free_multi_context(struct lookup_context *ctxt)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int rv;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!ctxt)
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
rv = 0;
|
|
Packit |
8480eb |
if (ctxt->m) {
|
|
Packit |
8480eb |
int i;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < ctxt->n; i++) {
|
|
Packit |
8480eb |
if (ctxt->m[i].mod)
|
|
Packit |
8480eb |
rv = rv || close_lookup(ctxt->m[i].mod);
|
|
Packit |
8480eb |
if (ctxt->m[i].argv)
|
|
Packit |
8480eb |
free_argv(ctxt->m[i].argc, ctxt->m[i].argv);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
free(ctxt->m);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (ctxt->argl)
|
|
Packit |
8480eb |
free(ctxt->argl);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return rv;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static struct lookup_context *update_multi_context(struct lookup_context *ctxt,
|
|
Packit |
8480eb |
struct lookup_context *new)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int i;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < new->n && i < ctxt->n; i++) {
|
|
Packit |
8480eb |
if (new->m[i].mod)
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!ctxt->m[i].mod)
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* reinit or open failed, use old one, questionable but
|
|
Packit |
8480eb |
* we need to do something.
|
|
Packit |
8480eb |
*/
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
new->m[i].argc = ctxt->m[i].argc;
|
|
Packit |
8480eb |
new->m[i].argv = ctxt->m[i].argv;
|
|
Packit |
8480eb |
ctxt->m[i].argv = NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return new;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct list_head nsslist;
|
|
Packit |
8480eb |
struct list_head *head, *p;
|
|
Packit |
8480eb |
struct lookup_mod *mod;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF], *estr;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!argv || !argv[0])
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (*argv[0] == '/') {
|
|
Packit |
8480eb |
open_lookup("file", MODPREFIX, format, argc, argv, &mod);
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strncmp(argv[0], "file", 4) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "yp", 2) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "nisplus", 7) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "nis", 3) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "ldaps", 5) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "ldap", 4) ||
|
|
Packit |
8480eb |
!strncmp(argv[0], "sss", 3)) {
|
|
Packit |
8480eb |
char type[MAX_MAP_TYPE_STRING];
|
|
Packit |
8480eb |
char *fmt;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
strcpy(type, argv[0]);
|
|
Packit |
8480eb |
fmt = strchr(type, ',');
|
|
Packit |
8480eb |
if (!fmt)
|
|
Packit |
8480eb |
fmt = (char *) format;
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
*fmt = '\0';
|
|
Packit |
8480eb |
fmt++;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod);
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
INIT_LIST_HEAD(&nsslist);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (nsswitch_parse(&nsslist)) {
|
|
Packit |
8480eb |
if (!list_empty(&nsslist))
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
logerr("can't to read name service switch config.");
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
head = &nsslist;
|
|
Packit |
8480eb |
list_for_each(p, head) {
|
|
Packit |
8480eb |
struct nss_source *this;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
int ret;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
this = list_entry(p, struct nss_source, list);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strcmp(this->source, "files")) {
|
|
Packit |
8480eb |
char src_file[] = "file";
|
|
Packit |
8480eb |
char src_prog[] = "program";
|
|
Packit |
8480eb |
struct stat st;
|
|
Packit |
8480eb |
char *type, *path, *save_argv0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(argv[0]) + 2);
|
|
Packit |
8480eb |
if (!path) {
|
|
Packit |
8480eb |
estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr(MODPREFIX "error: %s", estr);
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
strcpy(path, AUTOFS_MAP_DIR);
|
|
Packit |
8480eb |
strcat(path, "/");
|
|
Packit |
8480eb |
strcat(path, argv[0]);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
|
|
Packit |
8480eb |
free(path);
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (st.st_mode & __S_IEXEC)
|
|
Packit |
8480eb |
type = src_prog;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
type = src_file;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
save_argv0 = (char *) argv[0];
|
|
Packit |
8480eb |
argv[0] = path;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = open_lookup(type, MODPREFIX,
|
|
Packit |
8480eb |
format, argc, argv, &mod);
|
|
Packit |
8480eb |
if (status == NSS_STATUS_SUCCESS) {
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
free(save_argv0);
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
argv[0] = save_argv0;
|
|
Packit |
8480eb |
free(path);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
ret = check_nss_result(this, status);
|
|
Packit |
8480eb |
if (ret >= 0)
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
status = open_lookup(this->source, MODPREFIX,
|
|
Packit |
8480eb |
format, argc, argv, &mod);
|
|
Packit |
8480eb |
if (status == NSS_STATUS_SUCCESS) {
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
ret = check_nss_result(this, status);
|
|
Packit |
8480eb |
if (ret >= 0)
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_init(const char *my_mapfmt,
|
|
Packit |
8480eb |
int argc, const char *const *argv, void **context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt;
|
|
Packit |
8480eb |
int i;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
*context = NULL;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
ctxt = alloc_context(my_mapfmt, argc, argv);
|
|
Packit |
8480eb |
if (!ctxt)
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < ctxt->n; i++) {
|
|
Packit |
8480eb |
ctxt->m[i].mod = nss_open_lookup(my_mapfmt,
|
|
Packit |
8480eb |
ctxt->m[i].argc, ctxt->m[i].argv);
|
|
Packit |
8480eb |
if (!ctxt->m[i].mod) {
|
|
Packit |
8480eb |
logerr(MODPREFIX "error opening module");
|
|
Packit |
8480eb |
free_multi_context(ctxt);
|
|
Packit |
8480eb |
free(ctxt);
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
*context = ctxt;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_reinit(const char *my_mapfmt,
|
|
Packit |
8480eb |
int argc, const char *const *argv, void **context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt = (struct lookup_context *) *context;
|
|
Packit |
8480eb |
struct list_head nsslist;
|
|
Packit |
8480eb |
struct list_head *head, *p;
|
|
Packit |
8480eb |
struct lookup_context *new;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF], *estr;
|
|
Packit |
8480eb |
int i, ret = 0;
|
|
Packit |
8480eb |
int status;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
new = alloc_context(my_mapfmt, argc, argv);
|
|
Packit |
8480eb |
if (!new)
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < new->n; i++) {
|
|
Packit |
8480eb |
if (i >= ctxt->n) {
|
|
Packit |
8480eb |
new->m[i].mod = nss_open_lookup(my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc,
|
|
Packit |
8480eb |
new->m[i].argv);
|
|
Packit |
8480eb |
if (!new->m[i].mod) {
|
|
Packit |
8480eb |
logerr(MODPREFIX "error opening module");
|
|
Packit |
8480eb |
/* TODO: check */
|
|
Packit |
8480eb |
ret = 1;
|
|
Packit |
8480eb |
goto out;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (*new->m[i].argv[0] == '/') {
|
|
Packit |
8480eb |
if (strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]))
|
|
Packit |
8480eb |
open_lookup("file", MODPREFIX,
|
|
Packit |
8480eb |
my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc,
|
|
Packit |
8480eb |
new->m[i].argv,
|
|
Packit |
8480eb |
&new->m[i].mod);
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
if (reinit_lookup(new->m[i].mod, "file",
|
|
Packit |
8480eb |
MODPREFIX, my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc, new->m[i].argv))
|
|
Packit |
8480eb |
new->m[i].mod = NULL;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strncmp(new->m[i].argv[0], "file", 4) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "yp", 2) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "nisplus", 7) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "nis", 3) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "ldaps", 5) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "ldap", 4) ||
|
|
Packit |
8480eb |
!strncmp(new->m[i].argv[0], "sss", 3)) {
|
|
Packit |
8480eb |
char type[MAX_MAP_TYPE_STRING];
|
|
Packit |
8480eb |
char *fmt;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
strcpy(type, new->m[i].argv[0]);
|
|
Packit |
8480eb |
fmt = strchr(type, ',');
|
|
Packit |
8480eb |
if (!fmt)
|
|
Packit |
8480eb |
fmt = (char *) my_mapfmt;
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
*fmt = '\0';
|
|
Packit |
8480eb |
fmt++;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]) &&
|
|
Packit |
8480eb |
!strcmp(new->m[i].argv[1], ctxt->m[i].argv[1])) {
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
if (reinit_lookup(new->m[i].mod, new->m[i].argv[0],
|
|
Packit |
8480eb |
MODPREFIX, fmt,
|
|
Packit |
8480eb |
new->m[i].argc - 1, new->m[i].argv + 1))
|
|
Packit |
8480eb |
new->m[i].mod = NULL;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
} else {
|
|
Packit |
8480eb |
open_lookup(type, MODPREFIX, fmt,
|
|
Packit |
8480eb |
new->m[i].argc - 1,
|
|
Packit |
8480eb |
new->m[i].argv + 1,
|
|
Packit |
8480eb |
&new->m[i].mod);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
INIT_LIST_HEAD(&nsslist);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (nsswitch_parse(&nsslist)) {
|
|
Packit |
8480eb |
if (!list_empty(&nsslist))
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
logerr("can't to read name service switch config.");
|
|
Packit |
8480eb |
/* TODO: check */
|
|
Packit |
8480eb |
ret = 1;
|
|
Packit |
8480eb |
goto out;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
head = &nsslist;
|
|
Packit |
8480eb |
list_for_each(p, head) {
|
|
Packit |
8480eb |
struct nss_source *this;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
this = list_entry(p, struct nss_source, list);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strcmp(this->source, ctxt->m[i].mod->type)) {
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
if (reinit_lookup(new->m[i].mod, this->source,
|
|
Packit |
8480eb |
MODPREFIX, my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc, new->m[i].argv))
|
|
Packit |
8480eb |
new->m[i].mod = NULL;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!strcmp(this->source, "files")) {
|
|
Packit |
8480eb |
char src_file[] = "file";
|
|
Packit |
8480eb |
char src_prog[] = "program";
|
|
Packit |
8480eb |
struct stat st;
|
|
Packit |
8480eb |
char *type, *path, *save_argv0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
path = malloc(strlen(AUTOFS_MAP_DIR) +
|
|
Packit |
8480eb |
strlen(new->m[i].argv[0]) + 2);
|
|
Packit |
8480eb |
if (!path) {
|
|
Packit |
8480eb |
estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr(MODPREFIX "error: %s", estr);
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
ret = 1;
|
|
Packit |
8480eb |
goto out;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
strcpy(path, AUTOFS_MAP_DIR);
|
|
Packit |
8480eb |
strcat(path, "/");
|
|
Packit |
8480eb |
strcat(path, new->m[i].argv[0]);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) {
|
|
Packit |
8480eb |
free(path);
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (st.st_mode & __S_IEXEC)
|
|
Packit |
8480eb |
type = src_prog;
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
type = src_file;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
save_argv0 = (char *) new->m[i].argv[0];
|
|
Packit |
8480eb |
new->m[i].argv[0] = path;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (strcmp(type, ctxt->m[i].mod->type)) {
|
|
Packit |
8480eb |
status = open_lookup(type,
|
|
Packit |
8480eb |
MODPREFIX,
|
|
Packit |
8480eb |
my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc,
|
|
Packit |
8480eb |
new->m[i].argv,
|
|
Packit |
8480eb |
&new->m[i].mod);
|
|
Packit |
8480eb |
if (status == NSS_STATUS_SUCCESS) {
|
|
Packit |
8480eb |
free(save_argv0);
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
} else {
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
if (reinit_lookup(new->m[i].mod, type,
|
|
Packit |
8480eb |
MODPREFIX, my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc, new->m[i].argv))
|
|
Packit |
8480eb |
new->m[i].mod = NULL;
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
free(save_argv0);
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
new->m[i].argv[0] = save_argv0;
|
|
Packit |
8480eb |
free(path);
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (strcmp(this->source, ctxt->m[i].mod->type)) {
|
|
Packit |
8480eb |
status = open_lookup(this->source, MODPREFIX,
|
|
Packit |
8480eb |
my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc,
|
|
Packit |
8480eb |
new->m[i].argv,
|
|
Packit |
8480eb |
&new->m[i].mod);
|
|
Packit |
8480eb |
if (status == NSS_STATUS_SUCCESS)
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
} else {
|
|
Packit |
8480eb |
new->m[i].mod = ctxt->m[i].mod;
|
|
Packit |
8480eb |
if (reinit_lookup(new->m[i].mod, this->source,
|
|
Packit |
8480eb |
MODPREFIX, my_mapfmt,
|
|
Packit |
8480eb |
new->m[i].argc, new->m[i].argv))
|
|
Packit |
8480eb |
new->m[i].mod = NULL;
|
|
Packit |
8480eb |
else {
|
|
Packit |
8480eb |
ctxt->m[i].mod = NULL;
|
|
Packit |
8480eb |
break;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
free_sources(&nsslist);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
out:
|
|
Packit |
8480eb |
/* Update new context with any needed old context */
|
|
Packit |
8480eb |
*context = update_multi_context(ctxt, new);
|
|
Packit |
8480eb |
free_multi_context(ctxt);
|
|
Packit |
8480eb |
free(ctxt);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return ret;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_read_master(struct master *master, time_t age, void *context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt = (struct lookup_context *) context;
|
|
Packit |
8480eb |
struct map_source *source;
|
|
Packit |
8480eb |
int i, ret, at_least_1 = 0;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
source = ap->entry->current;
|
|
Packit |
8480eb |
ap->entry->current = NULL;
|
|
Packit |
8480eb |
master_source_current_signal(ap->entry);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < ctxt->n; i++) {
|
|
Packit |
8480eb |
master_source_current_wait(ap->entry);
|
|
Packit |
8480eb |
ap->entry->current = source;
|
|
Packit |
8480eb |
ret = ctxt->m[i].mod->lookup_read_map(ap, age,
|
|
Packit |
8480eb |
ctxt->m[i].mod->context);
|
|
Packit |
8480eb |
if (ret & LKP_FAIL || ret == LKP_NOTSUP)
|
|
Packit |
8480eb |
continue;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
at_least_1 = 1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!at_least_1)
|
|
Packit |
8480eb |
return NSS_STATUS_NOTFOUND;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return NSS_STATUS_SUCCESS;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt = (struct lookup_context *) context;
|
|
Packit |
8480eb |
struct map_source *source;
|
|
Packit |
8480eb |
int i;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
source = ap->entry->current;
|
|
Packit |
8480eb |
ap->entry->current = NULL;
|
|
Packit |
8480eb |
master_source_current_signal(ap->entry);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
for (i = 0; i < ctxt->n; i++) {
|
|
Packit |
8480eb |
master_source_current_wait(ap->entry);
|
|
Packit |
8480eb |
ap->entry->current = source;
|
|
Packit |
8480eb |
if (ctxt->m[i].mod->lookup_mount(ap, name, name_len,
|
|
Packit |
8480eb |
ctxt->m[i].mod->context) == 0)
|
|
Packit |
8480eb |
return NSS_STATUS_SUCCESS;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NSS_STATUS_NOTFOUND; /* No module succeeded */
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int lookup_done(void *context)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_context *ctxt = (struct lookup_context *) context;
|
|
Packit |
8480eb |
int rv;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
rv = free_multi_context(ctxt);
|
|
Packit |
8480eb |
free(ctxt);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return rv;
|
|
Packit |
8480eb |
}
|