Hi, When trying to bind to ldapd using a dn which has an invalid userPassword entry, e.eg. a “defective” SHA valus like “{SHA}alpha”, ldapd currently returns 1 (Operations Error).
The patch below changes this to 49 (Invalid Credentials). There are basically two reasons for this: 1. The userPassword is a multi-valued attribute, i.e. there can be more than one in an ldap entry. Now when you have a valid and a defective entry and the binding user supplies a password which does not match the valid entry you get different results whether the defective entry comes last (return value 1) or not (return value 49). When the supplied password matches the valid entry the bind succeeds independent of order. A change to return value 49 gets consistent results. For a single userPassword entry 49 also is not wrong, as the supplied password still doesn't match the entry (even if it is defective). 2. RFC 4511 defines the result code “Operations Error” as follows: “operationsError (1) Indicates that the operation is not properly sequenced with relation to other operations (of same or different type). For example, this code is returned if the client attempts to StartTLS [RFC4346] while there are other uncompleted operations or if a TLS layer was already installed.” A defective password entry in no way is an operations error of the ldapd server. Also I don't think it is the server's job to take care of the correctness of password entries. There is no provision in the LDAP RFCs to stop one from entering an incorrect entry. I checked this with other directory servers: 389, apache ds, and openldap. All three accept incorrect entries and all three return 49 (Invalid Credentials) on bind attempts. Best regards Robert ----------------------------------------------- commit e9fe05bf15bf216ea7759cd64f17103008e1b69e (master) from: Robert Klein <rokl...@roklein.de> date: Sun Mar 1 15:49:40 2020 UTC ldapd: fix return values for illegal passwords diff 7a641edbd5c2c2686d4a80fd730967f00e58e681 f62b80b397c780e8273b5cc67d544b951c4c9d1f blob - f8debff7a2d6a0feb9cf984905de385b029b8744 blob + 094a8360e326ac7956c54a7dc8380df81c23efa5 --- usr.sbin/ldapd/auth.c +++ usr.sbin/ldapd/auth.c @@ -218,12 +218,12 @@ check_password(struct request *req, const char *stored int sz; if (stored_passwd == NULL) - return -1; + return 0; if (strncmp(stored_passwd, "{SHA}", 5) == 0) { sz = b64_pton(stored_passwd + 5, tmp, sizeof(tmp)); if (sz != SHA_DIGEST_LENGTH) - return (-1); + return (0); SHA1_Init(&ctx); SHA1_Update(&ctx, passwd, strlen(passwd)); SHA1_Final(md, &ctx); @@ -231,7 +231,7 @@ check_password(struct request *req, const char *stored } else if (strncmp(stored_passwd, "{SSHA}", 6) == 0) { sz = b64_pton(stored_passwd + 6, tmp, sizeof(tmp)); if (sz <= SHA_DIGEST_LENGTH) - return (-1); + return (0); salt = tmp + SHA_DIGEST_LENGTH; SHA1_Init(&ctx); SHA1_Update(&ctx, passwd, strlen(passwd)); @@ -241,11 +241,11 @@ check_password(struct request *req, const char *stored } else if (strncmp(stored_passwd, "{CRYPT}", 7) == 0) { encpw = crypt(passwd, stored_passwd + 7); if (encpw == NULL) - return (-1); + return (0); return (strcmp(encpw, stored_passwd + 7) == 0 ? 1 : 0); } else if (strncmp(stored_passwd, "{BSDAUTH}", 9) == 0) { if (send_auth_request(req, stored_passwd + 9, passwd) == -1) - return (-1); + return (0); return 2; /* Operation in progress. */ } else return (strcmp(stored_passwd, passwd) == 0 ? 1 : 0);