コード例 #1
0
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;
}
コード例 #2
0
ファイル: dir_svc_client.c プロジェクト: arnelh/Examples
// double the data buffer we're using with this node as long as we're no allocating 1MB
// return true on success 
inline tDataBufferPtr double_databuffer_or_bail(tDirReference directoryRef, tDataBufferPtr dataBufferPtr)
{
	unsigned long newBufferSize = 1024;
	if (dataBufferPtr)
	{
		newBufferSize = dataBufferPtr->fBufferSize * 2;
		dsDataBufferDeAllocate(directoryRef, dataBufferPtr);
		if (newBufferSize > 1024*1024)
			return NULL;
	}
	return dsDataBufferAllocate(directoryRef, newBufferSize);
}
コード例 #3
0
ファイル: dir_svc_client.c プロジェクト: arnelh/Examples
void KADirectoryNodeFree(KADirectoryNode *instance)
{
	if (instance->_name) 
		free(instance->_name);

    if (instance->_dataBufferPtr)
		dsDataBufferDeAllocate(instance->_directoryRef, instance->_dataBufferPtr);

    if (instance->_nodeRef)
        dsCloseDirNode(instance->_nodeRef);
		
	free(instance);
}
コード例 #4
0
/*
** Name: DoubleBufferSize
**
** Description:
**	Handles case where Open Directory returns eDSBufferTooSmall.
**	buffer size will ONLY be doubled if that error as been passed in.
**
** Input:
**	errPtr - Error returned by failing OD call.
**	tDataBufferPtr - Buffer to be doubled.
**	dirRef - Open Directory connection.
**
** Output:
**	tDataBufferPtr - Buffer to be doubled.
**
** History:
**	30-Jun-2005 (hanje04)
**	    Created.
*/
void
DoubleBufferSize(
    tDirStatus *        errPtr,
    tDirNodeReference   dirRef,
    tDataBufferPtr *    bufPtrPtr
)
{
    tDirStatus      err;
    tDirStatus      junk;
    tDataBufferPtr  tmpBuf;

    if (*errPtr == eDSBufferTooSmall)
    {
        /*
            ** If the buffer size is already bigger than MAX_BUFF_GROW, don't try to
            ** double it again; something has gone horribly wrong.
        */

        err = eDSNoErr;
        if ( (*bufPtrPtr)->fBufferSize >= MAX_BUFF_GROW )
            err = eDSAllocationFailed;

        if (err == eDSNoErr)
        {
            tmpBuf = dsDataBufferAllocate(dirRef, (*bufPtrPtr)->fBufferSize * 2);
            if (tmpBuf == NULL)
                err = eDSAllocationFailed;
            else
            {
                err=dsDataBufferDeAllocate(dirRef, *bufPtrPtr);
                if(err == eDSNoErr);
                *bufPtrPtr = tmpBuf;
            }
        }

        /*
        ** If err is eDSNoErr, the buffer expansion was successful
               ** so we leave *errPtr set to eDSBufferTooSmall.  If err
               ** is any other value, the expansion failed and we set
               ** *errPtr to that error.
        */

        if (err != eDSNoErr) {
            *errPtr = err;
        }
    }
}
コード例 #5
0
ファイル: dir_svc_client.c プロジェクト: arnelh/Examples
// 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;
}
コード例 #6
0
tDirStatus userAuthInfo(tDirReference pDirRef, tDirNodeReference pNodeRef, const char *pszUsername, tDataListPtr *ppAuthNodeListOut)
{
    tDirStatus dsErr = eDSNoErr;
    tDirStatus dsCleanErr = eDSNoErr;
    /* Create a buffer for the resulting authentication info */
    tDataBufferPtr pTmpBuf = dsDataBufferAllocate(pDirRef, s_cBufferSize);
    if (pTmpBuf)
    {
        /* Create the necessary lists for kDSNAttrMetaNodeLocation and kDSNAttrRecordName. */
        tDataListPtr pRecordType = dsBuildListFromStrings(pDirRef, kDSStdRecordTypeUsers, NULL);
        tDataListPtr pRecordName = dsBuildListFromStrings(pDirRef, pszUsername, NULL);
        tDataListPtr pRequestedAttributes = dsBuildListFromStrings(pDirRef, kDSNAttrMetaNodeLocation, kDSNAttrRecordName, NULL);
        if (!(   pRecordType == NULL
              || pRecordName == NULL
              || pRequestedAttributes == NULL))
        {
            /* Now search for the first matching record */
            UInt32 cRecords = 1;
            tContextData pCtx = NULL;
            dsErr = dsGetRecordList(pNodeRef,
                                    pTmpBuf,
                                    pRecordName,
                                    eDSExact,
                                    pRecordType,
                                    pRequestedAttributes,
                                    false,
                                    &cRecords,
                                    &pCtx);
            if (   dsErr == eDSNoErr
                && cRecords >= 1)
            {
                /* Process the first found record. Look at any attribute one by one. */
                tAttributeListRef pRecAttrListRef = NULL;
                tRecordEntryPtr pRecEntry = NULL;
                tDataListPtr pAuthNodeList = NULL;
                dsErr = dsGetRecordEntry(pNodeRef, pTmpBuf, 1, &pRecAttrListRef, &pRecEntry);
                if (dsErr == eDSNoErr)
                {
                    for (size_t i = 1; i <= pRecEntry->fRecordAttributeCount; ++i)
                    {
                        tAttributeValueListRef pAttrValueListRef = NULL;
                        tAttributeEntryPtr pAttrEntry = NULL;
                        /* Get the information for this attribute. */
                        dsErr = dsGetAttributeEntry(pNodeRef, pTmpBuf, pRecAttrListRef, i,
                                                    &pAttrValueListRef, &pAttrEntry);
                        if (dsErr == eDSNoErr)
                        {
                            tAttributeValueEntryPtr pValueEntry = NULL;
                            /* Has any value? */
                            if (pAttrEntry->fAttributeValueCount > 0)
                            {
                                dsErr = dsGetAttributeValue(pNodeRef, pTmpBuf, 1, pAttrValueListRef, &pValueEntry);
                                if (dsErr == eDSNoErr)
                                {
                                    /* Check for kDSNAttrMetaNodeLocation */
                                    if (strcmp(pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrMetaNodeLocation) == 0)
                                    {
                                        /* Convert the meta location attribute to a path node list */
                                        pAuthNodeList = dsBuildFromPath(pDirRef,
                                                                        pValueEntry->fAttributeValueData.fBufferData,
                                                                        "/");
                                        if (pAuthNodeList == NULL)
                                            dsErr = eDSAllocationFailed;
                                    }
                                }
                            }

                            if (pValueEntry != NULL)
                                dsDeallocAttributeValueEntry(pDirRef, pValueEntry);
                            if (pAttrValueListRef)
                                dsCloseAttributeValueList(pAttrValueListRef);
                            if (pAttrEntry != NULL)
                                dsDeallocAttributeEntry(pDirRef, pAttrEntry);

                            if (dsErr != eDSNoErr)
                                break;
                        }
                    }
                }
                /* Copy the results */
                if (dsErr == eDSNoErr)
                {
                    if (pAuthNodeList != NULL)
                    {
                        /* Copy out results. */
                        *ppAuthNodeListOut = pAuthNodeList;
                        pAuthNodeList = NULL;
                    }
                    else
                        dsErr = eDSAttributeNotFound;
                }

                if (pAuthNodeList != NULL)
                {
                    dsCleanErr = dsDataListDeallocate(pDirRef, pAuthNodeList);
                    if (dsCleanErr == eDSNoErr)
                        free(pAuthNodeList);
                }
                if (pRecAttrListRef)
                    dsCloseAttributeList(pRecAttrListRef);
                if (pRecEntry != NULL)
                    dsDeallocRecordEntry(pDirRef, pRecEntry);
            }
            else
                dsErr = eDSRecordNotFound;
            if (pCtx)
                dsReleaseContinueData(pDirRef, pCtx);
        }
        else
            dsErr = eDSAllocationFailed;
        if (pRequestedAttributes != NULL)
        {
            dsCleanErr = dsDataListDeallocate(pDirRef, pRequestedAttributes);
            if (dsCleanErr == eDSNoErr)
                free(pRequestedAttributes);
        }
        if (pRecordName != NULL)
        {
            dsCleanErr = dsDataListDeallocate(pDirRef, pRecordName);
            if (dsCleanErr == eDSNoErr)
                free(pRecordName);
        }
        if (pRecordType != NULL)
        {
            dsCleanErr = dsDataListDeallocate(pDirRef, pRecordType);
            if (dsCleanErr == eDSNoErr)
                free(pRecordType);
        }
        dsDataBufferDeAllocate(pDirRef, pTmpBuf);
    }
    else
        dsErr = eDSAllocationFailed;

    return dsErr;
}
コード例 #7
0
tDirStatus authWithNode(tDirReference pDirRef, tDataListPtr pAuthNodeList, const char *pszUsername, const char *pszPassword)
{
    tDirStatus dsErr = eDSNoErr;
    /* Open the authentication node. */
    tDirNodeReference pAuthNodeRef = NULL;
    dsErr = dsOpenDirNode(pDirRef, pAuthNodeList, &pAuthNodeRef);
    if (dsErr == eDSNoErr)
    {
        /* How like we to authenticate! */
        tDataNodePtr pAuthMethod = dsDataNodeAllocateString(pDirRef, kDSStdAuthNodeNativeClearTextOK);
        if (pAuthMethod)
        {
            /* Create the memory holding the authentication data. The data
             * structure consists of 4 byte length of the username + zero byte,
             * the username itself, a 4 byte length of the password & the
             * password itself + zero byte. */
            tDataBufferPtr pAuthOutBuf = dsDataBufferAllocate(pDirRef, s_cBufferSize);
            if (pAuthOutBuf)
            {
                size_t cUserName = strlen(pszUsername) + 1;
                size_t cPassword = strlen(pszPassword) + 1;
                unsigned long cLen = 0;
                tDataBufferPtr pAuthInBuf = dsDataBufferAllocate(pDirRef, sizeof(cLen) + cUserName + sizeof(cLen) + cPassword);
                if (pAuthInBuf)
                {
                    /* Move the data into the buffer. */
                    pAuthInBuf->fBufferLength = 0;
                    /* Length of the username */
                    cLen = cUserName;
                    memcpy(&pAuthInBuf->fBufferData[pAuthInBuf->fBufferLength], &cLen, sizeof(cLen));
                    pAuthInBuf->fBufferLength += sizeof(cLen);
                    /* The username itself */
                    memcpy(&pAuthInBuf->fBufferData[pAuthInBuf->fBufferLength], pszUsername, cUserName);
                    pAuthInBuf->fBufferLength += cUserName;
                    /* Length of the password */
                    cLen = cPassword;
                    memcpy(&pAuthInBuf->fBufferData[pAuthInBuf->fBufferLength], &cLen, sizeof(cLen));
                    pAuthInBuf->fBufferLength += sizeof(cLen);
                    /* The password itself */
                    memcpy(&pAuthInBuf->fBufferData[pAuthInBuf->fBufferLength], pszPassword, cPassword);
                    pAuthInBuf->fBufferLength += cPassword;
                    /* Now authenticate */
                    dsErr = dsDoDirNodeAuth(pAuthNodeRef, pAuthMethod, true, pAuthInBuf, pAuthOutBuf, NULL);
                    /* Clean up. */
                    dsDataBufferDeAllocate(pDirRef, pAuthInBuf);
                }
                else
                    dsErr = eDSAllocationFailed;
                dsDataBufferDeAllocate(pDirRef, pAuthOutBuf);
            }
            else
                dsErr = eDSAllocationFailed;
            dsDataNodeDeAllocate(pDirRef, pAuthMethod);
        }
        else
            dsErr = eDSAllocationFailed;
        dsCloseDirNode(pAuthNodeRef);
    }

    return dsErr;
}
コード例 #8
0
ファイル: ds_passwd.c プロジェクト: OpenDarwin-CVS/SEDarwin
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;
}
コード例 #9
0
ファイル: lwdscache.c プロジェクト: FarazShaikh/LikewiseSMB2
DWORD
LwDsSendCustomCall(
    int command,
    pid_t pid
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    tDirReference hDirRef = 0;
    tDirNodeReference hNodeRef = 0;
    tDirStatus status = eDSNoErr;
    const char nodeName[] = "/Cache";
    tDataListPtr dirNodeName = NULL;
    tDataBufferPtr pPidRequest = NULL;
    tDataBufferPtr pPidResponse = NULL;
    DsCacheExceptionRqst * pRequest = NULL;

    status = dsOpenDirService(&hDirRef);
    if(status != eDSNoErr)
    {
        dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK;
        goto errorexit;
    }

    pPidRequest = dsDataBufferAllocate(hDirRef, sizeof(DsCacheExceptionRqst));
    if (pPidRequest == NULL)
    {
        dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK;
        goto errorexit;
    }

    pPidResponse = dsDataBufferAllocate(hDirRef, sizeof(int32_t));
    if (pPidResponse == NULL)
    {
        dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK;
        goto errorexit;
    }

    pRequest = (DsCacheExceptionRqst*)pPidRequest->fBufferData;

    memset(&pRequest->auth, 0, sizeof(pRequest->auth));
    pRequest->pid = pid;
    pPidRequest->fBufferLength = sizeof(DsCacheExceptionRqst);

    dirNodeName = dsBuildFromPath(hDirRef, nodeName, "/");
    if (dirNodeName == NULL)
    {
        dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK;
        goto errorexit;
    }

    status = dsOpenDirNode(hDirRef, dirNodeName, &hNodeRef);
    if (status != eDSNoErr)
    {
        // This can happen on older Tiger Mac OS X 10.4 systems, as there is no /Cache plugin.
        // It is okay to return successful in this scenario.
        goto errorexit;
    }

    status = dsDoPlugInCustomCall(hNodeRef, command, pPidRequest, pPidResponse);
    if (status != eDSNoErr)
    {
        dwError = LW_ERROR_FAILED_STARTUP_PREREQUISITE_CHECK;
        goto errorexit;
    }

errorexit:

    if (dirNodeName)
        dsDataListDeallocate(hDirRef, dirNodeName);

    if (hNodeRef)
        dsCloseDirNode(hNodeRef);

    if (pPidRequest)
        dsDataBufferDeAllocate(hDirRef, pPidRequest);

    if (pPidResponse)
        dsDataBufferDeAllocate(hDirRef, pPidResponse);

    if (hDirRef)
        dsCloseDirService(hDirRef);

    return dwError;
}
コード例 #10
0
ファイル: main.c プロジェクト: Deanzou/ppp
static int dsauth_chap(u_char *name, u_char *ourname, int id,
			struct chap_digest_type *digest,
			unsigned char *challenge, unsigned char *response,
			unsigned char *message, int message_space)
{
    tDirReference				dirRef;
    tDirNodeReference			userNode = 0;
    tDataNodePtr				authTypeDataNodePtr = 0;
    tDataBufferPtr				authDataBufPtr = 0;
    tDataBufferPtr				responseDataBufPtr = 0;
    tAttributeValueEntryPtr 	recordNameAttr = 0;
    tAttributeValueEntryPtr 	authAuthorityAttr = 0;
    tDirStatus					dsResult = eDSNoErr;
    int							authResult = 0;
    char						*ptr;
    MS_Chap2Response			*resp;  
    u_int32_t					userShortNameSize;
    u_int32_t					userNameSize = strlen((char*)name);
    u_int32_t					authDataSize;
    int							challenge_len, response_len;
	CFMutableDictionaryRef		serviceInfo = 0;
	CFMutableDictionaryRef		eventDetail;
	CFDictionaryRef				interface;
	CFStringRef					subtypeRef;
	CFStringRef					addrRef;

    
    challenge_len = *challenge++;	/* skip length, is 16 */
    response_len = *response++;

    // currently only support MS-CHAPv2
    if (digest->code != CHAP_MICROSOFT_V2
    	||	response_len != MS_CHAP2_RESPONSE_LEN
    	||	challenge_len != CHALLENGE_SIZE)
        return 0;

    resp = (MS_Chap2Response*)response;
    if ((dsResult = dsOpenDirService(&dirRef)) == eDSNoErr) {
	
        if ((authTypeDataNodePtr = dsDataNodeAllocateString(dirRef, kDSStdAuthMSCHAP2)) == 0) {
            error("DSAuth plugin: Could not allocate data buffer\n");
            goto cleanup;
        }
		
		//  setup service info
		interface = CFDictionaryGetValue(systemOptions, kRASEntInterface);
		if (interface && CFGetTypeID(interface) == CFDictionaryGetTypeID()) {
			subtypeRef = CFDictionaryGetValue(interface, kRASPropInterfaceSubType);		
			if (subtypeRef && CFGetTypeID(subtypeRef) == CFStringGetTypeID()) {	
				serviceInfo = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
				if (serviceInfo) {
					eventDetail = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
					if (eventDetail) {
						addrRef = CFStringCreateWithCString(0, remoteaddress, kCFStringEncodingUTF8);
						if (addrRef) {
							CFDictionaryAddValue(eventDetail, CFSTR("ClientIP"),  addrRef);
							CFRelease(addrRef);	
						}
						if (CFStringCompare(subtypeRef, kRASValInterfaceSubTypeL2TP, 0) == kCFCompareEqualTo) {
							CFDictionaryAddValue(eventDetail, CFSTR("HostPort"),  CFSTR("1701"));
							CFDictionaryAddValue(eventDetail, CFSTR("ProtocolName"),  CFSTR("L2TP"));
							CFDictionaryAddValue(eventDetail, CFSTR("ProtocolVersion"),  CFSTR("2"));
						} else if (CFStringCompare(subtypeRef, kRASValInterfaceSubTypePPTP, 0) == kCFCompareEqualTo) {
							CFDictionaryAddValue(eventDetail, CFSTR("HostPort"),  CFSTR("1723"));
							CFDictionaryAddValue(eventDetail, CFSTR("ProtocolName"),  CFSTR("PPTP"));
							CFDictionaryAddValue(eventDetail, CFSTR("ProtocolVersion"),  CFSTR("1"));
						} else
							CFDictionaryAddValue(eventDetail, CFSTR("ProtocolName"),  subtypeRef);
						
						CFDictionaryAddValue(eventDetail, CFSTR("ServiceName"),  CFSTR("VPN"));
						
						// add eventDetail to serviceInfo dict
						CFDictionaryAddValue(serviceInfo, CFSTR("ServiceInformation"), eventDetail);
						CFRelease(eventDetail);
						
						// allocate response buffer with service info
						if (dsServiceInformationAllocate(serviceInfo, BUF_LEN, &responseDataBufPtr) != eDSNoErr) {
							error("DSAuth plugin: Unable to allocate service info buffer\n");
							goto cleanup;
						}
					} else {
						error("DSAuth plugin: Unable to allocate eventDetail dictionary\n");
						goto cleanup;
					}
				} else {
					error("DSAuth plugin: Unable to allocate serviceInfo dictionary\n");
					goto cleanup;
				}
			} else {
				error("DSAuth plugin: No Interface subtype found\n");
				goto cleanup;
			}
		} else {
			error("DSAuth plugin: No Interface dictionary found\n");
			goto cleanup;
		}

        if (dsauth_find_user_node(dirRef, (char*)name, &userNode, &recordNameAttr, &authAuthorityAttr) == 0) {  
            userShortNameSize = recordNameAttr->fAttributeValueData.fBufferLength;
            authDataSize = userNameSize + userShortNameSize + NT_RESPONSE_SIZE + (2 * CHALLENGE_SIZE) + (5 * sizeof(u_int32_t));   
            if ((authDataBufPtr = dsDataBufferAllocate(dirRef, authDataSize)) != 0) {   
                authDataBufPtr->fBufferLength = authDataSize;
                 
                // setup the response buffer           
                ptr = (char*)(authDataBufPtr->fBufferData);
                
                // 4 byte length & user name
                *((u_int32_t*)ptr) = userShortNameSize;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, recordNameAttr->fAttributeValueData.fBufferData, userShortNameSize);
                ptr += userShortNameSize;
                
                // 4 byte length & server challenge
                *((u_int32_t*)ptr) = CHALLENGE_SIZE;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, challenge, CHALLENGE_SIZE);
                ptr += CHALLENGE_SIZE;
                
                // 4 byte length & peer challenge
                *((u_int32_t*)ptr) = CHALLENGE_SIZE;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, resp->PeerChallenge, CHALLENGE_SIZE);
                ptr += CHALLENGE_SIZE;
                
                // 4 byte length & client digest
                *((u_int32_t*)ptr) = NT_RESPONSE_SIZE;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, resp->NTResp, NT_RESPONSE_SIZE);
                ptr += NT_RESPONSE_SIZE;
                
                // 4 byte length & user name (repeated)
                *((u_int32_t*)ptr) = userNameSize;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, name, userNameSize);
                
                if ((dsResult = dsDoDirNodeAuth(userNode, authTypeDataNodePtr, TRUE, authDataBufPtr, 
                        responseDataBufPtr, 0)) == eDSNoErr) {						
                    
                    // setup return data
                    if ((responseDataBufPtr->fBufferLength == MS_AUTH_RESPONSE_LENGTH + 4)
                                && *((u_int32_t*)(responseDataBufPtr->fBufferData)) == MS_AUTH_RESPONSE_LENGTH) {

                        responseDataBufPtr->fBufferData[4 + MS_AUTH_RESPONSE_LENGTH] = 0;
                         if (resp->Flags[0])
                                slprintf((char*)message, message_space, "S=%s", responseDataBufPtr->fBufferData + 4);
                        else
                                slprintf((char*)message, message_space, "S=%s M=%s",
                                        responseDataBufPtr->fBufferData + 4, "Access granted");
                        authResult = 1;
			if ((ccp_wantoptions[0].mppe)) {
			    if (!dsauth_set_mppe_keys(dirRef, userNode, response, authAuthorityAttr, challenge)) {
				error("DSAuth plugin: MPPE key required, but its retrieval failed.\n");
				authResult = 0;
			    }
			} 
                    } 
                } 
            }
            dsCloseDirNode(userNode);
            dsDeallocAttributeValueEntry(dirRef, recordNameAttr);
            dsDeallocAttributeValueEntry(dirRef, authAuthorityAttr);
        }
    
