//
// $Id: FileAttributeData.cpp,v 1.2 2004/07/12 17:59:47 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:	FileAttributeData.cpp
//  author: Jon Baker	
//  date:   13 Februauy 2004
//
//	This class will store all data for a Linux files attributes. 
//	The class is a child class of ProbeData and implments the Write() and ParseNode() function 
//****************************************************************************************//

#include "FileAttributeData.h"

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

	//	Init the data members
    testId		= "";
	path		= new TypedData(LITTERAL_TYPE, "");
	type		= "";
	group_id	= "";
	user_id		= "";
	a_time		= "";
	c_time		= "";
	m_time		= "";
	md5			= "";
	msg			= "";
	nvpPath = NULL;

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

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

    testId		= "";
	path		= new TypedData(LITTERAL_TYPE, "");
	type		= "";
	group_id	= "";
	user_id		= "";
	a_time		= "";
	c_time		= "";
	m_time		= "";
	md5			= "";
	msg			= "";
	nvpPath = NULL;
}

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

}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//
void FileAttributeData::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 FileAttributeData::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,");
	}

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

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

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

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

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

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

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

	//	Insert NULL for suid, guid, sticky, uread, uwrite, uexec, 
	//	gwrite, gread, gexec, oread, owrite, oexec
	sqlStmt.append("NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL");

	sqlStmt.append(")");
	
	return sqlStmt;

}

string FileAttributeData::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 ");

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

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

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

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

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

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

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

void FileAttributeData::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 FileAttributeData::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;
}
