--------------------- PatchSet 11853 Date: 2008/01/02 15:44:29 Author: hno Branch: SQUID_2_7 Tag: (none) Log: MFC: License cleanup to comply with GPLv2 or later. Replaced edir_ldapext.c with a cut down copy of pdb_nds.c from Samba about 3.0.24 or so (CVS copy, just before Samba changed license to GPLv3) Members: helpers/digest_auth/eDirectory/edir_ldapext.c:1.3->1.3.2.1 helpers/digest_auth/eDirectory/edir_ldapext.h:1.3->1.3.2.1 helpers/digest_auth/eDirectory/ldap_backend.c:1.3->1.3.2.1 Index: squid/helpers/digest_auth/eDirectory/edir_ldapext.c =================================================================== RCS file: /cvsroot/squid/squid/helpers/digest_auth/eDirectory/edir_ldapext.c,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- squid/helpers/digest_auth/eDirectory/edir_ldapext.c 13 Aug 2007 09:20:13 -0000 1.3 +++ squid/helpers/digest_auth/eDirectory/edir_ldapext.c 2 Jan 2008 15:44:29 -0000 1.3.2.1 @@ -1,27 +1,31 @@ /* - * Copyright (C) 2002-2004 Novell, Inc. + * NDS LDAP helper functions + * Copied From Samba-3.0.24 pdb_nds.c and trimmed down to the + * limited functionality needed to access the plain text password only * - * edir_ldapext.c LDAP extension for reading eDirectory universal password - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, contact Novell, Inc. + * Original copyright & license follows: * - * To contact Novell about this file by physical or electronic mail, you may - * find current contact information at www.novell.com. - */ + * Copyright (C) Vince Brimhall 2004-2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * +*/ #include "digest_common.h" -#ifdef _SQUID_MSWIN_ /* Native Windows port and MinGW */ +#ifdef _SQUID_MSWIN_ /* Native Windows port and MinGW */ #define snprintf _snprintf #include @@ -43,282 +47,591 @@ #include #endif +#include #include "edir_ldapext.h" -/* NMAS error codes */ -#define NMAS_E_BASE (-1600) +#define NMASLDAP_GET_LOGIN_CONFIG_REQUEST "2.16.840.1.113719.1.39.42.100.3" +#define NMASLDAP_GET_LOGIN_CONFIG_RESPONSE "2.16.840.1.113719.1.39.42.100.4" +#define NMASLDAP_SET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.11" +#define NMASLDAP_SET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.12" +#define NMASLDAP_GET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.13" +#define NMASLDAP_GET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.14" + +#define NMAS_LDAP_EXT_VERSION 1 + +#define SMB_MALLOC_ARRAY(type, nelem) calloc(sizeof(type), nelem) +#define DEBUG(level, args) + +/********************************************************************** + Take the request BER value and input data items and BER encodes the + data into the BER value +**********************************************************************/ + +static int berEncodePasswordData( + struct berval **requestBV, + const char *objectDN, + const char *password, + const char *password2) +{ + int err = 0, rc=0; + BerElement *requestBer = NULL; -#define NMAS_SUCCESS 0 -#define NMAS_E_SUCCESS NMAS_SUCCESS /* Alias */ -#define NMAS_OK NMAS_SUCCESS /* Alias */ - -#define NMAS_E_FRAG_FAILURE (NMAS_E_BASE-31) /* -1631 0xFFFFF9A1 */ -#define NMAS_E_BUFFER_OVERFLOW (NMAS_E_BASE-33) /* -1633 0xFFFFF99F */ -#define NMAS_E_SYSTEM_RESOURCES (NMAS_E_BASE-34) /* -1634 0xFFFFF99E */ -#define NMAS_E_INSUFFICIENT_MEMORY (NMAS_E_BASE-35) /* -1635 0xFFFFF99D */ -#define NMAS_E_NOT_SUPPORTED (NMAS_E_BASE-36) /* -1636 0xFFFFF99C */ -#define NMAS_E_INVALID_PARAMETER (NMAS_E_BASE-43) /* -1643 0xFFFFF995 */ -#define NMAS_E_INVALID_VERSION (NMAS_E_BASE-52) /* -1652 0xFFFFF98C */ - -/* OID of LDAP extenstion calls to read Universal Password */ -#define NMASLDAP_GET_PASSWORD_REQUEST "2.16.840.1.113719.1.39.42.100.13" -#define NMASLDAP_GET_PASSWORD_RESPONSE "2.16.840.1.113719.1.39.42.100.14" - -#define NMAS_LDAP_EXT_VERSION 1 + const char * utf8ObjPtr = NULL; + int utf8ObjSize = 0; + const char * utf8PwdPtr = NULL; + int utf8PwdSize = 0; + const char * utf8Pwd2Ptr = NULL; + int utf8Pwd2Size = 0; + + + /* Convert objectDN and tag strings from Unicode to UTF-8 */ + utf8ObjSize = strlen(objectDN)+1; + utf8ObjPtr = objectDN; + + if (password != NULL) + { + utf8PwdSize = strlen(password)+1; + utf8PwdPtr = password; + } + if (password2 != NULL) + { + utf8Pwd2Size = strlen(password2)+1; + utf8Pwd2Ptr = password2; + } + /* Allocate a BerElement for the request parameters. */ + if((requestBer = ber_alloc()) == NULL) + { + err = LDAP_ENCODING_ERROR; + goto Cleanup; + } -/* ------------------------------------------------------------------------ - * berEncodePasswordData - * ============================== - * RequestBer contents: - * clientVersion INTEGER - * targetObjectDN OCTET STRING - * password1 OCTET STRING - * password2 OCTET STRING - * - * Description: - * This function takes the request BER value and input data items - * and BER encodes the data into the BER value - * - * ------------------------------------------------------------------------ */ -int -berEncodePasswordData( - struct berval **requestBV, - char *objectDN, - char *password, - char *password2) + if (password != NULL && password2 != NULL) + { + /* BER encode the NMAS Version, the objectDN, and the password */ + rc = ber_printf(requestBer, "{iooo}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize, utf8Pwd2Ptr, utf8Pwd2Size); + } + else if (password != NULL) + { + /* BER encode the NMAS Version, the objectDN, and the password */ + rc = ber_printf(requestBer, "{ioo}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize); + } + else + { + /* BER encode the NMAS Version and the objectDN */ + rc = ber_printf(requestBer, "{io}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize); + } + + if (rc < 0) + { + err = LDAP_ENCODING_ERROR; + goto Cleanup; + } + else + { + err = 0; + } + + /* Convert the BER we just built to a berval that we'll send with the extended request. */ + if(ber_flatten(requestBer, requestBV) == LBER_ERROR) + { + err = LDAP_ENCODING_ERROR; + goto Cleanup; + } + +Cleanup: + + if(requestBer) + { + ber_free(requestBer, 1); + } + + return err; +} + +/********************************************************************** + Take the request BER value and input data items and BER encodes the + data into the BER value +**********************************************************************/ + +static int berEncodeLoginData( + struct berval **requestBV, + char *objectDN, + unsigned int methodIDLen, + unsigned int *methodID, + char *tag, + size_t putDataLen, + void *putData) { - int err = 0, rc = 0; - BerElement *requestBer = NULL; + int err = 0; + BerElement *requestBer = NULL; + + unsigned int i; + unsigned int elemCnt = methodIDLen / sizeof(unsigned int); + + char *utf8ObjPtr=NULL; + int utf8ObjSize = 0; + + char *utf8TagPtr = NULL; + int utf8TagSize = 0; + + utf8ObjPtr = objectDN; + utf8ObjSize = strlen(utf8ObjPtr)+1; + + utf8TagPtr = tag; + utf8TagSize = strlen(utf8TagPtr)+1; + + /* Allocate a BerElement for the request parameters. */ + if((requestBer = ber_alloc()) == NULL) + { + err = LDAP_ENCODING_ERROR; + goto Cleanup; + } - char *utf8ObjPtr = NULL; - int utf8ObjSize = 0; - char *utf8PwdPtr = NULL; - int utf8PwdSize = 0; - char *utf8Pwd2Ptr = NULL; - int utf8Pwd2Size = 0; - - - utf8ObjSize = strlen(objectDN) + 1; - utf8ObjPtr = objectDN; - - if (password != NULL) { - utf8PwdSize = strlen(password) + 1; - utf8PwdPtr = password; - } - if (password2 != NULL) { - utf8Pwd2Size = strlen(password2) + 1; - utf8Pwd2Ptr = password2; - } - /* Allocate a BerElement for the request parameters. */ - if ((requestBer = ber_alloc()) == NULL) { - err = NMAS_E_FRAG_FAILURE; - goto Cleanup; - } - if (password != NULL && password2 != NULL) { - /* BER encode the NMAS Version, the objectDN, and the password */ - rc = ber_printf(requestBer, "{iooo}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize, utf8Pwd2Ptr, utf8Pwd2Size); - } else if (password != NULL) { - /* BER encode the NMAS Version, the objectDN, and the password */ - rc = ber_printf(requestBer, "{ioo}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize, utf8PwdPtr, utf8PwdSize); - } else { /* BER encode the NMAS Version and the objectDN */ - rc = ber_printf(requestBer, "{io}", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize); - } + err = (ber_printf(requestBer, "{io", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize) < 0) ? LDAP_ENCODING_ERROR : 0; - if (rc < 0) { - err = NMAS_E_FRAG_FAILURE; - goto Cleanup; - } else { - err = 0; - } - - /* - * Convert the BER we just built to a berval that we'll send with the extended request. - */ - if (ber_flatten(requestBer, requestBV) == LBER_ERROR) { - err = NMAS_E_FRAG_FAILURE; - goto Cleanup; - } - Cleanup: - - if (requestBer) { - ber_free(requestBer, 1); - } - return err; -} /* End of berEncodePasswordData */ - -/* ------------------------------------------------------------------------ - * berDecodeLoginData() - * ============================== - * ResponseBer contents: - * serverVersion INTEGER - * error INTEGER - * data OCTET STRING - * - * Description: - * This function takes the reply BER Value and decodes the - * NMAS server version and return code and if a non null retData - * buffer was supplied, tries to decode the the return data and length - * - * ------------------------------------------------------------------------ */ -int -berDecodeLoginData( - struct berval *replyBV, - int *serverVersion, - size_t * retDataLen, - void *retData) + /* BER encode the MethodID Length and value */ + if (!err) + { + err = (ber_printf(requestBer, "{i{", methodIDLen) < 0) ? LDAP_ENCODING_ERROR : 0; + } + + for (i = 0; !err && i < elemCnt; i++) + { + err = (ber_printf(requestBer, "i", methodID[i]) < 0) ? LDAP_ENCODING_ERROR : 0; + } + + if (!err) + { + err = (ber_printf(requestBer, "}}", 0) < 0) ? LDAP_ENCODING_ERROR : 0; + } + + if(putData) + { + /* BER Encode the the tag and data */ + err = (ber_printf(requestBer, "oio}", utf8TagPtr, utf8TagSize, putDataLen, putData, putDataLen) < 0) ? LDAP_ENCODING_ERROR : 0; + } + else + { + /* BER Encode the the tag */ + err = (ber_printf(requestBer, "o}", utf8TagPtr, utf8TagSize) < 0) ? LDAP_ENCODING_ERROR : 0; + } + + if (err) + { + goto Cleanup; + } + + /* Convert the BER we just built to a berval that we'll send with the extended request. */ + if(ber_flatten(requestBer, requestBV) == LBER_ERROR) + { + err = LDAP_ENCODING_ERROR; + goto Cleanup; + } + +Cleanup: + + if(requestBer) + { + ber_free(requestBer, 1); + } + + return err; +} + +/********************************************************************** + Takes the reply BER Value and decodes the NMAS server version and + return code and if a non null retData buffer was supplied, tries to + decode the the return data and length +**********************************************************************/ + +static int berDecodeLoginData( + struct berval *replyBV, + int *serverVersion, + size_t *retDataLen, + void *retData ) { - int rc = 0, err = 0; - BerElement *replyBer = NULL; - char *retOctStr = NULL; - size_t retOctStrLen = 0; - - if ((replyBer = ber_init(replyBV)) == NULL) { - err = NMAS_E_SYSTEM_RESOURCES; - goto Cleanup; - } - if (retData) { - retOctStrLen = *retDataLen + 1; - retOctStr = (char *) malloc(retOctStrLen); - if (!retOctStr) { - err = NMAS_E_SYSTEM_RESOURCES; - goto Cleanup; - } - if ((rc = ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen)) != -1) { - if (*retDataLen >= retOctStrLen) { - memcpy(retData, retOctStr, retOctStrLen); - } else if (!err) { - err = NMAS_E_BUFFER_OVERFLOW; - } - *retDataLen = retOctStrLen; - } else if (!err) { - err = NMAS_E_FRAG_FAILURE; - } - } else { - if ((rc = ber_scanf(replyBer, "{ii}", serverVersion, &err)) == -1) { - if (!err) { - err = NMAS_E_FRAG_FAILURE; - } - } - } - - Cleanup: - - if (replyBer) { - ber_free(replyBer, 1); - } - if (retOctStr != NULL) { - memset(retOctStr, 0, retOctStrLen); - free(retOctStr); - } - return err; -} /* End of berDecodeLoginData */ - -/* ----------------------------------------------------------------------- - * nmasldap_get_password() - * ============================== - * - * Description: - * This API attempts to get the universal password - * - * ------------------------------------------------------------------------ */ -int -nmasldap_get_password( - LDAP * ld, - char *objectDN, - size_t * pwdSize, // in bytes - char *pwd) + int err = 0; + BerElement *replyBer = NULL; + char *retOctStr = NULL; + size_t retOctStrLen = 0; + + if((replyBer = ber_init(replyBV)) == NULL) + { + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + + if(retData) + { + retOctStrLen = *retDataLen + 1; + retOctStr = SMB_MALLOC_ARRAY(char, retOctStrLen); + if(!retOctStr) + { + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + + if(ber_scanf(replyBer, "{iis}", serverVersion, &err, retOctStr, &retOctStrLen) != -1) + { + if (*retDataLen >= retOctStrLen) + { + memcpy(retData, retOctStr, retOctStrLen); + } + else if (!err) + { + err = LDAP_NO_MEMORY; + } + + *retDataLen = retOctStrLen; + } + else if (!err) + { + err = LDAP_DECODING_ERROR; + } + } + else + { + if(ber_scanf(replyBer, "{ii}", serverVersion, &err) == -1) + { + if (!err) + { + err = LDAP_DECODING_ERROR; + } + } + } + +Cleanup: + + if(replyBer) + { + ber_free(replyBer, 1); + } + + if (retOctStr != NULL) + { + memset(retOctStr, 0, retOctStrLen); + free(retOctStr); + } + + return err; +} + +/********************************************************************** + Retrieves data in the login configuration of the specified object + that is tagged with the specified methodID and tag. +**********************************************************************/ + +static int getLoginConfig( + LDAP *ld, + char *objectDN, + unsigned int methodIDLen, + unsigned int *methodID, + char *tag, + size_t *dataLen, + void *data ) +{ + int err = 0; + struct berval *requestBV = NULL; + char *replyOID = NULL; + struct berval *replyBV = NULL; + int serverVersion = 0; + + /* Validate unicode parameters. */ + if((strlen(objectDN) == 0) || ld == NULL) + { + return LDAP_NO_SUCH_ATTRIBUTE; + } + + err = berEncodeLoginData(&requestBV, objectDN, methodIDLen, methodID, tag, 0, NULL); + if(err) + { + goto Cleanup; + } + + /* Call the ldap_extended_operation (synchronously) */ + if((err = ldap_extended_operation_s(ld, NMASLDAP_GET_LOGIN_CONFIG_REQUEST, + requestBV, NULL, NULL, &replyOID, &replyBV))) + { + goto Cleanup; + } + + /* Make sure there is a return OID */ + if(!replyOID) + { + err = LDAP_NOT_SUPPORTED; + goto Cleanup; + } + + /* Is this what we were expecting to get back. */ + if(strcmp(replyOID, NMASLDAP_GET_LOGIN_CONFIG_RESPONSE)) + { + err = LDAP_NOT_SUPPORTED; + goto Cleanup; + } + + /* Do we have a good returned berval? */ + if(!replyBV) + { + /* No; returned berval means we experienced a rather drastic error. */ + /* Return operations error. */ + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + + err = berDecodeLoginData(replyBV, &serverVersion, dataLen, data); + + if(serverVersion != NMAS_LDAP_EXT_VERSION) + { + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + +Cleanup: + + if(replyBV) + { + ber_bvfree(replyBV); + } + + /* Free the return OID string if one was returned. */ + if(replyOID) + { + ldap_memfree(replyOID); + } + + /* Free memory allocated while building the request ber and berval. */ + if(requestBV) + { + ber_bvfree(requestBV); + } + + /* Return the appropriate error/success code. */ + return err; +} + +/********************************************************************** + Attempts to get the Simple Password +**********************************************************************/ + +static int nmasldap_get_simple_pwd( + LDAP *ld, + char *objectDN, + size_t pwdLen, + char *pwd ) { - int err = 0; + int err = 0; + unsigned int methodID = 0; + unsigned int methodIDLen = sizeof(methodID); + char tag[] = {'P','A','S','S','W','O','R','D',' ','H','A','S','H',0}; + char *pwdBuf=NULL; + size_t pwdBufLen, bufferLen; + + bufferLen = pwdBufLen = pwdLen+2; + pwdBuf = SMB_MALLOC_ARRAY(char, pwdBufLen); /* digest and null */ + if(pwdBuf == NULL) + { + return LDAP_NO_MEMORY; + } - struct berval *requestBV = NULL; - char *replyOID = NULL; - struct berval *replyBV = NULL; - int serverVersion; - char *pwdBuf; - size_t pwdBufLen, bufferLen; + err = getLoginConfig(ld, objectDN, methodIDLen, &methodID, tag, &pwdBufLen, pwdBuf); + if (err == 0) + { + if (pwdBufLen !=0) + { + pwdBuf[pwdBufLen] = 0; /* null terminate */ + + switch (pwdBuf[0]) + { + case 1: /* cleartext password */ + break; + case 2: /* SHA1 HASH */ + case 3: /* MD5_ID */ + case 4: /* UNIXCrypt_ID */ + case 8: /* SSHA_ID */ + default: /* Unknown digest */ + err = LDAP_INAPPROPRIATE_AUTH; /* only return clear text */ + break; + } + + if (!err) + { + if (pwdLen >= pwdBufLen-1) + { + memcpy(pwd, &pwdBuf[1], pwdBufLen-1); /* skip digest tag and include null */ + } + else + { + err = LDAP_NO_MEMORY; + } + } + } + } -#ifdef NOT_N_PLAT_NLM - int currentThreadGroupID; -#endif + if (pwdBuf != NULL) + { + memset(pwdBuf, 0, bufferLen); + free(pwdBuf); + } - /* Validate char parameters. */ - if (objectDN == NULL || (strlen(objectDN) == 0) || pwdSize == NULL || ld == NULL) { - return NMAS_E_INVALID_PARAMETER; - } - bufferLen = pwdBufLen = *pwdSize; - pwdBuf = (char *) malloc(pwdBufLen + 2); - if (pwdBuf == NULL) { - return NMAS_E_INSUFFICIENT_MEMORY; - } -#ifdef NOT_N_PLAT_NLM - currentThreadGroupID = SetThreadGroupID(nmasLDAPThreadGroupID); -#endif + return err; +} - err = berEncodePasswordData(&requestBV, objectDN, NULL, NULL); - if (err) { - goto Cleanup; - } - /* Call the ldap_extended_operation (synchronously) */ - if ((err = ldap_extended_operation_s(ld, NMASLDAP_GET_PASSWORD_REQUEST, requestBV, NULL, NULL, &replyOID, &replyBV))) { - goto Cleanup; - } - /* Make sure there is a return OID */ - if (!replyOID) { - err = NMAS_E_NOT_SUPPORTED; - goto Cleanup; - } - /* Is this what we were expecting to get back. */ - if (strcmp(replyOID, NMASLDAP_GET_PASSWORD_RESPONSE)) { - err = NMAS_E_NOT_SUPPORTED; - goto Cleanup; - } - /* Do we have a good returned berval? */ - if (!replyBV) { - /* - * No; returned berval means we experienced a rather drastic error. - * Return operations error. - */ - err = NMAS_E_SYSTEM_RESOURCES; - goto Cleanup; - } - err = berDecodeLoginData(replyBV, &serverVersion, &pwdBufLen, pwdBuf); - - if (serverVersion != NMAS_LDAP_EXT_VERSION) { - err = NMAS_E_INVALID_VERSION; - goto Cleanup; - } - if (!err && pwdBufLen != 0) { - if (*pwdSize >= pwdBufLen + 1 && pwd != NULL) { - memcpy(pwd, pwdBuf, pwdBufLen); - pwd[pwdBufLen] = 0; /* add null termination */ - } - *pwdSize = pwdBufLen; /* does not include null termination */ - } - Cleanup: - - if (replyBV) { - ber_bvfree(replyBV); - } - /* Free the return OID string if one was returned. */ - if (replyOID) { - ldap_memfree(replyOID); - } - /* Free memory allocated while building the request ber and berval. */ - if (requestBV) { - ber_bvfree(requestBV); - } - if (pwdBuf != NULL) { - memset(pwdBuf, 0, bufferLen); - free(pwdBuf); - } -#ifdef NOT_N_PLAT_NLM - SetThreadGroupID(currentThreadGroupID); -#endif - /* Return the appropriate error/success code. */ - return err; -} /* end of nmasldap_get_password */ +/********************************************************************** + Attempts to get the Universal Password +**********************************************************************/ + +static int nmasldap_get_password( + LDAP *ld, + char *objectDN, + size_t *pwdSize, /* in bytes */ + unsigned char *pwd ) +{ + int err = 0; + + struct berval *requestBV = NULL; + char *replyOID = NULL; + struct berval *replyBV = NULL; + int serverVersion; + char *pwdBuf; + size_t pwdBufLen, bufferLen; + + /* Validate char parameters. */ + if(objectDN == NULL || (strlen(objectDN) == 0) || pwdSize == NULL || ld == NULL) + { + return LDAP_NO_SUCH_ATTRIBUTE; + } + + bufferLen = pwdBufLen = *pwdSize; + pwdBuf = SMB_MALLOC_ARRAY(char, pwdBufLen+2); + if(pwdBuf == NULL) + { + return LDAP_NO_MEMORY; + } + + err = berEncodePasswordData(&requestBV, objectDN, NULL, NULL); + if(err) + { + goto Cleanup; + } + + /* Call the ldap_extended_operation (synchronously) */ + if((err = ldap_extended_operation_s(ld, NMASLDAP_GET_PASSWORD_REQUEST, requestBV, NULL, NULL, &replyOID, &replyBV))) + { + goto Cleanup; + } + + /* Make sure there is a return OID */ + if(!replyOID) + { + err = LDAP_NOT_SUPPORTED; + goto Cleanup; + } + + /* Is this what we were expecting to get back. */ + if(strcmp(replyOID, NMASLDAP_GET_PASSWORD_RESPONSE)) + { + err = LDAP_NOT_SUPPORTED; + goto Cleanup; + } + + /* Do we have a good returned berval? */ + if(!replyBV) + { + /* No; returned berval means we experienced a rather drastic error. */ + /* Return operations error. */ + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + + err = berDecodeLoginData(replyBV, &serverVersion, &pwdBufLen, pwdBuf); + + if(serverVersion != NMAS_LDAP_EXT_VERSION) + { + err = LDAP_OPERATIONS_ERROR; + goto Cleanup; + } + + if (!err && pwdBufLen != 0) + { + if (*pwdSize >= pwdBufLen+1 && pwd != NULL) + { + memcpy(pwd, pwdBuf, pwdBufLen); + pwd[pwdBufLen] = 0; /* add null termination */ + } + *pwdSize = pwdBufLen; /* does not include null termination */ + } + +Cleanup: + + if(replyBV) + { + ber_bvfree(replyBV); + } + + /* Free the return OID string if one was returned. */ + if(replyOID) + { + ldap_memfree(replyOID); + } + + /* Free memory allocated while building the request ber and berval. */ + if(requestBV) + { + ber_bvfree(requestBV); + } + + if (pwdBuf != NULL) + { + memset(pwdBuf, 0, bufferLen); + free(pwdBuf); + } + + /* Return the appropriate error/success code. */ + return err; +} + +/********************************************************************** + Get the user's password from NDS. + *********************************************************************/ + +int nds_get_password( + LDAP *ld, + char *object_dn, + size_t *pwd_len, + char *pwd ) +{ + int rc = -1; + + rc = nmasldap_get_password(ld, object_dn, pwd_len, (unsigned char *)pwd); + if (rc == LDAP_SUCCESS) { +#ifdef DEBUG_PASSWORD + DEBUG(100,("nmasldap_get_password returned %s for %s\n", pwd, object_dn)); +#endif + DEBUG(5, ("NDS Universal Password retrieved for %s\n", object_dn)); + } else { + DEBUG(3, ("NDS Universal Password NOT retrieved for %s\n", object_dn)); + } + + if (rc != LDAP_SUCCESS) { + rc = nmasldap_get_simple_pwd(ld, object_dn, *pwd_len, pwd); + if (rc == LDAP_SUCCESS) { +#ifdef DEBUG_PASSWORD + DEBUG(100,("nmasldap_get_simple_pwd returned %s for %s\n", pwd, object_dn)); +#endif + DEBUG(5, ("NDS Simple Password retrieved for %s\n", object_dn)); + } else { + /* We couldn't get the password */ + DEBUG(3, ("NDS Simple Password NOT retrieved for %s\n", object_dn)); + return LDAP_INVALID_CREDENTIALS; + } + } + + /* We got the password */ + return LDAP_SUCCESS; +} + Index: squid/helpers/digest_auth/eDirectory/edir_ldapext.h =================================================================== RCS file: /cvsroot/squid/squid/helpers/digest_auth/eDirectory/edir_ldapext.h,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- squid/helpers/digest_auth/eDirectory/edir_ldapext.h 13 Aug 2007 09:20:13 -0000 1.3 +++ squid/helpers/digest_auth/eDirectory/edir_ldapext.h 2 Jan 2008 15:44:29 -0000 1.3.2.1 @@ -1,14 +1 @@ -/* - * edir_ldapext.h - * - * AUTHOR: Guy Antony Halse - * - * stubs for FreeRadius's edir_ldapext.h - * - */ -#define UNIVERSAL_PASS_LEN 256 -#define NMAS_SUCCESS 0 - -extern int berEncodePasswordData(struct berval **requestBV, char *objectDN, char *password, char *password2); -extern int berDecodeLoginData(struct berval *replyBV, int *serverVersion, size_t * retDataLen, void *retData); -extern int nmasldap_get_password(LDAP * ld, char *objectDN, size_t * pwdSize, char *pwd); +int nds_get_password(LDAP *ld, char *object_dn, size_t * pwd_len, char *pwd); Index: squid/helpers/digest_auth/eDirectory/ldap_backend.c =================================================================== RCS file: /cvsroot/squid/squid/helpers/digest_auth/eDirectory/ldap_backend.c,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- squid/helpers/digest_auth/eDirectory/ldap_backend.c 13 Aug 2007 09:20:13 -0000 1.3 +++ squid/helpers/digest_auth/eDirectory/ldap_backend.c 2 Jan 2008 15:44:29 -0000 1.3.2.1 @@ -49,14 +49,14 @@ /* Globals */ static LDAP *ld = NULL; -static char *passattr = NULL; +static const char *passattr = NULL; static char *ldapServer = NULL; -static char *userbasedn = NULL; -static char *userdnattr = NULL; -static char *usersearchfilter = NULL; -static char *binddn = NULL; -static char *bindpasswd = NULL; -static char *delimiter = ":"; +static const char *userbasedn = NULL; +static const char *userdnattr = NULL; +static const char *usersearchfilter = NULL; +static const char *binddn = NULL; +static const char *bindpasswd = NULL; +static const char *delimiter = ":"; static int encrpass = 0; static int searchscope = LDAP_SCOPE_SUBTREE; static int persistent = 0; @@ -80,7 +80,7 @@ #endif static void ldapconnect(void); -static int readSecret(char *filename); +static int readSecret(const char *filename); /* Yuck.. we need to glue to different versions of the API */ @@ -198,7 +198,7 @@ char filter[8192]; char searchbase[8192]; char *universal_password = NULL; - size_t universal_password_len = UNIVERSAL_PASS_LEN; + size_t universal_password_len = 256; int nmas_res = 0; int rc = -1; if (ld) { @@ -262,8 +262,8 @@ values = malloc(sizeof(char *)); /* actually talk to NMAS to get a password */ - nmas_res = nmasldap_get_password(ld, ldap_get_dn(ld, entry), &universal_password_len, universal_password); - if (nmas_res == NMAS_SUCCESS && universal_password) { + nmas_res = nds_get_password(ld, ldap_get_dn(ld, entry), &universal_password_len, universal_password); + if (nmas_res == LDAP_SUCCESS && universal_password) { if (debug) printf("NMAS returned value %s\n", universal_password); values[0] = universal_password; @@ -427,7 +427,7 @@ setbuf(stdout, NULL); while (argc > 1 && argv[1][0] == '-') { - char *value = ""; + const char *value = ""; char option = argv[1][1]; switch (option) { case 'P': @@ -604,7 +604,7 @@ } if (!ldapServer) - ldapServer = "localhost"; + ldapServer = (char *) "localhost"; if (!userbasedn || !((passattr != NULL) || (edir_universal_passwd && usersearchfilter && version == LDAP_VERSION3 && use_tls))) { fprintf(stderr, "Usage: " PROGRAM_NAME " -b basedn -f filter [options] ldap_server_name\n\n"); @@ -644,7 +644,7 @@ return 0; } static int -readSecret(char *filename) +readSecret(const char *filename) { char buf[BUFSIZ]; char *e = 0; @@ -665,13 +665,10 @@ if ((e = strrchr(buf, '\r'))) *e = 0; - bindpasswd = (char *) calloc(sizeof(char), strlen(buf) + 1); - if (bindpasswd) { - strcpy(bindpasswd, buf); - } else { + bindpasswd = strdup(buf); + if (!bindpasswd) { fprintf(stderr, PROGRAM_NAME " ERROR: can not allocate memory\n"); } - fclose(f); return 0; @@ -680,7 +677,7 @@ void LDAPHHA1(RequestData * requestData) { - char *password = ""; + char *password; ldapconnect(); password = getpassword(requestData->user, requestData->realm); if (password != NULL) {