mech-ntlm.c revision 7bafda1813454621e03615e83d55bccfa7cc56bd
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina * NTLM and NTLMv2 authentication mechanism.
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina * Copyright (c) 2004 Andrey Panin <pazke@donpac.ru>
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina * This software is released under the MIT license.
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina /* requested: */
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina const unsigned char *challenge;
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina /* received: */
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březinastatic bool lm_verify_credentials(struct ntlm_auth_request *request,
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina const unsigned char *credentials, size_t size)
bbc34d5a6e84d6c337bd89a22d33e365eb466226Pavel Březina const unsigned char *client_response;
bbc34d5a6e84d6c337bd89a22d33e365eb466226Pavel Březina auth_request_log_error(&request->auth_request, "lm",
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech "invalid credentials length");
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech ntlmssp_buffer_length(request->response, lm_response);
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech client_response = ntlmssp_buffer_data(request->response, lm_response);
fd04b25eaa5cd105da4122854d8bc1e702760e60Jakub Hrozek auth_request_log_error(&request->auth_request, "ntlm",
b0e8c1802557645e2ff6a88c54c520b0f0ff9ebbPetr Cech "LM response length is too small");
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek ntlmssp_v1_response(credentials, request->challenge, lm_response);
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozek return memcmp(lm_response, client_response, LM_RESPONSE_SIZE) == 0;
4e5e846de22407f825fe3b4040d79606818a2419Jakub Hrozeklm_credentials_callback(enum passdb_result result,
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina if (lm_verify_credentials(request, credentials, size))
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březinantlm_verify_credentials(struct ntlm_auth_request *request,
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina const unsigned char *credentials, size_t size)
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina struct auth_request *auth_request = &request->auth_request;
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina const unsigned char *client_response;
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina ntlmssp_buffer_length(request->response, ntlm_response);
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech client_response = ntlmssp_buffer_data(request->response, ntlm_response);
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech /* try LM authentication unless NTLM2 was negotiated */
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina auth_request_log_error(&request->auth_request, "ntlm",
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina "invalid credentials length");
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina if (response_length > NTLMSSP_RESPONSE_SIZE) {
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina unsigned char ntlm_v2_response[NTLMSSP_V2_RESPONSE_SIZE];
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina const unsigned char *blob =
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina * Authentication target == NULL because we are acting
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina * as a standalone server, not as NT domain member.
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina return memcmp(ntlm_v2_response, client_response,
e87b2a6e94c1066b3044fe683825ff5b4f8716c2Pavel Březina unsigned char ntlm_response[NTLMSSP_RESPONSE_SIZE];
e87b2a6e94c1066b3044fe683825ff5b4f8716c2Pavel Březina const unsigned char *client_lm_response =
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina ntlmssp_buffer_data(request->response, lm_response);
360a4be4266d6a72be99dfd252623dc0527f5b84Pavel Březina ntlmssp2_response(credentials, request->challenge,
3a5ea81007bd38ce511c37f65cc45d4b6b95ec44Pavel Březina ntlmssp_v1_response(credentials, request->challenge,
3a5ea81007bd38ce511c37f65cc45d4b6b95ec44Pavel Březinantlm_credentials_callback(enum passdb_result result,
3a5ea81007bd38ce511c37f65cc45d4b6b95ec44Pavel Březina const unsigned char *credentials, size_t size,
e87b2a6e94c1066b3044fe683825ff5b4f8716c2Pavel Březina ret = ntlm_verify_credentials(request, credentials, size);
71965bb18407ff45ada9e47cb6def086e48663c6Pavel Březina /* NTLM credentials not found or didn't want to use them,
71965bb18407ff45ada9e47cb6def086e48663c6Pavel Březina try with LM credentials */
71965bb18407ff45ada9e47cb6def086e48663c6Pavel Březina auth_request_lookup_credentials(auth_request, "LANMAN",
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cechmech_ntlm_auth_continue(struct auth_request *auth_request,
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech if (!ntlmssp_check_request(ntlm_request, data_size, &error)) {
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech message = ntlmssp_create_challenge(request->pool, ntlm_request,
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech request->ntlm2_negotiated = flags & NTLMSSP_NEGOTIATE_NTLM2;
c4d4fe1603420fe8f3d256a3a446974699563ff3Petr Cech request->unicode_negotiated = flags & NTLMSSP_NEGOTIATE_UNICODE;
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina if (!ntlmssp_check_response(response, data_size, &error)) {
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina request->response = p_malloc(request->pool, data_size);
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina memcpy(request->response, response, data_size);
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina username = ntlmssp_t_str(request->response, user,
6c2e507bd1571f9c7e26c5c9d60753b29fb75578Jakub Hrozek if (!auth_request_set_username(auth_request, username, &error)) {
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina auth_request_lookup_credentials(auth_request, "NTLM",
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březinastatic struct auth_request *mech_ntlm_auth_new(void)
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina pool = pool_alloconly_create("ntlm_auth_request", 1024);
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina request = p_new(pool, struct ntlm_auth_request, 1);
3688374991afb34bbaf2b7843683fc13dd77879dPavel Březina .flags = MECH_SEC_DICTIONARY | MECH_SEC_ACTIVE,