|
|
/*
** p r o t s t o r . c p p ** ** Purpose: ** Functions to provide blob-level access to the pstore ** ** Note: ** LocalAlloc/Free are used for memory allocation ** ** History ** 2/12/97: (t-erikne) created ** ** Copyright (C) Microsoft Corp. 1997. */
///////////////////////////////////////////////////////////////////////////
//
// Depends on
//
#include "pch.hxx"
#include <pstore.h>
#include "wstrings.h"
#include <error.h>
#ifdef MAC
#include <mapinls.h>
#endif // !MAC
#include <BadStrFunctions.h>
///////////////////////////////////////////////////////////////////////////
//
// Static Things
//
static void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset);
#ifdef DEBUG
#define test3sub_string L"Test 3 SUBType"
// {220D5CC2-853A-11d0-84BC-00C04FD43F8F}
static GUID test3sub = { 0x220d5cc2, 0x853a, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
// {4E741310-850D-11d0-84BB-00C04FD43F8F}
static GUID NOT_EXIST = { 0x4e741310, 0x850d, 0x11d0, { 0x84, 0xbb, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
// {FFAC62F0-8533-11d0-84BC-00C04FD43F8F}
#define NoRuleSubType_string L"Foobar bang with no rules"
static GUID NoRuleSubType = { 0xffac62f0, 0x8533, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
#endif
///////////////////////////////////////////////////////////////////////////
//
// Functions
//
OESTDAPI_(HRESULT) PSTSetNewData( IN IPStore *const pISecProv, IN const GUID *const guidType, IN const GUID *const guidSubt, IN LPCWSTR wszAccountName, IN const BLOB *const pclear, OUT BLOB *const phandle) { HRESULT hr = S_OK; const int cchLookup = 80; WCHAR wszLookup[cchLookup]; PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""}; DWORD count = 0; BYTE *pb = NULL;
if (!(pISecProv && guidType && guidSubt && wszAccountName && pclear && pclear->pBlobData && pclear->cbSize)) return E_INVALIDARG;
if (phandle) phandle->pBlobData = NULL;
StrCpyNW(wszLookup, wszAccountName, cchLookup);
do { // if they didn't give us an out param for the lookup, then it is
// dumb to make one. Just try the AccountName
if (phandle) _PST_GenerateTagName(wszLookup, cchLookup, count++);
hr = pISecProv->WriteItem( PST_KEY_CURRENT_USER, guidType, guidSubt, wszLookup, pclear->cbSize, pclear->pBlobData, &PromptInfo, PST_CF_NONE, PST_NO_OVERWRITE);
if (!phandle) { // if we didn't get an out param, we are done regardless
break; } } while (PST_E_ITEM_EXISTS == hr);
if (SUCCEEDED(hr)) { // we created it
if (phandle) { phandle->cbSize = (lstrlenW(wszLookup) + 1) * sizeof(WCHAR);
//NOTE: LocalAlloc is our memory allocator
phandle->pBlobData = (BYTE *)LocalAlloc(LMEM_ZEROINIT, phandle->cbSize); if (!phandle->pBlobData) { hr = E_OUTOFMEMORY; goto exit; } StrCpyNW((LPWSTR)phandle->pBlobData, wszLookup, (phandle->cbSize / sizeof(wszLookup[0]))); } }
exit: return hr; }
OESTDAPI_(HRESULT) PSTGetData( IN IPStore *const pISecProv, IN const GUID *const guidType, IN const GUID *const guidSubt, IN LPCWSTR wszLookupName, OUT BLOB *const pclear) { HRESULT hr; PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""};
pclear->pBlobData = NULL; pclear->cbSize = 0;
if (!(pISecProv && wszLookupName && pclear)) return E_INVALIDARG; if (SUCCEEDED(hr = pISecProv->OpenItem( PST_KEY_CURRENT_USER, guidType, guidSubt, wszLookupName, PST_READ, &PromptInfo, 0))) { hr = pISecProv->ReadItem( PST_KEY_CURRENT_USER, guidType, guidSubt, wszLookupName, &pclear->cbSize, &pclear->pBlobData, // ppbData
&PromptInfo, // pPromptInfo
0); // dwFlags
// don't care if this fails
pISecProv->CloseItem( PST_KEY_CURRENT_USER, guidType, guidSubt, wszLookupName, 0); }
if (FAILED(TrapError(hr))) hr = hrPasswordNotFound; return hr; }
OESTDAPI_(LPWSTR) WszGenerateNameFromBlob(IN BLOB blob) { LPWSTR szW = NULL; TCHAR szT[100]; DWORD *pdw; TCHAR *pt; int i, max; DWORD cch;
if (blob.cbSize > ARRAYSIZE(szT) || blob.cbSize % sizeof(DWORD)) return NULL;
cch = (blob.cbSize*2)+1; szW = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, cch*sizeof(WCHAR)); if (!szW) return NULL;
pt = szT; szT[0] = '\000'; pdw = (DWORD *)blob.pBlobData;
max = blob.cbSize / sizeof(DWORD); for (i = 0; i < max; i++, pdw++) { DWORD cchLeft = (ARRAYSIZE(szT) - (DWORD)(pt - szT) - 1); // Good old typing will convert the pointer math to # of chars instead of # of bytes.
if (cchLeft) { pt += wnsprintf(pt, cchLeft, "%X", *pdw); } } *pt = '\000';
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szT, cch, szW, cch); szW[cch-1] = 0;
return szW; }
OESTDAPI_(void) PSTFreeHandle(LPBYTE pb) { if (pb) LocalFree((HLOCAL)pb); }
OESTDAPI_(HRESULT) PSTCreateTypeSubType_NoUI( IN IPStore *const pISecProv, IN const GUID *const guidType, IN LPCWSTR szType, IN const GUID *const guidSubt, IN LPCWSTR szSubt) { #ifdef ENABLE_RULES
PST_ACCESSRULESET RuleSet; PST_ACCESSRULE rgRules[2]; #endif
PST_TYPEINFO Info; HRESULT hr;
if (!pISecProv) return E_INVALIDARG;
Info.cbSize = sizeof(PST_TYPEINFO);
// if type is not available the create it
Info.szDisplayName = (LPWSTR)szType; if (S_OK != (hr = pISecProv->CreateType(PST_KEY_CURRENT_USER, guidType, &Info, 0))) { if (PST_E_TYPE_EXISTS != hr) goto exit; }
// make rules for read, write access
#ifdef ATH_RELEASE_BUILD
#error Need to enable access rules for protected store passwords? (t-erikne)
#endif
#ifdef ENABLE_RULES
// Do Rule Stuff
RuleSet.cbSize = sizeof(PST_ACCESSRULESET); RuleSet.cRules = 2; RuleSet.rgRules = rgRules;
//PST_BINARYCHECKDATA bindata;
PST_ACCESSCLAUSE rgClauses[1]; //N need to or on on the authenticode stuff
// derive the calling exe (me) and only allow access to me
rgClauses[0].ClaTYPE_GUID = PST_CURRENT_EXE; rgClauses[0].cbClauseData = 0; rgClauses[0].pbClauseData = NULL; rgRules[0].AccessModeFlags = PST_READ; // READ: just exe
rgRules[0].cClauses = 1; rgRules[0].rgClauses = rgClauses; rgRules[1].AccessModeFlags = PST_WRITE; // WRITE: just exe
rgRules[1].cClauses = 1; rgRules[1].rgClauses = rgClauses; #endif
// create the server password subtype
Info.szDisplayName = (LPWSTR)szSubt; if (S_OK != (hr = pISecProv->CreateSubtype( PST_KEY_CURRENT_USER, guidType, guidSubt, &Info, #ifdef ENABLE_RULES
&Rules, #else
NULL, #endif
0))) { if (PST_E_TYPE_EXISTS != hr) goto exit; }
hr = S_OK; // cool if we made it here
exit: return hr; }
///////////////////////////////////////////////////////////////////////////
//
// Static utility functions
//
void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset) { SYSTEMTIME stNow; FILETIME ftNow; const int cchArrLen = 32; WCHAR wszTime[cchArrLen]; TCHAR szT[cchArrLen]; UINT ich=0; UINT cchLen=lstrlenW(pwsz);
GetLocalTime(&stNow); ZeroMemory(&ftNow, sizeof(ftNow)); SystemTimeToFileTime(&stNow, &ftNow);
// Raid 48394 - 2 backslashes in account friendly name causes the account to not be fully created
while (ich < cchLen) { if (L'\\' == pwsz[ich]) { MoveMemory((LPBYTE)pwsz + (sizeof(WCHAR) * ich), (LPBYTE)pwsz + ((ich + 1) * sizeof(WCHAR)), (cchLen - ich) * sizeof(WCHAR)); cchLen--; } else ich++; }
wnsprintf(szT, ARRAYSIZE(szT), TEXT("%08.8lX"), ftNow.dwLowDateTime+offset); if (MultiByteToWideChar(CP_ACP, 0, szT, -1, wszTime, cchArrLen)) { const int cchTime = lstrlenW(wszTime); if (long(cch) > lstrlenW(pwsz)+cchTime) StrCatBuffW(pwsz, wszTime, cch); else StrCpyNW(&pwsz[cch-cchTime-1], wszTime, (cchTime + 1)); } return; }
|