[tac_plus] plugin-loading: 2/3: invoking plugins
Steve Kemp
steve at steve.org.uk
Wed Aug 22 08:44:32 UTC 2012
--- a/pwlib.c
+++ b/pwlib.c
@@ -44,6 +44,10 @@
void *);
#endif
+#if HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
/*
* Generic password verification routines for des, file and cleartext passwords
*/
@@ -53,6 +57,7 @@
static int pam_verify(char *, char *);
#endif
static int passwd_file_verify(char *, char *, struct authen_data *, char *);
+static int plugin_verify(char *, char *,char *);
/* Adjust data->status depending on whether a user has expired or not */
void
@@ -204,6 +209,18 @@
return(data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
}
+
+ p = tac_find_substring("plugin", cfg_passwd);
+ if (p) {
+ /* skip past the length of "plugin" to get any extra data. */
+ if (!plugin_verify(name,passwd, p+6)) {
+ data->status = TAC_PLUS_AUTHEN_STATUS_FAIL;
+ } else {
+ data->status = TAC_PLUS_AUTHEN_STATUS_PASS;
+ }
+ return(data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
+ }
+
p = tac_find_substring("file ", cfg_passwd);
if (p) {
return(passwd_file_verify(name, passwd, data, p));
@@ -376,9 +393,95 @@
return(data->status == TAC_PLUS_AUTHEN_STATUS_PASS);
}
+
+/*
+ * Verify authentication via an external plugin.
+ */
+static int
+plugin_verify(char *user, char *supplied_passwd, char *extra_args)
+{
+ int (*auth)(char *, char *, char *); /* plugin function signature */
+ void *handle; /* handle to open library */
+ struct stat sb; /* stat buffer */
+ char *error;
+ int ret;
+
+#ifdef DLFCN
+
+ if ( stat( session.sso_plugin, &sb ) != 0 )
+ {
+ report(LOG_ERR, "%s: Plugin not found %s",
+ session.peer,
+ session.auth_plugin );
+ return(0);
+ }
+
+ handle = dlopen( session.auth_plugin, RTLD_LAZY);
+ if (!handle)
+ {
+ report(LOG_ERR, "%s: Plugin load error: %s",
+ session.peer,
+ dlerror());
+
+ return(0);
+ }
+
+ dlerror(); /* Clear any existing error */
+
+ /* get the function, by name */
+ *(void **) (&auth) = dlsym(handle, "plugin_authenticate");
+
+ if ((error = dlerror()) != NULL)
+ {
+ report(LOG_ERR, "%s: Plugin symbol error: %s",
+ session.peer,
+ error);
+ session.peer,
+ dlerror());
+
+ return(0);
+ }
+
+ /* Clear any existing error */
+ dlerror();
+
+ /* get the function, by name */
+ *(void **) (&auth) = dlsym(handle, "plugin_authenticate");
+
+ if ((error = dlerror()) != NULL)
+ {
+ report(LOG_ERR, "%s: Plugin symbol error: %s",
+ session.peer,
+ error);
+
+ return(0);
+ }
+
+ ret = (*auth)(user, supplied_passwd, extra_args);
+
+ if (debug & DEBUG_PASSWD_FLAG) {
+ report(LOG_ERR, "%s: Plugin call (%s,%s,%s) -> %d",
+ session.peer, user, supplied_passwd, extra_args, ret );
+ }
+
+ /**
+ * Cleanup
+ */
+ dlclose(handle);
+ return( ret );
+
+#else
+ report(LOG_ERR, "%s: Plugin call (%s,%s,%s) ignored - no dlopen()",
+ session.peer, user, supplied_passwd, extra_args);
+
+ return 0;
+#endif
+}
+
+
/*
* verify that this user/password is valid per a passwd(5) style database.
- * Return 0 if invalid.
+ * return 0 if invalid.
*/
static int
passwd_file_verify(char *user, char *supplied_passwd, struct authen_data *data,
More information about the tac_plus
mailing list