NET_API_STATUS NetrFileGetInfo( PSRVSVC_CONTEXT pContext, /* IN */ PCWSTR pwszServername, /* IN OPTIONAL */ DWORD dwFileId, /* IN */ DWORD dwInfoLevel, /* IN */ PBYTE* ppBuffer /* OUT */ ) { NET_API_STATUS status = ERROR_SUCCESS; srvsvc_NetFileInfo info; BAIL_ON_INVALID_PTR(pContext, status); BAIL_ON_INVALID_PTR(ppBuffer, status); memset(&info, 0, sizeof(info)); *ppBuffer = NULL; TRY { status = _NetrFileGetInfo( pContext->hBinding, (PWSTR)pwszServername, dwFileId, dwInfoLevel, &info); } CATCH_ALL(pDceException) { NTSTATUS ntStatus = LwRpcStatusToNtStatus(pDceException->match.value); status = LwNtStatusToWin32Error(ntStatus); } ENDTRY; BAIL_ON_WIN_ERROR(status); status = SrvSvcCopyNetFileInfo(dwInfoLevel, &info, ppBuffer); BAIL_ON_WIN_ERROR(status); cleanup: SrvSvcClearNetFileInfo(dwInfoLevel, &info); return status; error: goto cleanup; }
DWORD DsrAllocateDsRoleInfo( OUT PDSR_ROLE_INFO pOut, IN OUT PDWORD pdwOffset, IN OUT PDWORD pdwSpaceLeft, IN PDSR_ROLE_INFO pIn, IN WORD swLevel, IN OUT PDWORD pdwSize ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PVOID pBuffer = pOut; BAIL_ON_INVALID_PTR(pdwOffset, ntStatus); BAIL_ON_INVALID_PTR(pIn, ntStatus); BAIL_ON_INVALID_PTR(pdwSize, ntStatus); switch(swLevel) { case DS_ROLE_BASIC_INFORMATION: LWBUF_ALLOC_DWORD(pBuffer, pIn->Basic.dwRole); LWBUF_ALLOC_DWORD(pBuffer, pIn->Basic.dwFlags); LWBUF_ALLOC_PWSTR(pBuffer, pIn->Basic.pwszDomain); LWBUF_ALLOC_PWSTR(pBuffer, pIn->Basic.pwszDnsDomain); LWBUF_ALLOC_PWSTR(pBuffer, pIn->Basic.pwszForest); LWBUF_ALLOC_BLOB(pBuffer, sizeof(pIn->Basic.DomainGuid), &pIn->Basic.DomainGuid); break; case DS_ROLE_UPGRADE_STATUS: LWBUF_ALLOC_WORD(pBuffer, pIn->Upgrade.swUpgradeStatus); LWBUF_ALIGN_TYPE(pdwOffset, pdwSize, pdwSpaceLeft, DWORD); LWBUF_ALLOC_DWORD(pBuffer, pIn->Upgrade.dwPrevious); break; case DS_ROLE_OP_STATUS: LWBUF_ALLOC_WORD(pBuffer, pIn->OpStatus.swStatus); break; default: ntStatus = STATUS_INVALID_PARAMETER; break; } BAIL_ON_WIN_ERROR(dwError); cleanup: if (dwError == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { dwError = LwNtStatusToWin32Error(dwError); } return dwError; error: goto cleanup; }
DWORD NetAllocateLocalGroupUsersInfo( PVOID pInfoBuffer, PDWORD pdwSpaceLeft, DWORD dwLevel, PVOID pSource, PDWORD pdwSize, NET_VALIDATION_LEVEL eValidation ) { DWORD err = ERROR_SUCCESS; PVOID pCursor = pInfoBuffer; switch (dwLevel) { case 0: err = NetAllocateLocalGroupUsersInfo0(&pCursor, pdwSpaceLeft, pSource, pdwSize, eValidation); break; default: err = ERROR_INVALID_LEVEL; break; } BAIL_ON_WIN_ERROR(err); cleanup: return err; error: goto cleanup; }
WINERROR WkssAllocateMemory( OUT PVOID *ppOut, IN size_t sSize ) { WINERROR winError = ERROR_SUCCESS; PVOID pMem = NULL; pMem = malloc(sSize); if (pMem == NULL) { winError = ERROR_OUTOFMEMORY; BAIL_ON_WIN_ERROR(winError); } memset(pMem, 0, sSize); *ppOut = pMem; cleanup: return winError; error: *ppOut = NULL; goto cleanup; }
NET_API_STATUS NetrFileClose( PSRVSVC_CONTEXT pContext, const wchar16_t *servername, UINT32 fileid ) { NET_API_STATUS status = ERROR_SUCCESS; BAIL_ON_INVALID_PTR(pContext, status); TRY { status = _NetrFileClose( pContext->hBinding, (wchar16_t *)servername, fileid); } CATCH_ALL(pDceException) { NTSTATUS ntStatus = LwRpcStatusToNtStatus(pDceException->match.value); status = LwNtStatusToWin32Error(ntStatus); } ENDTRY; BAIL_ON_WIN_ERROR(status); cleanup: return status; error: goto cleanup; }
NTSTATUS LsaInitBindingDefault( OUT PLSA_BINDING phBinding, IN PCWSTR pwszHostname, IN PIO_CREDS pCreds ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PSTR pszHostname = NULL; if (pwszHostname) { dwError = LwWc16sToMbs(pwszHostname, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } ntStatus = LsaInitBindingDefaultA(phBinding, pszHostname, pCreds); BAIL_ON_NT_STATUS(ntStatus); cleanup: LW_SAFE_FREE_MEMORY(pszHostname); return ntStatus; error: goto cleanup; }
static DWORD NetAllocateLocalGroupMembersInfo0( PVOID *ppCursor, PDWORD pdwSpaceLeft, PVOID pSource, PDWORD pdwSize, NET_VALIDATION_LEVEL eValidation ) { DWORD err = ERROR_SUCCESS; PVOID pCursor = NULL; DWORD dwSpaceLeft = 0; DWORD dwSize = 0; PSID pSid = (PSID)pSource; DWORD dwSidLen = 0; if (pdwSpaceLeft) { dwSpaceLeft = *pdwSpaceLeft; } if (pdwSize) { dwSize = *pdwSize; } if (ppCursor) { pCursor = *ppCursor; } dwSidLen = RtlLengthSid(pSid); /* lgrmi0_sid */ err = NetAllocBufferSid(&pCursor, &dwSpaceLeft, pSid, dwSidLen, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); if (pdwSpaceLeft) { *pdwSpaceLeft = dwSpaceLeft; } if (pdwSize) { *pdwSize = dwSize; } cleanup: return err; error: goto cleanup; }
static BOOLEAN CallNetrSamLogonInteractiveEx( NETR_BINDING hSchannel, NetrCredentials *pNetlogonCreds, PWSTR pwszServer, PWSTR pwszDomain, PWSTR pwszComputer, PWSTR pwszUsername, PWSTR pwszPassword, DWORD logonLevel, PDWORD pValidationLevels, DWORD numValidationLevels, NetrValidationInfo ***pppSamLogonInfo ) { BOOLEAN bRet = TRUE; DWORD dwError = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD validationLevel = 0; DWORD i = 0; NetrValidationInfo *pValidationInfo = NULL; NetrValidationInfo **ppSamLogonInfo = NULL; BYTE Authoritative = 0; DWORD totalNumLevels = 7; dwError = LwAllocateMemory(sizeof(ppSamLogonInfo[0]) * totalNumLevels, OUT_PPVOID(&ppSamLogonInfo)); BAIL_ON_WIN_ERROR(dwError); for (i = 0; i < numValidationLevels; i++) { validationLevel = pValidationLevels[i]; CALL_MSRPC(ntStatus, NetrSamLogonEx( hSchannel, pNetlogonCreds, pwszServer, pwszDomain, pwszComputer, pwszUsername, pwszPassword, logonLevel, validationLevel, &pValidationInfo, &Authoritative)); if (ntStatus) { bRet = FALSE; } ppSamLogonInfo[validationLevel] = pValidationInfo; } *pppSamLogonInfo = ppSamLogonInfo; error: return bRet; }
NET_API_STATUS NetShareEnum( IN PCWSTR pwszServername, IN DWORD dwLevel, OUT PBYTE *ppBuffer, IN DWORD dwMaxLen, OUT PDWORD pdwNumEntries, OUT PDWORD pdwTotalEntries, OUT PDWORD pdwResume ) { NET_API_STATUS err = ERROR_SUCCESS; PSRVSVC_CONTEXT pContext = NULL; BAIL_ON_INVALID_PTR(ppBuffer, err); BAIL_ON_INVALID_PTR(pdwNumEntries, err); BAIL_ON_INVALID_PTR(pdwTotalEntries, err); err = SrvSvcCreateContext(pwszServername, &pContext); BAIL_ON_WIN_ERROR(err); err = NetrShareEnum( pContext, pwszServername, dwLevel, ppBuffer, dwMaxLen, pdwNumEntries, pdwTotalEntries, pdwResume); BAIL_ON_WIN_ERROR(err); cleanup: if (pContext) { SrvSvcCloseContext(pContext); } return err; error: goto cleanup; }
static DWORD NetAllocateLocalGroupUsersInfo0( PVOID *ppCursor, PDWORD pdwSpaceLeft, PVOID pSource, PDWORD pdwSize, NET_VALIDATION_LEVEL eValidation ) { DWORD err = ERROR_SUCCESS; PVOID pCursor = NULL; DWORD dwSpaceLeft = 0; DWORD dwSize = 0; PWSTR pwszName = (PWSTR)pSource; if (pdwSpaceLeft) { dwSpaceLeft = *pdwSpaceLeft; } if (pdwSize) { dwSize = *pdwSize; } if (ppCursor) { pCursor = *ppCursor; } /* lgrui0_name */ err = NetAllocBufferWC16String(&pCursor, &dwSpaceLeft, pwszName, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); if (pdwSpaceLeft) { *pdwSpaceLeft = dwSpaceLeft; } if (pdwSize) { *pdwSize = dwSize; } cleanup: return err; error: goto cleanup; }
NET_API_STATUS NetServerGetInfo( IN PCWSTR pwszServername, IN DWORD dwLevel, OUT PBYTE *ppBuffer ) { NET_API_STATUS err = ERROR_SUCCESS; PSRVSVC_CONTEXT pContext = NULL; PBYTE pBuffer = NULL; BAIL_ON_INVALID_PTR(ppBuffer, err); err = SrvSvcCreateContext(pwszServername, &pContext); BAIL_ON_WIN_ERROR(err); err = NetrServerGetInfo(pContext, pwszServername, dwLevel, &pBuffer); BAIL_ON_WIN_ERROR(err); *ppBuffer = pBuffer; cleanup: if (pContext) { SrvSvcCloseContext(pContext); } return err; error: *ppBuffer = NULL; goto cleanup; }
NET_API_STATUS NetrShareDel( IN PSRVSVC_CONTEXT pContext, IN PCWSTR pwszServername, IN PCWSTR pwszSharename, IN DWORD dwReserved ) { NET_API_STATUS status = ERROR_SUCCESS; BAIL_ON_INVALID_PTR(pContext, status); BAIL_ON_INVALID_PTR(pwszSharename, status); TRY { status = _NetrShareDel( pContext->hBinding, (PWSTR)pwszServername, (PWSTR)pwszSharename, dwReserved); } CATCH_ALL(pDceException) { NTSTATUS ntStatus = LwRpcStatusToNtStatus(pDceException->match.value); status = LwNtStatusToWin32Error(ntStatus); } ENDTRY; BAIL_ON_WIN_ERROR(status); cleanup: return status; error: goto cleanup; }
DWORD WkssAllocateNetrWkstaInfo( OUT PNETR_WKSTA_INFO pOut, IN OUT PDWORD pdwOffset, IN OUT PDWORD pdwSpaceLeft, IN DWORD dwLevel, IN PNETR_WKSTA_INFO pIn, IN OUT PDWORD pdwSize ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PVOID pBuffer = NULL; BAIL_ON_INVALID_PTR(pOut, ntStatus); BAIL_ON_INVALID_PTR(pdwOffset, ntStatus); BAIL_ON_INVALID_PTR(pIn, ntStatus); BAIL_ON_INVALID_PTR(pdwSize, ntStatus); if (dwLevel >= 100 && dwLevel <= 102) { pBuffer = pOut->pInfo100; LWBUF_ALLOC_DWORD(pBuffer, pIn->pInfo100->wksta100_platform_id); LWBUF_ALLOC_WC16STR(pBuffer, pIn->pInfo100->wksta100_name); LWBUF_ALLOC_WC16STR(pBuffer, pIn->pInfo100->wksta100_domain); LWBUF_ALLOC_DWORD(pBuffer, pIn->pInfo100->wksta100_version_major); LWBUF_ALLOC_DWORD(pBuffer, pIn->pInfo100->wksta100_version_minor); } if (dwLevel >= 101 && dwLevel <= 102) { /* Level 101 is an extension of level 100 and pBuffer points to the same place as pInfo101 */ LWBUF_ALLOC_WC16STR(pBuffer, pIn->pInfo101->wksta101_domain); } if (dwLevel == 102) { /* Level 102 is an extension of level 101 and pBuffer points to the same place as pInfo102 */ LWBUF_ALLOC_DWORD(pBuffer, pIn->pInfo102->wksta102_logged_users); } if (pBuffer == NULL && pdwSpaceLeft != NULL) { /* No matching infolevel has been found */ dwError = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(dwError); } cleanup: if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return dwError; error: goto cleanup; }
NET_API_STATUS NetUserAdd( PCWSTR pwszHostname, DWORD dwLevel, PVOID pBuffer, PDWORD pdwParmErr ) { const DWORD dwUserAccess = USER_ACCESS_GET_NAME_ETC | USER_ACCESS_SET_LOC_COM | USER_ACCESS_GET_LOCALE | USER_ACCESS_GET_LOGONINFO | USER_ACCESS_GET_ATTRIBUTES | USER_ACCESS_GET_GROUPS | USER_ACCESS_GET_GROUP_MEMBERSHIP | USER_ACCESS_CHANGE_GROUP_MEMBERSHIP | USER_ACCESS_SET_ATTRIBUTES | USER_ACCESS_SET_PASSWORD; const DWORD dwDomainAccess = DOMAIN_ACCESS_CREATE_USER | DOMAIN_ACCESS_LOOKUP_INFO_1; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; PNET_CONN pConn = NULL; SAMR_BINDING hSamrBinding = NULL; DOMAIN_HANDLE hDomain = NULL; ACCOUNT_HANDLE hUser = NULL; DWORD dwSamrInfoLevel = 0; DWORD dwSamrPasswordInfoLevel = 0; DWORD dwParmErr = 0; UserInfo *pSamrUserInfo = NULL; UserInfo *pSamrPasswordUserInfo = NULL; DWORD dwSize = 0; DWORD dwSpaceLeft = 0; PIO_CREDS pCreds = NULL; PWSTR pwszUsername = NULL; DWORD dwRid = 0; BOOL bPasswordSet = FALSE; NET_VALIDATION_LEVEL eValidation = NET_VALIDATION_USER_ADD; BAIL_ON_INVALID_PTR(pBuffer, err); if (!(dwLevel == 1 || dwLevel == 2 || dwLevel == 3 || dwLevel == 4)) { err = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(err); } status = LwIoGetActiveCreds(NULL, &pCreds); BAIL_ON_NT_STATUS(status); err = NetAllocateSamrUserInfo(NULL, &dwSamrInfoLevel, NULL, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); dwSpaceLeft = dwSize; dwSize = 0; if (dwSpaceLeft) { status = NetAllocateMemory((void**)&pSamrUserInfo, dwSpaceLeft); BAIL_ON_NT_STATUS(status); } err = NetAllocateSamrUserInfo(&pSamrUserInfo->info21, &dwSamrInfoLevel, &dwSpaceLeft, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); status = NetConnectSamr(&pConn, pwszHostname, dwDomainAccess, 0, pCreds); BAIL_ON_NT_STATUS(status); hSamrBinding = pConn->Rpc.Samr.hBinding; hDomain = pConn->Rpc.Samr.hDomain; err = LwAllocateWc16StringFromUnicodeString( &pwszUsername, (PUNICODE_STRING)&pSamrUserInfo->info21.account_name); BAIL_ON_WIN_ERROR(err); status = SamrCreateUser(hSamrBinding, hDomain, pwszUsername, dwUserAccess, &hUser, &dwRid); if (status == STATUS_USER_EXISTS) { err = NERR_UserExists; } else if (status == STATUS_ALIAS_EXISTS) { err = NERR_GroupExists; } BAIL_ON_NT_STATUS(status); /* * Check if there's password to be set (if it's NULL * the function returns ERROR_INVALID_PASSWORD) */ dwSamrPasswordInfoLevel = 26; dwSize = 0; err = NetAllocateSamrUserInfo(NULL, &dwSamrPasswordInfoLevel, NULL, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); if (err == ERROR_SUCCESS) { dwSpaceLeft = dwSize; dwSize = 0; if (dwSpaceLeft) { status = NetAllocateMemory((void**)&pSamrPasswordUserInfo, dwSpaceLeft); BAIL_ON_NT_STATUS(status); } err = NetAllocateSamrUserInfo(&pSamrPasswordUserInfo->info26, &dwSamrPasswordInfoLevel, &dwSpaceLeft, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); status = SamrSetUserInfo(hSamrBinding, hUser, dwSamrPasswordInfoLevel, pSamrPasswordUserInfo); BAIL_ON_NT_STATUS(status); bPasswordSet = TRUE; } else if (err == ERROR_INVALID_PASSWORD) { /* This error only means we're not going to try set the password */ err = ERROR_SUCCESS; } else { BAIL_ON_WIN_ERROR(err); } /* * Prevent from trying to rename (to the same name) the account * that has just been created. Created samr user info buffer * contains whatever is passed from net user info buffer. */ if (dwSamrInfoLevel == 21 && (pSamrUserInfo->info21.fields_present & SAMR_FIELD_ACCOUNT_NAME)) { pSamrUserInfo->info21.fields_present ^= SAMR_FIELD_ACCOUNT_NAME; } /* * Disable the account only if there was no password */ if (!bPasswordSet && dwSamrInfoLevel == 21) { pSamrUserInfo->info21.account_flags |= ACB_DISABLED; } status = SamrSetUserInfo(hSamrBinding, hUser, dwSamrInfoLevel, pSamrUserInfo); BAIL_ON_NT_STATUS(status); status = SamrClose(hSamrBinding, hUser); BAIL_ON_NT_STATUS(status); cleanup: NetDisconnectSamr(&pConn); if (pdwParmErr) { *pdwParmErr = dwParmErr; } if (pSamrUserInfo) { NetFreeMemory(pSamrUserInfo); } if (pSamrPasswordUserInfo) { NetFreeMemory(pSamrPasswordUserInfo); } LW_SAFE_FREE_MEMORY(pwszUsername); if (pCreds) { LwIoDeleteCreds(pCreds); } if (err == ERROR_SUCCESS && status != STATUS_SUCCESS) { err = NtStatusToWin32Error(status); } return err; error: goto cleanup; }
NET_API_STATUS NetUserGetLocalGroups( PCWSTR pwszHostname, PCWSTR pwszUsername, DWORD dwLevel, DWORD dwFlags, PVOID *ppBuffer, DWORD dwMaxBufferSize, PDWORD pdwNumEntries, PDWORD pdwTotalEntries ) { const DWORD dwBuiltinDomainAccess = DOMAIN_ACCESS_OPEN_ACCOUNT | DOMAIN_ACCESS_ENUM_ACCOUNTS; const DWORD dwUserAccess = USER_ACCESS_GET_GROUP_MEMBERSHIP; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; PNET_CONN pConn = NULL; SAMR_BINDING hSamrBinding = NULL; DOMAIN_HANDLE hDomain = NULL; DOMAIN_HANDLE hBtinDomain = NULL; ACCOUNT_HANDLE hUser = NULL; PSID pDomainSid = NULL; PSID pUserSid = NULL; DWORD dwUserRid = 0; DWORD dwSidLen = 0; DWORD i = 0; PDWORD pdwUserRids = NULL; PDWORD pdwBuiltinUserRids = NULL; DWORD dwRidsCount = 0; DWORD dwBuiltinRidsCount = 0; DWORD dwInfoLevelSize = 0; DWORD dwTotalNumEntries = 0; PWSTR *ppwszAliasNames = NULL; PWSTR *ppwszBuiltinAliasNames = NULL; PDWORD pdwAliasTypes = NULL; PDWORD pdwBuiltinAliasTypes = NULL; PWSTR *ppwszLocalGroupNames = NULL; PVOID pSourceBuffer = NULL; PVOID pBuffer = NULL; PVOID pBufferCursor = NULL; DWORD dwSize = 0; DWORD dwTotalSize = 0; DWORD dwNumEntries = 0; DWORD dwSpaceAvailable = 0; PIO_CREDS pCreds = NULL; NET_VALIDATION_LEVEL eValidation = NET_VALIDATION_NONE; BAIL_ON_INVALID_PTR(pwszUsername, err); BAIL_ON_INVALID_PTR(ppBuffer, err); BAIL_ON_INVALID_PTR(pdwNumEntries, err); BAIL_ON_INVALID_PTR(pdwTotalEntries, err); switch (dwLevel) { case 0: dwInfoLevelSize = sizeof(LOCALGROUP_USERS_INFO_0); break; default: err = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(err); } status = LwIoGetActiveCreds(NULL, &pCreds); BAIL_ON_NT_STATUS(status); status = NetConnectSamr(&pConn, pwszHostname, 0, dwBuiltinDomainAccess, pCreds); BAIL_ON_NT_STATUS(status); hSamrBinding = pConn->Rpc.Samr.hBinding; hDomain = pConn->Rpc.Samr.hDomain; hBtinDomain = pConn->Rpc.Samr.hBuiltin; pDomainSid = pConn->Rpc.Samr.pDomainSid; status = NetOpenUser(pConn, pwszUsername, dwUserAccess, &hUser, &dwUserRid); BAIL_ON_NT_STATUS(status); dwSidLen = RtlLengthRequiredSid(pDomainSid->SubAuthorityCount + 1); err = LwAllocateMemory(dwSidLen, OUT_PPVOID(&pUserSid)); BAIL_ON_WIN_ERROR(err); status = RtlCopySid(dwSidLen, pUserSid, pDomainSid); BAIL_ON_NT_STATUS(status); status = RtlAppendRidSid(dwSidLen, pUserSid, dwUserRid); BAIL_ON_NT_STATUS(status); status = SamrGetAliasMembership(hSamrBinding, hDomain, &pUserSid, 1, &pdwUserRids, &dwRidsCount); BAIL_ON_NT_STATUS(status); status = SamrGetAliasMembership(hSamrBinding, hBtinDomain, &pUserSid, 1, &pdwBuiltinUserRids, &dwBuiltinRidsCount); BAIL_ON_NT_STATUS(status); dwTotalNumEntries = dwRidsCount + dwBuiltinRidsCount; err = LwAllocateMemory( sizeof(ppwszLocalGroupNames[0]) * dwTotalNumEntries, OUT_PPVOID(&ppwszLocalGroupNames)); BAIL_ON_WIN_ERROR(err); if (dwRidsCount > 0) { status = SamrLookupRids(hSamrBinding, hDomain, dwRidsCount, pdwUserRids, &ppwszAliasNames, &pdwAliasTypes); BAIL_ON_NT_STATUS(status); for (i = 0; i < dwRidsCount; i++) { ppwszLocalGroupNames[i] = ppwszAliasNames[i]; } } if (dwBuiltinRidsCount > 0) { status = SamrLookupRids(hSamrBinding, hBtinDomain, dwBuiltinRidsCount, pdwBuiltinUserRids, &ppwszBuiltinAliasNames, &pdwBuiltinAliasTypes); BAIL_ON_NT_STATUS(status); for (i = 0; i < dwBuiltinRidsCount; i++) { ppwszLocalGroupNames[i + dwRidsCount] = ppwszBuiltinAliasNames[i]; } } for (i = 0; i < dwTotalNumEntries; i++) { pSourceBuffer = ppwszLocalGroupNames[i]; dwSize = 0; err = NetAllocateLocalGroupUsersInfo(NULL, NULL, dwLevel, pSourceBuffer, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); dwTotalSize += dwSize; dwNumEntries++; if (dwTotalSize > dwMaxBufferSize) { dwTotalSize -= dwSize; dwNumEntries--; break; } } if (dwTotalNumEntries > 0 && dwNumEntries == 0) { err = ERROR_INSUFFICIENT_BUFFER; BAIL_ON_WIN_ERROR(err); } if (dwTotalSize) { status = NetAllocateMemory(OUT_PPVOID(&pBuffer), dwTotalSize); BAIL_ON_NT_STATUS(status); } dwSize = 0; pBufferCursor = pBuffer; dwSpaceAvailable = dwTotalSize; for (i = 0; i < dwNumEntries; i++) { pSourceBuffer = ppwszLocalGroupNames[i]; pBufferCursor = pBuffer + (i * dwInfoLevelSize); err = NetAllocateLocalGroupUsersInfo(pBufferCursor, &dwSpaceAvailable, dwLevel, pSourceBuffer, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); } if (dwNumEntries < dwTotalNumEntries) { err = ERROR_MORE_DATA; } status = SamrClose(hSamrBinding, hUser); BAIL_ON_NT_STATUS(status); *ppBuffer = pBuffer; *pdwNumEntries = dwNumEntries; *pdwTotalEntries = dwTotalNumEntries; cleanup: LW_SAFE_FREE_MEMORY(pUserSid); LW_SAFE_FREE_MEMORY(ppwszLocalGroupNames); if (pdwUserRids) { SamrFreeMemory(pdwUserRids); } if (pdwBuiltinUserRids) { SamrFreeMemory(pdwBuiltinUserRids); } if (ppwszAliasNames) { SamrFreeMemory(ppwszAliasNames); } if (pdwAliasTypes) { SamrFreeMemory(pdwAliasTypes); } if (ppwszBuiltinAliasNames) { SamrFreeMemory(ppwszBuiltinAliasNames); } if (pdwBuiltinAliasTypes) { SamrFreeMemory(pdwBuiltinAliasTypes); } if (pCreds) { LwIoDeleteCreds(pCreds); } return err; error: if (pBuffer) { NetFreeMemory(pBuffer); } *ppBuffer = NULL; *pdwNumEntries = 0; *pdwTotalEntries = 0; goto cleanup; }
NTSTATUS LsaLookupNames3( IN LSA_BINDING hBinding, IN POLICY_HANDLE hPolicy, IN UINT32 dwNumNames, IN PWSTR *ppwszNames, OUT RefDomainList **ppDomList, OUT TranslatedSid3 **ppSids, IN WORD swLevel, IN OUT PDWORD pdwCount ) { NTSTATUS ntStatus = STATUS_SUCCESS; NTSTATUS ntRetStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; UINT32 unknown1 = 0; UINT32 unknown2 = 0; PUNICODE_STRING pLsaNames = NULL; DWORD iName = 0; RefDomainList *pRefDomains = NULL; RefDomainList *pOutDomains = NULL; TranslatedSidArray3 SidArray = {0}; TranslatedSid3* pTransSids = NULL; DWORD dwOffset = 0; DWORD dwSpaceLeft = 0; DWORD dwSize = 0; BAIL_ON_INVALID_PTR(hBinding, ntStatus); BAIL_ON_INVALID_PTR(hPolicy, ntStatus); BAIL_ON_INVALID_PTR(ppwszNames, ntStatus); BAIL_ON_INVALID_PTR(ppDomList, ntStatus); BAIL_ON_INVALID_PTR(ppSids, ntStatus); BAIL_ON_INVALID_PTR(pdwCount, ntStatus); dwError = LwAllocateMemory(sizeof(pLsaNames[0]) * dwNumNames, OUT_PPVOID(&pLsaNames)); BAIL_ON_WIN_ERROR(dwError); for (iName = 0; iName < dwNumNames; iName++) { dwError = LwAllocateUnicodeStringFromWc16String( &pLsaNames[iName], ppwszNames[iName]); BAIL_ON_WIN_ERROR(dwError); } *pdwCount = 0; DCERPC_CALL(ntStatus, cli_LsaLookupNames3( (handle_t)hBinding, hPolicy, dwNumNames, pLsaNames, &pRefDomains, &SidArray, swLevel, pdwCount, unknown1, unknown2)); ntRetStatus = ntStatus; /* Status other than success doesn't have to mean failure here */ if (ntRetStatus != STATUS_SUCCESS && ntRetStatus != LW_STATUS_SOME_NOT_MAPPED) { BAIL_ON_NT_STATUS(ntRetStatus); } if (SidArray.count > 0) { ntStatus = LsaAllocateTranslatedSids3(NULL, &dwOffset, NULL, &SidArray, &dwSize); BAIL_ON_NT_STATUS(ntStatus); dwSpaceLeft = dwSize; dwSize = 0; dwOffset = 0; ntStatus = LsaRpcAllocateMemory(OUT_PPVOID(&pTransSids), dwSpaceLeft); BAIL_ON_NT_STATUS(ntStatus); ntStatus = LsaAllocateTranslatedSids3(pTransSids, &dwOffset, &dwSpaceLeft, &SidArray, &dwSize); BAIL_ON_NT_STATUS(ntStatus); } if (pRefDomains) { dwSize = 0; dwOffset = 0; ntStatus = LsaAllocateRefDomainList(NULL, &dwOffset, NULL, pRefDomains, &dwSize); BAIL_ON_NT_STATUS(ntStatus); dwSpaceLeft = dwSize; dwSize = 0; dwOffset = 0; ntStatus = LsaRpcAllocateMemory(OUT_PPVOID(&pOutDomains), dwSpaceLeft); BAIL_ON_NT_STATUS(ntStatus); ntStatus = LsaAllocateRefDomainList(pOutDomains, &dwOffset, &dwSpaceLeft, pRefDomains, &dwSize); BAIL_ON_NT_STATUS(ntStatus); } *ppSids = pTransSids; *ppDomList = pOutDomains; *pdwCount = SidArray.count; cleanup: if (pLsaNames) { for (iName = 0; iName < dwNumNames; iName++) { LwFreeUnicodeString(&(pLsaNames[iName])); } LW_SAFE_FREE_MEMORY(pLsaNames); } /* Free pointers returned from stub */ LsaCleanStubTranslatedSidArray3(&SidArray); if (pRefDomains) { LsaFreeStubRefDomainList(pRefDomains); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } if (ntStatus == STATUS_SUCCESS && (ntRetStatus == STATUS_SUCCESS || ntRetStatus == LW_STATUS_SOME_NOT_MAPPED)) { ntStatus = ntRetStatus; } return ntStatus; error: if (pTransSids) { LsaRpcFreeMemory(pTransSids); } if (pOutDomains) { LsaRpcFreeMemory(pOutDomains); } if (ppSids) { *ppSids = NULL; } if (ppDomList) { *ppDomList = NULL; } if (pdwCount) { *pdwCount = 0; } goto cleanup; }
NET_API_STATUS NetLocalGroupEnum( PCWSTR pwszHostname, DWORD dwLevel, PVOID *ppBuffer, DWORD dwMaxBufferSize, PDWORD pdwNumEntries, PDWORD pdwTotalNumEntries, PDWORD pdwResume ) { const DWORD dwAccountFlags = 0; const DWORD dwAliasAccessFlags = ALIAS_ACCESS_LOOKUP_INFO; const WORD wInfoLevel = ALIAS_INFO_ALL; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; DWORD dwResume = 0; PNET_CONN pConn = NULL; SAMR_BINDING hSamrBinding = NULL; DOMAIN_HANDLE hDomain = NULL; DOMAIN_HANDLE hBtinDomain = NULL; DWORD dwSamrResume = 0; PWSTR *ppwszDomainAliases = NULL; PDWORD pdwDomainRids = NULL; DWORD dwNumDomainEntries = 0; DWORD dwTotalNumDomainEntries = 0; PWSTR *ppwszBtinDomainAliases = NULL; PDWORD pdwBtinDomainRids = NULL; DWORD dwNumBtinDomainEntries = 0; DWORD dwTotalNumBtinDomainEntries = 0; DWORD dwTotalNumEntries = 0; DWORD dwNumEntries = 0; DWORD i = 0; PDWORD pdwRids = NULL; PWSTR *ppwszAliases = NULL; ACCOUNT_HANDLE hAlias = NULL; AliasInfo *pSamrAliasInfo = NULL; AliasInfoAll **ppAliasInfo = NULL; DWORD dwInfoLevelSize = 0; PVOID pSourceBuffer = NULL; DWORD dwSize = 0; DWORD dwTotalSize = 0; DWORD dwSpaceAvailable = 0; PVOID pBuffer = NULL; PVOID pBufferCursor = NULL; PIO_CREDS pCreds = NULL; NET_VALIDATION_LEVEL eValidation = NET_VALIDATION_NONE; BAIL_ON_INVALID_PTR(ppBuffer, err); BAIL_ON_INVALID_PTR(pdwNumEntries, err); BAIL_ON_INVALID_PTR(pdwTotalNumEntries, err); BAIL_ON_INVALID_PTR(pdwResume, err); switch (dwLevel) { case 0: dwInfoLevelSize = sizeof(LOCALGROUP_INFO_0); break; case 1: dwInfoLevelSize = sizeof(LOCALGROUP_INFO_1); break; default: err = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(err); } dwResume = *pdwResume; status = LwIoGetActiveCreds(NULL, &pCreds); BAIL_ON_NT_STATUS(status); status = NetConnectSamr(&pConn, pwszHostname, 0, 0, pCreds); BAIL_ON_NT_STATUS(status); hSamrBinding = pConn->Rpc.Samr.hBinding; hDomain = pConn->Rpc.Samr.hDomain; hBtinDomain = pConn->Rpc.Samr.hBuiltin; do { status = SamrEnumDomainAliases(hSamrBinding, hDomain, &dwSamrResume, dwAccountFlags, &ppwszDomainAliases, &pdwDomainRids, &dwNumDomainEntries); if (status != STATUS_SUCCESS && status != STATUS_MORE_ENTRIES) { BAIL_ON_NT_STATUS(status); } if (ppwszDomainAliases) { SamrFreeMemory(ppwszDomainAliases); ppwszDomainAliases = NULL; } if (pdwDomainRids) { SamrFreeMemory(pdwDomainRids); pdwDomainRids = NULL; } dwTotalNumDomainEntries += dwNumDomainEntries; dwNumDomainEntries = 0; } while (status == STATUS_MORE_ENTRIES); dwSamrResume = 0; do { status = SamrEnumDomainAliases(hSamrBinding, hBtinDomain, &dwSamrResume, dwAccountFlags, &ppwszBtinDomainAliases, &pdwBtinDomainRids, &dwNumBtinDomainEntries); if (status != STATUS_SUCCESS && status != STATUS_MORE_ENTRIES) { BAIL_ON_NT_STATUS(status); } if (ppwszBtinDomainAliases) { SamrFreeMemory(ppwszBtinDomainAliases); ppwszBtinDomainAliases = NULL; } if (pdwBtinDomainRids) { SamrFreeMemory(pdwBtinDomainRids); pdwBtinDomainRids = NULL; } dwTotalNumBtinDomainEntries += dwNumBtinDomainEntries; dwNumBtinDomainEntries = 0; } while (status == STATUS_MORE_ENTRIES); dwTotalNumEntries = dwTotalNumDomainEntries + dwTotalNumBtinDomainEntries; status = NetAllocateMemory(OUT_PPVOID(&pdwRids), sizeof(pdwRids[0]) * dwTotalNumEntries); BAIL_ON_NT_STATUS(status); status = NetAllocateMemory(OUT_PPVOID(&ppwszAliases), sizeof(ppwszAliases[0]) * dwTotalNumEntries); BAIL_ON_NT_STATUS(status); status = NetAllocateMemory(OUT_PPVOID(&ppAliasInfo), sizeof(ppAliasInfo[0]) * dwTotalNumEntries); BAIL_ON_NT_STATUS(status); dwTotalNumDomainEntries = 0; dwTotalNumBtinDomainEntries = 0; dwSamrResume = 0; do { status = SamrEnumDomainAliases(hSamrBinding, hDomain, &dwSamrResume, dwAccountFlags, &ppwszDomainAliases, &pdwDomainRids, &dwNumDomainEntries); if (status != STATUS_SUCCESS && status != STATUS_MORE_ENTRIES) { BAIL_ON_NT_STATUS(status); } for (i = 0; i < dwNumDomainEntries; i++) { err = LwAllocateWc16String(&ppwszAliases[dwTotalNumDomainEntries + i], ppwszDomainAliases[i]); BAIL_ON_WIN_ERROR(err); pdwRids[dwTotalNumDomainEntries + i] = pdwDomainRids[i]; } dwTotalNumDomainEntries += dwNumDomainEntries; dwNumDomainEntries = 0; if (ppwszDomainAliases) { SamrFreeMemory(ppwszDomainAliases); ppwszDomainAliases = NULL; } if (pdwDomainRids) { SamrFreeMemory(pdwDomainRids); pdwDomainRids = NULL; } } while (status == STATUS_MORE_ENTRIES); dwSamrResume = 0; do { status = SamrEnumDomainAliases(hSamrBinding, hBtinDomain, &dwSamrResume, dwAccountFlags, &ppwszBtinDomainAliases, &pdwBtinDomainRids, &dwNumBtinDomainEntries); if (status != STATUS_SUCCESS && status != STATUS_MORE_ENTRIES) { BAIL_ON_NT_STATUS(status); } for (i = 0; i < dwNumBtinDomainEntries; i++) { err = LwAllocateWc16String(&ppwszAliases[dwTotalNumDomainEntries + dwTotalNumBtinDomainEntries + i], ppwszBtinDomainAliases[i]); BAIL_ON_WIN_ERROR(err); pdwRids[dwTotalNumDomainEntries + dwTotalNumBtinDomainEntries + i] = pdwBtinDomainRids[i]; } dwTotalNumBtinDomainEntries += dwNumBtinDomainEntries; dwNumBtinDomainEntries = 0; if (ppwszBtinDomainAliases) { SamrFreeMemory(ppwszBtinDomainAliases); ppwszBtinDomainAliases = NULL; } if (pdwBtinDomainRids) { SamrFreeMemory(pdwBtinDomainRids); pdwBtinDomainRids = NULL; } } while (status == STATUS_MORE_ENTRIES); for (i = dwResume; i < dwTotalNumEntries; i++) { if (dwLevel == 0) { pSourceBuffer = ppwszAliases[i]; } else { DOMAIN_HANDLE hDom = NULL; DWORD dwRid = 0; hDom = (i < dwTotalNumDomainEntries) ? hDomain : hBtinDomain; dwRid = pdwRids[i]; status = SamrOpenAlias(hSamrBinding, hDom, dwAliasAccessFlags, dwRid, &hAlias); BAIL_ON_NT_STATUS(status); status = SamrQueryAliasInfo(hSamrBinding, hAlias, wInfoLevel, &pSamrAliasInfo); BAIL_ON_NT_STATUS(status); ppAliasInfo[i - dwResume] = &pSamrAliasInfo->all; pSourceBuffer = &pSamrAliasInfo->all; status = SamrClose(hSamrBinding, hAlias); BAIL_ON_NT_STATUS(status); } dwSize = 0; err = NetAllocateLocalGroupInfo(NULL, NULL, dwLevel, pSourceBuffer, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); dwTotalSize += dwSize; dwNumEntries++; if (dwTotalSize > dwMaxBufferSize) { dwTotalSize -= dwSize; dwNumEntries--; break; } } if (dwTotalNumEntries > 0 && dwNumEntries == 0) { err = ERROR_INSUFFICIENT_BUFFER; BAIL_ON_WIN_ERROR(err); } if (dwTotalSize) { status = NetAllocateMemory(OUT_PPVOID(&pBuffer), dwTotalSize); BAIL_ON_NT_STATUS(status); } dwSize = 0; pBufferCursor = pBuffer; dwSpaceAvailable = dwTotalSize; for (i = 0; i < dwNumEntries; i++) { if (dwLevel == 0) { pSourceBuffer = ppwszAliases[dwResume + i]; } else { pSourceBuffer = ppAliasInfo[i]; } pBufferCursor = pBuffer + (i * dwInfoLevelSize); err = NetAllocateLocalGroupInfo(pBufferCursor, &dwSpaceAvailable, dwLevel, pSourceBuffer, &dwSize, eValidation); BAIL_ON_WIN_ERROR(err); } if (dwResume + dwNumEntries < dwTotalNumEntries) { err = ERROR_MORE_DATA; } *ppBuffer = pBuffer; *pdwNumEntries = dwNumEntries; *pdwTotalNumEntries = dwTotalNumEntries; *pdwResume = dwResume + dwNumEntries; cleanup: NetDisconnectSamr(&pConn); if (pdwRids) { NetFreeMemory(pdwRids); } if (ppwszAliases) { for (i = 0; i < dwTotalNumEntries; i++) { LW_SAFE_FREE_MEMORY(ppwszAliases[i]); } NetFreeMemory(ppwszAliases); } if (ppAliasInfo) { for (i = 0; i < dwNumEntries; i++) { if (ppAliasInfo[i]) { SamrFreeMemory(ppAliasInfo[i]); } } NetFreeMemory(ppAliasInfo); } if (ppwszDomainAliases) { SamrFreeMemory(ppwszDomainAliases); } if (pdwDomainRids) { SamrFreeMemory(pdwDomainRids); } if (ppwszBtinDomainAliases) { SamrFreeMemory(ppwszBtinDomainAliases); } if (pdwBtinDomainRids) { SamrFreeMemory(pdwBtinDomainRids); } if (pCreds) { LwIoDeleteCreds(pCreds); } if (err == ERROR_SUCCESS && status != STATUS_SUCCESS) { err = NtStatusToWin32Error(status); } return err; error: if (pBuffer) { NetFreeMemory(pBuffer); } *ppBuffer = NULL; *pdwNumEntries = 0; *pdwTotalNumEntries = 0; *pdwResume = 0; goto cleanup; }
DWORD WkssAllocateNetrWkstaUserInfo( OUT PVOID pOut, IN OUT PDWORD pdwOffset, IN OUT PDWORD pdwSpaceLeft, IN DWORD dwLevel, IN PNETR_WKSTA_USER_INFO_CTR pIn, IN OUT PDWORD pdwSize ) { DWORD dwError = ERROR_SUCCESS; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD iUser = 0; DWORD dwCount = 0; PVOID pBuffer = pOut; BAIL_ON_INVALID_PTR(pdwOffset, ntStatus); BAIL_ON_INVALID_PTR(pIn, ntStatus); BAIL_ON_INVALID_PTR(pdwSize, ntStatus); switch (dwLevel) { case 0: dwCount = pIn->pInfo0->dwCount; break; case 1: dwCount = pIn->pInfo1->dwCount; break; default: dwError = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(dwError); } for (iUser = 0; iUser < dwCount; iUser++) { switch (dwLevel) { case 0: dwError = WkssAllocateNetrWkstaUserInfo0( pBuffer, pdwOffset, pdwSpaceLeft, &(pIn->pInfo0->pInfo[iUser]), pdwSize); break; case 1: dwError = WkssAllocateNetrWkstaUserInfo1( pBuffer, pdwOffset, pdwSpaceLeft, &(pIn->pInfo1->pInfo[iUser]), pdwSize); break; } BAIL_ON_WIN_ERROR(dwError); } cleanup: if (dwError == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { dwError = LwNtStatusToWin32Error(ntStatus); } return dwError; error: goto cleanup; }
NET_API_STATUS NetUserSetInfo( PCWSTR pwszHostname, PCWSTR pwszUsername, DWORD dwLevel, PVOID pBuffer, PDWORD pdwParmErr ) { /* This is necessary to be able to set account password. Otherwise we get access denied. Don't ask... */ const DWORD dwDomainAccess = DOMAIN_ACCESS_LOOKUP_INFO_1; const DWORD dwUserAccess = USER_ACCESS_GET_NAME_ETC | USER_ACCESS_GET_LOCALE | USER_ACCESS_GET_LOGONINFO | USER_ACCESS_GET_ATTRIBUTES | USER_ACCESS_GET_GROUPS | USER_ACCESS_GET_GROUP_MEMBERSHIP | USER_ACCESS_SET_LOC_COM | USER_ACCESS_SET_ATTRIBUTES | USER_ACCESS_CHANGE_PASSWORD | USER_ACCESS_SET_PASSWORD; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; PNET_CONN pConn = NULL; SAMR_BINDING hSamrBinding = NULL; ACCOUNT_HANDLE hUser = NULL; DWORD dwUserRid = 0; DWORD dwSamrInfoLevel = 0; DWORD dwSamrPasswordInfoLevel = 0; DWORD dwParmErr = 0; UserInfo *pSamrUserInfo = NULL; UserInfo *pSamrPasswordUserInfo = NULL; DWORD dwSize = 0; DWORD dwSpaceLeft = 0; PIO_CREDS pCreds = NULL; NET_VALIDATION_LEVEL eValidation = NET_VALIDATION_USER_SET; if (!(dwLevel == 0 || dwLevel == 1 || dwLevel == 2 || dwLevel == 3 || dwLevel == 4 || dwLevel == 1003 || dwLevel == 1007 || dwLevel == 1008 || dwLevel == 1011)) { err = ERROR_INVALID_LEVEL; BAIL_ON_WIN_ERROR(err); } BAIL_ON_INVALID_PTR(pwszUsername, err); BAIL_ON_INVALID_PTR(pBuffer, err); status = LwIoGetActiveCreds(NULL, &pCreds); BAIL_ON_NT_STATUS(status); err = NetAllocateSamrUserInfo(NULL, &dwSamrInfoLevel, NULL, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); dwSpaceLeft = dwSize; dwSize = 0; if (dwSpaceLeft) { status = NetAllocateMemory(OUT_PPVOID(&pSamrUserInfo), dwSpaceLeft); BAIL_ON_NT_STATUS(status); err = NetAllocateSamrUserInfo(&pSamrUserInfo->info21, &dwSamrInfoLevel, &dwSpaceLeft, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); } status = NetConnectSamr(&pConn, pwszHostname, dwDomainAccess, 0, pCreds); BAIL_ON_NT_STATUS(status); hSamrBinding = pConn->Rpc.Samr.hBinding; status = NetOpenUser(pConn, pwszUsername, dwUserAccess, &hUser, &dwUserRid); BAIL_ON_NT_STATUS(status); /* * Check if there's password to be set (if it's NULL * the function returns ERROR_INVALID_PASSWORD) */ dwSamrPasswordInfoLevel = 26; dwSize = 0; err = NetAllocateSamrUserInfo(NULL, &dwSamrPasswordInfoLevel, NULL, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); if (err == ERROR_SUCCESS) { dwSpaceLeft = dwSize; dwSize = 0; if (dwSpaceLeft) { status = NetAllocateMemory(OUT_PPVOID(&pSamrPasswordUserInfo), dwSpaceLeft); BAIL_ON_NT_STATUS(status); } err = NetAllocateSamrUserInfo(&pSamrPasswordUserInfo->info26, &dwSamrPasswordInfoLevel, &dwSpaceLeft, dwLevel, pBuffer, pConn, &dwSize, eValidation, &dwParmErr); BAIL_ON_WIN_ERROR(err); status = SamrSetUserInfo(hSamrBinding, hUser, dwSamrPasswordInfoLevel, pSamrPasswordUserInfo); BAIL_ON_NT_STATUS(status); } else if (err == ERROR_INVALID_LEVEL || (err == ERROR_INVALID_PASSWORD && dwLevel != 1003)) { /* This error only means we're not going to try set the password. Either it's set to NULL in infolevel where it's optional or called infolevel doesn't support setting password */ err = ERROR_SUCCESS; } else { BAIL_ON_WIN_ERROR(err); } if (dwSamrInfoLevel) { status = SamrSetUserInfo(hSamrBinding, hUser, dwSamrInfoLevel, pSamrUserInfo); BAIL_ON_NT_STATUS(status); } status = SamrClose(hSamrBinding, hUser); BAIL_ON_NT_STATUS(status); cleanup: NetDisconnectSamr(&pConn); if (pdwParmErr) { *pdwParmErr = dwParmErr; } if (pSamrUserInfo) { NetFreeMemory(pSamrUserInfo); } if (pCreds) { LwIoDeleteCreds(pCreds); } if (err == ERROR_SUCCESS && status != STATUS_SUCCESS) { err = LwNtStatusToWin32Error(status); } return err; error: goto cleanup; }
NET_API_STATUS NetGetDomainName( IN PCWSTR pwszHostname, OUT PWSTR *ppwszDomainName ) { const DWORD dwConnAccess = SAMR_ACCESS_OPEN_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS; NTSTATUS ntStatus = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; PNET_CONN pConn = NULL; size_t sDomainNameLen = 0; PWSTR pwszDomainName = NULL; PIO_CREDS pCreds = NULL; BAIL_ON_INVALID_PTR(ppwszDomainName, err); ntStatus = LwIoGetActiveCreds(NULL, &pCreds); BAIL_ON_NT_STATUS(ntStatus); ntStatus = NetConnectSamr(&pConn, pwszHostname, dwConnAccess, 0, pCreds); BAIL_ON_NT_STATUS(ntStatus); err = LwWc16sLen(pConn->Rpc.Samr.pwszDomainName, &sDomainNameLen); BAIL_ON_WIN_ERROR(err); ntStatus = NetAllocateMemory( OUT_PPVOID(&pwszDomainName), sizeof(pwszDomainName[0]) * (sDomainNameLen + 1)); BAIL_ON_NT_STATUS(ntStatus); err = LwWc16snCpy(pwszDomainName, pConn->Rpc.Samr.pwszDomainName, sDomainNameLen); BAIL_ON_WIN_ERROR(err); *ppwszDomainName = pwszDomainName; cleanup: NetDisconnectSamr(&pConn); if (pCreds) { LwIoDeleteCreds(pCreds); } if (err == ERROR_SUCCESS && ntStatus != STATUS_SUCCESS) { err = NtStatusToWin32Error(ntStatus); } return err; error: if (pwszDomainName) { NetFreeMemory(pwszDomainName); } *ppwszDomainName = NULL; goto cleanup; }
NTSTATUS NetOpenAlias( PNET_CONN pConn, PCWSTR pwszAliasname, DWORD dwAccessMask, ACCOUNT_HANDLE *phAlias, PDWORD pdwRid ) { const DWORD dwNumAliases = 1; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; SAMR_BINDING hSamrBinding = NULL; DOMAIN_HANDLE hDomains[2] = {0}; DOMAIN_HANDLE hDomain = NULL; ACCOUNT_HANDLE hAlias = NULL; PWSTR ppwszAliasnames[1] = {0}; PDWORD pdwRids = NULL; PDWORD pdwTypes = NULL; DWORD dwAliasRid = 0; DWORD i = 0; BAIL_ON_INVALID_PTR(pConn, err); BAIL_ON_INVALID_PTR(pwszAliasname, err); BAIL_ON_INVALID_PTR(phAlias, err); BAIL_ON_INVALID_PTR(pdwRid, err); hSamrBinding = pConn->Rpc.Samr.hBinding; hDomains[0] = pConn->Rpc.Samr.hDomain; hDomains[1] = pConn->Rpc.Samr.hBuiltin; err = LwAllocateWc16String(&ppwszAliasnames[0], pwszAliasname); BAIL_ON_WIN_ERROR(err); /* * Try to look for alias in host domain first, then in builtin */ for (i = 0; i < sizeof(hDomains)/sizeof(hDomains[0]); i++) { status = SamrLookupNames(hSamrBinding, hDomains[i], dwNumAliases, ppwszAliasnames, (PUINT32*)&pdwRids, (PUINT32*)&pdwTypes, NULL); if (status == STATUS_SUCCESS) { /* * Alias has been found in one of domains so pass * that domain handle further down */ hDomain = hDomains[i]; dwAliasRid = pdwRids[0]; break; } else if (status == STATUS_NONE_MAPPED) { if (pdwRids) { SamrFreeMemory((void*)pdwRids); pdwRids = NULL; } if (pdwTypes) { SamrFreeMemory((void*)pdwTypes); pdwTypes = NULL; } continue; } /* Catch other possible errors */ BAIL_ON_NT_STATUS(status); } /* Allow to open alias only if a valid one has been found */ BAIL_ON_NT_STATUS(status); status = SamrOpenAlias(hSamrBinding, hDomain, dwAccessMask, dwAliasRid, &hAlias); BAIL_ON_NT_STATUS(status); *pdwRid = dwAliasRid; *phAlias = hAlias; cleanup: LW_SAFE_FREE_MEMORY(ppwszAliasnames[0]); if (pdwRids) { SamrFreeMemory((void*)pdwRids); } if (pdwTypes) { SamrFreeMemory((void*)pdwTypes); } return status; error: *pdwRid = 0; *phAlias = NULL; goto cleanup; }
NET_API_STATUS NetFileEnum( PSRVSVC_CONTEXT pContext, /* IN */ PCWSTR pwszServername, /* IN OPTIONAL */ PCWSTR pwszBasepath, /* IN OPTIONAL */ PCWSTR pwszUsername, /* IN OPTIONAL */ DWORD dwInfoLevel, /* IN */ PBYTE* ppBuffer, /* OUT */ DWORD dwPrefmaxLen, /* IN */ PDWORD pdwEntriesRead, /* OUT */ PDWORD pdwTotalEntries, /* OUT */ PDWORD pdwResumeHandle /* IN OUT OPTIONAL */ ) { NET_API_STATUS status = 0; PBYTE pBuffer = NULL; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwResumeHandle = 0; if (!ppBuffer || !pdwEntriesRead || !pdwTotalEntries) { status = ERROR_INVALID_PARAMETER; BAIL_ON_WIN_ERROR(status); } status = NetrFileEnum( pContext, pwszServername, pwszBasepath, pwszUsername, dwInfoLevel, &pBuffer, dwPrefmaxLen, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle); BAIL_ON_WIN_ERROR(status); *ppBuffer = pBuffer; *pdwEntriesRead = dwEntriesRead; *pdwTotalEntries = dwTotalEntries; *pdwResumeHandle = dwResumeHandle; cleanup: return status; error: if (ppBuffer) { *ppBuffer = NULL; } if (pdwEntriesRead) { *pdwEntriesRead = 0; } if (pdwTotalEntries) { *pdwTotalEntries = 0; } if (pdwResumeHandle) { *pdwResumeHandle = 0; } goto cleanup; }
static NET_API_STATUS SrvSvcCopyNetFileInfo( UINT32 level, srvsvc_NetFileInfo* info, UINT8** bufptr ) { NET_API_STATUS status = ERROR_SUCCESS; void *ptr = NULL; BAIL_ON_INVALID_PTR(bufptr, status); BAIL_ON_INVALID_PTR(info, status); *bufptr = NULL; switch (level) { case 2: if (info->info2) { PFILE_INFO_2 a2; status = SrvSvcAllocateMemory(&ptr, sizeof(FILE_INFO_2), NULL); BAIL_ON_WIN_ERROR(status); a2 = (PFILE_INFO_2)ptr; *a2 = *info->info2; } break; case 3: if (info->info3) { PFILE_INFO_3 pFileInfo; status = SrvSvcAllocateMemory(&ptr, sizeof(FILE_INFO_3), NULL); BAIL_ON_WIN_ERROR(status); pFileInfo = (PFILE_INFO_3)ptr; *pFileInfo = *info->info3; pFileInfo->fi3_path_name = NULL; pFileInfo->fi3_username = NULL; if (info->info3->fi3_path_name) { status = SrvSvcAddDepStringW( pFileInfo, info->info3->fi3_path_name, &pFileInfo->fi3_path_name); BAIL_ON_WIN_ERROR(status); } if (info->info3->fi3_username) { status = SrvSvcAddDepStringW( pFileInfo, info->info3->fi3_username, &pFileInfo->fi3_username); BAIL_ON_WIN_ERROR(status); } } break; } *bufptr = (UINT8 *)ptr; cleanup: return status; error: if (ptr) { SrvSvcFreeMemory(ptr); } goto cleanup; }
BOOLEAN CreateRpcBinding( PVOID *phBinding, RPC_BINDING_TYPE eBindingType, PCWSTR pwszHostname, PCWSTR pwszBinding, PCREDENTIALS pCredentials ) { PCSTR pszNtlmsspAuth = "ntlmssp"; PCSTR pszSign = "sign"; PCSTR pszSeal = "seal"; BOOLEAN bRet = TRUE; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; unsigned32 rpcStatus = RPC_S_OK; LSA_BINDING hBinding = NULL; LW_PIO_CREDS pIoCreds = NULL; PWSTR pwszBindingString = NULL; size_t sBindingStringLen = 0; PSTR pszBindingString = NULL; PSTR *ppszOptions = NULL; DWORD iOpt = 0; DWORD i = 0; DWORD dwNumValidOptions = 0; unsigned32 AuthType = 0; unsigned32 ProtectionLevel = 0; SEC_WINNT_AUTH_IDENTITY *pNtlmSspAuthInfo = NULL; PVOID pAuthInfo = NULL; unsigned char *pszUuid = NULL; unsigned char *pszProtSeq = NULL; unsigned char *pszNetworkAddr = NULL; unsigned char *pszEndpoint = NULL; unsigned char *pszOptions = NULL; PSTR pszHostname = NULL; if (phBinding == NULL) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } if (pwszBinding) { dwError = LwAllocateWc16String(&pwszBindingString, pwszBinding); BAIL_ON_WIN_ERROR(dwError); dwError = LwWc16sLen(pwszBindingString, &sBindingStringLen); BAIL_ON_WIN_ERROR(dwError); dwError = LwWc16sToMbs(pwszBindingString, &pszBindingString); BAIL_ON_WIN_ERROR(dwError); ppszOptions = get_string_list(pszBindingString, ':'); if (ppszOptions == NULL) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } /* * Find and identify valid options */ while (ppszOptions[iOpt]) { if (!strcasecmp(pszNtlmsspAuth, ppszOptions[iOpt])) { AuthType = rpc_c_authn_winnt; dwNumValidOptions++; } else if (!strcasecmp(pszSign, ppszOptions[iOpt])) { ProtectionLevel = rpc_c_authn_level_pkt_integrity; dwNumValidOptions++; } else if (!strcasecmp(pszSeal, ppszOptions[iOpt])) { ProtectionLevel = rpc_c_authn_level_pkt_privacy; dwNumValidOptions++; } iOpt++; } } /* * Cut off the options from the binding string so it can * be passed to rpc routines */ if (dwNumValidOptions > 0) { i = sBindingStringLen; while (dwNumValidOptions && pwszBindingString[--i]) { if (pwszBindingString[i] == (WCHAR)':') { dwNumValidOptions--; } } pwszBindingString[i] = (WCHAR)'\0'; pszBindingString[i] = '\0'; } ntStatus = LwIoGetActiveCreds(NULL, &pIoCreds); BAIL_ON_NT_STATUS(ntStatus); if (pwszBindingString) { ntStatus = RpcInitBindingFromBindingString( (handle_t*)&hBinding, pwszBindingString, pIoCreds); } else { switch (eBindingType) { case RPC_LSA_BINDING: ntStatus = LsaInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_SAMR_BINDING: ntStatus = SamrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_NETLOGON_BINDING: ntStatus = NetrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_DSSETUP_BINDING: ntStatus = DsrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_WKSSVC_BINDING: ntStatus = WkssInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; default: ntStatus = STATUS_NOT_IMPLEMENTED; break; } } BAIL_ON_NT_STATUS(ntStatus); switch (AuthType) { case rpc_c_authn_winnt: dwError = LwAllocateMemory(sizeof(*pNtlmSspAuthInfo), OUT_PPVOID(&pNtlmSspAuthInfo)); BAIL_ON_WIN_ERROR(dwError); if (pCredentials->Ntlm.pwszDomain) { dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszDomain, &pNtlmSspAuthInfo->Domain); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->DomainLength = strlen(pNtlmSspAuthInfo->Domain); } dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszUsername, &pNtlmSspAuthInfo->User); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->UserLength = strlen(pNtlmSspAuthInfo->User); dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszPassword, &pNtlmSspAuthInfo->Password); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->PasswordLength = strlen(pNtlmSspAuthInfo->Password); pAuthInfo = (PVOID)pNtlmSspAuthInfo; break; default: pAuthInfo = NULL; break; } if (pwszHostname) { dwError = LwWc16sToMbs(pwszHostname, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } else { rpc_string_binding_parse((unsigned char*)pszBindingString, &pszUuid, &pszProtSeq, &pszNetworkAddr, &pszEndpoint, &pszOptions, &rpcStatus); if (rpcStatus) { ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NT_STATUS(ntStatus); } dwError = LwAllocateString((PSTR)pszNetworkAddr, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } if (AuthType) { rpc_binding_set_auth_info(hBinding, (unsigned char*)pszHostname, ProtectionLevel, AuthType, (rpc_auth_identity_handle_t)pAuthInfo, rpc_c_authz_name, /* authz_protocol */ &rpcStatus); if (rpcStatus) { ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NT_STATUS(ntStatus); } } *phBinding = hBinding; cleanup: if (pIoCreds) { LwIoDeleteCreds(pIoCreds); } LW_SAFE_FREE_MEMORY(pwszBindingString); LW_SAFE_FREE_MEMORY(pszBindingString); LW_SAFE_FREE_MEMORY(pszHostname); rpc_string_free(&pszUuid, &rpcStatus); rpc_string_free(&pszProtSeq, &rpcStatus); rpc_string_free(&pszNetworkAddr, &rpcStatus); rpc_string_free(&pszEndpoint, &rpcStatus); rpc_string_free(&pszOptions, &rpcStatus); if (ppszOptions) { free_string_list(ppszOptions); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } if (ntStatus != STATUS_SUCCESS) { bRet = FALSE; } return bRet; error: *phBinding = NULL; bRet = FALSE; goto cleanup; }
NTSTATUS SamrLookupNames( IN SAMR_BINDING hBinding, IN DOMAIN_HANDLE hDomain, IN DWORD dwNumNames, IN PWSTR *ppwszNames, OUT UINT32 **ppRids, OUT UINT32 **ppTypes, OUT UINT32 *pRidsCount ) { NTSTATUS ntStatus = STATUS_SUCCESS; NTSTATUS ntLookupStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PUNICODE_STRING pNames = NULL; DWORD iName = 0; IDS Rids = {0}; IDS Types = {0}; UINT32 *pRids = NULL; UINT32 *pTypes = NULL; DWORD dwOffset = 0; DWORD dwSpaceLeft = 0; DWORD dwSize = 0; BAIL_ON_INVALID_PTR(hBinding, ntStatus); BAIL_ON_INVALID_PTR(hDomain, ntStatus); BAIL_ON_INVALID_PTR(ppwszNames, ntStatus); BAIL_ON_INVALID_PTR(ppRids, ntStatus); BAIL_ON_INVALID_PTR(ppTypes, ntStatus); /* pRidsCount can be NULL, in which case the number of returned rids must match num_names. */ dwError = LwAllocateMemory(sizeof(pNames[0]) * dwNumNames, OUT_PPVOID(&pNames)); BAIL_ON_WIN_ERROR(dwError); for (iName = 0; iName < dwNumNames; iName++) { dwError = LwAllocateUnicodeStringFromWc16String( &pNames[iName], ppwszNames[iName]); BAIL_ON_WIN_ERROR(dwError); } DCERPC_CALL(ntStatus, cli_SamrLookupNames((handle_t)hBinding, hDomain, dwNumNames, pNames, &Rids, &Types)); if (ntStatus != STATUS_SUCCESS && ntStatus != STATUS_SOME_NOT_MAPPED) { BAIL_ON_NT_STATUS(ntStatus); } ntLookupStatus = ntStatus; if (Rids.dwCount != Types.dwCount) { ntStatus = STATUS_REPLY_MESSAGE_MISMATCH; BAIL_ON_NT_STATUS(ntStatus); } ntStatus = SamrAllocateIds(NULL, &dwOffset, NULL, &Rids, &dwSize); BAIL_ON_NT_STATUS(ntStatus); dwSpaceLeft = sizeof(pRids[0]) * Rids.dwCount; dwSize = 0; dwOffset = 0; ntStatus = SamrAllocateMemory(OUT_PPVOID(&pRids), dwSpaceLeft); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SamrAllocateIds(pRids, &dwOffset, &dwSpaceLeft, &Rids, &dwSize); BAIL_ON_NT_STATUS(ntStatus); dwSpaceLeft = sizeof(pTypes[0]) * Types.dwCount; dwSize = 0; dwOffset = 0; ntStatus = SamrAllocateMemory(OUT_PPVOID(&pTypes), dwSpaceLeft); BAIL_ON_NT_STATUS(ntStatus); ntStatus = SamrAllocateIds(pTypes, &dwOffset, &dwSpaceLeft, &Types, &dwSize); BAIL_ON_NT_STATUS(ntStatus); if (pRidsCount) { *pRidsCount = Rids.dwCount; } else if (Rids.dwCount != dwNumNames) { ntStatus = STATUS_REPLY_MESSAGE_MISMATCH; BAIL_ON_NT_STATUS(ntStatus); } *ppRids = pRids; *ppTypes = pTypes; cleanup: SamrCleanStubIds(&Rids); SamrCleanStubIds(&Types); if (pNames) { for (iName = 0; iName < dwNumNames; iName++) { LwFreeUnicodeString(&(pNames[iName])); } LW_SAFE_FREE_MEMORY(pNames); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } if (ntStatus == STATUS_SUCCESS && ntLookupStatus != STATUS_SUCCESS) { ntStatus = ntLookupStatus; } return ntStatus; error: if (pRids) { SamrFreeMemory(pRids); } if (pTypes) { SamrFreeMemory(pTypes); } if (pRidsCount) { *pRidsCount = 0; } if (ppRids) { *ppRids = NULL; } if (ppTypes) { *ppTypes = NULL; } goto cleanup; }
NTSTATUS NetOpenUser( PNET_CONN pConn, PCWSTR pwszUsername, DWORD dwAccessMask, ACCOUNT_HANDLE *phUser, PDWORD pdwRid ) { const DWORD dwNumUsers = 1; NTSTATUS status = STATUS_SUCCESS; WINERROR err = ERROR_SUCCESS; SAMR_BINDING hSamrBinding = NULL; DOMAIN_HANDLE hDomain = NULL; ACCOUNT_HANDLE hUser = NULL; PWSTR ppwszUsernames[1] = {0}; PDWORD pdwRids = NULL; PDWORD pdwTypes = NULL; BAIL_ON_INVALID_PTR(pConn, err); BAIL_ON_INVALID_PTR(pwszUsername, err); BAIL_ON_INVALID_PTR(phUser, err); BAIL_ON_INVALID_PTR(pdwRid, err); hSamrBinding = pConn->Rpc.Samr.hBinding; hDomain = pConn->Rpc.Samr.hDomain; err = LwAllocateWc16String(&ppwszUsernames[0], pwszUsername); BAIL_ON_WIN_ERROR(err); status = SamrLookupNames(hSamrBinding, hDomain, dwNumUsers, ppwszUsernames, &pdwRids, &pdwTypes, NULL); BAIL_ON_NT_STATUS(status); status = SamrOpenUser(hSamrBinding, hDomain, dwAccessMask, pdwRids[0], &hUser); BAIL_ON_NT_STATUS(status); *pdwRid = pdwRids[0]; *phUser = hUser; cleanup: if (pdwRids) { SamrFreeMemory(pdwRids); } if (pdwTypes) { SamrFreeMemory(pdwTypes); } LW_SAFE_FREE_MEMORY(ppwszUsernames[0]); return status; error: *pdwRid = 0; *phUser = NULL; goto cleanup; }
NTSTATUS SamrCreateDomAlias( IN SAMR_BINDING hBinding, IN DOMAIN_HANDLE hDomain, IN PWSTR pwszAliasName, IN UINT32 AccessMask, OUT ACCOUNT_HANDLE *phAlias, OUT PUINT32 pRid ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; UNICODE_STRING AliasName = {0}; ACCOUNT_HANDLE hAlias = NULL; UINT32 Rid = 0; BAIL_ON_INVALID_PTR(hBinding, ntStatus); BAIL_ON_INVALID_PTR(hDomain, ntStatus); BAIL_ON_INVALID_PTR(pwszAliasName, ntStatus); BAIL_ON_INVALID_PTR(phAlias, ntStatus); BAIL_ON_INVALID_PTR(pRid, ntStatus); dwError = LwAllocateUnicodeStringFromWc16String( &AliasName, pwszAliasName); BAIL_ON_WIN_ERROR(dwError); DCERPC_CALL(ntStatus, cli_SamrCreateDomAlias((handle_t)hBinding, hDomain, &AliasName, AccessMask, &hAlias, &Rid)); BAIL_ON_NT_STATUS(ntStatus); *phAlias = hAlias; *pRid = Rid; cleanup: LwFreeUnicodeString(&AliasName); if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (phAlias) { *phAlias = NULL; } if (pRid) { *pRid = 0; } goto cleanup; }
NTSTATUS LsaInitBindingFull( OUT PLSA_BINDING phBinding, IN PCWSTR pwszProtSeq, IN PCWSTR pwszHostname, IN PCWSTR pwszEndpoint, IN PCWSTR pwszUuid, IN PCWSTR pwszOptions, IN PIO_CREDS pCreds ) { NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; PSTR pszProtSeq = NULL; PSTR pszHostname = NULL; PSTR pszEndpoint = NULL; PSTR pszUuid = NULL; PSTR pszOptions = NULL; LSA_BINDING hBinding = NULL; BAIL_ON_INVALID_PTR(phBinding, ntStatus); BAIL_ON_INVALID_PTR(pwszProtSeq, ntStatus); dwError = LwWc16sToMbs(pwszProtSeq, &pszProtSeq); BAIL_ON_WIN_ERROR(dwError); if (pwszHostname) { dwError = LwWc16sToMbs(pwszHostname, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } dwError = LwWc16sToMbs(pwszEndpoint, &pszEndpoint); BAIL_ON_WIN_ERROR(dwError); if (pwszUuid) { dwError = LwWc16sToMbs(pwszUuid, &pszUuid); BAIL_ON_WIN_ERROR(dwError); } if (pwszOptions) { dwError = LwWc16sToMbs(pwszOptions, &pszOptions); BAIL_ON_WIN_ERROR(dwError); } ntStatus = LsaInitBindingFullA(&hBinding, pszProtSeq, pszHostname, pszEndpoint, pszUuid, pszOptions, pCreds); BAIL_ON_NT_STATUS(ntStatus); *phBinding = hBinding; cleanup: LW_SAFE_FREE_MEMORY(pszProtSeq); LW_SAFE_FREE_MEMORY(pszHostname); LW_SAFE_FREE_MEMORY(pszEndpoint); LW_SAFE_FREE_MEMORY(pszUuid); LW_SAFE_FREE_MEMORY(pszOptions); if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } return ntStatus; error: if (phBinding) { *phBinding = NULL; } goto cleanup; }
DWORD GetMachinePassword( OUT OPTIONAL PWSTR* ppwszDnsDomainName, OUT OPTIONAL PWSTR* ppwszMachineSamAccountName, OUT OPTIONAL PWSTR* ppwszMachinePassword, OUT OPTIONAL PWSTR* ppwszComputerName ) { DWORD dwError = 0; PWSTR pwszDnsDomainName = NULL; PWSTR pwszMachineSamAccountName = NULL; PWSTR pwszMachinePassword = NULL; PWSTR pwszComputerName = NULL; HANDLE hLsaConnection = NULL; PLSA_MACHINE_PASSWORD_INFO_A pPasswordInfo = NULL; dwError = LsaOpenServer(&hLsaConnection); BAIL_ON_WIN_ERROR(dwError); dwError = LsaAdGetMachinePasswordInfo(hLsaConnection, NULL, &pPasswordInfo); BAIL_ON_WIN_ERROR(dwError); if (ppwszDnsDomainName) { dwError = LwMbsToWc16s(pPasswordInfo->Account.DnsDomainName, &pwszDnsDomainName); BAIL_ON_WIN_ERROR(dwError); } if (ppwszMachineSamAccountName) { dwError = LwMbsToWc16s(pPasswordInfo->Account.SamAccountName, &pwszMachineSamAccountName); BAIL_ON_WIN_ERROR(dwError); } if (ppwszMachinePassword) { dwError = LwMbsToWc16s(pPasswordInfo->Password, &pwszMachinePassword); BAIL_ON_WIN_ERROR(dwError); } if (ppwszComputerName) { dwError = LwMbsToWc16s(pPasswordInfo->Account.SamAccountName, &pwszComputerName); BAIL_ON_WIN_ERROR(dwError); // Remove $ from account name pwszComputerName[wc16slen(pwszComputerName) - 1] = 0; } error: if (dwError) { LW_SAFE_FREE_MEMORY(pwszDnsDomainName); LW_SAFE_FREE_MEMORY(pwszMachineSamAccountName); LW_SECURE_FREE_WSTRING(pwszMachinePassword); LW_SAFE_FREE_MEMORY(pwszComputerName); } if (hLsaConnection) { LsaCloseServer(hLsaConnection); } if (pPasswordInfo) { LsaAdFreeMachinePasswordInfo(pPasswordInfo); } if (ppwszDnsDomainName) { *ppwszDnsDomainName = pwszDnsDomainName; } if (ppwszMachineSamAccountName) { *ppwszMachineSamAccountName = pwszMachineSamAccountName; } if (ppwszMachinePassword) { *ppwszMachinePassword = pwszMachinePassword; } if (ppwszComputerName) { *ppwszComputerName = pwszComputerName; } return dwError; }
static DWORD NetAllocateLocalGroupMembersInfo3( PVOID *ppCursor, PDWORD pdwSpaceLeft, PVOID pSource, PDWORD pdwSize, NET_VALIDATION_LEVEL eValidation ) { DWORD err = ERROR_SUCCESS; PVOID pCursor = NULL; DWORD dwSpaceLeft = 0; DWORD dwSize = 0; PNET_RESOLVED_NAME pName = (PNET_RESOLVED_NAME)pSource; PWSTR pwszDomainName = NULL; PWSTR pwszAccountName = NULL; if (pdwSpaceLeft) { dwSpaceLeft = *pdwSpaceLeft; } if (pdwSize) { dwSize = *pdwSize; } if (ppCursor) { pCursor = *ppCursor; } err = LwAllocateWc16StringFromUnicodeString( &pwszDomainName, &pName->DomainName); BAIL_ON_WIN_ERROR(err); err = LwAllocateWc16StringFromUnicodeString( &pwszAccountName, &pName->AccountName); BAIL_ON_WIN_ERROR(err); /* lgrmi3_domainandname */ err = NetAllocBufferNT4Name(&pCursor, &dwSpaceLeft, pwszDomainName, pwszAccountName, &dwSize); BAIL_ON_WIN_ERROR(err); if (pdwSpaceLeft) { *pdwSpaceLeft = dwSpaceLeft; } if (pdwSize) { *pdwSize = dwSize; } cleanup: return err; error: goto cleanup; }