cleanup:
		if (serviceInfo)
			CFRelease(serviceInfo);
        if (responseDataBufPtr)
            dsDataBufferDeAllocate(dirRef, responseDataBufPtr);
        if (authTypeDataNodePtr)
            dsDataNodeDeAllocate(dirRef, authTypeDataNodePtr);
        if (authDataBufPtr)
            dsDataBufferDeAllocate(dirRef, authDataBufPtr);

        dsCloseDirService(dirRef);
    }

    return authResult;
}
コード例 #11
0
tDirStatus
AuthenticateWithNode(
    tDirReference       dirRef,
    tDataListPtr        pathListToAuthNode,
    const char 		*username,
    const char 		*password
)
{
    tDirStatus          err;
    tDirStatus          junk;
    size_t              userNameLen;
    size_t              passwordLen;
    tDirNodeReference   authNodeRef;
    tDataNodePtr        authMethod;
    tDataBufferPtr      authOutBuf;
    tDataBufferPtr      authInBuf;
    unsigned long       length;

    if (!( (dirRef != NULL) || (pathListToAuthNode != NULL) ||
            (username != NULL) || (password != NULL) ) )
        return(eDSBadParam) ;

    authNodeRef = NULL;
    authMethod = NULL;
    authOutBuf = NULL;
    authInBuf = NULL;

    userNameLen = STlen(username);
    passwordLen = STlen(password);

    /* Open the authentication node. */

    err = dsOpenDirNode(dirRef, pathListToAuthNode, &authNodeRef);

    /*
    ** Create the input parameters to dsDoDirNodeAuth and then call it.
    ** The most complex input parameter to dsDoDirNodeAuth is authentication
    ** data itself, held in authInBuf.  This holds the following items:
    **
    ** 4 byte length of user name (includes trailing null)
    ** user name, including trailing null
    ** 4 byte length of password (includes trailing null)
    ** password, including trailing null
    */

    if (err == eDSNoErr)
    {
        authMethod = dsDataNodeAllocateString(dirRef,
                                              kDSStdAuthNodeNativeClearTextOK);
        if (authMethod == NULL)
            err = eDSAllocationFailed;
    }
    if (err == eDSNoErr)
    {
        /*
            ** Allocate some arbitrary amount of space for the authOutBuf.  This
            ** buffer comes back containing a credential generated by the
            ** authentication (apparently a kDS1AttrAuthCredential).  However,
            ** we never need this information, so we basically just create the
            ** buffer, pass it in to dsDoDirNodeAuth, and then throw it away.
            ** Unfortunately dsDoDirNodeAuth won't let us pass in NULL.
        */

        authOutBuf = dsDataBufferAllocate(dirRef, kDefaultDSBufferSize);
        if (authOutBuf == NULL)
            err = eDSAllocationFailed;
    }
    if (err == eDSNoErr)
    {
        authInBuf = dsDataBufferAllocate(dirRef,
                                         sizeof(length) + userNameLen + 1 +
                                         sizeof(length) + passwordLen + 1 );

        if (authInBuf == NULL)
            err = eDSAllocationFailed;
    }
    /* Move the data into the buffer. */
    if (err == eDSNoErr)
    {
        length = userNameLen + 1;   /* + 1 to include trailing null */
        err = dsDataBufferAppendData(authInBuf, &length, sizeof(length));
    }
    if (err == eDSNoErr)
    {
        err = dsDataBufferAppendData(authInBuf, username,
                                     userNameLen + 1);
    }
    if (err == eDSNoErr)
    {
        length = passwordLen + 1;   /* + 1 to include trailing null */
        err = dsDataBufferAppendData(authInBuf, &length, sizeof(length));
    }
    if (err == eDSNoErr)
        junk = dsDataBufferAppendData(authInBuf, password, passwordLen + 1);

    /* Call dsDoDirNodeAuth to do the authentication. */
    if (err == eDSNoErr)
        err = dsDoDirNodeAuthQ(dirRef, authNodeRef, authMethod,
                               true, authInBuf, &authOutBuf, NULL);

    /* Clean up. */

    if (authInBuf != NULL)
        dsDataBufferDeAllocate(dirRef, authInBuf);
    if (authOutBuf != NULL)
        dsDataBufferDeAllocate(dirRef, authOutBuf);
    if (authMethod != NULL)
        dsDataNodeDeAllocate(dirRef, authMethod);
    if (authNodeRef != NULL)
        dsCloseDirNode(authNodeRef);

    return err;
}
コード例 #12
0
tDirStatus
FindUsersAuthInfo(
    tDirReference       dirRef,
    tDirNodeReference   nodeRef,
    const char *        username,
    tDataListPtr *      pathListToAuthNodePtr
)
{
    tDirStatus          err;
    tDirStatus          junk;
    tDataBufferPtr      buf;
    tDataListPtr        recordType;
    tDataListPtr        recordName;
    tDataListPtr        requestedAttributes;
    unsigned long       recordCount;
    tAttributeListRef   foundRecAttrList;
    tContextData        context;
    tRecordEntryPtr     foundRecEntry;
    tDataListPtr        pathListToAuthNode;

    if (!( (dirRef != NULL) || (nodeRef != NULL) || (username != NULL) ||
            ( pathListToAuthNodePtr != NULL) || (*pathListToAuthNodePtr == NULL) ) )
        return(eDSBadParam);

    recordType = NULL;
    recordName = NULL;
    requestedAttributes = NULL;
    foundRecAttrList = NULL;
    context = NULL;
    foundRecEntry = NULL;
    pathListToAuthNode = NULL;

    /*
    ** Allocate a buffer for the record results.  We'll grow this
    ** buffer if it proves to be too small.
    */

    err = eDSNoErr;
    buf = dsDataBufferAllocate(dirRef, kDefaultDSBufferSize);
    if (buf == NULL)
        err = eDSAllocationFailed;

    /*
    ** Create the information needed for the search.  We're searching for
    ** a record of type kDSStdRecordTypeUsers whose name is "username".
    ** We want to get back the kDSNAttrMetaNodeLocation and kDSNAttrRecordName
    ** attributes.
    */

    if (err == eDSNoErr)
    {
        recordType = dsBuildListFromStrings(dirRef, kDSStdRecordTypeUsers, NULL);
        recordName = dsBuildListFromStrings(dirRef, username, NULL);
        requestedAttributes = dsBuildListFromStrings(dirRef,
                              kDSNAttrMetaNodeLocation, kDSNAttrRecordName, NULL);

        if ( (recordType == NULL) || (recordName == NULL) ||
                (requestedAttributes == NULL) )
            err = eDSAllocationFailed;
    }

    /* Search for a matching record. */

    if (err == eDSNoErr) {
        recordCount = 1;            /* we only want one match (the first) */

        err = dsGetRecordListQ(
                  dirRef,
                  nodeRef,
                  &buf,
                  recordName,
                  eDSExact,
                  recordType,
                  requestedAttributes,
                  false,
                  &recordCount,
                  &context
              );
    }

    if ( (err == eDSNoErr) && (recordCount < 1) )
        err = eDSRecordNotFound;

    /*
    ** Get the first record from the search.  Then enumerate the attributes for
    ** that record.  For each attribute, extract the first value (remember that
    ** attributes can by multi-value).  Then see if the attribute is one that
    ** we care about.  If it is, remember the value for later processing.
    */
    if (err == eDSNoErr)
        err = dsGetRecordEntry(nodeRef, buf, 1, &foundRecAttrList,
                               &foundRecEntry);

    if (err == eDSNoErr)
    {
        unsigned long attrIndex;

        /* Iterate over the attributes. */

        for (attrIndex = 1;
                attrIndex <= foundRecEntry->fRecordAttributeCount;
                attrIndex++)
        {
            tAttributeValueListRef  thisValue;
            tAttributeEntryPtr      thisAttrEntry;
            tAttributeValueEntryPtr thisValueEntry;
            const char *            thisAttrName;

            thisValue = NULL;
            thisAttrEntry = NULL;
            thisValueEntry = NULL;

            /* Get the information for this attribute. */

            err = dsGetAttributeEntry(nodeRef, buf, foundRecAttrList, attrIndex,
                                      &thisValue, &thisAttrEntry);

            if (err == eDSNoErr)
            {
                thisAttrName = thisAttrEntry->fAttributeSignature.fBufferData;

                /* We only care about attributes that have values. */

                if (thisAttrEntry->fAttributeValueCount > 0)
                {
                    /*
                    ** Get the first value for this attribute.  This is common
                    ** code for the two potential attribute values listed below,
                    ** so we do it first.
                    */

                    err = dsGetAttributeValue(nodeRef, buf, 1, thisValue,
                                              &thisValueEntry);

                    if (err == eDSNoErr)
                    {
                        const char *    thisValueDataPtr;
                        unsigned long   thisValueDataLen;

                        thisValueDataPtr = thisValueEntry->fAttributeValueData.fBufferData;
                        thisValueDataLen = thisValueEntry->fAttributeValueData.fBufferLength;

                        /*
                                    ** Handle each of the two attributes we care about;
                        ** ignore any others.
                        */

                        if ( STcompare(thisAttrName,
                                       kDSNAttrMetaNodeLocation) == 0 )
                        {

                            /*
                                        ** This is the kDSNAttrMetaNodeLocation attribute,
                            ** which contains a path to the node used for
                            ** authenticating this record; convert its value
                            ** into a path list.
                            */

                            pathListToAuthNode = dsBuildFromPath(
                                                     dirRef,
                                                     thisValueDataPtr,
                                                     "/"
                                                 );
                            if (pathListToAuthNode == NULL)
                                err = eDSAllocationFailed;

                        }
                    }
                    else
                    {
                        fprintf(stderr, "FindUsersAuthInfo: Unexpected no-value attribute '%s'.", thisAttrName);
                    }
                }

                /* Clean up. */

                if (thisValueEntry != NULL)
                    dsDeallocAttributeValueEntry(dirRef, thisValueEntry);
                if (thisValue != NULL)
                    dsCloseAttributeValueList(thisValue);
                if (thisAttrEntry != NULL)
                    dsDeallocAttributeEntry(dirRef, thisAttrEntry);

                if (err != eDSNoErr)
                    break;
            }
        } /* Check attr loop */
    }

    /* Copy results out to caller. */

    if (err == eDSNoErr)
    {
        if (pathListToAuthNode != NULL)
        {
            /* Copy out results. */

            *pathListToAuthNodePtr = pathListToAuthNode;

            /* NULL out locals so that we don't dispose them. */

            pathListToAuthNode = NULL;
        }
        else
            err = eDSAttributeNotFound;
    }

    /* Clean up. */

    if (pathListToAuthNode != NULL)
        dsDataListAndHeaderDeallocate(dirRef, pathListToAuthNode);
    if (foundRecAttrList != NULL)
        dsCloseAttributeList(foundRecAttrList);
    if (context != NULL)
        dsReleaseContinueData(dirRef, context);
    if (foundRecAttrList != NULL)
        dsDeallocRecordEntry(dirRef, foundRecEntry);
    if (requestedAttributes != NULL)
        dsDataListAndHeaderDeallocate(dirRef, requestedAttributes);
    if (recordName != NULL)
        dsDataListAndHeaderDeallocate(dirRef, recordName);
    if (recordType != NULL)
        dsDataListAndHeaderDeallocate(dirRef, recordType);
    if (buf != NULL)
        dsDataBufferDeAllocate(dirRef, buf);

    return err;
}
コード例 #13
0
tDirStatus
getdsnodepath(tDirReference dirRef, tDataListPtr *dsnodepath)
{
    tDirStatus          err;
    tDirStatus          junk;
    tDataBufferPtr      buf;
    tDirPatternMatch    patternToFind;
    unsigned long       nodeCount;
    tContextData        context;

    if (!( (dirRef != NULL) || ( dsnodepath != NULL) || (*dsnodepath == NULL) ) )
        return( eDSBadParam );

    if (authlocalonly)
        patternToFind = eDSLocalNodeNames;
    else
        patternToFind = eDSAuthenticationSearchNodeName;

    context = NULL;

    /*
    ** Allocate a buffer for the node find results.  We'll grow
    ** this buffer if it proves to be to small.
    */

    buf = dsDataBufferAllocate(dirRef, kDefaultDSBufferSize);
    err = eDSNoErr;
    if (buf == NULL)
        err = eDSAllocationFailed;

    /*
    ** Find the node.  Note that this is a degenerate case because
    ** we're only looking for a single node, the search node, so
    ** we don't need to loop calling dsFindDirNodes, which is the
    ** standard way of using dsFindDirNodes.
    */

    if (err == eDSNoErr)
    {
        err = dsFindDirNodesQ(
                  dirRef,
                  &buf,                               /* place results here */
                  NULL,                               /* no pattern, rather... */
                  patternToFind,                      /* ... hardwired search type */
                  &nodeCount,
                  &context
              );
    }

    /* If we didn't find any nodes, that's bad. */

    if ( (err == eDSNoErr) && (nodeCount < 1) )
        err = eDSNodeNotFound;

    /*
    ** Grab the first node from the buffer.  Note that the inDirNodeIndex
    ** parameter to dsGetDirNodeName is one-based, so we pass in the constant
    ** 1.
    **
    ** Also, if we found more than one, that's unusual, but not enough to
    ** cause us to error.
    */

    if (err == eDSNoErr)
        err = dsGetDirNodeName(dirRef, buf, 1, dsnodepath);

    /* Clean up. */

    if (context != NULL)
        dsReleaseContinueData(dirRef, context);
    if (buf != NULL)
        dsDataBufferDeAllocate(dirRef, buf);

    return err;
}
コード例 #14
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;
}
コード例 #15
0
ファイル: opendir.c プロジェクト: nemith/freeradius-server
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;
	uint32_t		uiCurr		 = 0;
	uint32_t		uiLen		 = 0;
	char			*username_string = NULL;
	char			*shortUserName	 = NULL;
	VALUE_PAIR		*response	 = pairfind(request->packet->vps, PW_MSCHAP2_RESPONSE, VENDORPEC_MICROSOFT);
