windows-nt/Source/XPSP1/NT/net/rras/cm/cmdial/ntlsa.cpp
2020-09-26 16:20:57 +08:00

483 lines
12 KiB
C++

//+----------------------------------------------------------------------------
//
// File: ntlsa.cpp
//
// Module: CMDIAL32.DLL
//
// Synopsis: This module contains the functions to allow Connection Manager to
// interact with the NT LSA security system.
//
// Copyright (c) 1996-1999 Microsoft Corporation
//
// Author: henryt created 02/23/98
// quintinb created Header 08/16/99
//
//+----------------------------------------------------------------------------
#include "cmmaster.h"
///////////////////////////////////////////////////////////////////////////////////
// defines
///////////////////////////////////////////////////////////////////////////////////
#ifndef STATUS_SUCCESS
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#endif
#define InitializeLsaObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( LSA_OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
///////////////////////////////////////////////////////////////////////////////////
// typedef's
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// func prototypes
///////////////////////////////////////////////////////////////////////////////////
void InitLsaString(
PLSA_UNICODE_STRING pLsaString,
LPWSTR pszString
);
///////////////////////////////////////////////////////////////////////////////////
// globals
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// Implementation
///////////////////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// Function: LSA_ReadString
//
// Synopsis: Read a string from the NT Local Security Authority (LSA)
// store.
//
// Arguments: pszKey The key to identify the string.
// pszStr The buffer in which the string is to be
// written to.
// dwStrLen The length of the string buffer in bytes.
//
// Returns: DWORD 0 for SUCCES
// GetLastError() for FAILURE
//
// History: henryt Created 5/15/97
//
//----------------------------------------------------------------------------
DWORD LSA_ReadString(
ArgsStruct *pArgs,
LPTSTR pszKey,
LPTSTR pszStr,
DWORD dwStrLen
)
{
DWORD dwErr;
LSA_OBJECT_ATTRIBUTES oaObjAttr;
LSA_HANDLE hPolicy = NULL;
NTSTATUS ntStatus = STATUS_SUCCESS;
LSA_UNICODE_STRING unicodeKey;
PLSA_UNICODE_STRING punicodeValue = NULL;
#if !defined(_UNICODE) && !defined(UNICODE)
LPWSTR pszUnicodeKey = NULL;
#endif
if (!pszKey || !pszStr)
{
CMASSERTMSG(FALSE, TEXT("LSA_ReadString -- Invalid Parameter passed."));
return ERROR_INVALID_PARAMETER;
}
//
// Open the LSA secret space for writing.
//
InitializeLsaObjectAttributes(&oaObjAttr, NULL, 0L, NULL, NULL);
ntStatus = pArgs->llsLsaLink.pfnOpenPolicy(NULL, &oaObjAttr, POLICY_READ, &hPolicy);
if (ntStatus == STATUS_SUCCESS)
{
#if !defined(_UNICODE) && !defined(UNICODE)
//
// need to convert the ANSI key to unicode
//
if (!(pszUnicodeKey = (LPWSTR)CmMalloc((lstrlenA(pszKey)+1)*sizeof(WCHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto exit;
}
if (!MultiByteToWideChar(CP_ACP, 0, pszKey, -1, pszUnicodeKey, (lstrlenA(pszKey)+1)*sizeof(WCHAR)))
{
CmFree(pszUnicodeKey);
dwErr = ERROR_INVALID_DATA;
goto exit;
}
//
// create a unicode key
//
InitLsaString(&unicodeKey, pszUnicodeKey);
CmFree(pszUnicodeKey);
#else
//
// create a unicode key
//
InitLsaString(&unicodeKey, pszKey);
#endif
//
// get it
//
ntStatus = pArgs->llsLsaLink.pfnRetrievePrivateData(hPolicy, &unicodeKey, &punicodeValue);
}
if (ntStatus != STATUS_SUCCESS)
{
dwErr = pArgs->llsLsaLink.pfnNtStatusToWinError(ntStatus);
#ifdef DEBUG
if (ERROR_SUCCESS != dwErr)
{
if (ERROR_FILE_NOT_FOUND == dwErr)
{
CMTRACE(TEXT("LSA_ReadPassword() NT password not found."));
}
else
{
CMTRACE1(TEXT("LSA_ReadPassword() NT failed, err=%u"), dwErr);
}
}
#endif
}
else
{
if (dwStrLen < punicodeValue->Length)
{
dwErr = ERROR_BUFFER_OVERFLOW;
goto exit;
}
#if !defined(_UNICODE) && !defined(UNICODE)
if (!WideCharToMultiByte(CP_ACP, 0, punicodeValue->Buffer, -1,
pszStr, dwStrLen, NULL, NULL))
{
dwErr = ERROR_INVALID_DATA;
goto exit;
}
#else
CopyMemory((PVOID)pszStr, (CONST PVOID)punicodeValue->Buffer, punicodeValue->Length);
#endif
dwErr = 0;
}
exit:
if (punicodeValue)
{
pArgs->llsLsaLink.pfnFreeMemory(punicodeValue);
}
if (hPolicy)
{
pArgs->llsLsaLink.pfnClose(hPolicy);
}
return dwErr;
}
//+---------------------------------------------------------------------------
//
// Function: LSA_WriteString
//
// Synopsis: Write a string to the NT Local Security Authority (LSA)
// store.
//
// Arguments: pszKey The key to identify the string.
// pszStr The string. This function deletes the
// string if this param is NULL.
//
// Returns: DWORD 0 for SUCCES
// GetLastError() for FAILURE
//
// History: henryt Created 5/15/97
//
//----------------------------------------------------------------------------
DWORD LSA_WriteString(
ArgsStruct *pArgs,
LPTSTR pszKey,
LPCTSTR pszStr
)
{
DWORD dwErr = 0;
LSA_OBJECT_ATTRIBUTES oaObjAttr;
LSA_HANDLE hPolicy = NULL;
NTSTATUS ntStatus = STATUS_SUCCESS;
LSA_UNICODE_STRING unicodeKey;
LSA_UNICODE_STRING unicodeValue;
#if !defined(_UNICODE) && !defined(UNICODE)
LPWSTR pszUnicodeKey = NULL;
LPWSTR pszUnicodePassword = NULL;
#endif
if (!pszKey)
{
return ERROR_INVALID_PARAMETER;
}
//
// Open the LSA secret space for writing.
//
InitializeLsaObjectAttributes(&oaObjAttr, NULL, 0L, NULL, NULL);
ntStatus = pArgs->llsLsaLink.pfnOpenPolicy(NULL, &oaObjAttr, POLICY_WRITE, &hPolicy);
if (ntStatus == STATUS_SUCCESS)
{
#if !defined(_UNICODE) && !defined(UNICODE)
//
// need to convert the ANSI key to unicode
//
if (!(pszUnicodeKey = (LPWSTR)CmMalloc((lstrlenA(pszKey)+1)*sizeof(WCHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto exit;
}
if (!MultiByteToWideChar(CP_ACP, 0, pszKey, -1, pszUnicodeKey, (lstrlenA(pszKey)+1)*sizeof(WCHAR)))
{
dwErr = ERROR_INVALID_DATA;
goto exit;
}
if (pszStr)
{
if (!(pszUnicodePassword = (LPWSTR)CmMalloc((lstrlenA(pszStr)+1)*sizeof(WCHAR))))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto exit;
}
if (!MultiByteToWideChar(CP_ACP, 0, pszStr, -1, pszUnicodePassword, (lstrlenA(pszStr)+1)*sizeof(WCHAR)))
{
dwErr = ERROR_INVALID_DATA;
goto exit;
}
}
//
// create a unicode key
//
InitLsaString(&unicodeKey, pszUnicodeKey);
if (pszStr)
{
//
// set the data
//
unicodeValue.Length = (lstrlenU(pszUnicodePassword)+1)*sizeof(WCHAR);
unicodeValue.Buffer = (PWSTR)pszUnicodePassword;
}
#else
//
// create a unicode key
//
InitLsaString(&unicodeKey, pszKey);
if (pszStr)
{
//
// set the data
//
unicodeValue.Length = (lstrlenU(pszStr)+1)*sizeof(TCHAR);
unicodeValue.Buffer = (PWSTR)pszStr;
}
#endif
//
// save it
//
ntStatus = pArgs->llsLsaLink.pfnStorePrivateData(hPolicy, &unicodeKey, pszStr? &unicodeValue : NULL);
}
if (ntStatus != STATUS_SUCCESS)
{
dwErr = pArgs->llsLsaLink.pfnNtStatusToWinError(ntStatus);
#ifdef DEBUG
if (ERROR_SUCCESS != dwErr)
{
if (ERROR_FILE_NOT_FOUND == dwErr)
{
CMTRACE(TEXT("LSA_WritePassword() NT password not found."));
}
else
{
CMTRACE1(TEXT("LSA_WritePassword() NT failed, err=%u"), dwErr);
}
}
#endif
}
if (hPolicy)
{
pArgs->llsLsaLink.pfnClose(hPolicy);
}
#if !defined(_UNICODE) && !defined(UNICODE)
if (pszUnicodeKey)
{
CmFree(pszUnicodeKey);
}
if (pszUnicodePassword)
{
CmFree(pszUnicodePassword);
}
#endif
return dwErr;
}
//+---------------------------------------------------------------------------
//
// Function: InitLsaString
//
// Synopsis: Init a LSA string.
//
// Arguments: pLsaString A LSA unicode string.
// pszString An unicode string.
//
// Returns: None
//
// History: henryt Created 5/15/97
//
//----------------------------------------------------------------------------
void InitLsaString(
PLSA_UNICODE_STRING pLsaString,
LPWSTR pszString
)
{
DWORD dwStringLength;
if (pszString == NULL)
{
pLsaString->Buffer = NULL;
pLsaString->Length = 0;
pLsaString->MaximumLength = 0;
return;
}
dwStringLength = lstrlenU(pszString);
pLsaString->Buffer = pszString;
pLsaString->Length = (USHORT) dwStringLength * sizeof(WCHAR);
pLsaString->MaximumLength=(USHORT)(dwStringLength+1) * sizeof(WCHAR);
}
//+---------------------------------------------------------------------------
//
// Function: InitLsa
//
// Synopsis: Basically does GetProcAddress()'s for all the LSA API's that
// we need since these API's don't exist in the Windows95 version
// of advapi32.dll.
//
// Arguments: NONE
//
// Returns: TRUE if SUCCESS
// FALSE otherwise.
//
// History: henryt Created 5/15/97
//
//----------------------------------------------------------------------------
BOOL InitLsa(
ArgsStruct *pArgs
)
{
LPCSTR apszLsa[] = {
"LsaOpenPolicy",
"LsaRetrievePrivateData",
"LsaStorePrivateData",
"LsaNtStatusToWinError",
"LsaClose",
"LsaFreeMemory",
NULL
};
MYDBGASSERT(sizeof(pArgs->llsLsaLink.apvPfnLsa)/sizeof(pArgs->llsLsaLink.apvPfnLsa[0]) ==
sizeof(apszLsa)/sizeof(apszLsa[0]));
ZeroMemory(&pArgs->llsLsaLink, sizeof(pArgs->llsLsaLink));
return (LinkToDll(&pArgs->llsLsaLink.hInstLsa,
"advapi32.dll",
apszLsa,
pArgs->llsLsaLink.apvPfnLsa));
}
//+---------------------------------------------------------------------------
//
// Function: DeInitLsa
//
// Synopsis: The reverse of InitLsa().
//
// Arguments: NONE
//
// Returns: TRUE if SUCCESS
// FALSE otherwise.
//
// History: henryt Created 5/15/97
//
//----------------------------------------------------------------------------
BOOL DeInitLsa(
ArgsStruct *pArgs
)
{
if (pArgs->llsLsaLink.hInstLsa)
{
FreeLibrary(pArgs->llsLsaLink.hInstLsa);
}
ZeroMemory(&pArgs->llsLsaLink, sizeof(pArgs->llsLsaLink));
return TRUE;
}