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.

454 lines
12 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: catdbcli.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include <wincrypt.h>
  12. #include "unicode.h"
  13. #include "catdb.h"
  14. #include "catdbcli.h"
  15. #include "..\..\cryptsvc\service.h"
  16. #include "errlog.h"
  17. #include "waitsvc.h"
  18. #ifndef KEYSVC_LOCAL_ENDPOINT
  19. #define KEYSVC_LOCAL_ENDPOINT (L"keysvc")
  20. #endif
  21. #ifndef KEYSVC_LOCAL_PROT_SEQ
  22. #define KEYSVC_LOCAL_PROT_SEQ (L"ncalrpc")
  23. #endif
  24. #define CATDBCLI_LOGERR_LASTERR() ErrLog_LogError(NULL, \
  25. ERRLOG_CLIENT_ID_CATDBCLI, \
  26. __LINE__, \
  27. 0, \
  28. FALSE, \
  29. FALSE);
  30. #define CATDBCLI_LOGERR(x) ErrLog_LogError(NULL, \
  31. ERRLOG_CLIENT_ID_CATDBCLI, \
  32. __LINE__, \
  33. x, \
  34. FALSE, \
  35. FALSE);
  36. #define MAX_RPCRETRIES 20
  37. void
  38. _SSCatDBTeardownRPCConnection(
  39. RPC_BINDING_HANDLE *phRPCBinding)
  40. {
  41. RpcBindingFree(phRPCBinding);
  42. }
  43. DWORD
  44. _SSCatDBSetupRPCConnection(
  45. RPC_BINDING_HANDLE *phRPCBinding)
  46. {
  47. unsigned short *pStringBinding = NULL;
  48. RPC_STATUS rpcStatus = RPC_S_OK;
  49. static BOOL fDone = FALSE;
  50. RPC_SECURITY_QOS RpcSecurityQOS;
  51. SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;;
  52. PSID pSID = NULL;
  53. WCHAR szName[64];
  54. DWORD cbName = 64;
  55. WCHAR szDomainName[256]; // max domain is 255
  56. DWORD cbDomainName = 256;
  57. SID_NAME_USE Use;
  58. //
  59. // wait for the service to be available before attempting bind
  60. //
  61. if (!WaitForCryptService(SZSERVICENAME, &fDone, TRUE))
  62. {
  63. CATDBCLI_LOGERR_LASTERR()
  64. if (GetLastError() == ERROR_SERVICE_DISABLED)
  65. {
  66. return ERROR_SERVICE_DISABLED;
  67. }
  68. else
  69. {
  70. return ERROR_SERVICE_NOT_ACTIVE;
  71. }
  72. }
  73. //
  74. // get a binding handle
  75. //
  76. if (RPC_S_OK != (rpcStatus = RpcStringBindingComposeW(
  77. NULL,
  78. (unsigned short *)KEYSVC_LOCAL_PROT_SEQ,
  79. NULL, //LPC - no machine name
  80. (unsigned short *)KEYSVC_LOCAL_ENDPOINT,
  81. 0,
  82. &pStringBinding)))
  83. {
  84. CATDBCLI_LOGERR(rpcStatus)
  85. goto Ret;
  86. }
  87. if (RPC_S_OK != (rpcStatus = RpcBindingFromStringBindingW(
  88. pStringBinding,
  89. phRPCBinding)))
  90. {
  91. CATDBCLI_LOGERR(rpcStatus)
  92. goto Ret;
  93. }
  94. if (RPC_S_OK != (rpcStatus = RpcEpResolveBinding(
  95. *phRPCBinding,
  96. ICatDBSvc_v1_0_c_ifspec)))
  97. {
  98. CATDBCLI_LOGERR(rpcStatus)
  99. _SSCatDBTeardownRPCConnection(phRPCBinding);
  100. goto Ret;
  101. }
  102. //
  103. // Set the autorization so that we will only call a Local Service process
  104. //
  105. memset(&RpcSecurityQOS, 0, sizeof(RpcSecurityQOS));
  106. RpcSecurityQOS.Version = RPC_C_SECURITY_QOS_VERSION;
  107. RpcSecurityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH;
  108. RpcSecurityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
  109. RpcSecurityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE;
  110. if (AllocateAndInitializeSid(&SIDAuth, 1,
  111. SECURITY_LOCAL_SYSTEM_RID,
  112. 0, 0, 0, 0, 0, 0, 0,
  113. &pSID) == 0)
  114. {
  115. CATDBCLI_LOGERR_LASTERR()
  116. goto Ret;
  117. }
  118. if (LookupAccountSidW(NULL,
  119. pSID,
  120. szName,
  121. &cbName,
  122. szDomainName,
  123. &cbDomainName,
  124. &Use) == 0)
  125. {
  126. CATDBCLI_LOGERR_LASTERR()
  127. goto Ret;
  128. }
  129. if (RPC_S_OK != (rpcStatus = RpcBindingSetAuthInfoExW(
  130. *phRPCBinding,
  131. szName,
  132. RPC_C_AUTHN_LEVEL_PKT,
  133. RPC_C_AUTHN_WINNT,
  134. NULL,
  135. 0,
  136. &RpcSecurityQOS)))
  137. {
  138. CATDBCLI_LOGERR(rpcStatus)
  139. goto Ret;
  140. }
  141. Ret:
  142. if (pStringBinding != NULL)
  143. {
  144. RpcStringFreeW(&pStringBinding);
  145. }
  146. if (pSID != NULL)
  147. {
  148. FreeSid( pSID );
  149. }
  150. return ((DWORD) rpcStatus);
  151. }
  152. DWORD
  153. Client_SSCatDBAddCatalog(
  154. /* [in] */ DWORD dwFlags,
  155. /* [in] */ LPCWSTR pwszSubSysGUID,
  156. /* [in] */ LPCWSTR pwszCatalogFile,
  157. /* [in] */ LPCWSTR pwszCatName,
  158. /* [out] */ LPWSTR *ppwszCatalogNameUsed)
  159. {
  160. RPC_BINDING_HANDLE hRPCBinding;
  161. DWORD dwErr = 0;
  162. DWORD dwRetryCount = 0;
  163. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  164. if (dwErr != 0)
  165. {
  166. CATDBCLI_LOGERR(dwErr)
  167. return dwErr;
  168. }
  169. dwErr = RPC_S_SERVER_TOO_BUSY;
  170. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  171. (dwRetryCount < MAX_RPCRETRIES))
  172. {
  173. __try
  174. {
  175. dwErr = SSCatDBAddCatalog(
  176. hRPCBinding,
  177. dwFlags,
  178. pwszSubSysGUID,
  179. pwszCatalogFile,
  180. pwszCatName,
  181. ppwszCatalogNameUsed);
  182. }
  183. __except ( EXCEPTION_EXECUTE_HANDLER )
  184. {
  185. dwErr = _exception_code();
  186. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  187. {
  188. Sleep(100);
  189. }
  190. }
  191. dwRetryCount++;
  192. }
  193. if (dwErr != 0)
  194. {
  195. CATDBCLI_LOGERR(dwErr)
  196. }
  197. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  198. return dwErr;
  199. }
  200. DWORD Client_SSCatDBDeleteCatalog(
  201. /* [in] */ DWORD dwFlags,
  202. /* [in] */ LPCWSTR pwszSubSysGUID,
  203. /* [in] */ LPCWSTR pwszCatalogFile)
  204. {
  205. RPC_BINDING_HANDLE hRPCBinding;
  206. DWORD dwErr = 0;
  207. DWORD dwRetryCount = 0;
  208. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  209. if (dwErr != 0)
  210. {
  211. CATDBCLI_LOGERR(dwErr)
  212. return dwErr;
  213. }
  214. dwErr = RPC_S_SERVER_TOO_BUSY;
  215. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  216. (dwRetryCount < MAX_RPCRETRIES))
  217. {
  218. __try
  219. {
  220. dwErr = SSCatDBDeleteCatalog(
  221. hRPCBinding,
  222. dwFlags,
  223. pwszSubSysGUID,
  224. pwszCatalogFile);
  225. }
  226. __except ( EXCEPTION_EXECUTE_HANDLER )
  227. {
  228. dwErr = _exception_code();
  229. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  230. {
  231. Sleep(100);
  232. }
  233. }
  234. dwRetryCount++;
  235. }
  236. if (dwErr != 0)
  237. {
  238. CATDBCLI_LOGERR(dwErr)
  239. }
  240. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  241. return dwErr;
  242. }
  243. DWORD
  244. Client_SSCatDBEnumCatalogs(
  245. /* [in] */ DWORD dwFlags,
  246. /* [in] */ LPCWSTR pwszSubSysGUID,
  247. /* [size_is][in] */ BYTE *pbHash,
  248. /* [in] */ DWORD cbHash,
  249. /* [out] */ DWORD *pdwNumCatalogNames,
  250. /* [size_is][size_is][out] */ LPWSTR **pppwszCatalogNames)
  251. {
  252. RPC_BINDING_HANDLE hRPCBinding;
  253. DWORD dwErr = 0;
  254. DWORD dwRetryCount = 0;
  255. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  256. if (dwErr != 0)
  257. {
  258. CATDBCLI_LOGERR(dwErr)
  259. return dwErr;
  260. }
  261. dwErr = RPC_S_SERVER_TOO_BUSY;
  262. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  263. (dwRetryCount < MAX_RPCRETRIES))
  264. {
  265. __try
  266. {
  267. dwErr = SSCatDBEnumCatalogs(
  268. hRPCBinding,
  269. dwFlags,
  270. pwszSubSysGUID,
  271. cbHash,
  272. pbHash,
  273. pdwNumCatalogNames,
  274. pppwszCatalogNames);
  275. }
  276. __except ( EXCEPTION_EXECUTE_HANDLER )
  277. {
  278. dwErr = _exception_code();
  279. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  280. {
  281. Sleep(100);
  282. }
  283. }
  284. dwRetryCount++;
  285. }
  286. if (dwErr != 0)
  287. {
  288. CATDBCLI_LOGERR(dwErr)
  289. }
  290. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  291. return dwErr;
  292. }
  293. DWORD
  294. Client_SSCatDBRegisterForChangeNotification(
  295. /* [in] */ DWORD_PTR EventHandle,
  296. /* [in] */ DWORD dwFlags,
  297. /* [in] */ LPCWSTR pwszSubSysGUID,
  298. /* [in] */ BOOL fUnRegister)
  299. {
  300. RPC_BINDING_HANDLE hRPCBinding;
  301. DWORD dwErr = 0;
  302. DWORD dwRetryCount = 0;
  303. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  304. if (dwErr != 0)
  305. {
  306. CATDBCLI_LOGERR(dwErr)
  307. return dwErr;
  308. }
  309. dwErr = RPC_S_SERVER_TOO_BUSY;
  310. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  311. (dwRetryCount < MAX_RPCRETRIES))
  312. {
  313. __try
  314. {
  315. dwErr = SSCatDBRegisterForChangeNotification(
  316. hRPCBinding,
  317. EventHandle,
  318. dwFlags,
  319. pwszSubSysGUID,
  320. fUnRegister);
  321. }
  322. __except ( EXCEPTION_EXECUTE_HANDLER )
  323. {
  324. dwErr = _exception_code();
  325. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  326. {
  327. Sleep(100);
  328. }
  329. }
  330. dwRetryCount++;
  331. }
  332. if (dwErr != 0)
  333. {
  334. CATDBCLI_LOGERR(dwErr)
  335. }
  336. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  337. return dwErr;
  338. }
  339. DWORD
  340. Client_SSCatDBPauseResumeService(
  341. /* [in] */ DWORD dwFlags,
  342. /* [in] */ BOOL fResume)
  343. {
  344. RPC_BINDING_HANDLE hRPCBinding;
  345. DWORD dwErr = 0;
  346. DWORD dwRetryCount = 0;
  347. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  348. if (dwErr != 0)
  349. {
  350. CATDBCLI_LOGERR(dwErr)
  351. return dwErr;
  352. }
  353. dwErr = RPC_S_SERVER_TOO_BUSY;
  354. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  355. (dwRetryCount < MAX_RPCRETRIES))
  356. {
  357. __try
  358. {
  359. dwErr = SSCatDBPauseResumeService(
  360. hRPCBinding,
  361. dwFlags,
  362. fResume);
  363. }
  364. __except ( EXCEPTION_EXECUTE_HANDLER )
  365. {
  366. dwErr = _exception_code();
  367. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  368. {
  369. Sleep(100);
  370. }
  371. }
  372. dwRetryCount++;
  373. }
  374. if (dwErr != 0)
  375. {
  376. CATDBCLI_LOGERR(dwErr)
  377. }
  378. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  379. return dwErr;
  380. }