首页 > 解决方案 > LdapJS 服务器 exop 处理失败

问题描述

我正在使用 Node.js 模块ldapjs版本 1.0.2 的 LDAP 服务器功能。我想处理 LDAP 1.3.6.1.4.1.4203.1.11.1 扩展操作(请参阅RFC 3062 = LDAP 密码修改)。

我的服务器配置...

   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;
   });

调用命令ldappasswd(来自 debian 包 ldap-utils)有效,处理程序方法以正确的方式调用。

使用“old”作为旧密码和“new”使用新密码的命令中的数据ldappasswd ... uid=user -A -S会产生以下十六进制值:

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 标记属性的开头,0x81 标记旧密码的开头,0x82 标记新密码的开头。这个字节后面的值是长度,后面是信息本身。

问题:
在处理程序方法中,requestValue 是一个带有无效分隔符的字符串。

0uid=user�old�new

将字符串转换为缓冲区 ( Buffer.from(req.reuqestValue) 会导致:

<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>

分隔符字节 0x80、0x81 和 0x82 被转换为ef bf bd,因此解析信息失败,因为类型丢失。

知道如何从requestValue属性中获取信息值吗?

标签: ldapldapjs

解决方案


可以通过安装版本next并使用req.requestValueBuffer代替来解决该问题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;
   })

该问题是由文件lib/messages/ext_request.js第 61 行中当前 ldapjs 主分支 ( ad451edc ) 中的错误引起的:

  this.requestName = ber.readString(0x80);
  if (ber.peek() === 0x81)
    try {
      this.requestValue = ber.readString(0x81);
    } catch (e) {
      this.requestValue = ber.readBuffer(0x81);
    }

如果是ldappasswd数据,readString()则调用该函数(不抛出异常),并且该函数始终使用 UTF-8 解码将缓冲区转换为字符串。那是错误的。此代码片段中的另一个错误是readBuffer(...)object 上不存在对 which的调用ber

在 ldapjs 存储库的下一个分支中,此错误由提交 b87e4bb中的错误修复解决。

错误修复 lib/messages/ext_request.js第82 行:

  this.requestName = ber.readString(0x80)
  if (ber.peek() === 0x81) {
    this.requestValueBuffer = ber.readString(0x81, true)
    this.requestValue = this.requestValueBuffer.toString('utf8')
  }

现在可以使用处理程序方法req.requestValueBuffer来获取原始请求数据字节。


推荐阅读