|
|
//+----------------------------------------------------------------------------
//
// 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; }
|