DirectoryTree / LdapRecord

A fully-featured LDAP framework.
https://ldaprecord.com
MIT License
519 stars 45 forks source link

[Bug] segfault - adding a user #456

Closed paulb-smartit closed 2 years ago

paulb-smartit commented 2 years ago

Environment:

Describe the bug:

When I try to save a new user I get a segfault. It either kills my artisan server or nginx instance.

May 26 19:13:03 laravel kernel: [166023.553501] php-fpm8.1[90799]: segfault at 208 ip 0000558209611b25 sp 00007ffee900e470 error 4 in php-fpm8.1[55820944a000+2ec000]
May 26 19:13:03 laravel kernel: [166023.553512] Code: 89 fd 53 41 8b 04 24 85 c0 0f 85 eb 4b e5 ff 48 89 f8 25 ff ff 1f 00 74 4c 48 89 fe 48 89 c2 48 81 e6 00 00 e0 ff 48 c1 ea 0c <8b> 8c 96 08 02 00 00 4c 3b 26 0f 85 bb 4b e5 ff 85 c9 79 5f 83 e1

This is the code I'm using for saving the user. I'm passing in an array $user[] with the attributes required. I removed all attributes other than the basic.

I had to populate objectClasses or I get a class violation.

            $base_dn = env('LDAP_BASE_DN', "dc=UNKNOWNBASEDN");

            $classes = [];

            foreach(User::$objectClasses as $class) {
                $classes[] = ['objectclass' => $class];
            };

            $ou = OrganizationalUnit::findOrFail($user['ou'].$base_dn);

            $ldapUser = (new User)->inside($ou);

            $ldapUser->objectclasses = $classes;
            $ldapUser->cn = sprintf("%s %s", $user['givenname'], $user['sn']); 

            try {
                $ldapUser->save();
            } catch (Exception $e) {
                return "failed!";
            }

It never gets to the exception or return.

I see in the ldap logs that it searches for the ou then boom.

628fc583 conn=3967 fd=15 ACCEPT from IP=192.168.48.1:54328 (IP=0.0.0.0:389)
628fc583 conn=3967 op=0 BIND dn="cn=admin,dc=xxx" method=128
628fc583 conn=3967 op=0 BIND dn="cn=admin,dc=xxx" mech=SIMPLE ssf=0
628fc583 conn=3967 op=0 RESULT tag=97 err=0 text=
628fc583 conn=3967 op=1 SRCH base="ou=staff,ou=people,dc=xxx" scope=0 deref=0 filter="(&(objectClass=top)(objectClass=organizationalUnit)(objectClass=*))"
628fc583 conn=3967 op=1 SRCH attr=entryuuid *
628fc583 conn=3967 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
628fc583 conn=3967 fd=15 closed (connection lost)
stevebauman commented 2 years ago

Hi @paulb-opusvl,

Can you confirm if this occurs from finding the OrganizationalUnit?

Try executing only OrganizationalUnit::findOrFail($dn) to see if this still occurs, and we can go from there 👍

paulb-smartit commented 2 years ago

It's definitely happening at the point of ->save() as I ca ndo a dd before and get this:

App\Ldap\User {#1348
  +exists: false
  +wasRecentlyCreated: false
  +wasRecentlyRenamed: false
  #dn: null
  #in: "ou=staff,ou=people,dc=xxx"
  #connection: null
  #guidKey: "entryuuid"
  #modifications: []
  #original: []
  #attributes: array:3 [
    "objectclasses" => array:3 [
      0 => array:1 [
        "objectclass" => "top"
      ]
      1 => array:1 [
        "objectclass" => "person"
      ]
      2 => array:1 [
        "objectclass" => "organizationalperson"
      ]
    ]
    "sn" => array:1 [
      0 => "Coyote"
    ]
    "cn" => array:1 [
      0 => "Whiley Coyote"
    ]
  ]
  #dates: []
  #casts: []
  #appends: []
  #dateFormat: null
  #defaultDates: array:2 [
    "createtimestamp" => "ldap"
    "modifytimestamp" => "ldap"
  ]
  #hidden: array:1 [
    0 => "userPassword"
  ]
  #visible: array:6 [
    0 => "cn"
    1 => "mail"
    2 => "sn"
    3 => "givenName"
    4 => "initials"
    5 => "uid"
  ]
  #passwordAttribute: "userpassword"
  #passwordHashMethod: "ssha"
stevebauman commented 2 years ago

Ok thanks for posting that. I see what may be going on here -- the objectclasses are formatted incorrectly. They must only be values, not key => value pairs.

You are also setting them when they do not need to be set as an attribute. The static object classes are inserted into the LDAP record during creation automatically.

Remove $ldapUser->objectclasses = $classes and then try creation again 👍

paulb-smartit commented 2 years ago

I can close this.

Not for the first time, I embarrass myself with something that once I figure it out becomes obvious.

The whole objectClasses was a red herring. What the error meant was that I was trying to use an attribute from a schema that didn't support it. My 3 object classes don't support my default rdn - uid. For that I had to add posixAccount and add in a lot more mandatory attributes.

Once I did that, the model saves into LDAP.

            $ou = OrganizationalUnit::findOrFail($user['ou'].$base_dn);

            $ldapUser = (new User)->inside($ou);

            $ldapUser->uid = $user['uid'];
            $ldapUser->sn = $user['sn'];
            $ldapUser->cn = sprintf("%s %s", $user['givenname'], $user['sn']); 
            $ldapUser->setDn($user['dn']);
            $ldapUser->userPassword = 'RoadRunner1234567890';
            $ldapUser->uidnumber = 999;
            $ldapUser->gidnumber = 999;
            $ldapUser->homedirectory = "/dev/null";

            $ldapUser->save();

Thanks for a great product.

stevebauman commented 2 years ago

Ah it happens to all of us haha, I'm so glad you've resolved this issue and posted the solution.

Always happy to help! Take care.