[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