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.

399 lines
11 KiB

  1. /*---------------------------------------------------------------------------
  2. File: CommaLog.cpp
  3. Comments: TError based log file with optional NTFS security initialization.
  4. This can be used to write a log file which only administrators can access.
  5. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  6. Proprietary and confidential to Mission Critical Software, Inc.
  7. REVISION LOG ENTRY
  8. Revision By: Christy Boles
  9. Revised on 02/15/99 10:49:07
  10. 09/05/01 Mark Oluper - use Windows File I/O API
  11. ---------------------------------------------------------------------------
  12. */
  13. //#include "stdafx.h"
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <share.h>
  17. #include <lm.h>
  18. #include "Common.hpp"
  19. #include "UString.hpp"
  20. #include "Err.hpp"
  21. #include "ErrDct.hpp"
  22. #include "sd.hpp"
  23. #include "SecObj.hpp"
  24. #include "CommaLog.hpp"
  25. #include "BkupRstr.hpp"
  26. #include "Folders.h"
  27. #define ADMINISTRATORS 1
  28. #define ACCOUNT_OPERATORS 2
  29. #define BACKUP_OPERATORS 3
  30. #define DOMAIN_ADMINS 4
  31. #define CREATOR_OWNER 5
  32. #define USERS 6
  33. #define SYSTEM 7
  34. extern TErrorDct err;
  35. #define BYTE_ORDER_MARK (0xFEFF)
  36. PSID // ret- SID for well-known account
  37. GetWellKnownSid(
  38. DWORD wellKnownAccount // in - one of the constants #defined above for the well-known accounts
  39. )
  40. {
  41. PSID pSid = NULL;
  42. // PUCHAR numsubs = NULL;
  43. // DWORD * rid = NULL;
  44. BOOL error = FALSE;
  45. SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
  46. SID_IDENTIFIER_AUTHORITY creatorIA = SECURITY_CREATOR_SID_AUTHORITY;
  47. //
  48. // Sid is the same regardless of machine, since the well-known
  49. // BUILTIN domain is referenced.
  50. //
  51. switch ( wellKnownAccount )
  52. {
  53. case CREATOR_OWNER:
  54. if( ! AllocateAndInitializeSid(
  55. &creatorIA,
  56. 2,
  57. SECURITY_BUILTIN_DOMAIN_RID,
  58. SECURITY_CREATOR_OWNER_RID,
  59. 0, 0, 0, 0, 0, 0,
  60. &pSid
  61. ))
  62. {
  63. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  64. }
  65. break;
  66. case ADMINISTRATORS:
  67. if( ! AllocateAndInitializeSid(
  68. &sia,
  69. 2,
  70. SECURITY_BUILTIN_DOMAIN_RID,
  71. DOMAIN_ALIAS_RID_ADMINS,
  72. 0, 0, 0, 0, 0, 0,
  73. &pSid
  74. ))
  75. {
  76. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  77. }
  78. break;
  79. case ACCOUNT_OPERATORS:
  80. if( ! AllocateAndInitializeSid(
  81. &sia,
  82. 2,
  83. SECURITY_BUILTIN_DOMAIN_RID,
  84. DOMAIN_ALIAS_RID_ACCOUNT_OPS,
  85. 0, 0, 0, 0, 0, 0,
  86. &pSid
  87. ))
  88. {
  89. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  90. }
  91. break;
  92. case BACKUP_OPERATORS:
  93. if( ! AllocateAndInitializeSid(
  94. &sia,
  95. 2,
  96. SECURITY_BUILTIN_DOMAIN_RID,
  97. DOMAIN_ALIAS_RID_BACKUP_OPS,
  98. 0, 0, 0, 0, 0, 0,
  99. &pSid
  100. ))
  101. {
  102. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  103. }
  104. break;
  105. case USERS:
  106. if( ! AllocateAndInitializeSid(
  107. &sia,
  108. 2,
  109. SECURITY_BUILTIN_DOMAIN_RID,
  110. DOMAIN_ALIAS_RID_USERS,
  111. 0, 0, 0, 0, 0, 0,
  112. &pSid
  113. ))
  114. {
  115. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  116. }
  117. break;
  118. case SYSTEM:
  119. if( ! AllocateAndInitializeSid(
  120. &sia,
  121. 1,
  122. SECURITY_LOCAL_SYSTEM_RID,
  123. 0, 0, 0, 0, 0, 0, 0,
  124. &pSid
  125. ))
  126. {
  127. err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError());
  128. }
  129. break;
  130. default:
  131. MCSASSERT(FALSE);
  132. break;
  133. }
  134. if ( error )
  135. {
  136. FreeSid(pSid);
  137. pSid = NULL;
  138. }
  139. return pSid;
  140. }
  141. BOOL // ret- whether log was successfully opened or not
  142. CommaDelimitedLog::LogOpen(
  143. PCTSTR filename, // in - name for log file
  144. BOOL protect, // in - if TRUE, try to ACL the file so only admins can access
  145. int mode // in - mode 0=overwrite, 1=append
  146. )
  147. {
  148. BOOL bOpen = FALSE;
  149. // close log if currently open
  150. if (m_hFile != INVALID_HANDLE_VALUE)
  151. {
  152. LogClose();
  153. }
  154. // if a file name was specified
  155. if (filename && filename[0])
  156. {
  157. // open or create file and share for both reading and writing
  158. m_hFile = CreateFile(
  159. filename,
  160. GENERIC_WRITE,
  161. FILE_SHARE_READ|FILE_SHARE_WRITE,
  162. NULL,
  163. OPEN_ALWAYS,
  164. FILE_ATTRIBUTE_NORMAL,
  165. NULL
  166. );
  167. // if file successfully opened
  168. if (m_hFile != INVALID_HANDLE_VALUE)
  169. {
  170. // if append specified move file pointer to end of file
  171. // if overwrite specified move file pointer to beginning of file
  172. // either way if pointer is at beginning of file after moving then write byte order mark
  173. if (SetFilePointer(m_hFile, 0, NULL, mode ? FILE_END : FILE_BEGIN) == 0)
  174. {
  175. DWORD dwWritten;
  176. WCHAR chByteOrderMark = BYTE_ORDER_MARK;
  177. WriteFile(m_hFile, &chByteOrderMark, sizeof(chByteOrderMark), &dwWritten, NULL);
  178. }
  179. bOpen = TRUE;
  180. }
  181. }
  182. // if file successfully opened and protect specified
  183. // set permissions on file so that only Administrators alias has access
  184. if (bOpen && protect)
  185. {
  186. WCHAR fname[MAX_PATH+1];
  187. safecopy(fname,filename);
  188. if ( GetBkupRstrPriv(NULL, TRUE) )
  189. {
  190. // Set the SD for the file to Administrators Full Control only.
  191. TFileSD sd(fname);
  192. if ( sd.GetSecurity() != NULL )
  193. {
  194. PSID mySid = GetWellKnownSid(ADMINISTRATORS);
  195. TACE ace(ACCESS_ALLOWED_ACE_TYPE,0,DACL_FULLCONTROL_MASK,mySid);
  196. PACL acl = NULL; // start with an empty ACL
  197. sd.GetSecurity()->ACLAddAce(&acl,&ace,-1);
  198. if (acl == NULL)
  199. {
  200. bOpen = FALSE;
  201. }
  202. else if (!sd.GetSecurity()->SetDacl(acl,TRUE))
  203. {
  204. bOpen = FALSE;
  205. }
  206. else if (!sd.WriteSD())
  207. {
  208. bOpen = FALSE;
  209. }
  210. }
  211. else
  212. {
  213. bOpen = FALSE;
  214. }
  215. }
  216. else
  217. {
  218. err.SysMsgWrite(ErrW,GetLastError(),DCT_MSG_NO_BR_PRIV_SD,fname,GetLastError());
  219. bOpen = FALSE;
  220. }
  221. }
  222. if (!bOpen && (m_hFile != INVALID_HANDLE_VALUE))
  223. {
  224. LogClose();
  225. }
  226. return bOpen;
  227. }
  228. BOOL CommaDelimitedLog::MsgWrite(
  229. const _TCHAR msg[] ,// in -error message to display
  230. ... // in -printf args to msg pattern
  231. ) const
  232. {
  233. TCHAR suffix[350];
  234. int lenSuffix = sizeof(suffix)/sizeof(TCHAR);
  235. va_list argPtr;
  236. va_start(argPtr, msg);
  237. int cch = _vsntprintf(suffix, lenSuffix - 1, msg, argPtr);
  238. suffix[lenSuffix - 1] = '\0';
  239. va_end(argPtr);
  240. // append carriage return and line feed characters
  241. if ((cch >= 0) && (cch < (lenSuffix - 2)))
  242. {
  243. suffix[cch++] = _T('\r');
  244. suffix[cch++] = _T('\n');
  245. suffix[cch] = _T('\0');
  246. }
  247. else
  248. {
  249. suffix[lenSuffix - 3] = _T('\r');
  250. suffix[lenSuffix - 2] = _T('\n');
  251. cch = lenSuffix;
  252. }
  253. return LogWrite(suffix, cch);
  254. }
  255. BOOL CommaDelimitedLog::LogWrite(PCTSTR msg, int len) const
  256. {
  257. BOOL bWrite = FALSE;
  258. // if file was successfully opened
  259. if (m_hFile != INVALID_HANDLE_VALUE)
  260. {
  261. // move file pointer to end of file and write data
  262. // moving file pointer to end guarantees that all writes append to file
  263. // especially when the file has been opened by multiple writers
  264. DWORD dwWritten;
  265. SetFilePointer(m_hFile, 0, NULL, FILE_END);
  266. bWrite = WriteFile(m_hFile, msg, len * sizeof(_TCHAR), &dwWritten, NULL);
  267. }
  268. return bWrite;
  269. }
  270. //----------------------------------------------------------------------------
  271. // Password Log LogOpen Method
  272. //
  273. // Synopsis
  274. // If the password log path is specified then attempt to open file. If unable
  275. // to open specified file then attempt to open default file. Note that if the
  276. // specified path is the same as the default path then no further attempt to
  277. // open file is made.
  278. // If the password log path is not specified then simply attempt to open the
  279. // default file.
  280. // Note that errors are logged to the current error log.
  281. //
  282. // Arguments
  283. // pszPath - specified path to passwords log
  284. //
  285. // Return Value
  286. // Returns TRUE if able to open a file otherwise FALSE.
  287. //----------------------------------------------------------------------------
  288. BOOL CPasswordLog::LogOpen(PCTSTR pszPath)
  289. {
  290. //
  291. // If password file is specified then attempt to open it.
  292. //
  293. if (pszPath && _tcslen(pszPath) > 0)
  294. {
  295. if (CommaDelimitedLog::LogOpen(pszPath, TRUE, 1) == FALSE)
  296. {
  297. err.MsgWrite(ErrE, DCT_MSG_OPEN_PASSWORD_LOG_FAILURE_S, pszPath);
  298. }
  299. }
  300. //
  301. // If not specified or unable to open then attempt to open default passwords file.
  302. //
  303. if (IsOpen() == FALSE)
  304. {
  305. //
  306. // If able to retrieve default path for passwords file and the path is
  307. // different from the specified path then attempt to open the file.
  308. //
  309. _bstr_t strDefaultPath = GetLogsFolder() + _T("Passwords.txt");
  310. if (strDefaultPath.length() > 0)
  311. {
  312. if ((pszPath == NULL) || (_tcsicmp(pszPath, strDefaultPath) != 0))
  313. {
  314. //
  315. // If able to open default passwords file then
  316. // log message stating default path otherwise
  317. // log failure.
  318. //
  319. if (CommaDelimitedLog::LogOpen(strDefaultPath, TRUE, 1))
  320. {
  321. err.MsgWrite(ErrI, DCT_MSG_NEW_PASSWORD_LOG_S, (_TCHAR*)strDefaultPath);
  322. }
  323. else
  324. {
  325. err.MsgWrite(ErrE, DCT_MSG_OPEN_PASSWORD_LOG_FAILURE_S, (_TCHAR*)strDefaultPath);
  326. }
  327. }
  328. }
  329. else
  330. {
  331. err.MsgWrite(ErrE, DCT_MSG_CANNOT_RETRIEVE_DEFAULT_PASSWORD_LOG_PATH);
  332. }
  333. }
  334. return IsOpen();
  335. }