1

I have uses ldapjs module of nodejs to interact with my active directory.

i can bind and add user into the active directory with these functions...

    ldapOptions = {
      url: //my ldap server ip,
      connectionTimeOut: 30000,
      reconnect: true
    }

    const ldapClient = ldapJs.createClient(ldapOptions)

    ldapClient.bind(adminDn, adminPass, (error) => {
      if (error) {
        // break the code
      } else {
          let newUser = {
                cn: username,
                sn: username,
                description: // some desc,
                objectClass: ['inetOrgPerson', 'user', 'person', 'top'],
                userPassword: password
            }

           ldapClient.add(dn, newUser, err => {
                if (err) {
                    console.log(err)
                    // break the code
                } else {
                    console.log('success')
                 }
        }

    }

but after adding process the account is disabled and user must change password a the next login. is this default active directory policy or the ldapjs defaults? and if it is how can i change the defaults...

Update

I've active Active Directory Certificate Service on my windows server(Active directory)

after that, export that certificate on active directory and added to my trust cert on my machine...

the ldapjs docs suggest to use nodejs/tls options to communicate with the ldaps server...

const ldapOptions = {
    url: 'ldaps://test-server.part.loc',
    connectTimeout: 1000,
    reconnect: false,
    tlsOptions: {
        // key and cert is create on my own but just created by openssl. do i have ti trusted it to my machine or server?
        key: fs.readFileSync('my_cert.pem'),
        cert: fs.readFileSync('my_key.pem'),
        // this is the certificate of the active directory 
        ca: fs.readFileSync('fuck_cert.pem'),

        checkServerIdentity: () => { return null; },
    }
}

but still getting the error:

Error: error:0909006C:PEM routines:get_name:no start line

library: 'PEM routines',

function: 'get_name',

reason: 'no start line',

code: 'ERR_OSSL_PEM_NO_START_LINE'

khodekazemi
  • 143
  • 10
  • have you tried using the attribute: `userAccountControl` and setting its value to 512? [Reference](https://support.microsoft.com/en-us/help/305144/how-to-use-useraccountcontrol-to-manipulate-user-account-properties) – Jawad May 18 '20 at 06:26
  • @Jawad can you explain more? actually iam new to ldapjs.. – khodekazemi May 18 '20 at 07:02
  • i did tried the `userAccountControl: 512` but i have got `UnwillingToPerformError` error. :( @Jawad – khodekazemi May 18 '20 at 13:26

1 Answers1

2

Are you able to manually enable an account that was created this way? If not, I suspect the password wasn't actually set.

The userPassword attribute can only be used if it's enabled. Even then, it's really just an alias for the real password attribute, unicodePwd. But unicodePwd takes some very specific formatting.

You also have to make sure that you have a secure connection to AD before you can set the password. You can do this by connecting to the LDAPS (LDAP over SSL) port of 636. The ldapjs library allows you to just use ldaps:// in front of your server name - you can't use the IP since the name on the SSL certificate must match the domain name you are using to connect. And the SSL certificate must be trusted on the computer you are running this on. This might cause you problems.

I also noticed that you're missing the sAMAccountName attribute, which is a required attribute. I see you're setting the sn attribute to username, but that attribute is for the user's surname (last name).

All of this together, you can try this (just change the name of the domain at the top):

ldapOptions = {
  url: "ldaps://example.com",
  connectionTimeOut: 30000,
  reconnect: true
}

const ldapClient = ldapJs.createClient(ldapOptions)

ldapClient.bind(adminDn, adminPass, (error) => {
    if (error) {
        // break the code
    } else {
        let newUser = {
            cn: username,
            sAMAccountName: username,
            description: // some desc,
            objectClass: 'user',
            unicodePwd: new Buffer('"' + password + '"', 'utf16le').toString(),
            userAccountControl: 512 //NORMAL_ACCOUNT
        }

        ldapClient.add(dn, newUser, err => {
            if (err) {
                console.log(err)
                // break the code
            } else {
                console.log('success')
            }
        }
    }
}

I'm not a NodeJS developer, so I've never actually done this with the ldapjs library. But I've done all this with C#. This should get you pretty close. Let me know if this gives you any errors. I suspect any errors might be from the SSL certificate.

The correct encoding for the password I found here.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84