windows-nt/Source/XPSP1/NT/ds/security/services/ca/certlib/mapi.cpp
2020-09-26 16:20:57 +08:00

298 lines
6.9 KiB
C++

//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: certlib.cpp
//
// Contents: Cert Server wrapper routines
//
//---------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <ntlsa.h>
#define wszCERTMAPIINFO L"CertServerMapiInfo"
void
InitLsaString(
OUT LSA_UNICODE_STRING *plus,
IN WCHAR const *pwsz,
IN DWORD cb)
{
if (MAXDWORD == cb)
{
cb = lstrlenW(pwsz) * sizeof(WCHAR);
}
plus->Buffer = const_cast<WCHAR *>(pwsz);
plus->Length = (USHORT) cb;
plus->MaximumLength = plus->Length + sizeof(WCHAR);
}
HRESULT
OpenPolicy(
IN WCHAR const *pwszServerName,
DWORD DesiredAccess,
LSA_HANDLE *phPolicy)
{
HRESULT hr;
LSA_OBJECT_ATTRIBUTES oa;
LSA_UNICODE_STRING ServerString;
LSA_UNICODE_STRING *plusServer;
ZeroMemory(&oa, sizeof(oa));
plusServer = NULL;
if (NULL != pwszServerName)
{
InitLsaString(&ServerString, pwszServerName, MAXDWORD);
plusServer = &ServerString;
}
hr = LsaOpenPolicy(plusServer, &oa, DesiredAccess, phPolicy);
if (!NT_SUCCESS(hr))
{
_JumpError(hr, error, "LsaOpenPolicy");
}
error:
return(hr);
}
HRESULT
SaveString(
IN WCHAR const *pwszIn,
IN DWORD cwcIn,
OUT WCHAR **ppwszOut)
{
HRESULT hr;
WCHAR *pwsz;
*ppwszOut = NULL;
pwsz = (WCHAR *) LocalAlloc(LMEM_FIXED, (cwcIn + 1) * sizeof(WCHAR));
if (NULL == pwsz)
{
hr = E_OUTOFMEMORY;
_JumpError(hr, error, "LocalAlloc");
}
CopyMemory(pwsz, pwszIn, cwcIn * sizeof(WCHAR));
pwsz[cwcIn] = L'\0';
*ppwszOut = pwsz;
hr = S_OK;
error:
return(hr);
}
//+--------------------------------------------------------------------------
// myGetMapiInfo -- Retrieve a Name/Password from a global LSA secret
//+--------------------------------------------------------------------------
HRESULT
myGetMapiInfo(
OPTIONAL IN WCHAR const *pwszServerName,
OUT WCHAR **ppwszProfileName,
OUT WCHAR **ppwszLogonName,
OUT WCHAR **ppwszPassword)
{
HRESULT hr;
LSA_HANDLE hPolicy;
UNICODE_STRING lusSecretKeyName;
UNICODE_STRING *plusSecretData = NULL;
DWORD cwc;
DWORD cwcProfileName;
DWORD cwcLogonName;
DWORD cwcPassword;
WCHAR const *pwsz;
WCHAR *pwszProfileName = NULL;
WCHAR *pwszLogonName = NULL;
WCHAR *pwszPassword = NULL;
if (NULL == ppwszProfileName ||
NULL == ppwszLogonName ||
NULL == ppwszPassword)
{
hr = E_POINTER;
_JumpError(hr, error, "no data");
}
InitLsaString(&lusSecretKeyName, wszCERTMAPIINFO, MAXDWORD);
hr = OpenPolicy(pwszServerName, POLICY_GET_PRIVATE_INFORMATION, &hPolicy);
if (!NT_SUCCESS(hr))
{
_JumpError(hr, error, "OpenPolicy");
}
hr = LsaRetrievePrivateData(hPolicy, &lusSecretKeyName, &plusSecretData);
LsaClose(hPolicy);
if (!NT_SUCCESS(hr))
{
_PrintError2(hr, "LsaRetrievePrivateData", STATUS_OBJECT_NAME_NOT_FOUND);
if ((HRESULT) STATUS_OBJECT_NAME_NOT_FOUND == hr)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
_JumpError2(hr, error, "LsaRetrievePrivateData", hr);
}
if (NULL == plusSecretData || NULL == plusSecretData->Buffer)
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
_JumpError(hr, error, "no data");
}
pwsz = (WCHAR const *) plusSecretData->Buffer;
cwc = plusSecretData->Length / sizeof(WCHAR);
for (cwcProfileName = 0; cwcProfileName < cwc; cwcProfileName++)
{
if (L'\0' == pwsz[cwcProfileName])
{
break;
}
}
if (cwcProfileName == cwc)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
_JumpError(hr, error, "bad data");
}
for (cwcLogonName = cwcProfileName + 1; cwcLogonName < cwc; cwcLogonName++)
{
if (L'\0' == pwsz[cwcLogonName])
{
break;
}
}
if (cwcLogonName == cwc)
{
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
_JumpError(hr, error, "bad data");
}
cwcLogonName -= cwcProfileName + 1;
cwcPassword = cwc - (cwcProfileName + 1 + cwcLogonName + 1);
hr = SaveString(pwsz, cwcProfileName, &pwszProfileName);
_JumpIfError(hr, error, "SaveString");
hr = SaveString(&pwsz[cwcProfileName + 1], cwcLogonName, &pwszLogonName);
_JumpIfError(hr, error, "SaveString");
hr = SaveString(
&pwsz[cwcProfileName + 1 + cwcLogonName + 1],
cwcPassword,
&pwszPassword);
_JumpIfError(hr, error, "SaveString");
*ppwszProfileName = pwszProfileName;
pwszProfileName = NULL;
*ppwszLogonName = pwszLogonName;
pwszLogonName = NULL;
*ppwszPassword = pwszPassword;
pwszPassword = NULL;
error:
if (NULL != pwszProfileName)
{
ZeroMemory(pwszProfileName, cwcProfileName * sizeof(WCHAR));
LocalFree(pwszProfileName);
}
if (NULL != pwszLogonName)
{
ZeroMemory(pwszLogonName, cwcLogonName * sizeof(WCHAR));
LocalFree(pwszLogonName);
}
if (NULL != pwszPassword)
{
ZeroMemory(pwszPassword, cwcPassword * sizeof(WCHAR));
LocalFree(pwszPassword);
}
if (NULL != plusSecretData)
{
if (NULL != plusSecretData->Buffer)
{
ZeroMemory(plusSecretData->Buffer, plusSecretData->Length);
}
LsaFreeMemory(plusSecretData);
}
return(hr);
}
//+--------------------------------------------------------------------------
// mySaveMapiInfo -- Persist the specified Name/Password to a global LSA secret
//+--------------------------------------------------------------------------
HRESULT
mySaveMapiInfo(
OPTIONAL IN WCHAR const *pwszServerName,
OUT WCHAR const *pwszProfileName,
OUT WCHAR const *pwszLogonName,
OUT WCHAR const *pwszPassword)
{
HRESULT hr;
LSA_HANDLE hPolicy;
UNICODE_STRING lusSecretKeyName;
UNICODE_STRING lusSecretData;
WCHAR wszSecret[MAX_PATH];
DWORD cwc;
WCHAR *pwsz;
if (NULL == pwszProfileName ||
NULL == pwszLogonName ||
NULL == pwszPassword)
{
hr = E_POINTER;
_JumpError(hr, error, "NULL parm");
}
cwc = lstrlen(pwszProfileName) + 1 +
lstrlen(pwszLogonName) + 1 +
lstrlen(pwszPassword);
if (ARRAYSIZE(wszSecret) <= cwc)
{
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
_JumpError(hr, error, "overflow");
}
pwsz = wszSecret;
wcscpy(pwsz, pwszProfileName);
pwsz += lstrlen(pwsz) + 1;
wcscpy(pwsz, pwszLogonName);
pwsz += lstrlen(pwsz) + 1;
wcscpy(pwsz, pwszPassword);
InitLsaString(&lusSecretData, wszSecret, cwc * sizeof(WCHAR));
InitLsaString(&lusSecretKeyName, wszCERTMAPIINFO, MAXDWORD);
hr = OpenPolicy(pwszServerName, POLICY_CREATE_SECRET, &hPolicy);
if (!NT_SUCCESS(hr))
{
_JumpError(hr, error, "OpenPolicy");
}
hr = LsaStorePrivateData(hPolicy, &lusSecretKeyName, &lusSecretData);
LsaClose(hPolicy);
if (!NT_SUCCESS(hr))
{
_JumpError(hr, error, "LsaStorePrivateData");
}
hr = S_OK;
error:
ZeroMemory(wszSecret, sizeof(wszSecret));
return(hr);
}