KADirectoryNode *KADirectoryNodeCreateFromUserRecord(tDirReference directoryRef, CFDictionaryRef user_record) { KADirectoryNode *auth_node = NULL; const void *metanode_name = NULL; if (!user_record) return NULL; do { if (!CFDictionaryGetValueIfPresent(user_record, CFSTR(kDSNAttrMetaNodeLocation), &metanode_name) || !metanode_name) break; if (CFStringGetTypeID() != CFGetTypeID(metanode_name)) break; char metanode_name_cstring[1024]; if (!CFStringGetCString((CFStringRef)metanode_name, metanode_name_cstring, sizeof(metanode_name_cstring), kCFStringEncodingUTF8)) break; tDataListPtr metanode_name_list_ptr = dsBuildFromPath(directoryRef, metanode_name_cstring, "/"); if (!metanode_name_list_ptr) break; auth_node = KADirectoryNodeCreate(directoryRef, metanode_name_list_ptr); dsDataListDeallocate(directoryRef, metanode_name_list_ptr); } while (false); return auth_node; }
CFArrayRef find_records_by_attribute_value(KADirectoryNode *node, const char *recordType, const char *attributeType, tDirPatternMatch matchType, const char *attributeValue, const char *attributesReturned) { tDataNodePtr attributeTypeDataNode = dsDataNodeAllocateString(node->_directoryRef, kDSNAttrAuthenticationAuthority); tDataNodePtr attributeValueDataNode = dsDataNodeAllocateString(node->_directoryRef, attributeValue); tDataListPtr recordTypeDataList = dsBuildListFromStrings(node->_directoryRef, recordType, NULL); tDataListPtr returnAttributesDataList = dsBuildListFromStrings(node->_directoryRef, attributesReturned, NULL); CFArrayRef results = find_records_by_attribute_value_internal(node, recordTypeDataList, attributeTypeDataNode, matchType, attributeValueDataNode, returnAttributesDataList); if (attributeTypeDataNode) dsDataNodeDeAllocate(node->_directoryRef, attributeTypeDataNode); if (attributeValueDataNode) dsDataNodeDeAllocate(node->_directoryRef, attributeValueDataNode); if (recordTypeDataList) dsDataListDeallocate(node->_directoryRef, recordTypeDataList); if (returnAttributesDataList) dsDataListDeallocate(node->_directoryRef, returnAttributesDataList); return results; }
//---------------------------------------------------------------------- // dsauth_find_user_node //---------------------------------------------------------------------- static int dsauth_find_user_node(tDirReference dirRef, char *user_name, tDirNodeReference *user_node, tAttributeValueEntryPtr *recordNameAttr, tAttributeValueEntryPtr *authAuthorityAttr) { tDirStatus dsResult = eDSNoErr; tDataListPtr userPathDataListPtr = 0; UInt32 searchNodeCount; tAttributeValueEntryPtr userNodePath = 0; tDirNodeReference searchNodeRef = 0; *user_node = 0; // init return values *recordNameAttr = 0; *authAuthorityAttr = 0; // get search node ref if ((dsResult = dsauth_get_search_node_ref(dirRef, 1, &searchNodeRef, &searchNodeCount)) == eDSNoErr) { // get the meta node location attribute from the user's record dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDSNAttrMetaNodeLocation, &userNodePath); if (dsResult == eDSNoErr && userNodePath != 0) { // open the user node and return the node ref if ((userPathDataListPtr = dsBuildFromPath(dirRef, userNodePath->fAttributeValueData.fBufferData, "/"))) { dsResult = dsOpenDirNode(dirRef, userPathDataListPtr, user_node); dsDataListDeallocate(dirRef, userPathDataListPtr); } if (dsResult == eDSNoErr) dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDSNAttrRecordName, recordNameAttr); // DSAuth_hex_print("authAuth find_u_node unmae", user_name, strlen(user_name)); // DSAuth_hex_print("authAuth find_u_node recName", (*recordNameAttr)->fAttributeValueData.fBufferData, (*recordNameAttr)->fAttributeValueData.fBufferLength); if (dsResult == eDSNoErr) dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDSNAttrAuthenticationAuthority, authAuthorityAttr); // DSAuth_hex_print("authAuth find_u_node", (*authAuthorityAttr)->fAttributeValueData.fBufferData, (*authAuthorityAttr)->fAttributeValueData.fBufferLength); } if (userNodePath) dsDeallocAttributeValueEntry(dirRef, userNodePath); dsCloseDirNode(searchNodeRef); // close the search node ref } if (dsResult != eDSNoErr || *user_node == 0 || *recordNameAttr == 0 || *authAuthorityAttr == 0) { if (*user_node) dsCloseDirNode(*user_node); if (*recordNameAttr) dsDeallocAttributeValueEntry(dirRef, *recordNameAttr); if (*authAuthorityAttr) dsDeallocAttributeValueEntry(dirRef, *authAuthorityAttr); return -1; } return 0; }
static long UnregisterGPONode( PCSTR pszDomain, PCSTR pszGPOName ) { long macError = eDSNoErr; tDataListPtr nodeNameList = NULL; char szChildNodeName[1024]; if (!pszDomain) { macError = eDSEmptyParameter; GOTO_CLEANUP_ON_MACERROR( macError ); } /* Build up node names for each child node found */ nodeNameList = dsDataListAllocate(0); if ( !nodeNameList ) { macError = eDSAllocationFailed; GOTO_CLEANUP_ON_MACERROR( macError ); } memset(szChildNodeName, 0, sizeof(szChildNodeName)); strcpy(szChildNodeName, PLUGIN_ROOT_PATH); strcat(szChildNodeName, "/"); strcat(szChildNodeName, pszDomain); strcat(szChildNodeName, "/"); strcat(szChildNodeName, pszGPOName); macError = dsBuildListFromPathAlloc(0, nodeNameList, szChildNodeName, "/"); GOTO_CLEANUP_ON_MACERROR( macError ); macError = DSUnregisterNode(GlobalState.Signature, nodeNameList); cleanup: if (nodeNameList) { dsDataListDeallocate(0, nodeNameList); free(nodeNameList); } return macError; }
/* ** Name: dsDataListAndHeaderDeallocate ** ** Description: ** dsDataListDeallocate deallocates the list contents but /not/ the ** list header (because the list header could be allocated on the ** stack). This routine is a wrapper that deallocates both. It's ** the logical opposite of the various list allocation routines ** (for example, dsBuildFromPath). ** ** Input: ** inDirReference - data list to be deallocated ** inDataList - list header ** Output: ** None. ** ** History: ** 30-Jun-2005 (hanje04) ** Created. */ tDirStatus dsDataListAndHeaderDeallocate( tDirReference inDirReference, tDataListPtr inDataList ) { tDirStatus err; if (!(inDirReference != NULL) || (inDataList != NULL) ) return(eDSBadParam); err = dsDataListDeallocate(inDirReference, inDataList); if (err == eDSNoErr) { free(inDataList); } return err; }
// 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; }
/* * This must be called between GS_ACQUIRE_EXCLUSIVE() and GS_RELEASE(). */ static long Activate(void) { long macError = eDSNoErr; tDataListPtr nodeNameList = NULL; BOOLEAN bIsStarted = FALSE; LOG_ENTER(""); LOG("Verify that LSASS service is operational"); GlobalState.IsStartupComplete = false; // Verify that startup has completed successfully for lsass service. GetLsaStatus(&bIsStarted); if (bIsStarted) { LOG("LSASS service is operational"); GlobalState.IsStartupComplete = true; } if ( !GlobalState.DsRoot ) { macError = dsOpenDirService( &GlobalState.DsRoot ); GOTO_CLEANUP_ON_MACERROR( macError ); } if ( !GlobalState.NodeNameList ) { nodeNameList = dsDataListAllocate(0); if ( !nodeNameList ) { macError = eDSAllocationFailed; GOTO_CLEANUP_ON_MACERROR( macError ); } macError = dsBuildListFromPathAlloc(0, nodeNameList, PLUGIN_ROOT_PATH, "/"); GOTO_CLEANUP_ON_MACERROR( macError ); macError = DSRegisterNode(GlobalState.Signature, nodeNameList, kDirNodeType); GOTO_CLEANUP_ON_MACERROR( macError ); GlobalState.NodeNameList = nodeNameList; nodeNameList = NULL; } if ( !GlobalState.NodeDictionary ) { GlobalState.NodeDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } cleanup: if (nodeNameList) { dsDataListDeallocate(0, nodeNameList); free(nodeNameList); } if (macError) { long localMacError = Deactivate(); if (localMacError) { LOG_ERROR("Unexpected error: %d", localMacError); } } LOG_LEAVE("--> %d", macError); return macError; }
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; }
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; }
DECLEXPORT(AuthResult) AUTHCALL AuthEntry(const char *szCaller, PAUTHUUID pUuid, AuthGuestJudgement guestJudgement, const char *szUser, const char *szPassword, const char *szDomain, int fLogon, unsigned clientId) { /* Validate input */ AssertPtrReturn(szUser, AuthResultAccessDenied); AssertPtrReturn(szPassword, AuthResultAccessDenied); /* Result to a default value */ AuthResult result = AuthResultAccessDenied; /* Only process logon requests. */ if (!fLogon) return result; /* Return value is ignored by the caller. */ tDirStatus dsErr = eDSNoErr; tDirStatus dsCleanErr = eDSNoErr; tDirReference pDirRef = NULL; /* Connect to the Directory Service. */ dsErr = dsOpenDirService(&pDirRef); if (dsErr == eDSNoErr) { /* Fetch the default search node */ tDataListPtr pSearchNodeList = NULL; dsErr = defaultSearchNodePath(pDirRef, &pSearchNodeList); if (dsErr == eDSNoErr) { /* Open the default search node */ tDirNodeReference pSearchNodeRef = NULL; dsErr = dsOpenDirNode(pDirRef, pSearchNodeList, &pSearchNodeRef); if (dsErr == eDSNoErr) { /* Search for the user info, fetch the authentication node & * the authentication user name. This allows the client to * specify a long user name even if the name which is used to * authenticate has the short form. */ tDataListPtr pAuthNodeList = NULL; dsErr = userAuthInfo(pDirRef, pSearchNodeRef, szUser, &pAuthNodeList); if (dsErr == eDSNoErr) { /* Open the authentication node and do the authentication. */ dsErr = authWithNode(pDirRef, pAuthNodeList, szUser, szPassword); if (dsErr == eDSNoErr) result = AuthResultAccessGranted; dsCleanErr = dsDataListDeallocate(pDirRef, pAuthNodeList); if (dsCleanErr == eDSNoErr) free(pAuthNodeList); } dsCloseDirNode(pSearchNodeRef); } dsCleanErr = dsDataListDeallocate(pDirRef, pSearchNodeList); if (dsCleanErr == eDSNoErr) free(pSearchNodeList); } dsCloseDirService(pDirRef); } return result; }
tDirStatus SaveAuthAuthoritiesWithRecordRef( CDSLocalPlugin* inPlugin, tDirNodeReference inNodeRef, tRecordReference inRecordRef, CAuthAuthority &inAATank ) { tDirStatus siResult = eDSAuthFailed; UInt32 avIndex = 0; UInt32 avCount = 0; char *aaStr = NULL; CFMutableDictionaryRef nodeDict = NULL; CFStringRef preRootAuthString = NULL; tDataListPtr attrValueList = NULL; try { // retrieve the same nodeDict the plugin object is going to use CFDictionaryRef openRecordDict = inPlugin->RecordDictForRecordRef( inRecordRef ); if ( openRecordDict == NULL ) throw( eDSInvalidRecordRef ); nodeDict = (CFMutableDictionaryRef)CFDictionaryGetValue( openRecordDict, CFSTR(kOpenRecordDictNodeDict) ); if ( nodeDict == NULL ) throw( eDSInvalidNodeRef ); preRootAuthString = (CFStringRef) CFDictionaryGetValue( nodeDict, CFSTR(kNodeAuthenticatedUserName) ); if ( preRootAuthString != NULL ) CFRetain( preRootAuthString ); CFDictionarySetValue( nodeDict, CFSTR(kNodeAuthenticatedUserName), CFSTR("root") ); avCount = inAATank.GetValueCount(); if ( avCount == 0 ) { siResult = inPlugin->RemoveAttribute( inRecordRef, CFSTR(kDSNAttrAuthenticationAuthority) ); } else { attrValueList = dsDataListAllocate( 0 ); for ( avIndex = 0; avIndex < avCount; avIndex++ ) { aaStr = inAATank.GetValueAtIndex( avIndex ); if ( aaStr != NULL ) { siResult = dsAppendStringToListAlloc( 0, attrValueList, aaStr ); DSFreeString( aaStr ); if ( siResult != eDSNoErr ) throw( siResult ); } } // need to use SetAttributeValues() instead of RemoveAttribute() to avoid deleting the // shadow hash files. tDataNodePtr attrTypeNode = dsDataNodeAllocateString( 0, kDSNAttrAuthenticationAuthority ); sSetAttributeValues apiData = { kSetAttributeValues, 0, inRecordRef, attrTypeNode, attrValueList }; char *recTypeStr = inPlugin->GetRecordTypeFromRef( inRecordRef ); siResult = inPlugin->SetAttributeValues( &apiData, recTypeStr ); DSFreeString( recTypeStr ); dsDataNodeDeAllocate( 0, attrTypeNode ); } if ( siResult != eDSNoErr ) throw( siResult ); } catch( tDirStatus err ) { DbgLog( kLogPlugin, "SaveAuthAuthorities(): got error %d", err ); siResult = err; } if ( preRootAuthString != NULL ) { CFDictionarySetValue( nodeDict, CFSTR(kNodeAuthenticatedUserName), preRootAuthString ); CFRelease( preRootAuthString ); } else { CFDictionaryRemoveValue( nodeDict, CFSTR(kNodeAuthenticatedUserName) ); } DSFreeString( aaStr ); if ( attrValueList != NULL ) { dsDataListDeallocate( 0, attrValueList ); free( attrValueList ); } return siResult; }
int AuthCleartext( char *inUsername, char *inPassword ) { tDirReference dsRef = 0; tDirNodeReference dsSearchNodeRef = 0; tDirNodeReference dsUserNodeRef = 0; tDirStatus dsStatus; char *pRecordName = NULL; char *pNodeName = NULL; // Key steps to Authenticating a user: // - First locate the user in the directory // - Open Directory Service reference // - Locate and open the Search Node // - Locate the user's official RecordName and Directory Node based on the username provided // - Then use authentication appropriate for the type of method // Open Directory Services reference dsStatus = dsOpenDirService( &dsRef ); if( dsStatus == eDSNoErr ) { // use utility function in DSUtility.h to open the search node dsStatus = OpenSearchNode( dsRef, &dsSearchNodeRef ); if( dsStatus == eDSNoErr ) { // use utility function in DSUtility.h to locate the user information dsStatus = LocateUserRecordNameAndNode( dsRef, dsSearchNodeRef, inUsername, &pRecordName, &pNodeName ); if( dsStatus == eDSNoErr ) { // we should have values available, but let's check to be sure if( pNodeName != NULL && pNodeName[0] != '\0' && pRecordName != NULL && pRecordName[0] != '\0' ) { // need to create a tDataListPtr from the "/plugin/node" path, using "/" as the separator tDataListPtr dsUserNodePath = dsBuildFromPath( dsRef, pNodeName, "/" ); dsStatus = dsOpenDirNode( dsRef, dsUserNodePath, &dsUserNodeRef ); if( dsStatus == eDSNoErr ) { // Use our Utility routine to do the authentication dsStatus = DoPasswordAuth( dsRef, dsUserNodeRef, kDSStdAuthNodeNativeClearTextOK, pRecordName, inPassword ); // Determine if successful. There are cases where you may receive other errors // such as eDSAuthPasswordExpired. if( dsStatus == eDSNoErr ) { printf( "Successful: Authentication successful for user '%s'\n", pRecordName ); } else { printf( "Failure: Authentication for user '%s' - %d\n", pRecordName, dsStatus ); } } // free the data list as it is no longer needed dsDataListDeallocate( dsRef, dsUserNodePath ); free( dsUserNodePath ); dsUserNodePath = NULL; } // need to free any node name that may have been returned if( pNodeName != NULL ) { free( pNodeName ); pNodeName = NULL; } // need to free any record name that may have been returned if( pRecordName != NULL ) { free( pRecordName ); pRecordName = NULL; } } // close the search node cause we are done here dsCloseDirNode( dsSearchNodeRef ); dsSearchNodeRef = 0; } else { printf( "Unable to locate and open the Search node\n" ); return 1; } // need to close Directory Services at this point dsCloseDirService( dsRef ); dsRef = 0; } return dsStatus; }
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; }
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; }
CFArrayRef find_user_records_by_name(KADirectoryNode *node, const char *username) { tDirStatus status = 0; long unsigned record_count = 0; // This is an input variable too tContextData continuation_data_ptr = NULL; CFMutableArrayRef results = NULL; tDataListPtr recordTypeDataList = dsBuildListFromStrings(node->_directoryRef, kDSStdRecordTypeUsers, NULL); tDataListPtr returnAttributesDataList = dsBuildListFromStrings(node->_directoryRef, kDSAttributesAll, NULL); tDataListPtr record_name_ptr = dsBuildListFromStrings(node->_directoryRef, username, NULL); do { for (;;) { status = dsGetRecordList(node->_nodeRef, node->_dataBufferPtr, record_name_ptr, eDSExact, recordTypeDataList, returnAttributesDataList, false, /* attr info and data */ &record_count, &continuation_data_ptr); // Of all errors we only try to recover from eDSBufferTooSmall here if ((status != eDSBufferTooSmall) || !(node->_dataBufferPtr = double_databuffer_or_bail(node->_directoryRef, node->_dataBufferPtr))) break; } if (status) break; if (record_count > 0) { long unsigned i; if (!results) results = CFArrayCreateMutable(kCFAllocatorDefault, record_count, &kCFTypeArrayCallBacks); for (i=1; i <= record_count; i++) { CFMutableDictionaryRef record = get_record_at_index(node, i); if (record) { CFArrayAppendValue(results, record); CFRelease(record); } } } } while (continuation_data_ptr != NULL); if (record_name_ptr) dsDataListDeallocate(node->_directoryRef, record_name_ptr); if (recordTypeDataList) dsDataListDeallocate(node->_directoryRef, recordTypeDataList); if (returnAttributesDataList) dsDataListDeallocate(node->_directoryRef, returnAttributesDataList); if (continuation_data_ptr) dsReleaseContinueData(node->_nodeRef, continuation_data_ptr); return results; }
/* * This must be called between GS_ACQUIRE_EXCLUSIVE() and GS_RELEASE(). */ static long Deactivate(void) { long macError = eDSNoErr; PGROUP_POLICY_OBJECT pTemp = NULL; if ( GlobalState.NodeDictionary ) { CFRelease(GlobalState.NodeDictionary); GlobalState.NodeDictionary = NULL; } if ( GlobalState.NodeNameList ) { macError = DSUnregisterNode( GlobalState.Signature, GlobalState.NodeNameList ); if (macError) { LOG_ERROR("Unregister error: %d", macError); } dsDataListDeallocate(0, GlobalState.NodeNameList); free(GlobalState.NodeNameList); GlobalState.NodeNameList = NULL; } while (GlobalState.pGPOs) { pTemp = GlobalState.pGPOs; GlobalState.pGPOs = pTemp->pNext; pTemp->pNext = NULL; /* Remove node representing the GPO */ UnregisterGPONode(GlobalState.pszRealm, pTemp->pszDisplayName); GPA_SAFE_FREE_GPO_LIST(pTemp); } if ( GlobalState.pszRealm ) { LW_SAFE_FREE_STRING(GlobalState.pszRealm); GlobalState.pszRealm = NULL; } GlobalState.IsJoinedToAD = false; if ( GlobalState.pNetAdapterList ) { LWFreeNetAdapterList(GlobalState.pNetAdapterList); GlobalState.pNetAdapterList = NULL; } if ( GlobalState.DsRoot ) { dsCloseDirService( GlobalState.DsRoot ); GlobalState.DsRoot = 0; } if (GlobalState.pAllowAdminCheckData) { FreeAccessCheckData(GlobalState.pAllowAdminCheckData); GlobalState.pAllowAdminCheckData = NULL; } return macError; }
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; }
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; }