Am 03.02.16 20:55 schrieb(en) Eero Volotinen:
please share patch, so we all can take look of it?

Patch is attached, against the openvas-libraries-8.0.6 tarball:
- misc/ldap_connect_auth.h:
  - add the two extra config items
  - changed prototype of ldap_auth_info_new() and ldap_auth_bind() [any reason 
why they are not static in ldap_connect_auth.c, btw?]
- misc/ldap_connect_auth.c:
  - load the new config items from the key file
  - use them in the ldap info
  - free search base properly
  - in ldap_auth_bind(), if searching is requested first try an anonymous bind, 
search exactly /one/ item matching the search pattern, and use its dn to 
re-bind with the supplied password.  The former may need to be modified for 
servers not allowing anonymous binds, while the latter is rfc4513-compliant 
afaict and should thus always work.

I'm afraid I mixed up the indent style a little bit.

Still missing: GUI to let the admin enter the items in the browser.  I.e. the 
auth.conf files needs to be edited manually now.

Cheers
Albrecht.
--- ./misc/ldap_connect_auth.h.orig	2016-02-03 09:54:56.982087687 +0100
+++ ./misc/ldap_connect_auth.h	2016-02-03 09:54:56.978087647 +0100
@@ -45,7 +45,9 @@ typedef struct ldap_auth_info *ldap_auth
 struct ldap_auth_info
 {
   gchar *ldap_host;             ///< Adress of the ldap server, might include port.
-  gchar *auth_dn;               ///< DN to authenticate with.
+  gchar *auth_dn;               ///< DN to authenticate with, or the dn search pattern
+  gboolean search;		///< \ref auth_dn shall be used to search the dn
+  gchar *base;			///< Search base
   /** @brief Attribute to check against \ref role_user_values and
    *  @brief \ref role_admin_values. Empty string if n/a. */
   gchar *role_attribute;
@@ -69,15 +71,16 @@ int ldap_connect_authenticate (const gch
 void ldap_auth_info_free (ldap_auth_info_t);
 
 ldap_auth_info_t
-ldap_auth_info_new (const gchar *, const gchar *, const gchar *, gchar **,
-                    gchar **, gchar **, const gchar *, const gchar *, gboolean,
-                    gboolean);
+ldap_auth_info_new (const gchar *, const gchar *, gboolean, const gchar *,
+                    const gchar *, gchar **, gchar **, gchar **,
+                    const gchar *, const gchar *, gboolean, gboolean);
 
 gchar*
 ldap_auth_info_auth_dn (const ldap_auth_info_t, const gchar*);
 
 LDAP *
-ldap_auth_bind (const gchar *, const gchar *, const gchar *, gboolean);
+ldap_auth_bind (const gchar *, const gchar *, gboolean, const gchar *,
+                const gchar *, gboolean);
 
 gboolean ldap_auth_dn_is_good (const gchar *);
 
--- ./misc/ldap_connect_auth.c.orig	2016-02-03 09:54:56.974087668 +0100
+++ ./misc/ldap_connect_auth.c	2016-02-03 09:54:56.966087697 +0100
@@ -45,6 +45,8 @@
 
 #define KEY_LDAP_HOST "ldaphost"
 #define KEY_LDAP_DN_AUTH "authdn"
+#define KEY_LDAP_SEARCH "search"
+#define KEY_LDAP_BASE "base"
 #define KEY_LDAP_ROLE_ATTRIBUTE "role-attribute"
 #define KEY_LDAP_ROLE_USER_VALUES "role-user-values"
 #define KEY_LDAP_ROLE_ADMIN_VALUES "role-admin-values"
@@ -83,7 +85,9 @@ ldap_connect_authenticate (const gchar *
 
   dn = ldap_auth_info_auth_dn (info, username);
 
-  ldap = ldap_auth_bind (info->ldap_host, dn, password, !info->allow_plaintext);
+  ldap =
+    ldap_auth_bind (info->ldap_host, dn, info->search, info->base, password,
+                    !info->allow_plaintext);
 
   if (ldap == NULL) {
     g_debug("Could not bind to ldap host %s", info->ldap_host);
@@ -114,6 +118,10 @@ ldap_auth_info_from_key_file (GKeyFile *
   /** @todo Errors to be checked here, get string lists for the role values. */
   gchar *auth_dn = g_key_file_get_string (key_file, group,
                                           KEY_LDAP_DN_AUTH, NULL);
+  gboolean search = g_key_file_get_boolean (key_file, group,
+                                            KEY_LDAP_SEARCH, NULL);
+  gchar *base  = g_key_file_get_string (key_file, group,
+                                        KEY_LDAP_BASE, NULL);
   gchar *ldap_host = g_key_file_get_string (key_file, group,
                                             KEY_LDAP_HOST, NULL);
   gchar *role_attr = g_key_file_get_string (key_file, group,
@@ -145,6 +153,8 @@ ldap_auth_info_from_key_file (GKeyFile *
     is_connect = TRUE;
 
   ldap_auth_info_t info = ldap_auth_info_new (ldap_host, auth_dn,
+                                              search,
+                                              base,
                                               role_attr,
                                               role_usrv,
                                               role_admv,
@@ -155,6 +165,7 @@ ldap_auth_info_from_key_file (GKeyFile *
                                               is_connect);
 
   g_free (auth_dn);
+  g_free (base);
   g_free (ldap_host);
   g_free (role_attr);
   g_free (role_usrv);
@@ -174,6 +185,8 @@ ldap_auth_info_from_key_file (GKeyFile *
  * @param auth_dn           DN where the actual user name is to be inserted at
  *                          "%s", e.g. uid=%s,cn=users. Might not be NULL,
  *                          but empty, has to contain a single %s.
+ * @param search            whether to use auth_dn as search pattern to get the DN
+ * @param base              LDAP search base
  * @param role_attribute    Attribute that qualifies a role. Might not be NULL,
  *                          but empty.
  * @param role_user_values  Comma-separated list of values for
@@ -194,6 +207,7 @@ ldap_auth_info_from_key_file (GKeyFile *
  */
 ldap_auth_info_t
 ldap_auth_info_new (const gchar * ldap_host, const gchar * auth_dn,
+                    gboolean search, const gchar * base,
                     const gchar * role_attribute, gchar ** role_user_values,
                     gchar ** role_admin_values, gchar ** role_observer_values,
                     const gchar * ruletype_attr, const gchar * rule_attr,
@@ -215,6 +229,11 @@ ldap_auth_info_new (const gchar * ldap_h
   ldap_auth_info_t info = g_malloc0 (sizeof (struct ldap_auth_info));
   info->ldap_host = g_strdup (ldap_host);
   info->auth_dn = g_strdup (auth_dn);
+  info->search = search;
+  if (info->search && (base != NULL))
+    {
+      info->base = g_strdup (base);
+    }
   info->role_attribute = g_strdup (role_attribute);
   info->role_user_values = g_strdupv (role_user_values);
   info->role_admin_values = g_strdupv (role_admin_values);
@@ -239,6 +258,7 @@ ldap_auth_info_free (ldap_auth_info_t in
 
   g_free (info->ldap_host);
   g_free (info->auth_dn);
+  g_free (info->base);
   g_free (info->role_attribute);
   g_strfreev (info->role_admin_values);
   g_strfreev (info->role_observer_values);
@@ -274,6 +294,8 @@ ldap_auth_info_auth_dn (const ldap_auth_
  *
  * @param[in] host              Host to connect to.
  * @param[in] userdn            DN to authenticate against
+ * @param[in] search            search for the DN
+ * @param[in] base              DN search base
  * @param[in] password          Password for userdn.
  * @param[in] force_encryption  Whether or not to abort if connection
  *                              encryption via StartTLS or ldaps failed.
@@ -281,13 +303,15 @@ ldap_auth_info_auth_dn (const ldap_auth_
  * @return LDAP Handle or NULL if an error occured, authentication failed etc.
  */
 LDAP *
-ldap_auth_bind (const gchar * host, const gchar * userdn,
-                const gchar * password, gboolean force_encryption)
+ldap_auth_bind (const gchar * host, const gchar * userdn, gboolean search,
+                const gchar * base, const gchar * password,
+                gboolean force_encryption)
 {
   LDAP *ldap = NULL;
   int ldap_return = 0;
   int ldapv3 = LDAP_VERSION3;
   gchar *ldapuri = NULL;
+  gchar *use_dn = NULL;
   struct berval credential;
 
   if (host == NULL || userdn == NULL || password == NULL)
@@ -365,12 +389,65 @@ ldap_auth_bind (const gchar * host, cons
 
   g_free (ldapuri);
 
+  if (search)
+    {
+      /* perform anonymous bind */
+      credential.bv_val = NULL;
+      credential.bv_len = 0U;
+      ldap_return =
+        ldap_sasl_bind_s (ldap, NULL, LDAP_SASL_SIMPLE, &credential, NULL,
+                          NULL, NULL);
+      if (ldap_return != LDAP_SUCCESS)
+        {
+           g_warning ("LDAP authentication failure: %s",
+                      ldap_err2string (ldap_return));
+        }
+      else
+        {
+           char *attrs[2] = { "dn", NULL };
+           LDAPMessage *result = NULL;
+
+           /* search for the DN and unbind */
+           ldap_return =
+             ldap_search_ext_s (ldap, base, LDAP_SCOPE_SUBTREE, userdn, attrs,
+                                0, NULL, NULL, NULL, 1, &result);
+           if (ldap_return != LDAP_SUCCESS)
+             {
+                g_warning ("LDAP search for '%s' failed: %s",
+                           userdn, ldap_err2string (ldap_return));
+             }
+           else
+             {
+                gchar * found_dn;
+
+                found_dn = ldap_get_dn (ldap, result);
+                if ((found_dn == NULL) || (strlen(found_dn) == 0U))
+                  {
+                     g_warning ("LDAP: no DN found for '%s'", userdn);
+                  }
+                else
+                  {
+                     g_debug ("LDAP: '%s' -> '%s'", userdn, found_dn);
+                     use_dn = g_strdup (found_dn);
+                  }
+                ldap_memfree (found_dn);
+             }
+           ldap_msgfree (result);
+       }
+    }
+  else
+    {
+       use_dn = g_strdup (userdn);
+    }
+
+  if (use_dn != NULL)
+    {
   credential.bv_val = g_strdup (password);
   credential.bv_len = strlen (password);
-
   ldap_return =
-    ldap_sasl_bind_s (ldap, userdn, LDAP_SASL_SIMPLE, &credential, NULL, NULL,
-                      NULL);
+        ldap_sasl_bind_s (ldap, use_dn, LDAP_SASL_SIMPLE, &credential, NULL,
+                          NULL, NULL);
+      g_free (use_dn);
   g_free (credential.bv_val);
   if (ldap_return != LDAP_SUCCESS)
     {
@@ -378,6 +455,7 @@ ldap_auth_bind (const gchar * host, cons
                  ldap_err2string (ldap_return));
       return NULL;
     }
+    }
 
   return ldap;
 }

Attachment: pgpq2hCxB8Enb.pgp
Description: PGP signature

_______________________________________________
Openvas-discuss mailing list
[email protected]
https://lists.wald.intevation.org/cgi-bin/mailman/listinfo/openvas-discuss

Reply via email to