openafs: Improved calling of get-token script
[hcoop/debian/courier-authlib.git] / authldaplib.c
index 7313bf6..39b0245 100644 (file)
@@ -21,8 +21,8 @@
  * 
  * You should have received a copy of the GNU General Public License
  * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
- * Boston, MA  02111-1307, USA.
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
  */
 
 /*
@@ -126,7 +126,7 @@ authldap_free_config removed - no longer required.
 static char **l_get_values(LDAP *ld, LDAPMessage *entry, const char *attribut)
 {
        struct berval **p=ldap_get_values_len(ld, entry, attribut);
-       int n;
+       int i, n;
        char **a;
 
        if (!p)
@@ -144,8 +144,6 @@ static char **l_get_values(LDAP *ld, LDAPMessage *entry, const char *attribut)
                return NULL;
        }
 
-       int i;
-
        for (i=0; i<n; i++)
        {
                if ((a[i]=malloc(p[i]->bv_len+1)) == NULL)
@@ -264,6 +262,7 @@ struct ldap_info
        gid_t gid;
        int   timeout;
        int   authbind;
+        int   initbind;
        int   deref;
        int   protocol_version;
        int   tls;
@@ -393,6 +392,7 @@ int l=strlen(env);
                for (i=0; i<ldapauth_size; i++)
                        if (ldapauth[i] == '\n')
                                ldapauth[i]=0;
+               fclose(f);
        }
 
        for (i=0; i<ldapauth_size; )
@@ -470,6 +470,12 @@ static int authldap_read_config(struct ldap_info *ldap)
        if (p)
                sscanf(p,"%d",&ldap->authbind);
 
+       if (!read_env("LDAP_INITBIND", &p, "", 0, "1"))
+               return (0);
+
+       if (p)
+               sscanf(p,"%d",&ldap->initbind);
+
        if (!read_env("LDAP_BASEDN",&ldap->basedn,
                      "You need to specify a basedn in config file",1,NULL))
                return 0;
@@ -1000,40 +1006,44 @@ int     ldrc;
        /* Set dereferencing mode */
        if (ldaperror(ldrc = ldap_set_option(my_ldap_fp, LDAP_OPT_DEREF,
                                         (void *) & my_ldap.deref)) != LDAP_SUCCESS)
-         {
+       {
                const char *s=ldap_err2string(ldrc);
 
                err("ldap_set_option(DEREF) failed: %s", s);
                authldapclose();
                ldapconnfailure();
                return (-1);
-         }
+       }
 #endif
 
-  /* Bind to server */
-  if (courier_authdebug_login_level >= 2)
-  {
-         DPRINTF("binding to LDAP server as DN '%s', password '%s'",
-               my_ldap.binddn ? my_ldap.binddn : "<null>",
-               my_ldap.bindpw ? my_ldap.bindpw : "<null>");
-  }
-  else
-  {
-         DPRINTF("binding to LDAP server as DN '%s'",
-               my_ldap.binddn ? my_ldap.binddn : "<null>");
-  }
-
-  if (ldaperror(ldrc = l_simple_bind_s(my_ldap_fp,
-                                      my_ldap.binddn,
-                                      my_ldap.bindpw)) != LDAP_SUCCESS)
-    {
-    const char *s=ldap_err2string(ldrc);
-
-       err("ldap_simple_bind_s failed: %s", s);
-       authldapclose();
-       ldapconnfailure();
-       return (-1);
-    }
+       if(my_ldap.initbind)
+       {
+               /* Bind to server */
+               if (courier_authdebug_login_level >= 2)
+               {
+                       DPRINTF("binding to LDAP server as DN '%s', password '%s'",
+                               my_ldap.binddn ? my_ldap.binddn : "<null>",
+                               my_ldap.bindpw ? my_ldap.bindpw : "<null>");
+               }
+               else
+               {
+                       DPRINTF("binding to LDAP server as DN '%s'",
+                               my_ldap.binddn ? my_ldap.binddn : "<null>");
+               }
+
+               if (ldaperror(ldrc = l_simple_bind_s(my_ldap_fp,
+                                                    my_ldap.binddn,
+                                                    my_ldap.bindpw))
+                   != LDAP_SUCCESS)
+               {
+                       const char *s=ldap_err2string(ldrc);
+
+                       err("ldap_simple_bind_s failed: %s", s);
+                       authldapclose();
+                       ldapconnfailure();
+                       return (-1);
+               }
+       }
        return (0);
 }
 
