|
|
/*---------------------------------------------------------------------------
File: CommaLog.cpp
Comments: TError based log file with optional NTFS security initialization.
This can be used to write a log file which only administrators can access.
(c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved Proprietary and confidential to Mission Critical Software, Inc.
REVISION LOG ENTRY Revision By: Christy Boles Revised on 02/15/99 10:49:07
09/05/01 Mark Oluper - use Windows File I/O API --------------------------------------------------------------------------- */
//#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <share.h>
#include <lm.h>
#include "Common.hpp"
#include "UString.hpp"
#include "Err.hpp"
#include "ErrDct.hpp"
#include "sd.hpp"
#include "SecObj.hpp"
#include "CommaLog.hpp"
#include "BkupRstr.hpp"
#include "Folders.h"
#define ADMINISTRATORS 1
#define ACCOUNT_OPERATORS 2
#define BACKUP_OPERATORS 3
#define DOMAIN_ADMINS 4
#define CREATOR_OWNER 5
#define USERS 6
#define SYSTEM 7
extern TErrorDct err;
#define BYTE_ORDER_MARK (0xFEFF)
PSID // ret- SID for well-known account
GetWellKnownSid( DWORD wellKnownAccount // in - one of the constants #defined above for the well-known accounts
) { PSID pSid = NULL; // PUCHAR numsubs = NULL;
// DWORD * rid = NULL;
BOOL error = FALSE;
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; SID_IDENTIFIER_AUTHORITY creatorIA = SECURITY_CREATOR_SID_AUTHORITY; //
// Sid is the same regardless of machine, since the well-known
// BUILTIN domain is referenced.
//
switch ( wellKnownAccount ) { case CREATOR_OWNER: if( ! AllocateAndInitializeSid( &creatorIA, 2, SECURITY_BUILTIN_DOMAIN_RID, SECURITY_CREATOR_OWNER_RID, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break; case ADMINISTRATORS: if( ! AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break; case ACCOUNT_OPERATORS: if( ! AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break; case BACKUP_OPERATORS: if( ! AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break; case USERS: if( ! AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break; case SYSTEM: if( ! AllocateAndInitializeSid( &sia, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSid )) { err.SysMsgWrite(ErrE,GetLastError(),DCT_MSG_INITIALIZE_SID_FAILED_D,GetLastError()); } break;
default: MCSASSERT(FALSE); break; } if ( error ) { FreeSid(pSid); pSid = NULL; } return pSid; }
BOOL // ret- whether log was successfully opened or not
CommaDelimitedLog::LogOpen( PCTSTR filename, // in - name for log file
BOOL protect, // in - if TRUE, try to ACL the file so only admins can access
int mode // in - mode 0=overwrite, 1=append
) { BOOL bOpen = FALSE;
// close log if currently open
if (m_hFile != INVALID_HANDLE_VALUE) { LogClose(); }
// if a file name was specified
if (filename && filename[0]) { // open or create file and share for both reading and writing
m_hFile = CreateFile( filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
// if file successfully opened
if (m_hFile != INVALID_HANDLE_VALUE) { // if append specified move file pointer to end of file
// if overwrite specified move file pointer to beginning of file
// either way if pointer is at beginning of file after moving then write byte order mark
if (SetFilePointer(m_hFile, 0, NULL, mode ? FILE_END : FILE_BEGIN) == 0) { DWORD dwWritten; WCHAR chByteOrderMark = BYTE_ORDER_MARK;
WriteFile(m_hFile, &chByteOrderMark, sizeof(chByteOrderMark), &dwWritten, NULL); }
bOpen = TRUE; } }
// if file successfully opened and protect specified
// set permissions on file so that only Administrators alias has access
if (bOpen && protect) { WCHAR fname[MAX_PATH+1]; safecopy(fname,filename); if ( GetBkupRstrPriv(NULL, TRUE) ) { // Set the SD for the file to Administrators Full Control only.
TFileSD sd(fname);
if ( sd.GetSecurity() != NULL ) { PSID mySid = GetWellKnownSid(ADMINISTRATORS); TACE ace(ACCESS_ALLOWED_ACE_TYPE,0,DACL_FULLCONTROL_MASK,mySid); PACL acl = NULL; // start with an empty ACL
sd.GetSecurity()->ACLAddAce(&acl,&ace,-1); if (acl == NULL) { bOpen = FALSE; } else if (!sd.GetSecurity()->SetDacl(acl,TRUE)) { bOpen = FALSE; } else if (!sd.WriteSD()) { bOpen = FALSE; } } else { bOpen = FALSE; } } else { err.SysMsgWrite(ErrW,GetLastError(),DCT_MSG_NO_BR_PRIV_SD,fname,GetLastError()); bOpen = FALSE; } }
if (!bOpen && (m_hFile != INVALID_HANDLE_VALUE)) { LogClose(); } return bOpen; }
BOOL CommaDelimitedLog::MsgWrite( const _TCHAR msg[] ,// in -error message to display
... // in -printf args to msg pattern
) const { TCHAR suffix[350]; int lenSuffix = sizeof(suffix)/sizeof(TCHAR); va_list argPtr;
va_start(argPtr, msg); int cch = _vsntprintf(suffix, lenSuffix - 1, msg, argPtr); suffix[lenSuffix - 1] = '\0'; va_end(argPtr);
// append carriage return and line feed characters
if ((cch >= 0) && (cch < (lenSuffix - 2))) { suffix[cch++] = _T('\r'); suffix[cch++] = _T('\n'); suffix[cch] = _T('\0'); } else { suffix[lenSuffix - 3] = _T('\r'); suffix[lenSuffix - 2] = _T('\n'); cch = lenSuffix; }
return LogWrite(suffix, cch); }
BOOL CommaDelimitedLog::LogWrite(PCTSTR msg, int len) const { BOOL bWrite = FALSE;
// if file was successfully opened
if (m_hFile != INVALID_HANDLE_VALUE) { // move file pointer to end of file and write data
// moving file pointer to end guarantees that all writes append to file
// especially when the file has been opened by multiple writers
DWORD dwWritten;
SetFilePointer(m_hFile, 0, NULL, FILE_END);
bWrite = WriteFile(m_hFile, msg, len * sizeof(_TCHAR), &dwWritten, NULL); }
return bWrite; }
//----------------------------------------------------------------------------
// Password Log LogOpen Method
//
// Synopsis
// If the password log path is specified then attempt to open file. If unable
// to open specified file then attempt to open default file. Note that if the
// specified path is the same as the default path then no further attempt to
// open file is made.
// If the password log path is not specified then simply attempt to open the
// default file.
// Note that errors are logged to the current error log.
//
// Arguments
// pszPath - specified path to passwords log
//
// Return Value
// Returns TRUE if able to open a file otherwise FALSE.
//----------------------------------------------------------------------------
BOOL CPasswordLog::LogOpen(PCTSTR pszPath) { //
// If password file is specified then attempt to open it.
//
if (pszPath && _tcslen(pszPath) > 0) { if (CommaDelimitedLog::LogOpen(pszPath, TRUE, 1) == FALSE) { err.MsgWrite(ErrE, DCT_MSG_OPEN_PASSWORD_LOG_FAILURE_S, pszPath); } }
//
// If not specified or unable to open then attempt to open default passwords file.
//
if (IsOpen() == FALSE) { //
// If able to retrieve default path for passwords file and the path is
// different from the specified path then attempt to open the file.
//
_bstr_t strDefaultPath = GetLogsFolder() + _T("Passwords.txt");
if (strDefaultPath.length() > 0) { if ((pszPath == NULL) || (_tcsicmp(pszPath, strDefaultPath) != 0)) { //
// If able to open default passwords file then
// log message stating default path otherwise
// log failure.
//
if (CommaDelimitedLog::LogOpen(strDefaultPath, TRUE, 1)) { err.MsgWrite(ErrI, DCT_MSG_NEW_PASSWORD_LOG_S, (_TCHAR*)strDefaultPath); } else { err.MsgWrite(ErrE, DCT_MSG_OPEN_PASSWORD_LOG_FAILURE_S, (_TCHAR*)strDefaultPath); } } } else { err.MsgWrite(ErrE, DCT_MSG_CANNOT_RETRIEVE_DEFAULT_PASSWORD_LOG_PATH); } }
return IsOpen(); }
|