Bug 11530 - classicupgrade segfaults if ldap entry is missing gecos (and probably other attributes)
classicupgrade segfaults if ldap entry is missing gecos (and probably other a...
Status: RESOLVED FIXED
Product: Samba 4.1 and newer
Classification: Unclassified
Component: AD: LDB/DSDB/SAMDB
4.3.0
All All
: P5 major
: ---
Assigned To: Karolin Seeger
Samba QA Contact
:
Depends on:
Blocks: 11760
  Show dependency treegraph
 
Reported: 2015-09-24 08:40 UTC by Luca Olivetti
Modified: 2016-05-12 12:11 UTC (History)
5 users (show)

See Also:


Attachments
invert condition for pw_gecos/pw_dir/pw_shell (987 bytes, patch)
2015-10-15 10:09 UTC, Luca Olivetti
no flags Details
Patch for 4.3 (1.65 KB, patch)
2016-05-11 01:18 UTC, Garming Sam
abartlet: review+
Details
Patch for 4.4 (1.65 KB, patch)
2016-05-11 01:20 UTC, Garming Sam
abartlet: review+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Luca Olivetti 2015-09-24 08:40:50 UTC
When I stage a classicupgrade that worked fine with 4.2.x, it segfaults.

Running it through gdb I see it fails on an entry that's missing the gecos attribute, in fact if I add the missing gecos the classicupgrade terminates successfully.

root@dc1:/home/luca/samba4# gdb python
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from python...(no debugging symbols found)...done.
(gdb) run /usr/bin/samba-tool domain classicupgrade --dbdir=dbdir --use-xattrs=yes --realm=SAMBA.WETRON.ES --dns-backend=SAMBA_INTERNAL dbdir/smb.pdc.conf
Starting program: /usr/bin/python /usr/bin/samba-tool domain classicupgrade --dbdir=dbdir --use-xattrs=yes --realm=SAMBA.WETRON.ES --dns-backend=SAMBA_INTERNAL dbdir/smb.pdc.conf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Reading smb.conf
Can't find include file /etc/samba/logon.home.UNKNOWN
Processing section "[netlogon]"
Processing section "[Profiles]"
Processing section "[printers]"
Processing section "[print$]"
Processing section "[backup_publico]"
Processing section "[backup_privado]"
Processing section "[backup_eplan]"
Processing section "[backup_proyectos]"
Processing section "[proyectos]"
Processing section "[public]"
Processing section "[intranet]"
Processing section "[invitado]"
Processing section "[scanner]"
Processing section "[scanner_ofertas]"
Processing section "[scanner_administracion]"
Processing section "[scanner_rrhh]"
Processing section "[scanner_contabilidad]"
Processing section "[scanner_compras]"
Processing section "[merda1]"
Processing section "[merda2]"
Provisioning
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=WETRON))]
smbldap_open_connection: connection opened
ldap_connect_system: successful connection to the LDAP server
Exporting account policy
Exporting groups
ldapsam_setsamgrent: 48 entries in the base!
init_group_from_ldap: Entry found for group: 512
init_group_from_ldap: Entry found for group: 513
init_group_from_ldap: Entry found for group: 514
init_group_from_ldap: Entry found for group: 515
init_group_from_ldap: Entry found for group: 550
init_group_from_ldap: Entry found for group: 551
init_group_from_ldap: Entry found for group: 492
init_group_from_ldap: Entry found for group: 493
init_group_from_ldap: Entry found for group: 494
init_group_from_ldap: Entry found for group: 495
init_group_from_ldap: Entry found for group: 496
init_group_from_ldap: Entry found for group: 497
init_group_from_ldap: Entry found for group: 498
init_group_from_ldap: Entry found for group: 499
init_group_from_ldap: Entry found for group: 507
init_group_from_ldap: Entry found for group: 508
init_group_from_ldap: Entry found for group: 521
init_group_from_ldap: Entry found for group: 535
init_group_from_ldap: Entry found for group: 536
init_group_from_ldap: Entry found for group: 537
init_group_from_ldap: Entry found for group: 564
init_group_from_ldap: Entry found for group: 618
init_group_from_ldap: Entry found for group: 621
init_group_from_ldap: Entry found for group: 622
init_group_from_ldap: Entry found for group: 637
init_group_from_ldap: Entry found for group: 643
init_group_from_ldap: Entry found for group: 648
init_group_from_ldap: Entry found for group: 649
init_group_from_ldap: Entry found for group: 663
init_group_from_ldap: Entry found for group: 672
init_group_from_ldap: Entry found for group: 673
init_group_from_ldap: Entry found for group: 674
init_group_from_ldap: Entry found for group: 675
init_group_from_ldap: Entry found for group: 676
init_group_from_ldap: Entry found for group: 677
init_group_from_ldap: Entry found for group: 678
init_group_from_ldap: Entry found for group: 679
init_group_from_ldap: Entry found for group: 680
init_group_from_ldap: Entry found for group: 681
init_group_from_ldap: Entry found for group: 682
init_group_from_ldap: Entry found for group: 683
init_group_from_ldap: Entry found for group: 684
init_group_from_ldap: Entry found for group: 685
init_group_from_ldap: Entry found for group: 686
init_group_from_ldap: Entry found for group: 687
init_group_from_ldap: Entry found for group: 688
init_group_from_ldap: Entry found for group: 689
init_group_from_ldap: Entry found for group: 690
Ignoring group 'Print Operators' S-1-5-32-550 listed but then not found: Unable to enumerate members for alias, (-1073741487,The specified local group does not exist.)
Ignoring group 'Backup Operators' S-1-5-32-551 listed but then not found: Unable to enumerate members for alias, (-1073741487,The specified local group does not exist.)
Exporting users
smbldap_search_paged: base => [dc=wetron,dc=es], filter => [(&(uid=*)(objectclass=sambaSamAccount))],scope => [2], pagesize => [1024]
smbldap_search_paged: search was successful
init_sam_from_ldap: Entry found for user: root
smbldap_search_domain_info: Searching for:[(&(objectClass=sambaDomain)(sambaDomainName=WETRON))]
smbldap_open_connection: connection opened
ldap_connect_system: successful connection to the LDAP server
init_sam_from_ldap: Entry found for user: nobody

Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106     ../sysdeps/x86_64/strlen.S: El fitxer o directori no existeix.
(gdb) bt
#0  strlen () at ../sysdeps/x86_64/strlen.S:106
#1  0x00007fffe67547f4 in tcopy_passwd (mem_ctx=mem_ctx@entry=0xe4e2f0, from=from@entry=0x7fffffffd370) at ../lib/util/util_pw.c:39
#2  0x00007fffe6bae780 in init_sam_from_ldap (ldap_state=ldap_state@entry=0xa76050, sampass=sampass@entry=0xe4e2f0, entry=0xa76ef0) at ../source3/passdb/pdb_ldap.c:1029
#3  0x00007fffe6bb0356 in ldapsam_getsampwnam (my_methods=0xd24520, user=0xe4e2f0, sname=0x7fffdba9b294 "nobody") at ../source3/passdb/pdb_ldap.c:1507
#4  0x00007fffe6dff8b2 in py_pdb_getsampwnam (self=<optimized out>, args=<optimized out>) at ../source3/passdb/py_passdb.c:1402
#5  0x000000000049968d in PyEval_EvalFrameEx ()
#6  0x00000000004a090c in PyEval_EvalCodeEx ()
#7  0x0000000000499a52 in PyEval_EvalFrameEx ()
#8  0x00000000004a1c9a in ?? ()
#9  0x0000000000505f96 in PyObject_Call ()
#10 0x000000000049b07a in PyEval_EvalFrameEx ()
#11 0x00000000004a1c9a in ?? ()
#12 0x0000000000505f96 in PyObject_Call ()
#13 0x000000000049b07a in PyEval_EvalFrameEx ()
#14 0x00000000004a1c9a in ?? ()
#15 0x0000000000505f96 in PyObject_Call ()
#16 0x000000000049b07a in PyEval_EvalFrameEx ()
#17 0x00000000004a1c9a in ?? ()
#18 0x0000000000505f96 in PyObject_Call ()
#19 0x000000000049b07a in PyEval_EvalFrameEx ()
#20 0x00000000004a1634 in ?? ()
#21 0x000000000044e4a5 in PyRun_FileExFlags ()
#22 0x000000000044ec9f in PyRun_SimpleFileExFlags ()
#23 0x000000000044f904 in Py_Main ()
#24 0x00007ffff7818ec5 in __libc_start_main (main=0x44f9c2 <main>, argc=9, argv=0x7fffffffe608, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe5f8)
    at libc-start.c:287
