📄 pdb_nds.c
字号:
/* Unix SMB/CIFS mplementation. NDS LDAP helper functions for SAMBA 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 "includes.h"#include <lber.h>#include <ldap.h>#include <wchar.h>#include "smbldap.h"#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/********************************************************************** 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; 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; } 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; 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; } /* BER encode the NMAS Version and the objectDN */ err = (ber_printf(requestBer, "{io", NMAS_LDAP_EXT_VERSION, utf8ObjPtr, utf8ObjSize) < 0) ? LDAP_ENCODING_ERROR : 0; /* 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 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(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; 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(pwdBufLen); /* digest and null */ if(pwdBuf == NULL) { return LDAP_NO_MEMORY; } 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; } } } } if (pwdBuf != NULL) { memset(pwdBuf, 0, bufferLen); free(pwdBuf); } return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -