⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opendir.c

📁 使用最广泛的radius的linux的源码
💻 C
字号:
#ifdef __APPLE__/* * Open Directory support from Apple Inc. * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License version 2 only, 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 version 2 *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2007 Apple Inc. */#include	<freeradius-devel/ident.h>RCSID("$Id: opendir.c,v 1.8 2007/10/12 16:08:15 aland Exp $")#include	<freeradius-devel/radiusd.h>#include	<freeradius-devel/modules.h>#include	<freeradius-devel/rad_assert.h>#include        <freeradius-devel/md5.h>#include 	<ctype.h>#include	"smbdes.h"#include <DirectoryService/DirectoryService.h>static int getUserNodeRef(char* inUserName, char **outUserName,			  tDirNodeReference* userNodeRef, tDirReference dsRef){	tDataBuffer		*tDataBuff	= NULL;	tDirNodeReference	nodeRef		= 0;	long			status		= eDSNoErr;	tContextData		context		= NULL;	unsigned long		nodeCount	= 0;	unsigned long		attrIndex	= 0;	tDataList		*nodeName	= NULL;	tAttributeEntryPtr	pAttrEntry	= NULL;	tDataList		*pRecName	= NULL;	tDataList		*pRecType	= NULL;	tDataList		*pAttrType	= NULL;	unsigned long		recCount	= 0;	tRecordEntry		*pRecEntry	= NULL;	tAttributeListRef	attrListRef	= 0;	char			*pUserLocation	= NULL;	tAttributeValueListRef	valueRef	= 0;	tAttributeValueEntry	*pValueEntry	= NULL;	tDataList		*pUserNode	= NULL;	int			result		= RLM_MODULE_FAIL;		if (inUserName == NULL) {		radlog(L_ERR, "rlm_mschap: getUserNodeRef(): no username");		return RLM_MODULE_FAIL;	}    	tDataBuff = dsDataBufferAllocate(dsRef, 4096);	if (tDataBuff == NULL) {		radlog(L_ERR, "rlm_mschap: getUserNodeRef(): dsDataBufferAllocate() status = %ld", status);  		return RLM_MODULE_FAIL;	}		do {		/* find on search node */		status = dsFindDirNodes(dsRef, tDataBuff, NULL,					eDSAuthenticationSearchNodeName,					&nodeCount, &context);		if (status != eDSNoErr) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): no node found? status = %ld", status);  			result = RLM_MODULE_FAIL;			break;		}		if (nodeCount < 1) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): nodeCount < 1, status = %ld", status);  			result = RLM_MODULE_FAIL;			break;		}				status = dsGetDirNodeName(dsRef, tDataBuff, 1, &nodeName);		if (status != eDSNoErr) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsGetDirNodeName() status = %ld", status);  			result = RLM_MODULE_FAIL;			break;		}				status = dsOpenDirNode(dsRef, nodeName, &nodeRef);		dsDataListDeallocate(dsRef, nodeName);		free(nodeName);		nodeName = NULL;				if (status != eDSNoErr) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsOpenDirNode() status = %ld", status);  			result = RLM_MODULE_FAIL;			break;		}				pRecName = dsBuildListFromStrings(dsRef, inUserName, NULL);		pRecType = dsBuildListFromStrings(dsRef, kDSStdRecordTypeUsers,						  NULL);		pAttrType = dsBuildListFromStrings(dsRef,						   kDSNAttrMetaNodeLocation,						   kDSNAttrRecordName, NULL);				recCount = 1;		status = dsGetRecordList(nodeRef, tDataBuff, pRecName,					 eDSExact, pRecType, pAttrType, 0,					 &recCount, &context);		if (status != eDSNoErr || recCount == 0) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsGetRecordList() status = %ld, recCount=%lu", status, recCount);  			result = RLM_MODULE_FAIL;			break;		}				status = dsGetRecordEntry(nodeRef, tDataBuff, 1,					  &attrListRef, &pRecEntry);		if (status != eDSNoErr) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsGetRecordEntry() status = %ld", status);  			result = RLM_MODULE_FAIL;			break;			}				for (attrIndex = 1; (attrIndex <= pRecEntry->fRecordAttributeCount) && (status == eDSNoErr); attrIndex++) {			status = dsGetAttributeEntry(nodeRef, tDataBuff, attrListRef, attrIndex, &valueRef, &pAttrEntry);			if (status == eDSNoErr && pAttrEntry != NULL) {				if (strcmp(pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrMetaNodeLocation) == 0) {					status = dsGetAttributeValue(nodeRef, tDataBuff, 1, valueRef, &pValueEntry);					if (status == eDSNoErr && pValueEntry != NULL) {						pUserLocation = (char *) calloc(pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char));						memcpy(pUserLocation, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength);					}				} else if (strcmp(pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrRecordName) == 0) {					status = dsGetAttributeValue(nodeRef, tDataBuff, 1, valueRef, &pValueEntry);					if (status == eDSNoErr && pValueEntry != NULL) {						*outUserName = (char *) malloc(pValueEntry->fAttributeValueData.fBufferLength + 1);						bzero(*outUserName,pValueEntry->fAttributeValueData.fBufferLength + 1);						memcpy(*outUserName, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength);					}				}								if (pValueEntry != NULL) {					dsDeallocAttributeValueEntry(dsRef, pValueEntry);					pValueEntry = NULL;				}								dsDeallocAttributeEntry(dsRef, pAttrEntry);				pAttrEntry = NULL;				dsCloseAttributeValueList(valueRef);				valueRef = 0;			}		}				pUserNode = dsBuildFromPath(dsRef, pUserLocation, "/");		if (pUserNode == NULL) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsBuildFromPath() returned NULL");  			result = RLM_MODULE_FAIL;			break;		}				status = dsOpenDirNode(dsRef, pUserNode, userNodeRef);		dsDataListDeallocate(dsRef, pUserNode);		free(pUserNode);		if (status != eDSNoErr) {			radlog(L_ERR,"rlm_mschap: getUserNodeRef(): dsOpenDirNode() status = %ld", status);  			result = RLM_MODULE_FAIL;			break;		}				result = RLM_MODULE_OK;	}	while (0);		if (pRecEntry != NULL)		dsDeallocRecordEntry(dsRef, pRecEntry);	if (tDataBuff != NULL)		dsDataBufferDeAllocate(dsRef, tDataBuff);			if (pUserLocation != NULL)		free(pUserLocation);			if (pRecName != NULL) {		dsDataListDeallocate(dsRef, pRecName);		free(pRecName);	}	if (pRecType != NULL) {		dsDataListDeallocate(dsRef, pRecType);		free(pRecType);	}	if (pAttrType != NULL) {		dsDataListDeallocate(dsRef, pAttrType);		free(pAttrType);	}	if (nodeRef != 0)		dsCloseDirNode(nodeRef);		return  result;}int od_mschap_auth(REQUEST *request, VALUE_PAIR *challenge,		   VALUE_PAIR * usernamepair){	tDirStatus		status		 = eDSNoErr;	tDirReference		dsRef		 = 0;	tDirNodeReference	userNodeRef	 = 0;	tDataBuffer		*tDataBuff	 = NULL;	tDataBuffer		*pStepBuff	 = NULL;	tDataNode		*pAuthType	 = NULL;	unsigned long		uiCurr		 = 0;	unsigned long		uiLen		 = 0;	char			*username_string = NULL;	char			*shortUserName	 = NULL;	VALUE_PAIR		*response	 = pairfind(request->packet->vps, PW_MSCHAP2_RESPONSE);#ifndef NDEBUG	int t;#endif		username_string = (char *) malloc(usernamepair->length + 1);	if (username_string == NULL)		return RLM_MODULE_FAIL;		strlcpy(username_string, (char *)usernamepair->vp_strvalue,		usernamepair->length + 1);		status = dsOpenDirService(&dsRef);	if (status != eDSNoErr) {		free(username_string);		radlog(L_ERR,"rlm_mschap: od_mschap_auth(): dsOpenDirService = %d", status);		return RLM_MODULE_FAIL;	}    	status = getUserNodeRef(username_string, &shortUserName, &userNodeRef, dsRef);	if(status != RLM_MODULE_OK) {		DEBUG2("rlm_osx_od: ds_mschap_auth: getUserNodeRef failed");		if (username_string != NULL)			free(username_string);		if (dsRef != 0)			dsCloseDirService(dsRef);		return status;	}		/* We got a node; fill the stepBuffer 	   kDSStdAuthMSCHAP2	   MS-CHAPv2 authentication method. The Open Directory plug-in generates the reply data for the client. 	   The input buffer format consists of 	   a four byte length specifying the length of the user name that follows, the user name, 	   a four byte value specifying the length of the server challenge that follows, the server challenge, 	   a four byte value specifying the length of the peer challenge that follows, the peer challenge, 	   a four byte value specifying the length of the client's digest that follows, and the client's digest. 	   The output buffer consists of a four byte value specifying the length of the return digest for the client's challenge.	   r = FillAuthBuff(pAuthBuff, 5,	   strlen(inName), inName,						// Directory Services long or short name	   strlen(schal), schal,						// server challenge	   strlen(peerchal), peerchal,					// client challenge	   strlen(p24), p24,							// P24 NT-Response	   4, "User");									// must match the username that was used for the hash			   inName		= 	username_string	   schal		=   challenge->vp_strvalue	   peerchal	=   response->vp_strvalue + 2 (16 octets)	   p24			=   response->vp_strvalue + 26 (24 octets)	*/	pStepBuff = dsDataBufferAllocate(dsRef, 4096);	tDataBuff = dsDataBufferAllocate(dsRef, 4096);	pAuthType = dsDataNodeAllocateString(dsRef, kDSStdAuthMSCHAP2);	uiCurr = 0;		DEBUG2("	rlm_mschap:username_string = %s, shortUserName=%s (length = %lu)\n", username_string, shortUserName, strlen(shortUserName));		/* User name length + username */	uiLen = strlen(shortUserName);	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(size_t));	uiCurr += sizeof(size_t);	memcpy(&(tDataBuff->fBufferData[uiCurr]), shortUserName, uiLen);	uiCurr += uiLen;#ifndef NDEBUG	DEBUG2("	rlm_mschap: stepbuf server challenge:\t");	for (t = 0; t < challenge->length; t++) {		fprintf(stderr, "%02x", challenge->vp_strvalue[t]);	}	fprintf(stderr, "\n");#endif		/* server challenge (ie. my (freeRADIUS) challenge) */	uiLen = 16;	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(size_t));	uiCurr += sizeof(size_t);	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(challenge->vp_strvalue[0]),	       uiLen);	uiCurr += uiLen;	#ifndef NDEBUG	DEBUG2("	rlm_mschap: stepbuf peer challenge:\t\t");	for (t = 2; t < 18; t++) {		fprintf(stderr, "%02x", response->vp_strvalue[t]);	}	fprintf(stderr, "\n");#endif		/* peer challenge (ie. the client-generated response) */	uiLen = 16;	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(size_t));	uiCurr += sizeof(size_t);	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(response->vp_strvalue[2]),	       uiLen);	uiCurr += uiLen;		#ifndef NDEBUG	DEBUG2("	rlm_mschap stepbuf p24:\t\t");	for (t = 26; t < 50; t++) {		fprintf(stderr, "%02x", response->vp_strvalue[t]);	}	fprintf(stderr, "\n");#endif		/* p24 (ie. second part of client-generated response) */	uiLen =  24; /* strlen(&(response->vp_strvalue[26])); may contain NULL byte in the middle. */	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(size_t));	uiCurr += sizeof(size_t);	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(response->vp_strvalue[26]),	       uiLen);	uiCurr += uiLen;		/* Client generated use name (short name?) */	uiLen =  strlen(username_string);	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(size_t));	uiCurr += sizeof(size_t);	memcpy(&(tDataBuff->fBufferData[uiCurr]), username_string, uiLen);	uiCurr += uiLen;	tDataBuff->fBufferLength = uiCurr;		status = dsDoDirNodeAuth(userNodeRef, pAuthType, 1, tDataBuff,				 pStepBuff, NULL);	if (status == eDSNoErr) {		if (pStepBuff->fBufferLength > 4) {			unsigned long len;						memcpy(&len, pStepBuff->fBufferData, 4);			if (len == 40) {				char mschap_reply[41] = { '\0' };				pStepBuff->fBufferData[len+4] = '\0';				mschap_reply[0] = 'S';				mschap_reply[1] = '=';				memcpy(&(mschap_reply[2]), &(pStepBuff->fBufferData[4]), len);				mschap_add_reply(&request->reply->vps,						 *response->vp_strvalue,						 "MS-CHAP2-Success",						 mschap_reply, len+2);				DEBUG2("rlm_mschap: dsDoDirNodeAuth returns stepbuff: %s (len=%ld)\n", mschap_reply, len);			}		}	}	/* clean up */	if (username_string != NULL)		free(username_string);	if (shortUserName != NULL)		free(shortUserName);	if (tDataBuff != NULL)		dsDataBufferDeAllocate(dsRef, tDataBuff);	if (pStepBuff != NULL)		dsDataBufferDeAllocate(dsRef, pStepBuff);	if (pAuthType != NULL)		dsDataNodeDeAllocate(dsRef, pAuthType);	if (userNodeRef != 0)		dsCloseDirNode(userNodeRef);	if (dsRef != 0)		dsCloseDirService(dsRef);		if (status != eDSNoErr) {		errno = EACCES;		radlog(L_ERR, "rlm_mschap: authentication failed %d", status); /* <-- returns -14091 (eDSAuthMethodNotSupported) -14090 */		return RLM_MODULE_REJECT;	}		return RLM_MODULE_OK;}#endif /* __APPLE__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -