--- Begin Message ---
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));
--- End Message ---