aboutsummaryrefslogtreecommitdiffstats
path: root/modules/lookup_nisplus.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/lookup_nisplus.c')
-rw-r--r--modules/lookup_nisplus.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
new file mode 100644
index 0000000..dfaf675
--- /dev/null
+++ b/modules/lookup_nisplus.c
@@ -0,0 +1,107 @@
+#ident "$Id$"
+/*
+ * lookup_nisplus.c
+ *
+ * Module for Linux automountd to access a NIS+ automount map
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/ypclnt.h>
+
+#define MODULE_LOOKUP
+#include "automount.h"
+
+#define MAPFMT_DEFAULT "sun"
+
+#define MODPREFIX "lookup(nisplus): "
+
+struct lookup_context {
+ char *domainname;
+ char *mapname;
+ struct parse_mod *parse;
+};
+
+int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */
+
+int lookup_init(char *mapfmt, int argc, char **argv, void **context)
+{
+ struct lookup_context *ctxt;
+ int err;
+
+ if ( !(*context = ctxt = malloc(sizeof(struct lookup_context))) ) {
+ syslog(LOG_CRIT, MODPREFIX "%m");
+ return 1;
+ }
+
+ if ( argc < 1 ) {
+ syslog(LOG_CRIT, MODPREFIX "No map name");
+ return 1;
+ }
+ ctxt->mapname = argv[0];
+
+ err = yp_get_default_domain(&ctxt->domainname);
+ if ( err ) {
+ syslog(LOG_CRIT, MODPREFIX "map %s: %s\n", ctxt->mapname, yperr_string(err));
+ return 1;
+ }
+
+ if ( !mapfmt )
+ mapfmt = MAPFMT_DEFAULT;
+
+ return !(ctxt->parse = open_parse(mapfmt,MODPREFIX,argc-1,argv+1));
+}
+
+int lookup_mount(char *root, char *name, int name_len, void *context)
+{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+ char tablename[strlen (name) + strlen (ctxt->mapname) +
+ strlen (ctxt->domainname) + 20];
+ nis_result *result;
+ int rv;
+
+ syslog(LOG_DEBUG, MODPREFIX "looking up %s", name);
+
+ sprintf (tablename, "[key=%s],%s.org_dir.%s.", name, ctxt->mapname,
+ ctxt->domainname);
+
+
+ result = nis_list (tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+ if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ /* Try to get the "*" entry if there is one - note that we *don't*
+ modify "name" so & -> the name we used, not "*" */
+ sprintf (tablename, "[key=*],%s.org_dir.%s.", ctxt->mapname,
+ ctxt->domainname);
+ result = nis_list (tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+ }
+ if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) {
+ syslog(LOG_NOTICE, MODPREFIX "lookup for %s failed: %s", name,
+ nis_sperrno (result->status));
+ return 1;
+ }
+
+ syslog(LOG_DEBUG, MODPREFIX "%s -> %s", name,
+ NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_val[1].ec_value.ec_value_val);
+
+ rv = ctxt->parse->parse_mount(root,name,name_len,
+ NIS_RES_OBJECT(result)->EN_data.en_cols.en_cols_val[1].ec_value.ec_value_val,
+ ctxt->parse->context);
+ return rv;
+}
+
+int lookup_done(void *context)
+{
+ struct lookup_context *ctxt = (struct lookup_context *) context;
+ int rv = close_parse(ctxt->parse);
+ free(ctxt);
+ return rv;
+}