#25 0x0000000000578c4e in _start ()

Line 39 in util_pw.c is

              len += strlen(from->pw_gecos)+1;

coming from pdb_ldap.c, line 1029

              sampass->unix_pw = tcopy_passwd(sampass, &unix_pw);


a few lines earlier, I see that it gets and checks gecos:

                unix_pw.pw_gecos = smbldap_talloc_single_attribute(
                                priv2ld(ldap_state),
                                entry,
                                "gecos",
                                ctx);
                if (unix_pw.pw_gecos) {
                        unix_pw.pw_gecos = fullname;
                }


Shouldn't the condition be "if (!unix_pw.pw_gecos)" or "if (unix_pw.pw_gecos==NULL)"?

Note that the same check (for not null instead of null) is also done for unix_pw.pw_dir and unix_pw.pw_shell in the same function, but in those 2 cases it seems to clobber the result instead of accepting the null pointer.
Comment 1 Andrew Bartlett 2015-10-15 02:41:56 UTC
Thanks.  That would seem to be the correct fix.  Any chance of a git patch so I get can this fixed in master?
Comment 2 Andrew Bartlett 2015-10-15 02:43:19 UTC
The background is that we were trying to fall back if the gecos attribute was not present to the full name.  Sadly that hasn't worked out so well...
Comment 3 Luca Olivetti 2015-10-15 07:16:17 UTC
What puzzles is that pdb_ldap.c hasn't changed from samba 4.2.23, but it didn't segfault when I tested the classicupgrade with that version

