37#if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
39#define snprintf _snprintf
44#define LDAPAPI __cdecl
48#define LDAP_OPT_X_TLS 0x6000
50#define ber_alloc() ber_alloc_t(0)
63#define NMASLDAP_GET_LOGIN_CONFIG_REQUEST "2.16.840.1.113719.1.39.42.100.3"
64#define NMASLDAP_GET_LOGIN_CONFIG_RESPONSE "2.16.840.1.113719.1.39.42.100.4"
65#define NMASLDAP_SET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.11"
66#define NMASLDAP_SET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.12"
67#define NMASLDAP_GET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.13"
68#define NMASLDAP_GET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.14"
70#define NMAS_LDAP_EXT_VERSION 1
72#define SMB_MALLOC_ARRAY(type, nelem) calloc(sizeof(type), nelem)
73#define DEBUG(level, args)
81 struct berval **requestBV,
84 const char *password2)
87 BerElement *requestBer =
nullptr;
89 const char * utf8ObjPtr =
nullptr;
91 const char * utf8PwdPtr =
nullptr;
93 const char * utf8Pwd2Ptr =
nullptr;
97 utf8ObjSize = strlen(objectDN)+1;
98 utf8ObjPtr = objectDN;
100 if (password !=
nullptr) {
101 utf8PwdSize = strlen(password)+1;
102 utf8PwdPtr = password;
105 if (password2 !=
nullptr) {
106 utf8Pwd2Size = strlen(password2)+1;
107 utf8Pwd2Ptr = password2;
111 if ((requestBer = ber_alloc()) ==
nullptr) {
112 err = LDAP_ENCODING_ERROR;
113 ber_free(requestBer, 1);
117 if (password !=
nullptr && password2 !=
nullptr) {
119 rc = ber_printf(requestBer,
"{iooo}",
NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize, utf8Pwd2Ptr, utf8Pwd2Size);
120 }
else if (password !=
nullptr) {
122 rc = ber_printf(requestBer,
"{ioo}",
NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize);
129 err = LDAP_ENCODING_ERROR;
133 if ((ber_tag_t)ber_flatten(requestBer, requestBV) == LBER_ERROR) {
134 err = LDAP_ENCODING_ERROR;
139 ber_free(requestBer, 1);
151 struct berval **requestBV,
153 unsigned int methodIDLen,
154 unsigned int *methodID,
159 unsigned int elemCnt = methodIDLen /
sizeof(
unsigned int);
161 char *utf8ObjPtr=
nullptr;
164 char *utf8TagPtr =
nullptr;
167 utf8ObjPtr = objectDN;
168 utf8ObjSize = strlen(utf8ObjPtr)+1;
171 utf8TagSize = strlen(utf8TagPtr)+1;
174 BerElement *requestBer = ber_alloc();
176 return LDAP_ENCODING_ERROR;
180 ber_free(requestBer, 1);
181 return LDAP_ENCODING_ERROR;
185 if (ber_printf(requestBer,
"{i{", methodIDLen) < 0) {
186 ber_free(requestBer, 1);
187 return LDAP_ENCODING_ERROR;
190 for (
unsigned int i = 0; i < elemCnt; ++i) {
191 if (ber_printf(requestBer,
"i", methodID[i]) < 0) {
192 ber_free(requestBer, 1);
193 return LDAP_ENCODING_ERROR;
197 if (ber_printf(requestBer,
"}}", 0) < 0) {
198 ber_free(requestBer, 1);
199 return LDAP_ENCODING_ERROR;
204 if (ber_printf(requestBer,
"oio}", utf8TagPtr, utf8TagSize, putDataLen, putData, putDataLen) < 0) {
205 ber_free(requestBer, 1);
206 return LDAP_ENCODING_ERROR;
210 if (ber_printf(requestBer,
"o}", utf8TagPtr, utf8TagSize) < 0) {
211 ber_free(requestBer, 1);
212 return LDAP_ENCODING_ERROR;
217 if (
static_cast<ber_tag_t
>(ber_flatten(requestBer, requestBV)) == LBER_ERROR) {
218 ber_free(requestBer, 1);
219 return LDAP_ENCODING_ERROR;
222 ber_free(requestBer, 1);
233 struct berval *replyBV,
239 BerElement *replyBer =
nullptr;
240 char *retOctStr =
nullptr;
241 size_t retOctStrLen = 0;
243 if ((replyBer = ber_init(replyBV)) ==
nullptr) {
244 err = LDAP_OPERATIONS_ERROR;
245 }
else if (retData) {
246 retOctStrLen = *retDataLen + 1;
249 err = LDAP_OPERATIONS_ERROR;
250 }
else if (ber_scanf(replyBer,
"{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != LBER_ERROR) {
251 if (*retDataLen >= retOctStrLen) {
252 memcpy(retData, retOctStr, retOctStrLen);
254 err = LDAP_NO_MEMORY;
257 *retDataLen = retOctStrLen;
259 err = LDAP_DECODING_ERROR;
262 if (ber_scanf(replyBer,
"{ii}", serverVersion, &err) == LBER_ERROR) {
264 err = LDAP_DECODING_ERROR;
270 ber_free(replyBer, 1);
273 if (retOctStr !=
nullptr) {
274 memset(retOctStr, 0, retOctStrLen);
289 unsigned int methodIDLen,
290 unsigned int *methodID,
296 struct berval *requestBV =
nullptr;
297 char *replyOID =
nullptr;
298 struct berval *replyBV =
nullptr;
299 int serverVersion = 0;
302 if ((strlen(objectDN) == 0) ||
ld ==
nullptr) {
303 return LDAP_NO_SUCH_ATTRIBUTE;
306 err =
berEncodeLoginData(&requestBV, objectDN, methodIDLen, methodID, tag, 0,
nullptr);
310 requestBV,
nullptr,
nullptr, &replyOID, &replyBV))) {
313 }
else if (!replyOID) {
315 err = LDAP_NOT_SUPPORTED;
318 err = LDAP_NOT_SUPPORTED;
319 }
else if (!replyBV) {
324 err = LDAP_OPERATIONS_ERROR;
330 err = LDAP_OPERATIONS_ERROR;
340 ldap_memfree(replyOID);
345 ber_bvfree(requestBV);
363 unsigned int methodID = 0;
364 unsigned int methodIDLen =
sizeof(methodID);
365 char tag[] = {
'P',
'A',
'S',
'S',
'W',
'O',
'R',
'D',
' ',
'H',
'A',
'S',
'H',0};
366 char *pwdBuf=
nullptr;
367 size_t pwdBufLen, bufferLen;
369 bufferLen = pwdBufLen = pwdLen+2;
371 if (pwdBuf ==
nullptr) {
372 return LDAP_NO_MEMORY;
375 err =
getLoginConfig(
ld, objectDN, methodIDLen, &methodID, tag, &pwdBufLen, pwdBuf);
378 pwdBuf[pwdBufLen] = 0;
388 err = LDAP_INAPPROPRIATE_AUTH;
393 if (pwdLen >= pwdBufLen-1) {
394 memcpy(pwd, &pwdBuf[1], pwdBufLen-1);
396 err = LDAP_NO_MEMORY;
402 if (pwdBuf !=
nullptr) {
422 struct berval *requestBV =
nullptr;
423 char *replyOID =
nullptr;
424 struct berval *replyBV =
nullptr;
427 size_t pwdBufLen, bufferLen;
430 if (objectDN ==
nullptr || (strlen(objectDN) == 0) || pwdSize ==
nullptr ||
ld ==
nullptr) {
431 return LDAP_NO_SUCH_ATTRIBUTE;
434 bufferLen = pwdBufLen = *pwdSize;
436 if (pwdBuf ==
nullptr) {
437 return LDAP_NO_MEMORY;
445 }
else if (!replyOID) {
447 err = LDAP_NOT_SUPPORTED;
450 err = LDAP_NOT_SUPPORTED;
451 }
else if (!replyBV) {
455 err = LDAP_OPERATIONS_ERROR;
460 err = LDAP_OPERATIONS_ERROR;
462 }
else if (!err && pwdBufLen != 0) {
463 if (*pwdSize >= pwdBufLen+1 && pwd !=
nullptr) {
464 memcpy(pwd, pwdBuf, pwdBufLen);
467 *pwdSize = pwdBufLen;
477 ldap_memfree(replyOID);
482 ber_bvfree(requestBV);
485 if (pwdBuf !=
nullptr) {
507 if (rc == LDAP_SUCCESS) {
508 DEBUG(5, (
"NDS Universal Password retrieved for %s\n", object_dn));
510 DEBUG(3, (
"NDS Universal Password NOT retrieved for %s\n", object_dn));
513 if (rc != LDAP_SUCCESS) {
515 if (rc == LDAP_SUCCESS) {
516 DEBUG(5, (
"NDS Simple Password retrieved for %s\n", object_dn));
519 DEBUG(3, (
"NDS Simple Password NOT retrieved for %s\n", object_dn));
520 return LDAP_INVALID_CREDENTIALS;
static int nmasldap_get_simple_pwd(LDAP *ld, char *objectDN, size_t pwdLen, char *pwd)
#define SMB_MALLOC_ARRAY(type, nelem)
#define NMASLDAP_GET_LOGIN_CONFIG_REQUEST
static int berEncodeLoginData(struct berval **requestBV, char *objectDN, unsigned int methodIDLen, unsigned int *methodID, char *tag, size_t putDataLen, void *putData)
static int berEncodePasswordData(struct berval **requestBV, const char *objectDN, const char *password, const char *password2)
static int getLoginConfig(LDAP *ld, char *objectDN, unsigned int methodIDLen, unsigned int *methodID, char *tag, size_t *dataLen, void *data)
#define NMASLDAP_GET_PASSWORD_REQUEST
#define DEBUG(level, args)
int nds_get_password(LDAP *ld, char *object_dn, size_t *pwd_len, char *pwd)
#define NMASLDAP_GET_PASSWORD_RESPONSE
static int nmasldap_get_password(LDAP *ld, char *objectDN, size_t *pwdSize, unsigned char *pwd)
#define NMASLDAP_GET_LOGIN_CONFIG_RESPONSE
#define NMAS_LDAP_EXT_VERSION
static int berDecodeLoginData(struct berval *replyBV, int *serverVersion, size_t *retDataLen, void *retData)
void ZeroSensitiveMemory(void *dst, const size_t len)