@@ -1075,8 +1085,6 @@ static int auth_ldap_do2(const char *service,
                        int (*callback)(struct authinfo *, void *),
                         void *arg, const char *newpass);
 
-static char *escape_str(const char *);
-
 static int auth_ldap_retry(const char *service,
                           const char *user, const char *pass,
                           int (*callback)(struct authinfo *, void *),
@@ -1104,11 +1112,13 @@ static int auth_ldap_retry(const char *service,
        char *q;
        int i;
 
-       q=escape_str(user);
+       q=courier_auth_ldap_escape(user);
 
        if (!q)
-               return (auth_ldap_do2(service,
-                                     user, pass, callback, arg, newpass));
+       {
+               perror("malloc");
+               return 1;
+       }
 
        i=auth_ldap_do2(service, q, pass, callback, arg, newpass);
        free(q);
@@ -1137,7 +1147,7 @@ static int auth_ldap_do2(const char *service,
        char *v;
        const char *aname;
 
-       if (ldapopen()) return (1);
+       if (ldapopen()) return (-1);
 
        if (my_ldap.emailmap[0] == 0 || strchr(user, '@') == NULL)
                return (auth_ldap_do3(service, my_ldap.mail,
@@ -1181,11 +1191,10 @@ static int auth_ldap_do2(const char *service,
 
        if ((cnt=ldap_count_entries(my_ldap_fp, result)) != 1)
        {
-               free(srch);
-
                if (cnt)
                        err("emailmap: %d entries returned from search %s (but we need exactly 1)",
                               cnt, srch);
+               free(srch);
                ldap_msgfree(result);
                return -1;
        }
@@ -1738,43 +1747,6 @@ static int auth_ldap_do3(const char *service,
        return (rc);
 }
 
-/*
-** Escape a string with special LDAP characters.  Returns NULL if the original
-** string does not have any special LDAP characters (so we don't allocate
-** memory unless absolutely necessary).
-*/
-
-static char *escape_str(const char *user)
-{
-       int i;
-       const char *p;
-       char *q, *r;
-
-       for (i=0, p=user; *p; p++)
-               if (strchr("*()\\", *p))
-                       ++i;
-
-       if (i == 0)
-               return NULL;    /* No need to escape anything */
-
-       q=malloc(strlen(user)+i+1);
-
-       if (!q)
-       {
-               perror("malloc");
-               exit(1);
-       }
-
-       for (r=q, p=user; *p; p++)
-       {
-               if (strchr("*()\\", *p))
-                       *r++= '\\';
-               *r++ = *p;
-       }
-       *r=0;
-       return (q);
-}
-
 /**
  ** Create an emailmap search string.  I'm going to wrap this into an external
  ** variable, so I'll use generic coding here.
@@ -1892,7 +1864,11 @@ void auth_ldap_enumerate( void(*cb_func)(const char *name,
        int i, j;
        int msgid;
 
-       if (ldapopen()) return;
+       if (ldapopen())
+       {
+               (*cb_func)(NULL, 0, 0, NULL, NULL, NULL, void_arg);
+               return;
+       }
 
        read_env("LDAP_MAIL", &attributes[0], "", 0, "mail");
        read_env("LDAP_UID", &attributes[1], "", 0, 0);
@@ -2037,6 +2013,7 @@ void auth_ldap_enumerate( void(*cb_func)(const char *name,
 
                                if (!options)
                                {
+                                       l_value_free(names);
                                        perror("CRIT: auth_ldap_enumerate: malloc failed");
                                        return;
                                }