4
* Module for Linux automountd to access automount maps in hesiod filsys
15
#include <netinet/in.h>
16
#include <arpa/nameser.h>
21
#include "automount.h"
24
#define MAPFMT_DEFAULT "hesiod"
26
#define MODPREFIX "lookup(hesiod): "
27
#define HESIOD_LEN 512
29
struct lookup_context {
30
struct parse_mod *parser;
34
static pthread_mutex_t hesiod_mutex = PTHREAD_MUTEX_INITIALIZER;
36
int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
38
/* This initializes a context (persistent non-global data) for queries to
40
int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context)
42
struct lookup_context *ctxt = NULL;
43
char buf[MAX_ERR_BUF];
47
/* If we can't build a context, bail. */
48
ctxt = malloc(sizeof(struct lookup_context));
50
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
51
logerr(MODPREFIX "malloc: %s", estr);
55
/* Initialize the resolver. */
58
/* Initialize the hesiod context. */
59
if (hesiod_init(&(ctxt->hesiod_context)) != 0) {
60
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
61
logerr(MODPREFIX "hesiod_init(): %s", estr);
66
/* If a map type isn't explicitly given, parse it as hesiod entries. */
68
mapfmt = MAPFMT_DEFAULT;
70
/* Open the parser, if we can. */
71
ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
73
logerr(MODPREFIX "failed to open parse context");
82
int lookup_read_master(struct master *master, time_t age, void *context)
84
return NSS_STATUS_UNKNOWN;
87
int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
89
ap->entry->current = NULL;
90
master_source_current_signal(ap->entry);
92
return NSS_STATUS_UNKNOWN;
96
* Lookup and act on a filesystem name. In this case, lookup the "filsys"
97
* record in hesiod. If it's an AFS or NFS filesystem, parse it out. If
98
* it's an ERR filesystem, it's an error message we should log. Otherwise,
99
* assume it's something we know how to deal with already (generic).
101
int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context)
103
struct map_source *source;
104
struct mapent_cache *mc;
106
struct lookup_context *ctxt = (struct lookup_context *) context;
108
char **record, *best_record = NULL, *p;
109
int priority, lowest_priority = INT_MAX;
111
source = ap->entry->current;
112
ap->entry->current = NULL;
113
master_source_current_signal(ap->entry);
118
MODPREFIX "looking up root=\"%s\", name=\"%s\"",
121
chdir("/"); /* If this is not here the filesystem stays
122
busy, for some reason... */
124
status = pthread_mutex_lock(&hesiod_mutex);
128
hes_result = hesiod_resolve(ctxt->hesiod_context, name, "filsys");
129
if (!hes_result || !hes_result[0]) {
130
/* Note: it is not clear to me how to distinguish between
131
* the "no search results" case and other failures. --JM */
133
MODPREFIX "key \"%s\" not found in map", name);
134
status = pthread_mutex_unlock(&hesiod_mutex);
137
return NSS_STATUS_NOTFOUND;
140
/* autofs doesn't support falling back to alternate records, so just
141
find the record with the lowest priority and hope it works.
142
-- Aaron Ucko <amu@alum.mit.edu> 2002-03-11 */
143
for (record = hes_result; *record; ++record) {
144
p = strrchr(*record, ' ');
145
if ( p && isdigit(p[1]) ) {
146
priority = atoi(p+1);
148
priority = INT_MAX - 1;
150
if (priority < lowest_priority) {
151
lowest_priority = priority;
152
best_record = *record;
157
rv = cache_update(mc, source, name, best_record, time(NULL));
160
return NSS_STATUS_UNAVAIL;
163
MODPREFIX "lookup for \"%s\" gave \"%s\"",
166
rv = ctxt->parser->parse_mount(ap, name, name_len, best_record,
167
ctxt->parser->context);
169
hesiod_free_list(ctxt->hesiod_context, hes_result);
171
status = pthread_mutex_unlock(&hesiod_mutex);
176
* Unavailable due to error such as module load fail
177
* or out of memory, etc.
179
if (rv == 1 || rv == -1)
180
return NSS_STATUS_UNAVAIL;
182
return NSS_STATUS_SUCCESS;
185
/* This destroys a context for queries to this module. It releases the parser
186
structure (unloading the module) and frees the memory used by the context. */
187
int lookup_done(void *context)
189
struct lookup_context *ctxt = (struct lookup_context *) context;
190
int rv = close_parse(ctxt->parser);
192
hesiod_end(ctxt->hesiod_context);