Package: proftpd-mod-ldap
Severity: grave
Tags: patch

Hello,

When LDAPDoAuth  specifies an invalid  filter which leads to  no results
being returned, mod_ldap SIGSEGV with the following backtrace:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f073be4f6f0 (LWP 16253)]
0x00007f0739e60e72 in handle_ldap_getgroups (cmd=0x11f1470) at mod_ldap.c:1054
1054    mod_ldap.c: No such file or directory.
        in mod_ldap.c
(gdb) bt
#0  0x00007f0739e60e72 in handle_ldap_getgroups (cmd=0x11f1470) at 
mod_ldap.c:1054
#1  0x000000000042f332 in pr_module_call (m=0x7f073a0676a0, func=0x7f0739e60ac0 
<handle_ldap_getgroups>, cmd=0x1209c30) at modules.c:502
#2  0x0000000000431e28 in dispatch_auth (cmd=0x11f1470, match=0x47d172 
"getgroups", m=0x0) at auth.c:266
#3  0x0000000000431f52 in pr_auth_getgroups (p=0x11f13f0, name=<value optimized 
out>, group_ids=0x6a9ce0, group_names=0x6a9ce8) at auth.c:980
#4  0x0000000000432577 in auth_anonymous_group (p=<value optimized out>, 
login_name=0x7fffac929ca0, user_name=<value optimized out>, anon_name=0x0) at 
auth.c:1041
#5  pr_auth_get_anon_config (p=<value optimized out>, 
login_name=0x7fffac929ca0, user_name=<value optimized out>, anon_name=0x0) at 
auth.c:1169
#6  0x000000000045750d in auth_user (cmd=0x11d9688) at mod_auth.c:1756
#7  0x000000000042f332 in pr_module_call (m=0x69bc20, func=0x457470 
<auth_user>, cmd=0x1209c30) at modules.c:502
#8  0x0000000000413266 in _dispatch (cmd=0x11d9688, cmd_type=2, validate=<value 
optimized out>, match=0x11d9708 "USER") at main.c:459
#9  0x000000000041384b in pr_cmd_dispatch_phase (cmd=0x11d9688, phase=0, 
send_response=1) at main.c:725
#10 0x0000000000414cbc in cmd_loop (server=<value optimized out>, c=<value 
optimized out>) at main.c:916
#11 0x0000000000410655 in fork_server (fd=<value optimized out>, l=<value 
optimized out>, nofork=<value optimized out>) at main.c:1436
#12 0x0000000000412609 in daemon_loop () at main.c:1643
#13 0x00000000004149c5 in main (argc=1, argv=<value optimized out>, envp=<value 
optimized out>) at main.c:3044

Actually,   `pw'   pointer   is   dereferenced   in   `pr_log_debug(...,
pw->pw_name,    ...)'      whereas    `pw'    might     be    NULL    if
`pr_ldap_user_lookup()' called by `pr_ldap_getpwnam()' returns NULL when
there has been an error or no entry found.

I  have attached  to  this  email a  patch  to fix  this  issue. If  the
`pr_user_lookup()' fails  (either because of  an error or the  user does
not exist), my patch makes `ldap_handle_getgroups()' just returns (after
displaying an  error message) as I  think there is no  point at checking
the groups afterwards.   I might be missing something  though but as the
code is not documented, this is a bit hard to tell ;).

Regards,
Arnaud Fontaine

--- proftpd-dfsg-1.3.2e/contrib/mod_ldap.c.orig	2010-04-06 17:24:00.065027336 +0100
+++ proftpd-dfsg-1.3.2e/contrib/mod_ldap.c	2010-04-06 17:19:38.737029792 +0100
@@ -978,15 +978,21 @@
   }
 
   pw = pr_ldap_getpwnam(cmd->tmp_pool, cmd->argv[0]);
-  if (pw) {
-    gr = pr_ldap_getgrgid(cmd->tmp_pool, pw->pw_gid);
-    if (gr) {
-      pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": adding user %s primary group %s/%lu", pw->pw_name, gr->gr_name, (unsigned long)pw->pw_gid);
-      *((gid_t *) push_array(gids))   = pw->pw_gid;
-      *((char **) push_array(groups)) = pstrdup(session.pool, gr->gr_name);
-    } else {
-      pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": couldn't determine group name for user %s primary group %lu, skipping.", pw->pw_name, (unsigned long)pw->pw_gid);
-    }
+  /* If the user lookup fails, there is no point at looking at the groups */
+  if (!pw) {
+    pr_log_pri(PR_LOG_ERR, MOD_LDAP_VERSION ": ldap_handle_getgroups(): Invalid user %s or authentication filter",
+               cmd->argv[0]);
+
+    goto return_groups;
+  }
+
+  gr = pr_ldap_getgrgid(cmd->tmp_pool, pw->pw_gid);
+  if (gr) {
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": adding user %s primary group %s/%lu", pw->pw_name, gr->gr_name, (unsigned long)pw->pw_gid);
+    *((gid_t *) push_array(gids))   = pw->pw_gid;
+    *((char **) push_array(groups)) = pstrdup(session.pool, gr->gr_name);
+  } else {
+    pr_log_debug(DEBUG3, MOD_LDAP_VERSION ": couldn't determine group name for user %s primary group %lu, skipping.", pw->pw_name, (unsigned long)pw->pw_gid);
   }
 
   if (!ldap_gid_basedn) {
@@ -1047,7 +1053,7 @@
       continue;
     }
 
-    if (!pw || strtoul(LDAP_VALUE(gidNumber, 0), (char **)NULL, 10) != pw->pw_gid) {
+    if (strtoul(LDAP_VALUE(gidNumber, 0), (char **)NULL, 10) != pw->pw_gid) {
       *((gid_t *) push_array(gids)) =
         strtoul(LDAP_VALUE(gidNumber, 0), (char **)NULL, 10);
       *((char **) push_array(groups)) = pstrdup(session.pool, LDAP_VALUE(cn, 0));

Reply via email to