Add connection pool to rlm_mschap for wbclient contexts
authorMatthew Newton <mcn4@leicester.ac.uk>
Mon, 23 Mar 2015 22:59:50 +0000 (22:59 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 24 Mar 2015 01:21:59 +0000 (21:21 -0400)
raddb/mods-available/mschap
src/modules/rlm_mschap/auth_wbclient.c
src/modules/rlm_mschap/rlm_mschap.c
src/modules/rlm_mschap/rlm_mschap.h

index 15ee91b..6608b7d 100644 (file)
@@ -78,6 +78,63 @@ mschap {
 #      winbind_username = "%{mschap:User-Name}"
 #      winbind_domain = "%{mschap:NT-Domain}"
 
+       #
+       #  Information for the winbind connection pool.  The configuration
+       #  items below are the same for all modules which use the new
+       #  connection pool.
+       #
+       pool {
+               # Number of connections to start
+               start = ${thread[pool].start_servers}
+
+               # Minimum number of connections to keep open
+               min = ${thread[pool].min_spare_servers}
+
+               # Maximum number of connections
+               #
+               # If these connections are all in use and a new one
+               # is requested, the request will NOT get a connection.
+               #
+               # NOTE: This should be greater than or equal to "min" above.
+               max = ${thread[pool].max_servers}
+
+               # Spare connections to be left idle
+               #
+               # NOTE: Idle connections WILL be closed if "idle_timeout"
+               # is set.  This should be less than or equal to "max" above.
+               spare = ${thread[pool].max_spare_servers}
+
+               # Number of uses before the connection is closed
+               #
+               # NOTE: A setting of 0 means infinite (no limit).
+               uses = 0
+
+               # The lifetime (in seconds) of the connection
+               #
+               # NOTE: A setting of 0 means infinite (no limit).
+               lifetime = 86400
+
+               # The pool is checked for free connections every
+               # "cleanup_interval".  If there are free connections,
+               # then one of them is closed.
+               cleanup_interval = 300
+
+               # The idle timeout (in seconds).  A connection which is
+               # unused for this length of time will be closed.
+               #
+               # NOTE: A setting of 0 means infinite (no timeout).
+               idle_timeout = 600
+
+               # NOTE: All configuration settings are enforced.  If a
+               # connection is closed because of "idle_timeout",
+               # "uses", or "lifetime", then the total number of
+               # connections MAY fall below "min".  When that
+               # happens, it will open a new connection.  It will
+               # also log a WARNING message.
+               #
+               # The solution is to either lower the "min" connections,
+               # or increase lifetime/idle_timeout.
+       }
 
        passchange {
                # This support MS-CHAPv2 (not v1) password change
index 71b7ed6..644375a 100644 (file)
@@ -46,6 +46,7 @@ int do_auth_wbclient(rlm_mschap_t *inst, REQUEST *request,
                     uint8_t nthashhash[NT_DIGEST_LENGTH])
 {
        int rcode = -1;
+       struct wbcContext *wb_ctx;
        struct wbcAuthUserParams authparams;
        wbcErr err;
        int len;
@@ -105,10 +106,18 @@ int do_auth_wbclient(rlm_mschap_t *inst, REQUEST *request,
        /*
         * Send auth request across to winbind
         */
+       wb_ctx = fr_connection_get(inst->wb_pool);
+       if (wb_ctx == NULL) {
+               RERROR("Unable to get winbind connection from pool");
+               goto done;
+       }
+
        RDEBUG2("sending authentication request user='%s' domain='%s'", authparams.account_name,
                                                                        authparams.domain_name);
 
-       err = wbcCtxAuthenticateUserEx(inst->wb_ctx, &authparams, &info, &error);
+       err = wbcCtxAuthenticateUserEx(wb_ctx, &authparams, &info, &error);
+
+       fr_connection_release(inst->wb_pool, wb_ctx);
 
 
        /*
index b08b822..d0af021 100644 (file)
@@ -500,6 +500,40 @@ static ssize_t mschap_xlat(void *instance, REQUEST *request,
 }
 
 
+#ifdef WITH_AUTH_WINBIND
+/*
+ *     Free connection pool winbind context
+ */
+static int _mod_conn_free(struct wbcContext **wb_ctx)
+{
+       wbcCtxFree(*wb_ctx);
+
+       return 0;
+}
+
+/*
+ *     Create connection pool winbind context
+ */
+static void *mod_conn_create(TALLOC_CTX *ctx, UNUSED void *instance)
+{
+       struct wbcContext **wb_ctx;
+
+       wb_ctx = talloc_zero(ctx, struct wbcContext *);
+       *wb_ctx = wbcCtxCreate();
+
+       if (*wb_ctx == NULL) {
+               ERROR("failed to create winbind context");
+               talloc_free(wb_ctx);
+               return NULL;
+       }
+
+       talloc_set_destructor(wb_ctx, _mod_conn_free);
+
+       return *wb_ctx;
+}
+#endif
+
+
 static const CONF_PARSER passchange_config[] = {
        { "ntlm_auth", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_XLAT, rlm_mschap_t, ntlm_cpw), NULL },
        { "ntlm_auth_username", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_XLAT, rlm_mschap_t, ntlm_cpw_username), NULL },
@@ -565,10 +599,10 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance)
        if (inst->wb_username) {
 #ifdef WITH_AUTH_WINBIND
                inst->method = AUTH_WBCLIENT;
-       
-               inst->wb_ctx = wbcCtxCreate();
-               if (!inst->wb_ctx) {
-                       ERROR("rlm_mschap (%s): failed to create winbind context", name);
+
+               inst->wb_pool = fr_connection_pool_module_init(conf, inst, mod_conn_create, NULL, NULL);
+               if (!inst->wb_pool) {
+                       ERROR("rlm_mschap (%s): unable to initialise winbind connection pool", name);
                        return -1;
                }
 #else
@@ -624,13 +658,12 @@ static int mod_detach(UNUSED void *instance)
 #ifdef WITH_AUTH_WINBIND
        rlm_mschap_t *inst = instance;
 
-       wbcCtxFree(inst->wb_ctx);
+       fr_connection_pool_delete(inst->wb_pool);
 #endif
 
        return 0;
 }
 
-
 /*
  *     add_reply() adds either MS-CHAP2-Success or MS-CHAP-Error
  *     attribute to reply packet
index e67b25d..50bf885 100644 (file)
@@ -38,9 +38,7 @@ typedef struct rlm_mschap_t {
        MSCHAP_AUTH_METHOD      method;
        vp_tmpl_t               *wb_username;
        vp_tmpl_t               *wb_domain;
-#ifdef WITH_AUTH_WINBIND
-       struct wbcContext       *wb_ctx;
-#endif
+       fr_connection_pool_t    *wb_pool;
 #ifdef WITH_OPEN_DIRECTORY
        bool                    open_directory;
 #endif