#ifndef NDEBUG
	unsigned 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) {
		if (status != RLM_MODULE_NOOP) {
			RDEBUG2("od_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;
	
	RDEBUG2("OD username_string = %s, OD shortUserName=%s (length = %lu)\n", username_string, shortUserName, strlen(shortUserName));
	
	/* User name length + username */
	uiLen = (uint32_t)strlen(shortUserName);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(uiLen));
	uiCurr += sizeof(uiLen);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), shortUserName, uiLen);
	uiCurr += uiLen;
#ifndef NDEBUG
	RDEBUG2("	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(uiLen));
	uiCurr += sizeof(uiLen);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(challenge->vp_strvalue[0]),
	       uiLen);
	uiCurr += uiLen;
	
#ifndef NDEBUG
	RDEBUG2("	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(uiLen));
	uiCurr += sizeof(uiLen);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(response->vp_strvalue[2]),
	       uiLen);
	uiCurr += uiLen;	
	
#ifndef NDEBUG
	RDEBUG2("	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(uiLen));
	uiCurr += sizeof(uiLen);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), &(response->vp_strvalue[26]),
	       uiLen);
	uiCurr += uiLen;
	
	/* Client generated use name (short name?) */
	uiLen =  (uint32_t)strlen(username_string);
	memcpy(&(tDataBuff->fBufferData[uiCurr]), &uiLen, sizeof(uiLen));
	uiCurr += sizeof(uiLen);
	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) {
			uint32_t len;
			
			memcpy(&len, pStepBuff->fBufferData, sizeof(len));
			if (len == 40) {
				char mschap_reply[42] = { '\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, &request->reply->vps,
						 *response->vp_strvalue,
						 "MS-CHAP2-Success",
						 mschap_reply, len+2);
				RDEBUG2("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;
}
コード例 #16
0
ファイル: main.c プロジェクト: Deanzou/ppp
//----------------------------------------------------------------------
//      dsauth_pap
//----------------------------------------------------------------------
static int dsauth_pap(char *user, char *passwd, char **msgp, struct wordlist **paddrs, struct wordlist **popts)
{
    tDirReference				dirRef;
    tDirNodeReference			userNode = 0;
    tDataNodePtr				authTypeDataNodePtr = 0;
    tDataBufferPtr				authDataBufPtr = 0;
    tDataBufferPtr				responseDataBufPtr = 0;
    tAttributeValueEntryPtr 	recordNameAttr = 0;
    tAttributeValueEntryPtr 	authAuthorityAttr = 0;
    tDirStatus					dsResult = eDSNoErr;
    char						*ptr;
    int							authResult = 0;
    u_int32_t					userShortNameSize;
    
    u_int32_t					passwordSize = strlen(passwd);
    u_int32_t					authDataSize;

    if ((dsResult = dsOpenDirService(&dirRef)) == eDSNoErr) {    

        if ((responseDataBufPtr = dsDataBufferAllocate(dirRef, BUF_LEN)) == 0) {
            error("DSAuth plugin: Could not allocate data buffer\n");
            goto cleanup;
        }
        if ((authTypeDataNodePtr = dsDataNodeAllocateString(dirRef, kDSStdAuthNodeNativeNoClearText)) == 0) {
            error("DSAuth plugin: Could not allocate data buffer\n");
            goto cleanup;
        }

        if (dsauth_find_user_node(dirRef, user, &userNode, &recordNameAttr, &authAuthorityAttr) == 0) {            
            userShortNameSize = recordNameAttr->fAttributeValueData.fBufferLength;
            authDataSize = userShortNameSize + passwordSize + (2 * sizeof(u_int32_t));
            
            if ((authDataBufPtr = dsDataBufferAllocate(dirRef, authDataSize)) != 0) {   
                authDataBufPtr->fBufferLength = authDataSize;
            
                /* store user name and password into the auth buffer in the correct format */
                ptr = (char*)(authDataBufPtr->fBufferData);
                
                // 4 byte length & user name
                *((u_int32_t*)ptr) =  userShortNameSize;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, recordNameAttr->fAttributeValueData.fBufferData, userShortNameSize);
                ptr += userShortNameSize;
                
                // 4 byte length & password
                *((u_int32_t*)ptr) = passwordSize;
                ptr += sizeof(u_int32_t);
                memcpy(ptr, passwd, passwordSize);
                
                if ((dsResult = dsDoDirNodeAuth(userNode, authTypeDataNodePtr, TRUE, authDataBufPtr, 
                        responseDataBufPtr, 0)) == eDSNoErr) {						
                    authResult = 1;
                    info("DSAuth plugin: user authentication successful\n");
                }
                
                bzero(authDataBufPtr->fBufferData, authDataSize);	// don't leave password in buffer
            }
            dsCloseDirNode(userNode); 					// returned from dsauth_find_user()
            dsDeallocAttributeValueEntry(dirRef, recordNameAttr); 
            dsDeallocAttributeValueEntry(dirRef, authAuthorityAttr); 
        }
    
cleanup:

        if (responseDataBufPtr)
            dsDataBufferDeAllocate(dirRef, responseDataBufPtr);
        if (authTypeDataNodePtr)
            dsDataNodeDeAllocate(dirRef, authTypeDataNodePtr);
        if (authDataBufPtr)
            dsDataBufferDeAllocate(dirRef, authDataBufPtr);

        dsCloseDirService(dirRef);
    }
    
    return authResult;

}
コード例 #17
0
ファイル: opendir.c プロジェクト: nemith/freeradius-server
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;
}
コード例 #18
0
ファイル: main.c プロジェクト: Deanzou/ppp
//----------------------------------------------------------------------
//	dsauth_set_mppe_keys
//		get the mppe keys from the password server
//		if this fails - do nothing.  there is no way to
//		know if the keys are actually going to be needed
//		at this point.
//----------------------------------------------------------------------
static int dsauth_set_mppe_keys(tDirReference dirRef, tDirNodeReference userNode, u_char *remmd, 
				 tAttributeValueEntryPtr authAuthorityAttr,
				 const unsigned char *challenge)
{
    tDataNodePtr		authKeysDataNodePtr = 0;
    tDataBufferPtr		authDataBufPtr = 0;
    tDataBufferPtr		responseDataBufPtr = 0;
	tDataBufferPtr		chapDataBufPtr = NULL;
    tDirStatus 			dsResult = eDSNoErr;
    char				*ptr, *comma, *tagStart;
    MS_Chap2Response	*resp;  
    char				*keyaccessPassword = 0;
    char				*keyaccessName = 0;
    u_int32_t			keyaccessNameSize = 0;
    u_int32_t			keyaccessPasswordSize;
    int					len, i;
    u_int32_t			slotIDSize = 0;
	const char			*slotID;
	tContextData		dir_context = 0;
    int				status = 0;

    mppe_keys_set = 0;

 	// parse authAuthorityAttribute to determine if key agent needs to be used.
	// auth authority tag will be between 2 semicolons.
	tagStart = 0;
	ptr = authAuthorityAttr->fAttributeValueData.fBufferData;
	// DSAuth_hex_print("authAuth mppe", authAuthorityAttr->fAttributeValueData.fBufferData, authAuthorityAttr->fAttributeValueData.fBufferLength);
	for (i = 0; i < authAuthorityAttr->fAttributeValueData.fBufferLength; i++) {
		if (*ptr == ';') {
			if (tagStart == 0)
				tagStart = ptr + 1;
			else
				break;
		}
		ptr++;
	}
	
	if (*ptr != ';') {
		error("DSAuth plugin: Password Server not available for MPPE key retrieval.\n");
		return (status);
	}
	if (strncmp(tagStart, kDSTagAuthAuthorityPasswordServer, ptr - tagStart) == 0) {
		dsauth_get_admin_acct(&keyaccessNameSize, &keyaccessName, &keyaccessPasswordSize, &keyaccessPassword);
		if (keyaccessName == 0) {
			error("DSAuth plugin: Could not retrieve key agent account information.\n");
			return (status);
		}
		
		// PWS auths expect to receive the PWS ID in the MPPE phase
		comma = strchr(ptr, ',');
		if (comma == NULL) {
			error("DSAuth plugin: Could not retrieve slot ID.\n");
			return (status);
		}

		slotID = ptr + 1; // skip the ';' as well
		slotIDSize = comma - slotID;
	} else {
	        error("DSAuth plugin: unsupported authen authority: recved %s, want %s\n", tagStart, kDSTagAuthAuthorityPasswordServer);
		return (status);		// unsupported authentication authority - don't set the keys
	}
        
	resp = (MS_Chap2Response*)remmd;
	
    if ((responseDataBufPtr = dsDataBufferAllocate(dirRef, BUF_LEN)) == 0) {
        error("DSAuth plugin: Could not allocate data buffer\n");
        goto cleanup;
    }
    if ((authKeysDataNodePtr = dsDataNodeAllocateString(dirRef, kDSStdAuthMPPEMasterKeys)) == 0) {
        error("DSAuth plugin: Could not allocate data buffer\n");
        goto cleanup;
    }
    if ((authDataBufPtr = dsDataBufferAllocate(dirRef, BUF_LEN)) == 0) {   
        error("DSAuth plugin: Could not allocate data buffer\n");
        goto cleanup;
    }
	
	/*
	 * phase 1 uses an MSCHAP-style auth for the VPN agent (agent account, server challenge, peer challenge, agent NT response, agent account)
	 * phase 2 retrieves the keys (PWS ID of the user, client NT response, keysize)
	 */
	
	// Phase 1
	chapDataBufPtr = dsauth_agent_authbuffer(dirRef, keyaccessName, keyaccessNameSize,
						 keyaccessPassword, keyaccessPasswordSize,
						 challenge);
	if (chapDataBufPtr == NULL) {
		error("DSAuth plugin: Could not generate agent auth buffer\n");
		goto cleanup;
	}

	if ((dsResult = dsDoDirNodeAuth(userNode, authKeysDataNodePtr, TRUE, chapDataBufPtr, 
			responseDataBufPtr, &dir_context)) != eDSNoErr) {
		error("DSAuth plugin: Could not authenticate key agent for encryption key retrieval, err %d\n", dsResult);
		goto cleanup;
	}

	// Phase 2
	ptr = (char*)(authDataBufPtr->fBufferData);

	// DSAuth_hex_print("PWS ID", slotID, slotIDSize);
	// DSAuth_hex_print("NTResp", resp->NTResp, NT_RESPONSE_SIZE);

	// 4 byte length & slotID
	*((u_int32_t*)ptr) = slotIDSize;
	ptr += sizeof(u_int32_t);
	memcpy(ptr, slotID, slotIDSize);
	ptr += slotIDSize;

	// 4 byte length & client digest
	*((u_int32_t*)ptr) = NT_RESPONSE_SIZE;
	ptr += sizeof(u_int32_t);
	memcpy(ptr, resp->NTResp, NT_RESPONSE_SIZE);
	ptr += NT_RESPONSE_SIZE;

	// 4 byte length and master key len - always 128
	*((u_int32_t*)ptr) = 1;
	ptr += sizeof(u_int32_t);
	*ptr = MPPE_MAX_KEY_LEN;

	authDataBufPtr->fBufferLength = slotIDSize + NT_RESPONSE_SIZE + 1 + (3 * sizeof(u_int32_t));

	// get the mppe keys
	if ((dsResult = dsDoDirNodeAuth(userNode, authKeysDataNodePtr, TRUE, authDataBufPtr, 
		responseDataBufPtr, &dir_context)) == eDSNoErr) {
		if (responseDataBufPtr->fBufferLength == (2 * sizeof(u_int32_t)) + (2 * MPPE_MAX_KEY_LEN)) {
			ptr = (char*)(responseDataBufPtr->fBufferData);
			len = *((u_int32_t*)ptr);
			ptr += sizeof(u_int32_t);
			if (len == sizeof(mppe_send_key))
					memcpy(mppe_send_key, ptr, sizeof(mppe_send_key));
			ptr += len;
			len = *((u_int32_t*)ptr);
			ptr += sizeof(u_int32_t);
			if (len == sizeof(mppe_recv_key))
					memcpy(mppe_recv_key, ptr, sizeof(mppe_recv_key));
			mppe_keys_set = 1;
			status = 1;
		} else 
		    error("DSAuth plugin: Invalid MPPE data for encryption keys retrieval\n");

	} else
		error("DSAuth plugin: Failed to retrieve MPPE encryption keys from the password server: errno %d, ctxt %x\n", dsResult, dir_context);
        
cleanup:
	if (dir_context != 0) {
		dsReleaseContinueData(dirRef, dir_context);
	}
    if (keyaccessPassword) {
		bzero(keyaccessPassword, keyaccessPasswordSize);	// clear the admin password from memory
#if !TARGET_OS_EMBEDDED // This file is not built for Embedded
        SecKeychainItemFreeContent(NULL, keyaccessPassword);
#endif /* TARGET_OS_EMBEDDED */
    }
    if (keyaccessName) {
        free(keyaccessName);
    }
    if (responseDataBufPtr)
        dsDataBufferDeAllocate(dirRef, responseDataBufPtr);
    if (chapDataBufPtr)
        dsDataNodeDeAllocate(dirRef, chapDataBufPtr);
    if (authKeysDataNodePtr)
        dsDataNodeDeAllocate(dirRef, authKeysDataNodePtr);
    if (authDataBufPtr)
        dsDataBufferDeAllocate(dirRef, authDataBufPtr);
   
    return (status);
}
コード例 #19
0
long
LWIRecordListQuery::Test(
    IN const char* DsPath,
    IN tDataListPtr RecNameList,
    IN tDirPatternMatch PatternMatch,
    IN tDataListPtr RecTypeList,
    IN tDataListPtr AttribTypeList,
    IN dsBool AttribInfoOnly,
    IN unsigned long Size
    )
{
    long macError = eDSNoErr;
    tDirReference dirRef = 0;
    tDirNodeReference dirNode = 0;
    tDataListPtr dirNodeName = NULL;
    tDataBufferPtr pData = NULL;
    UInt32 outCount;
    tContextData continueData = NULL;

    LOG_ENTER("");

    macError = dsOpenDirService( &dirRef );
    GOTO_CLEANUP_ON_MACERROR( macError );

    pData = dsDataBufferAllocate(dirRef, Size);
    if (!pData)
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP();
    }

    dirNodeName = dsBuildFromPath( dirRef, DsPath, "/" );
    if (!dirNodeName)
    {
        macError = eDSAllocationFailed;
        GOTO_CLEANUP();
    }

    macError = dsOpenDirNode( dirRef, dirNodeName, &dirNode );
    GOTO_CLEANUP_ON_MACERROR( macError );

    macError = dsGetRecordList( dirNode,
                                pData,
                                RecNameList,
                                PatternMatch,
                                RecTypeList,
                                AttribTypeList,
                                AttribInfoOnly,
                                &outCount,
                                &continueData);
    GOTO_CLEANUP_ON_MACERROR( macError );

    LOG("Got %d records", outCount);

    if (pData->fBufferLength > 0)
    {
        LOG_BUFFER(pData->fBufferData, pData->fBufferLength);
    }

cleanup:

    if ( pData )
    {
        dsDataBufferDeAllocate( dirRef, pData );
    }

    if ( dirNodeName )
    {
        dsDataListDeallocate( dirRef, dirNodeName );
    }

    if ( dirNode )
    {
        dsCloseDirNode( dirNode );
    }

    if ( dirRef )
    {
        dsCloseDirService( dirRef );
    }

    LOG_LEAVE("--> %d", macError);

    return macError;
}