//---------------------------------------------------------------------- // 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; }
void CDirService::cleanup() { if (dsSearchNodeRef) dsCloseDirNode(dsSearchNodeRef); dsSearchNodeRef = 0; if (dsRef) dsCloseDirService(dsRef); dsRef = 0; }
// helper routine to fine a user's official RecordName // char *FindUserFromPrincipal( char *inPrincipal ) { // now let's parse the name and see if we can find a valid user.. tDirReference dsRef = 0; tDirNodeReference dsSearchNodeRef = 0; tDirStatus dsStatus; char *pRecordName = NULL; char *pNodeName = NULL; char *pUsername = strdup( inPrincipal ); char *pAtSymbol = strchr( pUsername, '@' ); // need to parse just the name of the user, since principal is user@REALM if( pAtSymbol != NULL ) { *pAtSymbol = '\0'; } // 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, pUsername, &pRecordName, &pNodeName ); if( dsStatus == eDSNoErr ) { // need to free any node name that may have been returned if( pNodeName != NULL ) { free( pNodeName ); pNodeName = NULL; } } // close the search node cause we are done here dsCloseDirNode( dsSearchNodeRef ); dsSearchNodeRef = 0; } else { printf( "Unable to locate and open the Search node to verify user\n" ); } // need to close Directory Services at this point dsCloseDirService( dsRef ); dsRef = 0; } if( pUsername != NULL ) { free( pUsername ); pUsername = NULL; } return pRecordName; }
//---------------------------------------------------------------------- // dsaccess_authorize_user //---------------------------------------------------------------------- static int dsaccess_authorize_user(u_char* name, int len) { tDirReference dirRef; tDirStatus dsResult = eDSNoErr; int authorized = 0; tDirNodeReference searchNodeRef; tAttributeValueEntryPtr gUID; UInt32 searchNodeCount; char* user_name; uuid_t userid; int result; int ismember; if (len < 1) { error("DSAccessControl plugin: invalid user name has zero length\n"); return 0; } if ((user_name = (char*)malloc(len + 1)) == 0) { error("DSAccessControl plugin: unable to allocate memory for user name\n"); return 0; } bcopy(name, user_name, len); *(user_name + len) = 0; if ((dsResult = dsOpenDirService(&dirRef)) == eDSNoErr) { // get the search node ref if ((dsResult = dsauth_get_search_node_ref(dirRef, 1, &searchNodeRef, &searchNodeCount)) == eDSNoErr) { // get the user's generated user Id if ((dsResult = dsauth_get_user_attr(dirRef, searchNodeRef, user_name, kDS1AttrGeneratedUID, &gUID)) == eDSNoErr) { if (gUID != 0) { if (!mbr_string_to_uuid(gUID->fAttributeValueData.fBufferData, userid)) { // check if user is member authorized result = mbr_check_service_membership(userid, VPN_SERVICE_NAME, &ismember); if (result == ENOENT || (result == 0 && ismember != 0)) authorized = 1; } dsDeallocAttributeValueEntry(dirRef, gUID); } } dsCloseDirNode(searchNodeRef); // close the search node } dsCloseDirService(dirRef); } if (authorized) notice("DSAccessControl plugin: User '%s' authorized for access\n", user_name); else notice("DSAccessControl plugin: User '%s' not authorized for access\n", user_name); free(user_name); return authorized; }
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); }
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 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; }
tDirStatus OpenLDAPNode( CDSLocalPlugin *inPlugin, CFMutableDictionaryRef inNodeDict, tDataListPtr inNodeName, tDirReference *outDSRef, tDirNodeReference *outNodeRef ) { tDirStatus status = eDSNoErr; tDirReference ldapDirRef = 0; tDirNodeReference ldapNodeRef = 0; CFNumberRef ldapNodeRefNumber = NULL; try { CFNumberRef ldapDirRefNumber = (CFNumberRef)CFDictionaryGetValue( inNodeDict, CFSTR(kNodeLDAPDirRef) ); if ( ldapDirRefNumber != NULL ) CFNumberGetValue( ldapDirRefNumber, kCFNumberLongType, &ldapDirRef ); if ( ldapDirRef == 0 ) { status = inPlugin->GetDirServiceRef( &ldapDirRef ); if ( status != eDSNoErr ) throw( status ); ldapDirRefNumber = CFNumberCreate( NULL, kCFNumberLongType, &ldapDirRef ); CFDictionaryAddValue( inNodeDict, CFSTR(kNodeLDAPDirRef), ldapDirRefNumber ); CFRelease( ldapDirRefNumber ); } // Free prior LDAP node ldapNodeRefNumber = (CFNumberRef)CFDictionaryGetValue( inNodeDict, CFSTR(kNodeLDAPNodeRef) ); if ( ldapNodeRefNumber != NULL ) { CFNumberGetValue( ldapNodeRefNumber, kCFNumberLongType, &ldapNodeRef ); if ( ldapNodeRef != 0 ) { dsCloseDirNode( ldapNodeRef ); ldapNodeRef = 0; } CFDictionaryRemoveValue( inNodeDict, CFSTR(kNodeLDAPNodeRef) ); ldapNodeRefNumber = NULL; } status = dsOpenDirNode( ldapDirRef, inNodeName, &ldapNodeRef ); if ( status == eDSNoErr ) { ldapNodeRefNumber = CFNumberCreate( NULL, kCFNumberLongType, &ldapNodeRef ); CFDictionaryAddValue( inNodeDict, CFSTR(kNodeLDAPNodeRef), ldapNodeRefNumber ); CFRelease( ldapNodeRefNumber ); } } catch ( tDirStatus catchStatus ) { status = catchStatus; } *outDSRef = ldapDirRef; *outNodeRef = ldapNodeRef; return status; }
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; }
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; }
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; }
/* ** Name: usrauthosx ** ** Description: ** Verify username and password on Mac OSX using Open Directory ** ** Input: ** username - user to authenicate ** password - password for username ** Output: ** sys_err - errors (if any) ** ** History: ** 30-Jun-2005 (hanje04) ** Created. */ STATUS usrauthosx(char *username, char *password, CL_ERR_DESC *sys_err) { STATUS status; tDirStatus err; tDirStatus junk; tDirReference dirRef; tDataListPtr pathListToSearchNode; tDirNodeReference searchNodeRef; tDataListPtr pathListToAuthNode; if (!( (username != NULL) || (password != NULL) ) ) return(FAIL) ; dirRef = NULL; pathListToSearchNode = NULL; searchNodeRef = NULL; pathListToAuthNode = NULL; /* Connect to Open Directory. */ err = dsOpenDirService(&dirRef); /* Open the search node. */ if (err == eDSNoErr) err = getdsnodepath(dirRef, &pathListToSearchNode); if (err == eDSNoErr) err = dsOpenDirNode(dirRef, pathListToSearchNode, &searchNodeRef); /* ** Search for the user's record and extract the user's authentication ** node and authentication user name. */ if (err == eDSNoErr) err = FindUsersAuthInfo(dirRef, searchNodeRef, username, &pathListToAuthNode); /* Open the authentication node and do the authentication. */ if (err == eDSNoErr) err = AuthenticateWithNode(dirRef, pathListToAuthNode, username, password); /* Clean up. */ if (pathListToAuthNode != NULL) dsDataListAndHeaderDeallocate(dirRef, pathListToAuthNode); if (searchNodeRef != NULL) dsCloseDirNode(searchNodeRef); if (pathListToSearchNode != NULL) dsDataListAndHeaderDeallocate(dirRef, pathListToSearchNode); if (dirRef != NULL) dsCloseDirService(dirRef); /* Set status based on Open Directory err value */ switch (err) { case eDSNoErr: status = OK; break; case eDSAuthFailed: case eDSAuthNewPasswordRequired: case eDSAuthPasswordExpired: status = GC_USRPWD_FAIL; break; case eDSAuthAccountInactive: case eDSAuthAccountExpired: case eDSAuthAccountDisabled: case eDSRecordNotFound: status = GC_LSN_FAIL; break; default: status = GC_LOGIN_FAIL; } return(status); }
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; }
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; }
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; }
//---------------------------------------------------------------------- // 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; }
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; }
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; }
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; }