VOID TestStringListRemoveShouldHaveCorrectLayout( VOID) { PCSTR ppszStrings[] = { "Test 1", "Test 2", "Test 3", "Test 4", "Test 5" }; PVMDIR_STRING_LIST pStringList = NULL; DWORD dwError = 0; DWORD i = 0; dwError = VmDirStringListInitialize(&pStringList, 10); ASSERT(dwError == 0); for (i = 0; i < VMDIR_ARRAY_SIZE(ppszStrings); ++i) { dwError = VmDirStringListAdd(pStringList, ppszStrings[i]); ASSERT(dwError == 0); } dwError = VmDirStringListRemove(pStringList, ppszStrings[2]); ASSERT(dwError == 0); ASSERT(pStringList->dwCount == VMDIR_ARRAY_SIZE(ppszStrings) - 1); ASSERT(pStringList->pStringList[0] == ppszStrings[0]); ASSERT(pStringList->pStringList[1] == ppszStrings[1]); ASSERT(pStringList->pStringList[2] == ppszStrings[3]); ASSERT(pStringList->pStringList[3] == ppszStrings[4]); }
VOID TestStringListAddLayout( VOID ) { PSTR ppszStrings[5]; DWORD dwError = 0; DWORD i = 0; PVMDIR_STRING_LIST pStringList; dwError = VmDirStringListInitialize(&pStringList, 10); ASSERT(dwError == 0); for (i = 0; i < VMDIR_ARRAY_SIZE(ppszStrings); ++i) { ppszStrings[i] = GenerateString(); dwError = VmDirStringListAdd(pStringList, ppszStrings[i]); ASSERT(dwError == 0); } ASSERT(pStringList->dwCount == VMDIR_ARRAY_SIZE(ppszStrings)); for (i = 0; i < VMDIR_ARRAY_SIZE(ppszStrings); ++i) { ASSERT(pStringList->pStringList[i] == ppszStrings[i]); } VmDirStringListFree(pStringList); }
VOID _Test_VmDirStringNCpyA_CallShouldSucceedWithTruncation( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szDestination[6] = { 'a' }; dwError = VmDirStringNCpyA( szDestination, VMDIR_ARRAY_SIZE(szDestination), "Hello, world!", VMDIR_ARRAY_SIZE(szDestination) - 1); TestAssertEquals(dwError, 0); TestAssertStrEquals(szDestination, "Hello"); }
DWORD VmDirPagedSearchCacheInsert( PVDIR_OPERATION pOperation, DWORD dwCandidatesProcessed ) { DWORD dwError = 0; PVDIR_PAGED_SEARCH_RECORD pSearchRecord = NULL; if (*pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie == '\0') { dwError = VmDirPagedSearchCacheNodeAllocate( &pSearchRecord, pOperation, dwCandidatesProcessed); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirStringCpyA( pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), pSearchRecord->pszGuid ); BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: VmDirPagedSearchCacheRecordFree(pSearchRecord); goto cleanup; }
static int VmDirMain(int argc, char* argv[]) { DWORD dwError = 0; LDAP *pLd = NULL; COMMAND_LINE_PARAMETER_STATE State = { 0 }; PLW_HASHMAP pUserToSidMapping = NULL; // Used to store "user/group SID" => "display name" mapping. PLW_HASHMAP pSidToUserMapping = NULL; // Used to store "display name" => "user/group SID" mapping. CHAR pszPasswordBuf[VMDIR_MAX_PWD_LEN + 1] = { 0 }; dwError = VmDirParseArguments( &CommandLineOptions, &State, argc, argv); BAIL_ON_VMDIR_ERROR(dwError); dwError = VdcGetUsersPassword(&State, pszPasswordBuf, VMDIR_ARRAY_SIZE(pszPasswordBuf)); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirSafeLDAPBind( &pLd, State.pszServerName, State.pszUserName, pszPasswordBuf); BAIL_ON_VMDIR_ERROR(dwError); dwError = VdcLoadUsersAndGroups(pLd, State.pszBaseDN, &pUserToSidMapping, &pSidToUserMapping); BAIL_ON_VMDIR_ERROR(dwError); // // We're either granting a user/group privileges on an object or just showing the // existing privileges on it. // if (State.pszGrantParameter) { dwError = VdcGrantPermissionToUser(pLd, pUserToSidMapping, State.pszObjectName, State.pszGrantParameter); } else if (State.pszRemoveParameter) { dwError = VdcRemovePermissionFromUser(pLd, pUserToSidMapping, State.pszObjectName, State.pszRemoveParameter); } else { dwError = VdcPrintSecurityDescriptorForObject(pLd, pSidToUserMapping, State.pszObjectName, State.bVerbose); } cleanup: VdcFreeHashMap(&pUserToSidMapping); VdcFreeHashMap(&pSidToUserMapping); return dwError; error: goto cleanup; }
VOID testStack( PVMDIR_TEST_STATE pState, PDEQUE pDeque ) { DWORD dwError = 0; PDEQUEUE_TEST_ELEMENT pElement = NULL; int i = 0; for (i = 0; i < VMDIR_ARRAY_SIZE(arrDequeTestData); i++) { dwError = dequePush(pDeque, &arrDequeTestData[i]); TestAssertEquals(dwError, ERROR_SUCCESS); } for (i = 0; i < VMDIR_ARRAY_SIZE(arrDequeTestData); i++) { dwError = dequePop(pDeque, (PVOID*)&pElement); TestAssertEquals(dwError, ERROR_SUCCESS); TestAssertPtrEquals(pElement, &arrDequeTestData[VMDIR_ARRAY_SIZE(arrDequeTestData)-i-1]); } }
VOID _Test_VmDirStringNCpyA_CallShouldFailCountMatchesSize( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szBuffer[4] = { 'a' }; dwError = VmDirStringNCpyA( szBuffer, VMDIR_ARRAY_SIZE(szBuffer), "abcd", 4); TestAssertEquals(dwError, ERROR_INVALID_PARAMETER); TestAssertEquals(szBuffer[0], 'a'); }
VOID _Test_VmDirStringNCpyA_EmptySourceStringWrongCount( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szDestination[16] = { 'a' }; dwError = VmDirStringNCpyA( szDestination, VMDIR_ARRAY_SIZE(szDestination), "", 10); TestAssertEquals(dwError, 0); TestAssertEquals(szDestination[0], '\0'); }
VOID _Test_VmDirStringNCpyA_SourceStringTooLong( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szDestination[4] = { 'a' }; dwError = VmDirStringNCpyA( szDestination, VMDIR_ARRAY_SIZE(szDestination), "Hello, world!", 7); TestAssertEquals(dwError, ERROR_INVALID_PARAMETER); TestAssertEquals(szDestination[0], 'a'); }
VOID _Test_VmDirStringNCpyA_NullSourceString( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szDestination[16] = { 'a' }; dwError = VmDirStringNCpyA( szDestination, VMDIR_ARRAY_SIZE(szDestination), NULL, 10); TestAssertEquals(dwError, ERROR_INVALID_PARAMETER); TestAssertEquals(szDestination[0], 'a'); }
static BOOLEAN _VmDirIsBenignReplConflict( PVDIR_ENTRY pEntry, PVDIR_ATTRIBUTE pAttr ) { int i = 0; CHAR excludeAttrs[] = {ATTR_USN_CHANGED}; DWORD dwError = 0; BOOLEAN bIsBenign = FALSE; VDIR_ENTRY consumerEntry = {0}; if (pEntry->eId) { if (!consumerEntry.dn.lberbv_val) { PVDIR_BACKEND_INTERFACE pBE = NULL; pBE = VmDirBackendSelect(NULL); assert(pBE); dwError = pBE->pfnBESimpleIdToEntry(pEntry->eId, &consumerEntry); BAIL_ON_VMDIR_ERROR(dwError); } for (i=0; i< VMDIR_ARRAY_SIZE(excludeAttrs); i++) { if (VmDirStringCompareA(pAttr->type.lberbv_val, &excludeAttrs[i], FALSE) == 0) { bIsBenign = TRUE; goto cleanup; } } bIsBenign = VmDirIsSameConsumerSupplierEntryAttr(pAttr, pEntry, &consumerEntry); } cleanup: VmDirFreeEntryContent(&consumerEntry); return bIsBenign; error: VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
static VOID ComputeRequiredAccess( SearchReq* pSearchReq ) { DWORD i = 0, j = 0; BOOLEAN bSDAttr = FALSE; PSTR pszAttr = NULL; PCSTR pszSDAttrs[] = { ATTR_OBJECT_SECURITY_DESCRIPTOR, ATTR_ACL_STRING }; pSearchReq->accessRequired = VMDIR_RIGHT_DS_READ_PROP; for (i = 0; pSearchReq->attrs && pSearchReq->attrs[i].lberbv.bv_val; i++) { bSDAttr = FALSE; pszAttr = pSearchReq->attrs[i].lberbv.bv_val; for (j = 0; j < VMDIR_ARRAY_SIZE(pszSDAttrs); j++) { if (VmDirStringCompareA(pszAttr, pszSDAttrs[j], FALSE) == 0) { bSDAttr = TRUE; break; } } if (bSDAttr) { // SD attributes require only READ_CONTROL pSearchReq->accessRequired = VMDIR_ENTRY_READ_ACL; } else { // any other attributes require READ_PROP pSearchReq->accessRequired = VMDIR_RIGHT_DS_READ_PROP; break; // no need to continue } } }
static PCSTR _VmDirDCConnType( VMDIR_DC_CONNECTION_TYPE connType ) { struct { VMDIR_DC_CONNECTION_TYPE connType; PCSTR pszConnTypeName; } static connTypeToNameTable[] = { { DC_CONNECTION_TYPE_BASIC, "basic" }, { DC_CONNECTION_TYPE_REPL, "replication" }, { DC_CONNECTION_TYPE_CLUSTER_STATE, "cluster state" }, }; return connType >= VMDIR_ARRAY_SIZE(connTypeToNameTable) ? VMDIR_PCSTR_UNKNOWN : connTypeToNameTable[connType].pszConnTypeName; }
VOID _Test_VmDirStringNCpyA_EmptySourceStringRightCount( PVMDIR_TEST_STATE pState ) { DWORD dwError = 0; CHAR szDestination[16] = { '\0' }; // // This call will yield different results on windows and linux. On // the former we call the _s version of strncpy so the string's first byte // will be NULL, regardless of what it is coming into the call. However, // on linux the string will be untouched after the call. // dwError = VmDirStringNCpyA( szDestination, VMDIR_ARRAY_SIZE(szDestination), "", 0); TestAssertEquals(dwError, 0); TestAssertEquals(szDestination[0], '\0'); }
DWORD VmDirTestGetGuid( PSTR *ppszGuid ) { DWORD dwError = 0; PSTR pszGuid = NULL; uuid_t guid = {0}; char szGuid[VMDIR_GUID_STR_LEN] = {0}; VmDirUuidGenerate(&guid); VmDirUuidToStringLower(&guid, szGuid, VMDIR_ARRAY_SIZE(szGuid)); dwError = VmDirAllocateStringA(szGuid, &pszGuid); BAIL_ON_VMDIR_ERROR(dwError); *ppszGuid = pszGuid; cleanup: return dwError; error: goto cleanup; }
static DWORD SetPagedSearchCookie( PVDIR_OPERATION pOperation, ENTRYID eId, DWORD dwCandidatesProcessed ) { DWORD dwError = 0; if (gVmdirGlobals.bPagedSearchReadAhead) { dwError = VmDirPagedSearchCacheInsert( pOperation, dwCandidatesProcessed); } if (dwError != 0 || !gVmdirGlobals.bPagedSearchReadAhead) { // // We were unable to cache the information necessary. Fallback to the // old cookie mechanism. // dwError = VmDirStringPrintFA( pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(pOperation->showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), "%llu", eId); BAIL_ON_VMDIR_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
static int _ParsePagedResultControlVal( VDIR_OPERATION * op, BerValue * controlValue, // Input: control value encoded as ber VDIR_PAGED_RESULT_CONTROL_VALUE * pageResultCtrlVal, // Output VDIR_LDAP_RESULT * lr // Output ) { int retVal = LDAP_SUCCESS; BerElementBuffer berbuf; BerElement * ber = (BerElement *)&berbuf; PSTR pszLocalErrorMsg = NULL; PSTR pszCookie = NULL; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_ParsePagedResultControlVal: Start." ); if (!op) { retVal = LDAP_PROTOCOL_ERROR; BAIL_ON_VMDIR_ERROR( retVal ); } ber_init2( ber, controlValue, LBER_USE_DER ); /* http://www.ietf.org/rfc/rfc2696.txt * * The searchControlValue is an OCTET STRING wrapping the BER-encoded version of the following SEQUENCE: * * realSearchControlValue ::= SEQUENCE { * size INTEGER (0..maxInt), * -- requested page size from client * -- result set size estimate from server * cookie OCTET STRING } */ if (ber_scanf(ber, "{ia}", &pageResultCtrlVal->pageSize, &pszCookie) == LBER_ERROR) { VMDIR_LOG_ERROR( VMDIR_LOG_MASK_ALL, "_ParsePagedResultControlVal: ber_scanf failed while parsing " "pageSize and cookie in the page result control value" ); lr->errCode = LDAP_PROTOCOL_ERROR; retVal = LDAP_NOTICE_OF_DISCONNECT; BAIL_ON_VMDIR_ERROR_WITH_MSG( retVal, (pszLocalErrorMsg), "Error in reading pageSize and cookie in the page result control value"); } if (pageResultCtrlVal->pageSize == 0) { retVal = LDAP_CANCELLED; VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "Search query was cancelled."); BAIL_ON_VMDIR_ERROR(retVal); } VmDirStringNCpyA( pageResultCtrlVal->cookie, VMDIR_ARRAY_SIZE(pageResultCtrlVal->cookie), pszCookie, VMDIR_ARRAY_SIZE(pageResultCtrlVal->cookie) - 1); VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "pageSize:%d", pageResultCtrlVal->pageSize ); VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "cookie:%s", pageResultCtrlVal->cookie ); cleanup: if (pszCookie) { ber_memfree(pszCookie); } // Even in the error case, syncDoneCtrl should be freed during operation delete. VMDIR_LOG_DEBUG( LDAP_DEBUG_TRACE, "_ParsePagedResultControlVal: End." ); VMDIR_SAFE_FREE_MEMORY(pszLocalErrorMsg); return retVal; error: VMDIR_APPEND_ERROR_MSG(lr->pszErrMsg, pszLocalErrorMsg); goto cleanup; }
/* * This generic search with pagination is new and isn't mature. Please be * careful with the * scope, base, and use an indexed filter. * Note that ulPageSize == 0 will ignore paging. */ DWORD VmDirFilterInternalSearch( PCSTR pszBaseDN, int searchScope, PCSTR pszFilter, unsigned long ulPageSize, PSTR *ppszPageCookie, PVDIR_ENTRY_ARRAY pEntryArray ) { DWORD dwError = 0; VDIR_OPERATION searchOP = {0}; VDIR_BERVALUE bervDN = VDIR_BERVALUE_INIT; PVDIR_FILTER pFilter = NULL; PVDIR_LDAP_CONTROL showPagedResultsCtrl = NULL; PSTR pszPageCookie = NULL; if ( !pszBaseDN || !pszFilter || !pEntryArray || (ulPageSize != 0 && ppszPageCookie == NULL)) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } if (ulPageSize != 0) { dwError = VmDirAllocateMemory( sizeof(VDIR_LDAP_CONTROL), (PVOID *)&showPagedResultsCtrl ); BAIL_ON_VMDIR_ERROR(dwError); showPagedResultsCtrl->value.pagedResultCtrlVal.pageSize = ulPageSize; if (ppszPageCookie && *ppszPageCookie) { VmDirStringNCpyA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie), *ppszPageCookie, VMDIR_ARRAY_SIZE(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie) - 1); } else { showPagedResultsCtrl->value.pagedResultCtrlVal.cookie[0] = '\0'; } } dwError = VmDirInitStackOperation( &searchOP, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_SEARCH, NULL ); BAIL_ON_VMDIR_ERROR(dwError); bervDN.lberbv.bv_val = (PSTR)pszBaseDN; bervDN.lberbv.bv_len = VmDirStringLenA(pszBaseDN); searchOP.pBEIF = VmDirBackendSelect( pszBaseDN ); assert(searchOP.pBEIF); dwError = VmDirBervalContentDup( &bervDN, &searchOP.reqDn); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.scope = searchScope; dwError = StrFilterToFilter(pszFilter, &pFilter); BAIL_ON_VMDIR_ERROR(dwError); searchOP.request.searchReq.filter = pFilter; pFilter = NULL; // search request takes over pFilter searchOP.showPagedResultsCtrl = showPagedResultsCtrl; dwError = VmDirInternalSearch( &searchOP ); BAIL_ON_VMDIR_ERROR(dwError); // caller takes over searchOP.internalSearchEntryArray contents pEntryArray->iSize = searchOP.internalSearchEntryArray.iSize; pEntryArray->pEntry = searchOP.internalSearchEntryArray.pEntry; searchOP.internalSearchEntryArray.iSize = 0; searchOP.internalSearchEntryArray.pEntry = NULL; if (showPagedResultsCtrl) { dwError = VmDirAllocateStringA(showPagedResultsCtrl->value.pagedResultCtrlVal.cookie, &pszPageCookie); BAIL_ON_VMDIR_ERROR(dwError); *ppszPageCookie = pszPageCookie; pszPageCookie = NULL; } cleanup: VMDIR_SAFE_FREE_MEMORY(showPagedResultsCtrl); VmDirFreeOperationContent(&searchOP); if (pFilter) { DeleteFilter(pFilter); } return dwError; error: goto cleanup; }