Bug 1749 - Segmentation fault in smbpasswd 3.0.6 (problems with LDAP)
Summary: Segmentation fault in smbpasswd 3.0.6 (problems with LDAP)
Status: RESOLVED DUPLICATE of bug 1715
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: File Services (show other bugs)
Version: 3.0.6
Hardware: x86 Linux
: P3 major
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-09-10 17:19 UTC by Igor Zhbanov
Modified: 2004-09-11 07:46 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Igor Zhbanov 2004-09-10 17:19:49 UTC
The command "smbpasswd -x zzz" (and many others) crashes with Segmentation
fault. User zzz doesn't exist but it doesn't matter.

The configure command line is: 
/configure  --prefix=/usr --with-readline --with-smbmount --with-libsmbclient \
  --with-privatedir=/etc/samba --with-lockdir=/var/lock/samba \
  --with-piddir=/var/run --with-configdir=/etc/samba \
  --with-logfilebase=/var/log/samba --localstatedir=/var \
  --with-pam_smbpass --with-ldapsam

Here is backtrace from GDB:
#0  0x4701fd83 in strlen () from /lib/i686/libc.so.6
#1  0x4701fab5 in strdup () from /lib/i686/libc.so.6
#2  0x080aa0a2 in append_attr (attr_list=0xbffff2c8, new_attr=0x0) at
passdb/pdb_ldap.c:1237
#3  0x080aa0fd in ldapsam_getsampwnam (my_methods=0x824b3e8, user=0x824b778,
sname=0x8166240 "zzz")
    at passdb/pdb_ldap.c:1256
#4  0x080a2e10 in context_getsampwnam (context=0x0, sam_acct=0x824b778,
username=0x8166240 "zzz")
    at passdb/pdb_interface.c:197
#5  0x080a4568 in pdb_getsampwnam (sam_acct=0x824b778, username=0x8166240 "zzz")
at passdb/pdb_interface.c:881
#6  0x0809f943 in local_password_change (user_name=0x8166240 "zzz",
local_flags=514, new_passwd=0x0,
    err_str=0xbffff790 "", err_str_len=1024, msg_str=0xbffff390 "",
msg_str_len=1024) at passdb/passdb.c:972
#7  0x0806b4c7 in password_change (remote_mach=0x0, username=0x8166240 "zzz",
old_passwd=0x0, new_pw=0x0,
    local_flags=136624344) at utils/smbpasswd.c:289
#8  0x0806b8eb in process_root (local_flags=514) at utils/smbpasswd.c:453
#9  0x0806bc3b in main (argc=3, argv=0xbffffc64) at utils/smbpasswd.c:591

The program is crashed in function append_attr() which is called with NULL
second argument (const char *new_attr).
Here is fragment from passdb/pdb_ldap.c:
----- BEGIN -----
static void append_attr(char ***attr_list, const char *new_attr)
{
	int i;

	for (i=0; (*attr_list)[i] != NULL; i++)
		;

	(*attr_list) = Realloc((*attr_list), sizeof(**attr_list) * (i+2));
	SMB_ASSERT((*attr_list) != NULL);
	(*attr_list)[i] = strdup(new_attr);
/* ###################### ^^^^^^^^^^^^^^^^ ### The crash happens here ##### */
	(*attr_list)[i+1] = NULL;
}
----- END -----

So, the first question is: should check agains NULL be added?
Or at least should SMB_ASSERT ((*new_attr) != NULL); be added?

Now let's find out where NULL cames from.
Here is the part of ldapsam_getsampwnam() function from passdb/pdb_ldap.c:
----- BEGIN -----
static NTSTATUS ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT
*user, const char *sname)
{
	NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
	struct ldapsam_privates *ldap_state = (struct ldapsam_privates
*)my_methods->private_data;
	LDAPMessage *result = NULL;
	LDAPMessage *entry = NULL;
	int count;
	char ** attr_list;
	int rc;
	
	attr_list = get_userattr_list( ldap_state->schema_ver );
	append_attr(&attr_list,
get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP));
...
----- END -----

Since second argument of append_attr() was NULL, we may see that
get_userattr_key2string(ldap_state->schema_ver,LDAP_ATTR_MOD_TIMESTAMP) == NULL.

Debugging shows that ldap_state->schema_ver is 1 (SCHEMAVER_SAMBAACCOUNT).

Now let's look at get_userattr_key2string() which is in passdb/pdb_ldap.c:
----- BEGIN -----
static const char* get_userattr_key2string( int schema_ver, int key )
{
	switch ( schema_ver ) {
		case SCHEMAVER_SAMBAACCOUNT:
			return get_attr_key2string( attrib_map_v22, key );
...
----- END -----

So, get_attr_key2string( attrib_map_v22, key )) == NULL.
Let's look at get_attr_key2string() in lib/smbldap.c:
----- BEGIN -----
/**********************************************************************
 perform a simple table lookup and return the attribute name 
 **********************************************************************/
 
 const char* get_attr_key2string( ATTRIB_MAP_ENTRY table[], int key )
{
	int i = 0;
	
	while ( table[i].attrib != LDAP_ATTR_LIST_END ) {
		if ( table[i].attrib == key )
			return table[i].name;
		i++;
	}
	
	return NULL;
}
...
----- END -----

The attrib_map_v22[] is defined in lib/smbldap.c:
----- BEGIN -----
/* attributes used by Samba 2.2 */

ATTRIB_MAP_ENTRY attrib_map_v22[] = {
	{ LDAP_ATTR_UID,		"uid" 		},
...
	{ LDAP_ATTR_ACB_INFO,		"acctFlags"	},
	{ LDAP_ATTR_LIST_END,		NULL 		}
};
----- END -----

The problem is that LDAP_ATTR_MOD_TIMESTAMP is not found in attrib_map_v22[]
array (it can be found in attrib_map_v30[]). The NULL is returned and it is
never checked until the crash.

I know what happen but I don't know how to fix it. :-)

P.S.
1) If you need more info or have some tests to run feel free to ask.
Comment 1 Igor Zhbanov 2004-09-11 07:35:51 UTC
It doesn't crashes when configured without "--with-ldapsam".
Comment 2 Volker Lendecke 2004-09-11 07:46:09 UTC

*** This bug has been marked as a duplicate of 1715 ***