//
// $Id: FilePermissionData.cpp,v 1.1 2004/06/01 17:05:20 bakerj Exp $
//
//************************** Property of the MITRE Corporation ***************************//
//
// Copyright (c) 2003 - The MITRE Corporation
//
// This file is part of the Query-based Network Assessment project.
//
// The Query-based Network Assessment is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License.
//
// The Query-based Network Assessment is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with the
// Query-based Network Assessment; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//****************************************************************************************//
//
//  file:	FilePermissionData.cpp
//  author: Jon Baker	
//  date:   13 Februauy 2004
//
//	This class will store all data for a Linux files permissions. 
//	The class is a child class of ProbeData and implments the Write() and ParseNode() function 
//****************************************************************************************//

#include "FilePermissionData.h"

//****************************************************************************************//
//								FilePermissionData Class								  //	
//****************************************************************************************//
FilePermissionData::FilePermissionData(string strFilePathIn)
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Initialize a new FilePermissionData and populate with the node's data
  // -----------------------------------------------------------------------

  //	Init the data members
  testId	= "";
  path	= new TypedData(LITTERAL_TYPE, "");
  gexec	= "";
  gread	= "";
  gwrite	= "";
  oexec	= "";
  oread	= "";
  owrite	= "";
  sgid	= "";
  sticky	= "";
  suid	= "";
  uexec	= "";
  uread	= "";
  uwrite	= "";
  msg		= "";

  //	Call the parse function
  Parse(strFilePathIn);
}

FilePermissionData::FilePermissionData()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Initialize a new FilePermissionData as an empty object.
  // -----------------------------------------------------------------------

  testId	= "";
  path	= new TypedData(LITTERAL_TYPE, "");
  gexec	= "";
  gread	= "";
  gwrite	= "";
  oexec	= "";
  oread	= "";
  owrite	= "";
  sgid	= "";
  sticky	= "";
  suid	= "";
  uexec	= "";
  uread	= "";
  uwrite	= "";
  msg		= "";
}

FilePermissionData::~FilePermissionData()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Do nothing for now
  // -----------------------------------------------------------------------

}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//
void FilePermissionData::Write(DBInterface *db)
{
 	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Insert or update the FilePermission data 
	//	
	// -----------------------------------------------------------------------

	//	if the file path is not set no need to write to the db
	if(this->path->data.compare("") != 0 )
	{
		//	Create the appropriate SQL statement
		string sqlStmt = "";
		if(RecordExists(db))
		{
			sqlStmt = CreateUpdate();
		}else
		{
			sqlStmt = CreateInsert();
		}

		db->ExecSQL(sqlStmt);
	}

	//	Display any messages if running in verbose mode
	if(Log::verboseMode && this->msg.compare("") != 0)
	{
		string displayMsg = "\nMessage from the File probe:\n";
		displayMsg.append("--------------------------------------------\n");
		displayMsg.append(this->msg);
		displayMsg.append("\n");
		
		cout << displayMsg << endl;;

		Log::WriteLog(displayMsg + "\n");
	} 
}

// ***************************************************************************************	//
//								Private members												//
// ***************************************************************************************	//
string FilePermissionData::CreateInsert()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Create an insert statment to isert the data in this object
  // -----------------------------------------------------------------------

	string sqlStmt= "";
	sqlStmt.append("INSERT INTO ");
	sqlStmt.append("RedHat_FileAttributes");
	sqlStmt.append(" VALUES (");

	//	path
	if(this->path->data.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->path->data) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	Insert NULL for filetype, UserId, GroupId, Atime, Ctime, Mtime, and MD5
	sqlStmt.append("NULL,NULL,NULL,NULL,NULL,NULL,NULL,");

	//	suid
	if(this->suid.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->suid) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	sgid
	if(this->sgid.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->sgid) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	sticky
	if(this->sticky.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->sticky) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uread
	if(this->uread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uwrite
	if(this->uwrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uwrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uexec
	if(this->uexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uexec) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gread
	if(this->gread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gwrite
	if(this->gwrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gwrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gexec
	if(this->gexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gexec) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	oread
	if(this->oread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->oread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	owrite
	if(this->owrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->owrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	oexec
	if(this->oexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->oexec) + "'");
	}else {
		sqlStmt.append("NULL");
	}

	sqlStmt.append(")");

	return sqlStmt;
}

string FilePermissionData::CreateUpdate()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Create an update statment to isert the data in this object
  // -----------------------------------------------------------------------

	string sqlStmt= "";
	sqlStmt.append("UPDATE ");
	sqlStmt.append("RedHat_FileAttributes ");
	sqlStmt.append("SET ");

	//	suid
	sqlStmt.append("SUID = ");
	if(this->suid.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->suid) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	sgid
	sqlStmt.append("SGID = ");
	if(this->sgid.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->sgid) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	sticky
	sqlStmt.append("STICKY = ");
	if(this->sticky.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->sticky) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uread
	sqlStmt.append("UREAD = ");
	if(this->uread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uwrite
	sqlStmt.append("UWRITE = ");
	if(this->uwrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uwrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	uexec
	sqlStmt.append("UEXEC = ");
	if(this->uexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->uexec) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gread
	sqlStmt.append("GREAD = ");
	if(this->gread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gwrite
	sqlStmt.append("GWRITE = ");
	if(this->gwrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gwrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	gexec
	sqlStmt.append("GEXEC = ");
	if(this->gexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->gexec) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	oread
	sqlStmt.append("OREAD = ");
	if(this->oread.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->oread) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	owrite
	sqlStmt.append("OWRITE = ");
	if(this->owrite.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->owrite) + "',");
	}else {
		sqlStmt.append("NULL,");
	}

	//	oexec
	sqlStmt.append("OEXEC = ");
	if(this->oexec.compare("") != 0) {
		sqlStmt.append("'" + Common::FixQuotes(this->oexec) + "'");
	}else {
		sqlStmt.append("NULL");
	}

       	sqlStmt.append("WHERE FilePath = ");
	//	path
	sqlStmt.append("'" + Common::FixQuotes(this->path->data) + "' ");

	return sqlStmt;
}

void FilePermissionData::Parse(string strFilePathIn)
{
  	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Parse the string to determine if the provided path is a litteral or
	//	a pattern match
	//
	// -----------------------------------------------------------------------

	string strType = strFilePathIn.substr(0,3);
	
	//	Get the type for the path
	if(strType.compare("LIT") == 0)
		this->path->type = LITTERAL_TYPE;
	else
		this->path->type = PATTERN_MATCH_TYPE;

	//	Set the value of the path
	this->path->data = strFilePathIn.substr(4, strFilePathIn.length() -4);
}

bool FilePermissionData::RecordExists(DBInterface *db)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Return true if a record exists in the database with the same filepath
	// -----------------------------------------------------------------------

	string sqlStmt= "";
	sqlStmt.append("SELECT * FROM RedHat_FileAttributes ");
	sqlStmt.append("WHERE FilePath = '");
	sqlStmt.append(this->path->data);
	sqlStmt.append("'");

	stringVector svResult;

	db->ExecSQL(sqlStmt, &svResult);
	
	if(svResult.size() > 0)
		return true;
	
	return false;
}