https://git.samba.org/?p=samba.git;a=blob;f=source3/passdb/pdb_ldap.c;h=0d2c302081a485cea919f6046b783f65a679ad4d;hb=baf4349dd5769b9bca4ac08f869f7b0fbb01a4ed
Comment 4 Luca Olivetti 2015-10-15 10:09:48 UTC
Created attachment 11496 [details]
invert condition for pw_gecos/pw_dir/pw_shell

With the attached patch I can successfully complete a classicupgrade even when an entry is missing the GECOS attribute.
I also checked and it correctly preserves the homeDirectory (mapped to unixHomeDirectory) and loginShell, though I didn't check if this didn't work with samba 4.2.x.
Comment 5 void 2015-11-10 14:11:17 UTC
Run into the same problem. The segfault comes from a change in tcopy_passwd from Nov 2014, which added strlen(from->...), which segfaults on NULL. 

I guess 4.2.x didn't have this change.
Comment 6 Dron 2016-02-04 14:00:00 UTC
Have same situation at 4.3.3
Patch is decided the problem.
Please, add patch to 4.3.5
Thanks.
Comment 7 Andrew Bartlett 2016-02-11 01:34:48 UTC
Merged in master as 5d759bd0d4bf7cae8b54b69af5ecacb7987c2a0f

We just need it backported now.
Comment 8 Dron 2016-04-01 06:42:22 UTC
4.3.6 is not containing this patch. It was really dejavu to see same bt in gdb, while thinking that this was fixed )
Comment 9 Timur Bakeyev 2016-04-13 14:30:24 UTC
Added as a local patch for FreeBSD 4.3.8.
Comment 10 Garming Sam 2016-05-11 01:18:19 UTC
Created attachment 12095 [details]
Patch for 4.3
Comment 11 Garming Sam 2016-05-11 01:20:43 UTC
Created attachment 12096 [details]
Patch for 4.4
Comment 12 Karolin Seeger 2016-05-11 11:56:02 UTC
(In reply to Garming Sam from comment #10)
Review is missing for this patch.
Comment 13 Karolin Seeger 2016-05-12 06:18:26 UTC
Pushed to autobuild-v4-[4|3]-test.
Comment 14 Karolin Seeger 2016-05-12 12:11:18 UTC
(In reply to Karolin Seeger from comment #13)
Pushed to both branches.
Closing out bug report.

Thanks!