I am using the LDAP server functionality of the Node.js module ldapjs version 1.0.2. I want to handle an LDAP 1.3.6.1.4.1.4203.1.11.1 extended operation (see RFC 3062 = LDAP Password Modify).
My server is configured...
const server = ldapjs.createServer( ... );
...
server.exop('1.3.6.1.4.1.4203.1.11.1', (req: any, res: any, next: any) => {
const requestValue = req.requestValue;
});
Calling the command ldappasswd
(from debian package ldap-utils) works, handler method is called in proper way.
The data from the ldappasswd ... uid=user -A -S
command with "old" as old password and "new" with new password results in the following hex values:
30 14 80 08 75 69 64 3d 73 75 72 66 81 03 6f 6c 64 82 03 6e 65 77
0 u i d = u s e r o l d n e w
0x80 marks the beginning of the attribute, 0x81 the beginning of the old password, 0x82 the beginning of the new password. The value after this byte is the length, followed by the information itself.
The problem:
Inside the handler methode, requestValue is a string with invalid separator characters.
0uid=user�old�new
Converting the string to a buffer ( Buffer.from(req.reuqestValue
) results in:
<Buffer 30 14 ef bf bd 08 75 69 64 3d 75 73 65 72 ef bf bd 03 6f 6c 64 ef bf bd 03 6e 65 77>
The separator bytes 0x80, 0x81 and 0x82 are converted to ef bf bd
and therefore parsing information fails, because type is lost.
Any idea how to get out the information values from the requestValue
attribute?
The problem can be solved by installing the version next
and using req.requestValueBuffer
instead of req.requestValue
:
npm install --save ldapjs@next
const server = ldapjs.createServer( ... );
...
server.exop('1.3.6.1.4.1.4203.1.11.1', (req: any, res: any, next: any) => {
const requestValue = req.requestValueBuffer;
})
The problem is caused by a bug in the current ldapjs master branch (ad451edc) in file lib/messages/ext_request.js line 61:
this.requestName = ber.readString(0x80);
if (ber.peek() === 0x81)
try {
this.requestValue = ber.readString(0x81);
} catch (e) {
this.requestValue = ber.readBuffer(0x81);
}
In case of ldappasswd
data the readString()
function is called (no exception thrown), and this function always converts the buffer to a string using UTF-8 decoding. That's wrong. An additional bug in this code snippet is the call of readBuffer(...)
which doesn't exist on the object ber
.
In the branch next of the ldapjs repository this bug is solved by the bugfix in commit b87e4bb.
Bugfix lib/messages/ext_request.js line 82:
this.requestName = ber.readString(0x80)
if (ber.peek() === 0x81) {
this.requestValueBuffer = ber.readString(0x81, true)
this.requestValue = this.requestValueBuffer.toString('utf8')
}
A handler method can now use req.requestValueBuffer
to get the original request data bytes.