Blame modules/lookup_multi.c

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
}