483 lines
12 KiB
C++
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;
|
|
}
|
|
|
|
|