static DWORD TestAddUser( HANDLE hLsaConnection, PSTR pszUser ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwUserInfoLevel = 0; PVOID pUserInfo = NULL; PSTR pszShell = "/bin/sh"; PSTR pszHomedir = "/home"; gid_t gid = 0; LSA_FIND_FLAGS FindFlags = 0; PCSTR pszTestDescription = "Verify LsaAddUser adds a user"; PCSTR pszTestAPIs = "LsaAddUser"; char szTestMsg[512] = { 0 }; dwError = GetGroupId( hLsaConnection, pszUser, &gid); BAIL_ON_TEST_BROKE(dwError); dwError = BuildUserInfo(0, gid, pszUser, pszShell, pszHomedir, (PLSA_USER_INFO_0*)&pUserInfo); BAIL_ON_TEST_BROKE(dwError); dwError = LsaAddUser( hLsaConnection, pUserInfo, dwUserInfoLevel); BAIL_ON_TEST_BROKE(dwError); dwError = LsaFindUserByName( hLsaConnection, pszUser, FindFlags, &pUserInfo); BAIL_ON_TEST_BROKE(dwError); if( !pUserInfo ) { dwError = LW_ERROR_TEST_FAILED; snprintf(szTestMsg, sizeof(szTestMsg), "unexpected result while adding the user %s", pszUser); LWT_LOG_TEST(szTestMsg); } cleanup: if (pUserInfo) { LsaFreeUserInfo(dwUserInfoLevel, pUserInfo); } return dwError; error: goto cleanup; }
/* * Lwt_LsaOpenSession * * Check that LsaEnumUsers, LsaBeginEnumUsers, LsaEndEnumUsers behave * as expected, mostly by matching information against pUsersCsv. */ DWORD Lwt_LsaOpenSession( HANDLE hLsaConnection, PTESTDATA pTestData ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; size_t nCurrentUser; PLWTUSER pUser = NULL; if ( ! pTestData) { dwError = LW_ERROR_TEST_SKIPPED; goto error; } /* For each user (line), verify the information is correct. */ for ( nCurrentUser = 0; nCurrentUser < pTestData->dwNumUsers; nCurrentUser++) { dwLocalError = GetUser(pTestData, nCurrentUser, &pUser); BAIL_ON_TEST_BROKE(dwLocalError); if ( !IsNullOrEmpty(pUser->pszNTName) ) { dwLocalError = CheckLsaOpenSession( hLsaConnection, pUser->pszNTName, pUser); BAIL_ON_TEST_BROKE(dwLocalError); } if ( !IsNullOrEmpty(pUser->pszUserPrincipalName) ) { dwLocalError = CheckLsaOpenSession( hLsaConnection, pUser->pszUserPrincipalName, pUser); BAIL_ON_TEST_BROKE(dwLocalError); } FreeUser(&pUser); } dwLocalError = VerifyNullHandling(hLsaConnection); BAIL_ON_TEST_BROKE(dwLocalError); cleanup: return dwError; error: goto cleanup; }
static DWORD GetGroupId( HANDLE hLsaConnection, PCSTR pszGroupName, gid_t* pGid ) { DWORD dwError = 0; PVOID pGroupInfo = NULL; DWORD dwGroupInfoLevel = 0; gid_t gid = 0; dwError = LsaFindGroupByName( hLsaConnection, pszGroupName, 0, dwGroupInfoLevel, &pGroupInfo); BAIL_ON_TEST_BROKE(dwError); switch(dwGroupInfoLevel) { case 0: { gid = ((PLSA_GROUP_INFO_0)pGroupInfo)->gid; break; } default: { dwError = LW_ERROR_INVALID_GROUP_INFO_LEVEL; BAIL_ON_TEST_BROKE(dwError); break; } } *pGid = gid; cleanup: if (pGroupInfo) { LsaFreeGroupInfo(dwGroupInfoLevel, pGroupInfo); } return dwError; error: *pGid = 0; goto cleanup; }
static DWORD TestAddGroup( HANDLE hLsaConnection, PSTR pszGroup ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwGroupInfoLevel = 1; PVOID pGroupInfo = NULL; LSA_FIND_FLAGS FindFlags = 0; PCSTR pszTestDescription = "Verify LsaAddGroup adds a group"; PCSTR pszTestAPIs = "LsaAddGroup"; char szTestMsg[512] = { 0 }; dwError = BuildGroupInfo(0, pszGroup, (PLSA_GROUP_INFO_1*)&pGroupInfo); BAIL_ON_TEST_BROKE(dwError); dwError = LsaAddGroup(hLsaConnection, pGroupInfo, dwGroupInfoLevel); BAIL_ON_TEST_BROKE(dwError); dwError = LsaFindGroupByName( hLsaConnection, pszGroup, FindFlags, dwGroupInfoLevel, &pGroupInfo); BAIL_ON_TEST_BROKE(dwError); if( !pGroupInfo ) { dwError = LW_ERROR_TEST_FAILED; snprintf(szTestMsg, sizeof(szTestMsg), "unexpected result while adding the group %s", pszGroup); LWT_LOG_TEST(szTestMsg); } cleanup: if (pGroupInfo) { LsaFreeGroupInfo(dwGroupInfoLevel, pGroupInfo); } return dwError; error: goto cleanup; }
static DWORD BuildUserInfo( uid_t uid, gid_t gid, PCSTR pszLoginId, PCSTR pszShell, PCSTR pszHomedir, PLSA_USER_INFO_0* ppUserInfo ) { DWORD dwError = 0; PLSA_USER_INFO_0 pUserInfo = NULL; DWORD dwUserInfoLevel = 0; dwError = LwAllocateMemory( sizeof(LSA_USER_INFO_0), (PVOID*)&pUserInfo ); BAIL_ON_TEST_BROKE(dwError); pUserInfo->uid = uid; pUserInfo->gid = gid; dwError = LwAllocateString(pszLoginId, &pUserInfo->pszName); BAIL_ON_TEST_BROKE(dwError); dwError = LwAllocateString(pszShell, &pUserInfo->pszShell); BAIL_ON_TEST_BROKE(dwError); dwError = LwAllocateString(pszHomedir, &pUserInfo->pszHomedir); BAIL_ON_TEST_BROKE(dwError); // TODO: Gecos *ppUserInfo = pUserInfo; cleanup: return dwError; error: if (pUserInfo) { LsaFreeUserInfo(dwUserInfoLevel, pUserInfo); } goto cleanup; }
int find_user_by_name_main( int argc, char *argv[] ) { DWORD dwError = LW_ERROR_SUCCESS; HANDLE hLsaConnection = NULL; PTESTDATA pTestData = NULL; dwError = Lwt_LsaTestSetup( argc, argv, &hLsaConnection, &pTestData); if ( dwError ) { goto error; } dwError = Lwt_LsaFindUserByName( hLsaConnection, pTestData); BAIL_ON_TEST_BROKE(dwError); cleanup: Lwt_LsaTestTeardown( &hLsaConnection, &pTestData); return LwtMapErrorToProgramStatus(dwError); error: goto cleanup; }
static DWORD TestDelUser( HANDLE hLsaConnection, PSTR pszUser ) { DWORD dwError = LW_ERROR_SUCCESS; LSA_FIND_FLAGS FindFlags = 0; PVOID pUserInfo = NULL; PCSTR pszTestDescription = "Verify LsaDeleteUserByName adds a user"; PCSTR pszTestAPIs = "LsaDeleteUserByName"; char szTestMsg[512] = { 0 }; dwError = LsaDeleteUserByName( hLsaConnection, pszUser); BAIL_ON_TEST_BROKE(dwError); dwError = LsaFindUserByName( hLsaConnection, pszUser, FindFlags, &pUserInfo); BAIL_ON_TEST_BROKE(dwError); if( pUserInfo ) { dwError = LW_ERROR_TEST_FAILED; snprintf(szTestMsg, sizeof(szTestMsg), "unexpected result while deleting the user %s", pszUser); LWT_LOG_TEST(szTestMsg); } cleanup: return dwError; error: goto cleanup; }
DWORD Lwt_LsaTestLocalProvider( HANDLE hLsaConnection ) { DWORD dwError = LW_ERROR_SUCCESS; char szGroup[10]=""; char szUser[10] = ""; GetRandomName(szGroup, szUser, 8); dwError = LsaOpenServer(&hLsaConnection); BAIL_ON_TEST_BROKE(dwError); dwError = TestAddGroup( hLsaConnection, szGroup); BAIL_ON_TEST_BROKE(dwError); // dwError = TestEnumGroups( hLsaConnection, szGroup); // BAIL_ON_TEST_BROKE(dwError); dwError = TestDelGroup( hLsaConnection, szGroup); BAIL_ON_TEST_BROKE(dwError); dwError = TestAddUser( hLsaConnection, szUser); BAIL_ON_TEST_BROKE(dwError); // dwError = TestEnumUsers( hLsaConnection, szUser); // BAIL_ON_TEST_BROKE(dwError); dwError = TestDelUser( hLsaConnection, szUser); BAIL_ON_TEST_BROKE(dwError); cleanup: if (hLsaConnection != (HANDLE)NULL) { LsaCloseServer(hLsaConnection); } return dwError; error: goto cleanup; }
static DWORD BuildGroupInfo( gid_t gid, PCSTR pszGroupName, PLSA_GROUP_INFO_1* ppGroupInfo ) { DWORD dwError = 0; PLSA_GROUP_INFO_1 pGroupInfo = NULL; DWORD dwGroupInfoLevel = 1; dwError = LwAllocateMemory( sizeof(LSA_GROUP_INFO_1), (PVOID*)&pGroupInfo); BAIL_ON_TEST_BROKE(dwError); pGroupInfo->gid = gid; dwError = LwAllocateString(pszGroupName, &pGroupInfo->pszName); BAIL_ON_TEST_BROKE(dwError); *ppGroupInfo = pGroupInfo; cleanup: return dwError; error: if (pGroupInfo) { LsaFreeGroupInfo(dwGroupInfoLevel, pGroupInfo); } *ppGroupInfo = NULL; goto cleanup; }
/* * VerifyErrorConditions * * Check for proper operation with deliberate errors. */ static DWORD VerifyErrorConditions( HANDLE hLsaConnection ) { PCSTR pszTestDescription = "LsaEnumUsers returns error given invalid parameters."; PCSTR pszTestAPIs = "LsaBeginEnumUsers," "LsaEnumUsers," "LsaFreeUserInfoList," "LsaEndEnumUsers"; char szTestMsg[128] = { 0 }; HANDLE hResume = NULL; DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; /* Case : LsaBeginEnumUsers: Call LsaBeginEnumUsers and then LsaEndEnumUsers. */ dwLocalError = LsaBeginEnumUsers( hLsaConnection, 0, /* UserInfoLevel. */ 10, /* Max users to return. */ 0, /* Flags. */ &hResume); BAIL_ON_TEST_BROKE(dwLocalError); if ( hResume != (HANDLE)NULL) { LsaEndEnumUsers(hLsaConnection, hResume); hResume = NULL; } cleanup: if ( hResume != (HANDLE)NULL) { LsaEndEnumUsers(hLsaConnection, hResume); hResume = NULL; } LWT_LOG_TEST(szTestMsg); return dwError; error: goto cleanup; }
static DWORD ValidateEnumUsersForInvalidData( HANDLE hLsaConnection, PTESTDATA pTestData ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwFailDataIndex = 0; PLWTFAILDATA pLwtFailData = NULL; if (!pTestData || !pTestData->pInvalidDataIface) { dwError = LW_ERROR_TEST_SKIPPED; BAIL_ON_TEST_BROKE(dwError); } for (dwFailDataIndex = 0; dwFailDataIndex < pTestData->dwNumInvalidDataSet; dwFailDataIndex++) { dwError = GetInvalidDataRecord( pTestData, dwFailDataIndex, &pLwtFailData); BAIL_ON_LWT_ERROR(dwError); dwError = CheckAPIForInvalidData(hLsaConnection, pLwtFailData); } cleanup: return dwError; error: if (pLwtFailData) { FreeInvalidDataRecord(pLwtFailData); } goto cleanup; }
/* * CheckLsaEnumUsers * * Check LSA_USER_INFO_* list from LsaEnumUsers has expected user. * */ DWORD CheckLsaEnumUsers( HANDLE hLsaConnection, PCSTR pszUser, DWORD dwUserInfoLevel, DWORD dwMaxNumUsers ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; DWORD dwNumUsers = 0; HANDLE hResume = NULL; PVOID *ppUserInfoList = NULL; /* Set to true if we ever return more users than we should. * Used to avoid repeating messages uselessly. */ BOOL bViolated_dwMaxNumUsers = 0; char szTestMsg[128] = { 0 }; PCSTR pszTestDescription = "LsaEnumUsers retrieved LSA_USER_INFO_* list containing expected user."; PCSTR pszTestAPIs = "LsaBeginEnumUsers," "LsaEnumUsers," "LsaFreeUserInfoList," "LsaEndEnumUsers"; snprintf( szTestMsg, sizeof(szTestMsg), "Looking for %s, lists of max length %lu, dwUserInfoLevel = %lu.", pszUser, (unsigned long)dwMaxNumUsers, (unsigned long)dwUserInfoLevel); /* Only one flag right now: LSA_FIND_FLAGS_NSS */ dwLocalError = LsaBeginEnumUsers( hLsaConnection, dwUserInfoLevel, dwMaxNumUsers, 0, /* Flags */ &hResume); BAIL_ON_TEST_BROKE(dwLocalError); do { dwNumUsers = 0; dwLocalError = LsaEnumUsers( hLsaConnection, hResume, &dwNumUsers, (PVOID**) &ppUserInfoList); BAIL_ON_TEST_BROKE(dwLocalError); /* Avoid testing/reporting problem more than once. */ if ( ! bViolated_dwMaxNumUsers ) { if ( dwNumUsers > dwMaxNumUsers ) { char buf[64]; bViolated_dwMaxNumUsers = 1; snprintf( buf, sizeof(buf), "Violation: returned %lu users.", (unsigned long)dwNumUsers); Lwt_strcat( szTestMsg, sizeof(szTestMsg), buf); dwError = LW_ERROR_TEST_FAILED; } } if ( CheckForUserInUserInfoList( dwUserInfoLevel, ppUserInfoList, dwNumUsers, pszUser) == LW_ERROR_SUCCESS ) { /* Found user, good, time to leave. */ goto cleanup; } LsaFreeUserInfoList(dwUserInfoLevel, ppUserInfoList, dwNumUsers); ppUserInfoList = NULL; } while ( dwNumUsers > 0 ); /* If we are here, a user was missing. */ dwError = LW_ERROR_TEST_FAILED; cleanup: if ( ppUserInfoList ) { LsaFreeUserInfoList(dwUserInfoLevel, ppUserInfoList, dwNumUsers); ppUserInfoList = NULL; dwNumUsers = 0; } if ( hResume != (HANDLE)NULL) { LsaEndEnumUsers(hLsaConnection, hResume); hResume = NULL; } LWT_LOG_TEST(szTestMsg); return dwError; error: goto cleanup; }
/* * Lwt_LsaEnumUsers * * Check that LsaEnumUsers, LsaBeginEnumUsers, LsaEndEnumUsers behave * as expected, mostly by matching information against pUsersCsv. */ DWORD Lwt_LsaEnumUsers( HANDLE hLsaConnection, PTESTDATA pTestData ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; size_t nCurrentUser; PLWTUSER pUser = NULL; if (!pTestData) { dwError = LW_ERROR_TEST_SKIPPED; goto error; } /* For each user (line), verify the information is correct. */ for ( nCurrentUser = 0; nCurrentUser < pTestData->dwNumUsers; nCurrentUser++) { DWORD dwUserInfoLevel; dwLocalError = GetUser(pTestData, nCurrentUser, &pUser); BAIL_ON_TEST_BROKE(dwLocalError); for ( dwUserInfoLevel = 0; dwUserInfoLevel < 3; dwUserInfoLevel++) { PCSTR pszName = pUser->pszNTName; if ( pUser->pszAlias ) pszName = pUser->pszAlias; if ( pszName ) { dwLocalError = CheckLsaEnumUsers( hLsaConnection, pszName, dwUserInfoLevel, 1); BAIL_ON_TEST_BROKE(dwLocalError); dwLocalError = CheckLsaEnumUsers( hLsaConnection, pszName, dwUserInfoLevel, 100); BAIL_ON_TEST_BROKE(dwLocalError); dwLocalError = CheckLsaEnumUsers( hLsaConnection, pszName, dwUserInfoLevel, 500); BAIL_ON_TEST_BROKE(dwLocalError); } } FreeUser(&pUser); } VerifyErrorConditions(hLsaConnection); cleanup: if ( pUser ) { FreeUser(&pUser); } return dwError; error: goto cleanup; }
/* * ValidateForInvalidParams * * Function validates the API for Invalid function parameters. * */ static DWORD ValidateForInvalidParams( HANDLE hLsaConnection, PTESTDATA pTestData ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; DWORD dwTest = 0; CHAR szTestMsg[256] = { 0 }; PLWTFAILDATA pInvalidData = NULL; PVOID pUserInfo = NULL; PCSTR pszTestAPIs = "LsaFindUserByName"; PCSTR pszTestDescription = "API returns invalid parameter error for invalid function parameters"; if ( !pTestData || !pTestData->pInvalidDataIface ) { dwLocalError = LW_ERROR_TEST_SKIPPED; BAIL_ON_TEST_BROKE(dwLocalError); } for ( dwTest = 0; dwTest < pTestData->dwNumInvalidDataSet; dwTest++ ) { dwLocalError = GetInvalidDataRecord( pTestData, dwTest, &pInvalidData); BAIL_ON_TEST_BROKE(dwLocalError); if ( LWTUSER_INVALID == pInvalidData->Field ) { dwLocalError = LsaFindUserByName( hLsaConnection, pInvalidData->pszUserName, pInvalidData->dwLevel, &pUserInfo ); if ( dwLocalError != pInvalidData->dwErrorCode ) { dwError = LW_ERROR_TEST_FAILED; snprintf( szTestMsg, sizeof(szTestMsg), "API returned with error code (%lu) for invalid user name parameter", (unsigned long)dwLocalError); LWT_LOG_TEST(szTestMsg); } FreeUserInfo(pInvalidData->dwLevel, pUserInfo); } if ( LWTUSERINFOLEVEL_INVALID == pInvalidData->Field ) { dwLocalError = LsaFindUserByName( hLsaConnection, pInvalidData->pszUserName, pInvalidData->dwLevel, &pUserInfo ); if ( dwLocalError != pInvalidData->dwErrorCode ) { dwError = LW_ERROR_TEST_FAILED; snprintf( szTestMsg, sizeof(szTestMsg), "API returned with error code (%lu) for invalid user name parameter", (unsigned long)dwLocalError); LWT_LOG_TEST(szTestMsg); } FreeUserInfo(pInvalidData->dwLevel, pUserInfo); } FreeInvalidDataRecord(pInvalidData); } error: return dwError; }
DWORD Lwt_LsaFindUserByName( HANDLE hLsaConnection, PTESTDATA pTestData ) { DWORD dwError = LW_ERROR_SUCCESS; DWORD dwLocalError = LW_ERROR_SUCCESS; size_t nCurrentUser; PLWTUSER pUser = NULL; PLSA_USER_INFO_0 pUserInfo0 = NULL; PLSA_USER_INFO_1 pUserInfo1 = NULL; if ( ! pTestData ) { dwError = LW_ERROR_TEST_SKIPPED; goto error; } /* For each user (line), verify the information is correct. */ for ( nCurrentUser = 0; nCurrentUser < pTestData->dwNumUsers; nCurrentUser++ ) { dwLocalError = GetUser( pTestData, nCurrentUser, &pUser); BAIL_ON_TEST_BROKE(dwLocalError); if ( pUser->pszNTName ) { dwLocalError = FindUserByName0( hLsaConnection, pUser, pUser->pszNTName, &pUserInfo0); BAIL_ON_TEST_BROKE(dwLocalError); } if ( pUserInfo0 ) { dwLocalError = MatchUserInfo0( pUser, pUser->pszNTName, pUserInfo0); BAIL_ON_TEST_BROKE(dwLocalError); LsaFreeUserInfo(0, pUserInfo0); pUserInfo0 = NULL; } if ( pUser->pszUserPrincipalName ) { dwLocalError = FindUserByName0( hLsaConnection, pUser, pUser->pszUserPrincipalName, &pUserInfo0); BAIL_ON_TEST_BROKE(dwLocalError); } if ( pUserInfo0 ) { dwLocalError = MatchUserInfo0( pUser, pUser->pszUserPrincipalName, pUserInfo0); BAIL_ON_TEST_BROKE(dwLocalError); LsaFreeUserInfo(0, pUserInfo0); pUserInfo0 = NULL; } if ( pUser->pszNTName ) { dwLocalError = FindUserByName1( hLsaConnection, pUser, pUser->pszNTName, &pUserInfo1); BAIL_ON_TEST_BROKE(dwLocalError); } if ( pUserInfo1 ) { LsaFreeUserInfo(1, pUserInfo1); pUserInfo1 = NULL; } FreeUser(&pUser); } dwLocalError = VerifyNullHandling(hLsaConnection); BAIL_ON_TEST_BROKE(dwLocalError); dwLocalError = ValidateForInvalidParams(hLsaConnection, pTestData); BAIL_ON_TEST_BROKE(dwLocalError); cleanup: if ( pUserInfo0 ) { LsaFreeUserInfo(0, pUserInfo0); pUserInfo0 = NULL; } if ( pUserInfo1 ) { LsaFreeUserInfo(1, pUserInfo1); pUserInfo1 = NULL; } if ( pUser ) { FreeUser(&pUser); } return dwError; error: goto cleanup; }