tDirStatus defaultSearchNodePath(tDirReference pDirRef, tDataListPtr *pdsNodePath)
{
    tDirStatus dsErr = eDSNoErr;
    /* Create a buffer for the resulting nodes */
    tDataBufferPtr pTmpBuf = NULL;
    pTmpBuf = dsDataBufferAllocate(pDirRef, s_cBufferSize);
    if (pTmpBuf)
    {
        /* Try to find the default search node for local names */
        UInt32 cNodes;
        tContextData pCtx = NULL;
        dsErr = dsFindDirNodes(pDirRef, pTmpBuf, NULL, eDSLocalNodeNames, &cNodes, &pCtx);
        /* Any nodes found? */
        if (   dsErr == eDSNoErr
            && cNodes >= 1)
            /* The first path of the node list is what we looking for. */
            dsErr = dsGetDirNodeName(pDirRef, pTmpBuf, 1, pdsNodePath);
        else
            dsErr = eDSNodeNotFound;

        if (pCtx)
            dsReleaseContinueData(pDirRef, pCtx);
        dsDataBufferDeAllocate(pDirRef, pTmpBuf);
    }
    else
        dsErr = eDSAllocationFailed;

    return dsErr;
}
Ejemplo n.º 2
0
/*
** Name: dsFindDirNodesQ
**
** Description:
**	Wrapper for system call dsFindDirNodes(). Handles the case where it
**	returns eDSBufferTooSmall by calling DoubleBufferSize and
**	re-calling dsFindDirNodes().
**
** History:
**	30-Jun-2005 (hanje04)
**	    Created.
*/
tDirStatus
dsFindDirNodesQ(
    tDirReference		inDirReference,
    tDataBufferPtr *	inOutDataBufferPtrPtr,
    tDataListPtr		inNodeNamePattern,
    tDirPatternMatch	inPatternMatchType,
    unsigned long		*outDirNodeCount,
    tContextData		*inOutContinueData
)
{
    tDirStatus  err;

    do
    {
        do
        {
            err = dsFindDirNodes(
                      inDirReference,
                      *inOutDataBufferPtrPtr,
                      inNodeNamePattern,
                      inPatternMatchType,
                      outDirNodeCount,
                      inOutContinueData
                  );
            DoubleBufferSize(&err, inDirReference, inOutDataBufferPtrPtr);
        } while (err == eDSBufferTooSmall);
    } while ( (err == eDSNoErr) && (*outDirNodeCount == 0) &&
              (*inOutContinueData != NULL) );

    return err;
}
Ejemplo n.º 3
0
// Only returning the first node (used for finding eDSSearchNodeName)
tDirStatus KADirectoryClientGetNode(tDirReference directoryRef, tDirPatternMatch pattern, KADirectoryNode **node)
{
    tDirStatus status = eDSNoErr;	
    unsigned long node_count = 0;
    tContextData continuation_data_ptr = NULL;
	tDataBufferPtr _dataBufferPtr = dsDataBufferAllocate(directoryRef, 1024);
	
	for (;;)
	{
		status = dsFindDirNodes(directoryRef, _dataBufferPtr, NULL, pattern, &node_count, &continuation_data_ptr);

		if ((status != eDSBufferTooSmall) || !(_dataBufferPtr = double_databuffer_or_bail(directoryRef,_dataBufferPtr)))
			break;
	}

    if (status == eDSNoErr)
	{
		tDataListPtr node_name_ptr = NULL;

		if (continuation_data_ptr)
			dsReleaseContinueData(directoryRef, continuation_data_ptr);

		// eDSNoNodeFound would've been returned already
		assert( node_count > 0 );
		
		status = dsGetDirNodeName(directoryRef, _dataBufferPtr,
								  1, // get first node
								  &node_name_ptr);

		if (status == eDSNoErr)
		{
			if (node)
				*node = KADirectoryNodeCreate(directoryRef, node_name_ptr);
			dsDataListDeallocate(directoryRef, node_name_ptr);
		}
	}
	
    if (_dataBufferPtr)
		dsDataBufferDeAllocate(directoryRef, _dataBufferPtr);

	return status;
}
Ejemplo n.º 4
0
static long od_check_passwd(char const *uname, char const *password)
{
	long			result 		= eDSAuthFailed;
	tDirReference		dsRef 		= 0;
	tDataBuffer		*tDataBuff;
	tDirNodeReference	nodeRef 	= 0;
	long			status 		= eDSNoErr;
	tContextData		context		= 0;
	uint32_t		nodeCount 	= 0;
	uint32_t		attrIndex 	= 0;
	tDataList		*nodeName 	= NULL;
	tAttributeEntryPtr	pAttrEntry 	= NULL;
	tDataList		*pRecName 	= NULL;
	tDataList		*pRecType 	= NULL;
	tDataList		*pAttrType 	= NULL;
	uint32_t		recCount 	= 0;
	tRecordEntry		*pRecEntry 	= NULL;
	tAttributeListRef	attrListRef 	= 0;
	char			*pUserLocation 	= NULL;
	char			*pUserName 	= NULL;
	tAttributeValueListRef	valueRef 	= 0;
	tAttributeValueEntry	*pValueEntry 	= NULL;
	tDataList		*pUserNode 	= NULL;
	tDirNodeReference	userNodeRef 	= 0;
	tDataBuffer		*pStepBuff 	= NULL;
	tDataNode		*pAuthType 	= NULL;
	tAttributeValueEntry	*pRecordType 	= NULL;
	uint32_t		uiCurr 		= 0;
	uint32_t		uiLen 		= 0;
	uint32_t		pwLen 		= 0;
	
	if (!uname || !password)
		return result;
	
	do
	{		
		status = dsOpenDirService( &dsRef );
		if ( status != eDSNoErr )
			return result;
		
		tDataBuff = dsDataBufferAllocate( dsRef, 4096 );
		if (!tDataBuff)
			break;
		
		/* find user on search node */
		status = dsFindDirNodes( dsRef, tDataBuff, NULL, eDSSearchNodeName, &nodeCount, &context );
		if (status != eDSNoErr || nodeCount < 1)
			break;
		
		status = dsGetDirNodeName( dsRef, tDataBuff, 1, &nodeName );
		if (status != eDSNoErr)
			break;
		
		status = dsOpenDirNode( dsRef, nodeName, &nodeRef );
		dsDataListDeallocate( dsRef, nodeName );
		free( nodeName );
		nodeName = NULL;
		if (status != eDSNoErr)
			break;

		pRecName = dsBuildListFromStrings( dsRef, uname, NULL );
		pRecType = dsBuildListFromStrings( dsRef, kDSStdRecordTypeUsers, kDSStdRecordTypeComputers, kDSStdRecordTypeMachines, NULL );
		pAttrType = dsBuildListFromStrings( dsRef, kDSNAttrMetaNodeLocation, kDSNAttrRecordName, kDSNAttrRecordType, NULL );
		
		recCount = 1;
		status = dsGetRecordList( nodeRef, tDataBuff, pRecName, eDSExact, pRecType,
													pAttrType, 0, &recCount, &context );
		if ( status != eDSNoErr || recCount == 0 )
			break;
				
		status = dsGetRecordEntry( nodeRef, tDataBuff, 1, &attrListRef, &pRecEntry );
		if ( status != eDSNoErr )
			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 )
					{
						pUserName = (char *) calloc( pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) );
						memcpy( pUserName, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength );
					}
				}
				else
				if ( strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrRecordType ) == 0 )
				{
					status = dsGetAttributeValue( nodeRef, tDataBuff, 1, valueRef, &pValueEntry );
					if ( status == eDSNoErr && pValueEntry != NULL )
					{
						pRecordType = pValueEntry;
						pValueEntry = NULL;
					}
				}
				
				if ( pValueEntry != NULL ) {
					dsDeallocAttributeValueEntry( dsRef, pValueEntry );
					pValueEntry = NULL;
				}
				if ( pAttrEntry != NULL ) {
					dsDeallocAttributeEntry( dsRef, pAttrEntry );
					pAttrEntry = NULL;
				}
				dsCloseAttributeValueList( valueRef );
				valueRef = 0;
			}
		}
		
		pUserNode = dsBuildFromPath( dsRef, pUserLocation, "/" );
		status = dsOpenDirNode( dsRef, pUserNode, &userNodeRef );
		dsDataListDeallocate( dsRef, pUserNode );
		free( pUserNode );
		pUserNode = NULL;
		if ( status != eDSNoErr )
			break;
		
		pStepBuff = dsDataBufferAllocate( dsRef, 128 );
		
		pAuthType = dsDataNodeAllocateString( dsRef, kDSStdAuthNodeNativeClearTextOK );
		uiCurr = 0;
		
		/* User name */
		uiLen = (uint32_t)strlen( pUserName );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof(uiLen) );
		uiCurr += (uint32_t)sizeof( uiLen );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), pUserName, uiLen );
		uiCurr += uiLen;
		
		/* pw */
		pwLen = (uint32_t)strlen( password );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &pwLen, sizeof(pwLen) );
		uiCurr += (uint32_t)sizeof( pwLen );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), password, pwLen );
		uiCurr += pwLen;
		
		tDataBuff->fBufferLength = uiCurr;
		
		result = dsDoDirNodeAuthOnRecordType( userNodeRef, pAuthType, 1, tDataBuff, pStepBuff, NULL, &pRecordType->fAttributeValueData );
	}
	while ( 0 );
	
	/* clean up */
	if (pAuthType != NULL) {
		dsDataNodeDeAllocate( dsRef, pAuthType );
		pAuthType = NULL;
	}
	if (pRecordType != NULL) {
		dsDeallocAttributeValueEntry( dsRef, pRecordType );
		pRecordType = NULL;
	}
	if (tDataBuff != NULL) {
		bzero( tDataBuff, tDataBuff->fBufferSize );
		dsDataBufferDeAllocate( dsRef, tDataBuff );
		tDataBuff = NULL;
	}
	if (pStepBuff != NULL) {
		dsDataBufferDeAllocate( dsRef, pStepBuff );
		pStepBuff = NULL;
	}
	if (pUserLocation != NULL) {
		free(pUserLocation);
		pUserLocation = NULL;
	}
	if (pRecName != NULL) {
		dsDataListDeallocate( dsRef, pRecName );
		free( pRecName );
		pRecName = NULL;
	}
	if (pRecType != NULL) {
		dsDataListDeallocate( dsRef, pRecType );
		free( pRecType );
		pRecType = NULL;
	}
	if (pAttrType != NULL) {
		dsDataListDeallocate( dsRef, pAttrType );
		free( pAttrType );
		pAttrType = NULL;
	}
	if (nodeRef != 0) {
		dsCloseDirNode(nodeRef);
		nodeRef = 0;
	}
	if (dsRef != 0) {
		dsCloseDirService(dsRef);
		dsRef = 0;
	}
	
	return result;
}
Ejemplo n.º 5
0
int ds_check_passwd(char *uname, char *domain)
{
	char 						*p					= NULL;
	tDirReference				dsRef				= 0;
    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;
	char					   *pUserName			= NULL;
	tAttributeValueListRef		valueRef			= 0;
	tAttributeValueEntry  	 	*pValueEntry		= NULL;
	tDataList				   *pUserNode			= NULL;
	tDirNodeReference			userNodeRef			= 0;
	tDataBuffer					*pStepBuff			= NULL;
	tDataNode				   *pAuthType			= NULL;
	unsigned long				uiCurr				= 0;
	unsigned long				uiLen				= 0;
	
	do
	{
		if (uname == NULL)
			SaySorryAndBail();
		
		printf("Checking password for %s.\n", uname);
		p = getpass("Password:"******"/" );
			if ( nodeName == NULL ) break;
			
			// find
			status = dsFindDirNodes( dsRef, tDataBuff, nodeName, eDSiExact, &nodeCount, &context );
		}
		else
		{
			// find on search node
			status = dsFindDirNodes( dsRef, tDataBuff, NULL, eDSSearchNodeName, &nodeCount, &context );
		}
		
		if ( status != eDSNoErr )
			SaySorryAndBail();
		
		if ( nodeCount < 1 )
			SaySorryAndBail();
		
		status = dsGetDirNodeName( dsRef, tDataBuff, 1, &nodeName );
		if (status != eDSNoErr)
			SaySorryAndBail();
		
		status = dsOpenDirNode( dsRef, nodeName, &nodeRef );
		dsDataListDeallocate( dsRef, nodeName );
		free( nodeName );
		nodeName = NULL;
		if (status != eDSNoErr)
			SaySorryAndBail();
		
		pRecName = dsBuildListFromStrings( dsRef, uname, 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 )
			SaySorryAndBail();
				
		status = dsGetRecordEntry( nodeRef, tDataBuff, 1, &attrListRef, &pRecEntry );
		if ( status != eDSNoErr )
			SaySorryAndBail();
		
		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 )
					{
						pUserName = (char *) calloc( pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) );
						memcpy( pUserName, 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, "/" );
		status = dsOpenDirNode( dsRef, pUserNode, &userNodeRef );
		if ( status != eDSNoErr )
			SaySorryAndBail();
		
		pStepBuff = dsDataBufferAllocate( dsRef, 128 );
		
		pAuthType = dsDataNodeAllocateString( dsRef, kDSStdAuthNodeNativeClearTextOK );
		uiCurr = 0;
		
		// User name
		uiLen = strlen( pUserName );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) );
		uiCurr += sizeof( unsigned long );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), pUserName, uiLen );
		uiCurr += uiLen;
		
		// pw
		uiLen = strlen( p );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), &uiLen, sizeof( unsigned long ) );
		uiCurr += sizeof( unsigned long );
		memcpy( &(tDataBuff->fBufferData[ uiCurr ]), p, uiLen );
		uiCurr += uiLen;
		
		tDataBuff->fBufferLength = uiCurr;
		
		status = dsDoDirNodeAuth( userNodeRef, pAuthType, 1, tDataBuff, pStepBuff, NULL );
		
	}
	while ( 0 );
	
	// clean up
	if (tDataBuff != NULL) {
		memset(tDataBuff, 0, tDataBuff->fBufferSize);
		dsDataBufferDeAllocate( dsRef, tDataBuff );
		tDataBuff = NULL;
	}
	
	if (pStepBuff != NULL) {
		dsDataBufferDeAllocate( dsRef, pStepBuff );
		pStepBuff = NULL;
	}
	if (pUserLocation != NULL ) {
		free(pUserLocation);
		pUserLocation = NULL;
	}
	if (pRecName != NULL) {
		dsDataListDeallocate( dsRef, pRecName );
		free( pRecName );
		pRecName = NULL;
	}
	if (pRecType != NULL) {
		dsDataListDeallocate( dsRef, pRecType );
		free( pRecType );
		pRecType = NULL;
	}
	if (pAttrType != NULL) {
		dsDataListDeallocate( dsRef, pAttrType );
		free( pAttrType );
		pAttrType = NULL;
	}
	if (nodeRef != 0) {
		dsCloseDirNode(nodeRef);
		nodeRef = 0;
	}
	if (dsRef != 0) {
		dsCloseDirService(dsRef);
		dsRef = 0;
	}
	
	if ( status != eDSNoErr )
	{
		errno = EACCES;
		fprintf(stderr, "Sorry\n");
		exit(1);
	}
	
	return 0;
}
Ejemplo n.º 6
0
static int getUserNodeRef(char* inUserName, char **outUserName,
			  tDirNodeReference* userNodeRef, tDirReference dsRef)
{
	tDataBuffer             *tDataBuff	= NULL;
	tDirNodeReference       nodeRef		= 0;
	long                    status		= eDSNoErr;
	tContextData            context		= 0;
	uint32_t           	nodeCount	= 0;
	uint32_t                attrIndex	= 0;
	tDataList               *nodeName	= NULL;
	tAttributeEntryPtr      pAttrEntry	= NULL;
	tDataList               *pRecName	= NULL;
	tDataList               *pRecType	= NULL;
	tDataList               *pAttrType	= NULL;
	uint32_t           	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=%u", 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;
			}
		}
		
		/* OpenDirectory doesn't support mschapv2 authentication against
		 * Active Directory.  AD users need to be authenticated using the
		 * normal freeradius AD path (i.e. ntlm_auth).
		 */
		if (strncmp(pUserLocation, kActiveDirLoc, strlen(kActiveDirLoc)) == 0) {
			DEBUG2("[mschap] OpenDirectory authentication returning noop.  OD doesn't support MSCHAPv2 for ActiveDirectory users.");
			result = RLM_MODULE_NOOP;
			break;
		}
        
		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;
}