Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

351 lines
9.7 KiB

  1. /*
  2. ** p r o t s t o r . c p p
  3. **
  4. ** Purpose:
  5. ** Functions to provide blob-level access to the pstore
  6. **
  7. ** Note:
  8. ** LocalAlloc/Free are used for memory allocation
  9. **
  10. ** History
  11. ** 2/12/97: (t-erikne) created
  12. **
  13. ** Copyright (C) Microsoft Corp. 1997.
  14. */
  15. ///////////////////////////////////////////////////////////////////////////
  16. //
  17. // Depends on
  18. //
  19. #include "pch.hxx"
  20. #include <pstore.h>
  21. #include "wstrings.h"
  22. #include <error.h>
  23. #ifdef MAC
  24. #include <mapinls.h>
  25. #endif // !MAC
  26. #include <BadStrFunctions.h>
  27. ///////////////////////////////////////////////////////////////////////////
  28. //
  29. // Static Things
  30. //
  31. static void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset);
  32. #ifdef DEBUG
  33. #define test3sub_string L"Test 3 SUBType"
  34. // {220D5CC2-853A-11d0-84BC-00C04FD43F8F}
  35. static GUID test3sub =
  36. { 0x220d5cc2, 0x853a, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
  37. // {4E741310-850D-11d0-84BB-00C04FD43F8F}
  38. static GUID NOT_EXIST =
  39. { 0x4e741310, 0x850d, 0x11d0, { 0x84, 0xbb, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
  40. // {FFAC62F0-8533-11d0-84BC-00C04FD43F8F}
  41. #define NoRuleSubType_string L"Foobar bang with no rules"
  42. static GUID NoRuleSubType =
  43. { 0xffac62f0, 0x8533, 0x11d0, { 0x84, 0xbc, 0x0, 0xc0, 0x4f, 0xd4, 0x3f, 0x8f } };
  44. #endif
  45. ///////////////////////////////////////////////////////////////////////////
  46. //
  47. // Functions
  48. //
  49. OESTDAPI_(HRESULT) PSTSetNewData(
  50. IN IPStore *const pISecProv,
  51. IN const GUID *const guidType,
  52. IN const GUID *const guidSubt,
  53. IN LPCWSTR wszAccountName,
  54. IN const BLOB *const pclear,
  55. OUT BLOB *const phandle)
  56. {
  57. HRESULT hr = S_OK;
  58. const int cchLookup = 80;
  59. WCHAR wszLookup[cchLookup];
  60. PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""};
  61. DWORD count = 0;
  62. BYTE *pb = NULL;
  63. if (!(pISecProv &&
  64. guidType && guidSubt &&
  65. wszAccountName &&
  66. pclear && pclear->pBlobData && pclear->cbSize))
  67. return E_INVALIDARG;
  68. if (phandle)
  69. phandle->pBlobData = NULL;
  70. StrCpyNW(wszLookup, wszAccountName, cchLookup);
  71. do
  72. {
  73. // if they didn't give us an out param for the lookup, then it is
  74. // dumb to make one. Just try the AccountName
  75. if (phandle)
  76. _PST_GenerateTagName(wszLookup, cchLookup, count++);
  77. hr = pISecProv->WriteItem(
  78. PST_KEY_CURRENT_USER,
  79. guidType,
  80. guidSubt,
  81. wszLookup,
  82. pclear->cbSize,
  83. pclear->pBlobData,
  84. &PromptInfo,
  85. PST_CF_NONE,
  86. PST_NO_OVERWRITE);
  87. if (!phandle)
  88. {
  89. // if we didn't get an out param, we are done regardless
  90. break;
  91. }
  92. }
  93. while (PST_E_ITEM_EXISTS == hr);
  94. if (SUCCEEDED(hr))
  95. {
  96. // we created it
  97. if (phandle)
  98. {
  99. phandle->cbSize = (lstrlenW(wszLookup) + 1) * sizeof(WCHAR);
  100. //NOTE: LocalAlloc is our memory allocator
  101. phandle->pBlobData = (BYTE *)LocalAlloc(LMEM_ZEROINIT, phandle->cbSize);
  102. if (!phandle->pBlobData)
  103. {
  104. hr = E_OUTOFMEMORY;
  105. goto exit;
  106. }
  107. StrCpyNW((LPWSTR)phandle->pBlobData, wszLookup, (phandle->cbSize / sizeof(wszLookup[0])));
  108. }
  109. }
  110. exit:
  111. return hr;
  112. }
  113. OESTDAPI_(HRESULT) PSTGetData(
  114. IN IPStore *const pISecProv,
  115. IN const GUID *const guidType,
  116. IN const GUID *const guidSubt,
  117. IN LPCWSTR wszLookupName,
  118. OUT BLOB *const pclear)
  119. {
  120. HRESULT hr;
  121. PST_PROMPTINFO PromptInfo = { sizeof(PST_PROMPTINFO), 0, NULL, L""};
  122. pclear->pBlobData = NULL;
  123. pclear->cbSize = 0;
  124. if (!(pISecProv && wszLookupName && pclear))
  125. return E_INVALIDARG;
  126. if (SUCCEEDED(hr = pISecProv->OpenItem(
  127. PST_KEY_CURRENT_USER,
  128. guidType,
  129. guidSubt,
  130. wszLookupName,
  131. PST_READ,
  132. &PromptInfo,
  133. 0)))
  134. {
  135. hr = pISecProv->ReadItem(
  136. PST_KEY_CURRENT_USER,
  137. guidType,
  138. guidSubt,
  139. wszLookupName,
  140. &pclear->cbSize,
  141. &pclear->pBlobData, // ppbData
  142. &PromptInfo, // pPromptInfo
  143. 0); // dwFlags
  144. // don't care if this fails
  145. pISecProv->CloseItem(
  146. PST_KEY_CURRENT_USER,
  147. guidType,
  148. guidSubt,
  149. wszLookupName,
  150. 0);
  151. }
  152. if (FAILED(TrapError(hr)))
  153. hr = hrPasswordNotFound;
  154. return hr;
  155. }
  156. OESTDAPI_(LPWSTR) WszGenerateNameFromBlob(IN BLOB blob)
  157. {
  158. LPWSTR szW = NULL;
  159. TCHAR szT[100];
  160. DWORD *pdw;
  161. TCHAR *pt;
  162. int i, max;
  163. DWORD cch;
  164. if (blob.cbSize > ARRAYSIZE(szT) ||
  165. blob.cbSize % sizeof(DWORD))
  166. return NULL;
  167. cch = (blob.cbSize*2)+1;
  168. szW = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, cch*sizeof(WCHAR));
  169. if (!szW)
  170. return NULL;
  171. pt = szT;
  172. szT[0] = '\000';
  173. pdw = (DWORD *)blob.pBlobData;
  174. max = blob.cbSize / sizeof(DWORD);
  175. for (i = 0; i < max; i++, pdw++)
  176. {
  177. DWORD cchLeft = (ARRAYSIZE(szT) - (DWORD)(pt - szT) - 1); // Good old typing will convert the pointer math to # of chars instead of # of bytes.
  178. if (cchLeft)
  179. {
  180. pt += wnsprintf(pt, cchLeft, "%X", *pdw);
  181. }
  182. }
  183. *pt = '\000';
  184. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szT, cch, szW, cch);
  185. szW[cch-1] = 0;
  186. return szW;
  187. }
  188. OESTDAPI_(void) PSTFreeHandle(LPBYTE pb)
  189. {
  190. if (pb)
  191. LocalFree((HLOCAL)pb);
  192. }
  193. OESTDAPI_(HRESULT) PSTCreateTypeSubType_NoUI(
  194. IN IPStore *const pISecProv,
  195. IN const GUID *const guidType,
  196. IN LPCWSTR szType,
  197. IN const GUID *const guidSubt,
  198. IN LPCWSTR szSubt)
  199. {
  200. #ifdef ENABLE_RULES
  201. PST_ACCESSRULESET RuleSet;
  202. PST_ACCESSRULE rgRules[2];
  203. #endif
  204. PST_TYPEINFO Info;
  205. HRESULT hr;
  206. if (!pISecProv)
  207. return E_INVALIDARG;
  208. Info.cbSize = sizeof(PST_TYPEINFO);
  209. // if type is not available the create it
  210. Info.szDisplayName = (LPWSTR)szType;
  211. if (S_OK != (hr = pISecProv->CreateType(PST_KEY_CURRENT_USER,
  212. guidType,
  213. &Info,
  214. 0)))
  215. {
  216. if (PST_E_TYPE_EXISTS != hr)
  217. goto exit;
  218. }
  219. // make rules for read, write access
  220. #ifdef ATH_RELEASE_BUILD
  221. #error Need to enable access rules for protected store passwords? (t-erikne)
  222. #endif
  223. #ifdef ENABLE_RULES
  224. // Do Rule Stuff
  225. RuleSet.cbSize = sizeof(PST_ACCESSRULESET);
  226. RuleSet.cRules = 2;
  227. RuleSet.rgRules = rgRules;
  228. //PST_BINARYCHECKDATA bindata;
  229. PST_ACCESSCLAUSE rgClauses[1];
  230. //N need to or on on the authenticode stuff
  231. // derive the calling exe (me) and only allow access to me
  232. rgClauses[0].ClaTYPE_GUID = PST_CURRENT_EXE;
  233. rgClauses[0].cbClauseData = 0;
  234. rgClauses[0].pbClauseData = NULL;
  235. rgRules[0].AccessModeFlags = PST_READ; // READ: just exe
  236. rgRules[0].cClauses = 1;
  237. rgRules[0].rgClauses = rgClauses;
  238. rgRules[1].AccessModeFlags = PST_WRITE; // WRITE: just exe
  239. rgRules[1].cClauses = 1;
  240. rgRules[1].rgClauses = rgClauses;
  241. #endif
  242. // create the server password subtype
  243. Info.szDisplayName = (LPWSTR)szSubt;
  244. if (S_OK !=
  245. (hr = pISecProv->CreateSubtype(
  246. PST_KEY_CURRENT_USER,
  247. guidType,
  248. guidSubt,
  249. &Info,
  250. #ifdef ENABLE_RULES
  251. &Rules,
  252. #else
  253. NULL,
  254. #endif
  255. 0)))
  256. {
  257. if (PST_E_TYPE_EXISTS != hr)
  258. goto exit;
  259. }
  260. hr = S_OK; // cool if we made it here
  261. exit:
  262. return hr;
  263. }
  264. ///////////////////////////////////////////////////////////////////////////
  265. //
  266. // Static utility functions
  267. //
  268. void _PST_GenerateTagName(LPWSTR pwsz, DWORD cch, DWORD offset)
  269. {
  270. SYSTEMTIME stNow;
  271. FILETIME ftNow;
  272. const int cchArrLen = 32;
  273. WCHAR wszTime[cchArrLen];
  274. TCHAR szT[cchArrLen];
  275. UINT ich=0;
  276. UINT cchLen=lstrlenW(pwsz);
  277. GetLocalTime(&stNow);
  278. ZeroMemory(&ftNow, sizeof(ftNow));
  279. SystemTimeToFileTime(&stNow, &ftNow);
  280. // Raid 48394 - 2 backslashes in account friendly name causes the account to not be fully created
  281. while (ich < cchLen)
  282. {
  283. if (L'\\' == pwsz[ich])
  284. {
  285. MoveMemory((LPBYTE)pwsz + (sizeof(WCHAR) * ich), (LPBYTE)pwsz + ((ich + 1) * sizeof(WCHAR)), (cchLen - ich) * sizeof(WCHAR));
  286. cchLen--;
  287. }
  288. else
  289. ich++;
  290. }
  291. wnsprintf(szT, ARRAYSIZE(szT), TEXT("%08.8lX"), ftNow.dwLowDateTime+offset);
  292. if (MultiByteToWideChar(CP_ACP, 0, szT, -1, wszTime, cchArrLen))
  293. {
  294. const int cchTime = lstrlenW(wszTime);
  295. if (long(cch) > lstrlenW(pwsz)+cchTime)
  296. StrCatBuffW(pwsz, wszTime, cch);
  297. else
  298. StrCpyNW(&pwsz[cch-cchTime-1], wszTime, (cchTime + 1));
  299. }
  300. return;
  301. }