19 package org.sleuthkit.datamodel;
21 import com.google.common.annotations.Beta;
22 import com.google.common.cache.Cache;
23 import com.google.common.cache.CacheBuilder;
24 import com.google.common.collect.ImmutableSet;
25 import com.google.common.eventbus.EventBus;
26 import com.mchange.v2.c3p0.ComboPooledDataSource;
27 import com.mchange.v2.c3p0.DataSources;
28 import com.mchange.v2.c3p0.PooledDataSource;
29 import com.zaxxer.sparsebits.SparseBitSet;
30 import java.beans.PropertyVetoException;
31 import java.io.BufferedInputStream;
32 import java.io.BufferedOutputStream;
34 import java.io.FileInputStream;
35 import java.io.FileOutputStream;
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39 import java.io.UnsupportedEncodingException;
40 import java.net.InetAddress;
41 import java.net.URLEncoder;
42 import java.nio.charset.StandardCharsets;
43 import java.nio.file.Paths;
44 import java.sql.Connection;
45 import java.sql.DriverManager;
46 import java.sql.PreparedStatement;
47 import java.sql.ResultSet;
48 import java.sql.SQLException;
49 import java.sql.Statement;
50 import java.text.SimpleDateFormat;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Collection;
54 import java.util.Collections;
55 import java.util.concurrent.atomic.AtomicBoolean;
56 import java.util.concurrent.atomic.AtomicInteger;
57 import java.util.Date;
58 import java.util.EnumMap;
59 import java.util.HashMap;
60 import java.util.HashSet;
61 import java.util.LinkedHashMap;
62 import java.util.List;
64 import java.util.MissingResourceException;
65 import java.util.Objects;
66 import java.util.Properties;
67 import java.util.ResourceBundle;
69 import java.util.UUID;
70 import java.util.concurrent.TimeUnit;
71 import java.util.concurrent.locks.ReentrantReadWriteLock;
72 import java.util.logging.Level;
73 import java.util.logging.Logger;
74 import java.util.stream.Collectors;
75 import org.apache.commons.lang3.StringUtils;
76 import org.postgresql.util.PSQLState;
94 import org.sqlite.SQLiteConfig;
95 import org.sqlite.SQLiteDataSource;
96 import org.sqlite.SQLiteJDBCLoader;
104 private static final int MAX_DB_NAME_LEN_BEFORE_TIMESTAMP = 47;
109 private static final long BASE_ARTIFACT_ID = Long.MIN_VALUE;
110 private static final Logger logger = Logger.getLogger(
SleuthkitCase.class.getName());
111 private static final ResourceBundle bundle = ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle");
112 private static final int IS_REACHABLE_TIMEOUT_MS = 1000;
113 private static final String SQL_ERROR_CONNECTION_GROUP =
"08";
114 private static final String SQL_ERROR_AUTHENTICATION_GROUP =
"28";
115 private static final String SQL_ERROR_PRIVILEGE_GROUP =
"42";
116 private static final String SQL_ERROR_RESOURCE_GROUP =
"53";
117 private static final String SQL_ERROR_LIMIT_GROUP =
"54";
118 private static final String SQL_ERROR_INTERNAL_GROUP =
"xx";
120 private static final Set<String> CORE_TABLE_NAMES = ImmutableSet.of(
122 "tsk_event_descriptions",
135 "tsk_files_derived_method",
138 "blackboard_artifact_tags",
139 "blackboard_artifacts",
140 "blackboard_attributes",
141 "blackboard_artifact_types",
142 "blackboard_attribute_types",
144 "file_encoding_types",
145 "ingest_module_types",
146 "ingest_job_status_types",
149 "ingest_job_modules",
152 "account_relationships",
156 private static final Set<String> CORE_INDEX_NAMES = ImmutableSet.of(
160 "artifact_artifact_objID",
165 "relationships_account1",
166 "relationships_account2",
167 "relationships_relationship_source_obj_id",
168 "relationships_date_time",
169 "relationships_relationship_type",
170 "relationships_data_source_obj_id",
173 "events_data_source_obj_id",
174 "events_file_obj_id",
175 "events_artifact_id");
177 private static final String TSK_VERSION_KEY =
"TSK_VER";
178 private static final String SCHEMA_MAJOR_VERSION_KEY =
"SCHEMA_MAJOR_VERSION";
179 private static final String SCHEMA_MINOR_VERSION_KEY =
"SCHEMA_MINOR_VERSION";
180 private static final String CREATION_SCHEMA_MAJOR_VERSION_KEY =
"CREATION_SCHEMA_MAJOR_VERSION";
181 private static final String CREATION_SCHEMA_MINOR_VERSION_KEY =
"CREATION_SCHEMA_MINOR_VERSION";
183 private final ConnectionPool connections;
184 private final Object carvedFileDirsLock =
new Object();
185 private final static int MAX_CARVED_FILES_PER_FOLDER = 2000;
186 private final Map<Long, CarvedFileDirInfo> rootIdsToCarvedFileDirs =
new HashMap<>();
187 private final Map<Long, FileSystem> fileSystemIdMap =
new HashMap<>();
188 private final List<ErrorObserver> sleuthkitCaseErrorObservers =
new ArrayList<>();
189 private final String databaseName;
190 private final String dbPath;
191 private final DbType dbType;
192 private final String caseDirPath;
194 private final String caseHandleIdentifier;
195 private String dbBackupPath;
196 private AtomicBoolean timelineEventsDisabled =
new AtomicBoolean(
false);
201 private final Object rootDirectoryMapLock =
new Object();
202 private final Map<RootDirectoryKey, Long> rootDirectoryMap =
new HashMap<>();
203 private final Cache<Long, Boolean> isRootDirectoryCache
204 = CacheBuilder.newBuilder().maximumSize(200000).expireAfterAccess(5, TimeUnit.MINUTES).build();
210 private final Map<Long, SparseBitSet> hasChildrenBitSetMap =
new HashMap<>();
212 private long nextArtifactId;
217 private final ReentrantReadWriteLock rwLock =
new ReentrantReadWriteLock(
true);
232 private final Map<String, Set<Long>> deviceIdToDatasourceObjIdMap =
new HashMap<>();
234 private final EventBus eventBus =
new EventBus(
"SleuthkitCase-EventBus");
237 eventBus.register(listener);
241 eventBus.unregister(listener);
244 void fireTSKEvent(Object event) {
245 eventBus.post(event);
249 private final Map<Long, Content> frequentlyUsedContentMap =
new HashMap<>();
251 private Examiner cachedCurrentExaminer = null;
254 Properties p =
new Properties(System.getProperties());
255 p.put(
"com.mchange.v2.log.MLog",
"com.mchange.v2.log.FallbackMLog");
256 p.put(
"com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL",
"SEVERE");
257 System.setProperties(p);
276 if (info.getHost() == null || info.getHost().isEmpty()) {
277 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingHostname"));
278 }
else if (info.getPort() == null || info.getPort().isEmpty()) {
279 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPort"));
280 }
else if (info.getUserName() == null || info.getUserName().isEmpty()) {
281 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingUsername"));
282 }
else if (info.getPassword() == null || info.getPassword().isEmpty()) {
283 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPassword"));
287 Class.forName(
"org.postgresql.Driver");
288 Connection conn = DriverManager.getConnection(
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres", info.getUserName(), info.getPassword());
292 }
catch (SQLException ex) {
294 String sqlState = ex.getSQLState().toLowerCase();
295 if (sqlState.startsWith(SQL_ERROR_CONNECTION_GROUP)) {
297 if (InetAddress.getByName(info.getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) {
299 result = bundle.getString(
"DatabaseConnectionCheck.Port");
301 result = bundle.getString(
"DatabaseConnectionCheck.HostnameOrPort");
303 }
catch (IOException | MissingResourceException any) {
305 result = bundle.getString(
"DatabaseConnectionCheck.Everything");
307 }
else if (sqlState.startsWith(SQL_ERROR_AUTHENTICATION_GROUP)) {
308 result = bundle.getString(
"DatabaseConnectionCheck.Authentication");
309 }
else if (sqlState.startsWith(SQL_ERROR_PRIVILEGE_GROUP)) {
310 result = bundle.getString(
"DatabaseConnectionCheck.Access");
311 }
else if (sqlState.startsWith(SQL_ERROR_RESOURCE_GROUP)) {
312 result = bundle.getString(
"DatabaseConnectionCheck.ServerDiskSpace");
313 }
else if (sqlState.startsWith(SQL_ERROR_LIMIT_GROUP)) {
314 result = bundle.getString(
"DatabaseConnectionCheck.ServerRestart");
315 }
else if (sqlState.startsWith(SQL_ERROR_INTERNAL_GROUP)) {
316 result = bundle.getString(
"DatabaseConnectionCheck.InternalServerIssue");
318 result = bundle.getString(
"DatabaseConnectionCheck.Connection");
321 }
catch (ClassNotFoundException ex) {
322 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.Installation"));
338 Class.forName(
"org.sqlite.JDBC");
339 this.dbPath = dbPath;
340 this.dbType = dbType;
342 this.caseDirPath = dbFile.getParentFile().getAbsolutePath();
343 this.databaseName = dbFile.
getName();
344 this.connections =
new SQLiteConnections(dbPath);
345 this.caseHandle = caseHandle;
346 this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier();
348 logSQLiteJDBCDriverInfo();
368 private SleuthkitCase(String host,
int port, String dbName, String userName, String password, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, DbType dbType)
throws Exception {
370 this.databaseName = dbName;
371 this.dbType = dbType;
372 this.caseDirPath = caseDirPath;
373 this.connections =
new PostgreSQLConnections(host, port, dbName, userName, password);
374 this.caseHandle = caseHandle;
375 this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier();
379 private void init() throws Exception {
380 blackboard =
new Blackboard(
this);
381 updateDatabaseSchema(null);
382 try (CaseDbConnection connection = connections.getConnection()) {
383 blackboard.initBlackboardArtifactTypes(connection);
384 blackboard.initBlackboardAttributeTypes(connection);
385 initNextArtifactId(connection);
386 initIngestModuleTypes(connection);
387 initIngestStatusTypes(connection);
388 initReviewStatuses(connection);
389 initEncodingTypes(connection);
390 populateHasChildrenMap(connection);
391 updateExaminers(connection);
392 initDBSchemaCreationVersion(connection);
395 fileManager =
new FileManager(
this);
396 communicationsMgr =
new CommunicationsManager(
this);
397 timelineMgr =
new TimelineManager(
this);
398 dbAccessManager =
new CaseDbAccessManager(
this);
399 taggingMgr =
new TaggingManager(
this);
400 scoringManager =
new ScoringManager(
this);
401 osAccountRealmManager =
new OsAccountRealmManager(
this);
402 osAccountManager =
new OsAccountManager(
this);
403 hostManager =
new HostManager(
this);
404 personManager =
new PersonManager(
this);
405 hostAddressManager =
new HostAddressManager(
this);
413 static Set<String> getCoreTableNames() {
414 return Collections.unmodifiableSet(CORE_TABLE_NAMES);
422 static Set<String> getCoreIndexNames() {
423 return Collections.unmodifiableSet(CORE_INDEX_NAMES);
434 boolean getHasChildren(Content content) {
435 long objId = content.getId();
436 long mapIndex = objId / Integer.MAX_VALUE;
437 int mapValue = (int) (objId % Integer.MAX_VALUE);
439 synchronized (hasChildrenBitSetMap) {
440 if (hasChildrenBitSetMap.containsKey(mapIndex)) {
441 return hasChildrenBitSetMap.get(mapIndex).get(mapValue);
452 private void setHasChildren(Long objId) {
453 long mapIndex = objId / Integer.MAX_VALUE;
454 int mapValue = (int) (objId % Integer.MAX_VALUE);
456 synchronized (hasChildrenBitSetMap) {
457 if (hasChildrenBitSetMap.containsKey(mapIndex)) {
458 hasChildrenBitSetMap.get(mapIndex).set(mapValue);
460 SparseBitSet bitSet =
new SparseBitSet();
461 bitSet.set(mapValue);
462 hasChildrenBitSetMap.put(mapIndex, bitSet);
475 return communicationsMgr;
515 return dbAccessManager;
535 return scoringManager;
546 return osAccountRealmManager;
557 return osAccountManager;
579 return personManager;
590 return hostAddressManager;
602 private void initNextArtifactId(CaseDbConnection connection)
throws SQLException {
604 try (Statement statement = connection.createStatement()) {
605 ResultSet resultSet = connection.executeQuery(statement,
"SELECT MAX(artifact_id) AS max_artifact_id FROM blackboard_artifacts");
607 nextArtifactId = resultSet.getLong(
"max_artifact_id") + 1;
608 if (nextArtifactId == 1) {
609 nextArtifactId = BASE_ARTIFACT_ID;
623 private void initIngestModuleTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
624 Statement statement = null;
625 ResultSet resultSet = null;
628 statement = connection.createStatement();
629 for (IngestModuleType type : IngestModuleType.values()) {
631 String query =
"INSERT INTO ingest_module_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"')";
633 query +=
" ON CONFLICT ON CONSTRAINT ingest_module_types_pkey DO NOTHING";
635 statement.execute(query);
636 }
catch (SQLException ex) {
637 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_module_types WHERE type_id = " + type.ordinal() +
";");
639 if (resultSet.getLong(
"count") == 0) {
647 closeResultSet(resultSet);
648 closeStatement(statement);
660 private void initIngestStatusTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
661 Statement statement = null;
662 ResultSet resultSet = null;
665 statement = connection.createStatement();
666 for (IngestJobStatusType type : IngestJobStatusType.values()) {
668 String query =
"INSERT INTO ingest_job_status_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"')";
670 query +=
" ON CONFLICT ON CONSTRAINT ingest_job_status_types_pkey DO NOTHING";
672 statement.execute(query);
673 }
catch (SQLException ex) {
674 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_job_status_types WHERE type_id = " + type.ordinal() +
";");
676 if (resultSet.getLong(
"count") == 0) {
684 closeResultSet(resultSet);
685 closeStatement(statement);
696 private void initReviewStatuses(CaseDbConnection connection)
throws SQLException, TskCoreException {
697 Statement statement = null;
698 ResultSet resultSet = null;
701 statement = connection.createStatement();
702 for (BlackboardArtifact.ReviewStatus status : BlackboardArtifact.ReviewStatus.values()) {
704 String query =
"INSERT INTO review_statuses (review_status_id, review_status_name, display_name) "
705 +
"VALUES (" + status.getID() +
",'" + status.getName() +
"','" + status.getDisplayName() +
"')";
707 query +=
" ON CONFLICT ON CONSTRAINT review_statuses_pkey DO NOTHING";
709 statement.execute(query);
710 }
catch (SQLException ex) {
711 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM review_statuses WHERE review_status_id = " + status.getID());
713 if (resultSet.getLong(
"count") == 0) {
721 closeResultSet(resultSet);
722 closeStatement(statement);
734 private void initEncodingTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
735 Statement statement = null;
736 ResultSet resultSet = null;
739 statement = connection.createStatement();
740 for (TskData.EncodingType type : TskData.EncodingType.values()) {
742 String query =
"INSERT INTO file_encoding_types (encoding_type, name) VALUES (" + type.getType() +
" , '" + type.name() +
"')";
744 query +=
" ON CONFLICT ON CONSTRAINT file_encoding_types_pkey DO NOTHING";
746 statement.execute(query);
747 }
catch (SQLException ex) {
748 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM file_encoding_types WHERE encoding_type = " + type.getType());
750 if (resultSet.getLong(
"count") == 0) {
758 closeResultSet(resultSet);
759 closeStatement(statement);
772 private void updateExaminers(CaseDbConnection connection)
throws SQLException, TskCoreException {
774 String loginName = System.getProperty(
"user.name");
775 if (loginName.isEmpty()) {
776 logger.log(Level.SEVERE,
"Cannot determine logged in user name");
782 PreparedStatement statement;
785 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_EXAMINER_POSTGRESQL);
788 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_EXAMINER_SQLITE);
791 throw new TskCoreException(
"Unknown DB Type: " +
getDatabaseType().name());
793 statement.clearParameters();
794 statement.setString(1, loginName);
795 connection.executeUpdate(statement);
796 }
catch (SQLException ex) {
797 throw new TskCoreException(
"Error inserting row in tsk_examiners. login name: " + loginName, ex);
810 private void populateHasChildrenMap(CaseDbConnection connection)
throws TskCoreException {
811 long timestamp = System.currentTimeMillis();
813 Statement statement = null;
814 ResultSet resultSet = null;
817 statement = connection.createStatement();
818 resultSet = statement.executeQuery(
"select distinct par_obj_id from tsk_objects");
820 synchronized (hasChildrenBitSetMap) {
821 while (resultSet.next()) {
822 setHasChildren(resultSet.getLong(
"par_obj_id"));
825 long delay = System.currentTimeMillis() - timestamp;
826 logger.log(Level.INFO,
"Time to initialize parent node cache: {0} ms", delay);
827 }
catch (SQLException ex) {
828 throw new TskCoreException(
"Error populating parent node cache", ex);
830 closeResultSet(resultSet);
831 closeStatement(statement);
842 void addDataSourceToHasChildrenMap() throws TskCoreException {
844 CaseDbConnection connection = connections.getConnection();
846 populateHasChildrenMap(connection);
848 closeConnection(connection);
861 private void updateDatabaseSchema(String dbPath)
throws Exception {
862 CaseDbConnection connection = null;
863 ResultSet resultSet = null;
864 Statement statement = null;
867 connection = connections.getConnection();
868 connection.beginTransaction();
870 boolean hasMinorVersion =
false;
871 ResultSet columns = connection.getConnection().getMetaData().getColumns(null, null,
"tsk_db_info",
"schema%");
872 while (columns.next()) {
873 if (columns.getString(
"COLUMN_NAME").equals(
"schema_minor_ver")) {
874 hasMinorVersion =
true;
879 int dbSchemaMajorVersion;
880 int dbSchemaMinorVersion = 0;
882 statement = connection.createStatement();
883 resultSet = connection.executeQuery(statement,
"SELECT schema_ver"
884 + (hasMinorVersion ?
", schema_minor_ver" :
"")
885 +
" FROM tsk_db_info");
886 if (resultSet.next()) {
887 dbSchemaMajorVersion = resultSet.getInt(
"schema_ver");
888 if (hasMinorVersion) {
890 dbSchemaMinorVersion = resultSet.getInt(
"schema_minor_ver");
893 throw new TskCoreException();
895 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(dbSchemaMajorVersion, dbSchemaMinorVersion);
902 if (
false == CURRENT_DB_SCHEMA_VERSION.
isCompatible(dbSchemaVersion)) {
904 throw new TskUnsupportedSchemaVersionException(
905 "Unsupported DB schema version " + dbSchemaVersion +
", the highest supported schema version is " + CURRENT_DB_SCHEMA_VERSION.
getMajor() +
".X");
906 }
else if (dbSchemaVersion.compareTo(CURRENT_DB_SCHEMA_VERSION) < 0) {
909 if (null != dbPath) {
912 String backupFilePath = dbPath +
".schemaVer" + dbSchemaVersion.toString() +
".backup";
914 dbBackupPath = backupFilePath;
921 dbSchemaVersion = updateFromSchema2toSchema3(dbSchemaVersion, connection);
922 dbSchemaVersion = updateFromSchema3toSchema4(dbSchemaVersion, connection);
923 dbSchemaVersion = updateFromSchema4toSchema5(dbSchemaVersion, connection);
924 dbSchemaVersion = updateFromSchema5toSchema6(dbSchemaVersion, connection);
925 dbSchemaVersion = updateFromSchema6toSchema7(dbSchemaVersion, connection);
926 dbSchemaVersion = updateFromSchema7toSchema7dot1(dbSchemaVersion, connection);
927 dbSchemaVersion = updateFromSchema7dot1toSchema7dot2(dbSchemaVersion, connection);
928 dbSchemaVersion = updateFromSchema7dot2toSchema8dot0(dbSchemaVersion, connection);
929 dbSchemaVersion = updateFromSchema8dot0toSchema8dot1(dbSchemaVersion, connection);
930 dbSchemaVersion = updateFromSchema8dot1toSchema8dot2(dbSchemaVersion, connection);
931 dbSchemaVersion = updateFromSchema8dot2toSchema8dot3(dbSchemaVersion, connection);
932 dbSchemaVersion = updateFromSchema8dot3toSchema8dot4(dbSchemaVersion, connection);
933 dbSchemaVersion = updateFromSchema8dot4toSchema8dot5(dbSchemaVersion, connection);
934 dbSchemaVersion = updateFromSchema8dot5toSchema8dot6(dbSchemaVersion, connection);
935 dbSchemaVersion = updateFromSchema8dot6toSchema9dot0(dbSchemaVersion, connection);
936 dbSchemaVersion = updateFromSchema9dot0toSchema9dot1(dbSchemaVersion, connection);
937 dbSchemaVersion = updateFromSchema9dot1toSchema9dot2(dbSchemaVersion, connection);
938 dbSchemaVersion = updateFromSchema9dot2toSchema9dot3(dbSchemaVersion, connection);
942 statement = connection.createStatement();
943 connection.executeUpdate(statement,
"UPDATE tsk_db_info SET schema_ver = " + dbSchemaVersion.getMajor() +
", schema_minor_ver = " + dbSchemaVersion.getMinor());
944 connection.executeUpdate(statement,
"UPDATE tsk_db_info_extended SET value = " + dbSchemaVersion.getMajor() +
" WHERE name = '" + SCHEMA_MAJOR_VERSION_KEY +
"'");
945 connection.executeUpdate(statement,
"UPDATE tsk_db_info_extended SET value = " + dbSchemaVersion.getMinor() +
" WHERE name = '" + SCHEMA_MINOR_VERSION_KEY +
"'");
950 connection.commitTransaction();
951 }
catch (Exception ex) {
952 rollbackTransaction(connection);
955 closeResultSet(resultSet);
956 closeStatement(statement);
957 closeConnection(connection);
969 private void initDBSchemaCreationVersion(CaseDbConnection connection)
throws SQLException {
971 Statement statement = null;
972 ResultSet resultSet = null;
973 String createdSchemaMajorVersion =
"0";
974 String createdSchemaMinorVersion =
"0";
977 statement = connection.createStatement();
978 resultSet = connection.executeQuery(statement,
"SELECT name, value FROM tsk_db_info_extended");
979 while (resultSet.next()) {
980 String name = resultSet.getString(
"name");
981 if (name.equals(CREATION_SCHEMA_MAJOR_VERSION_KEY) || name.equals(
"CREATED_SCHEMA_MAJOR_VERSION")) {
982 createdSchemaMajorVersion = resultSet.getString(
"value");
983 }
else if (name.equals(CREATION_SCHEMA_MINOR_VERSION_KEY) || name.equals(
"CREATED_SCHEMA_MINOR_VERSION")) {
984 createdSchemaMinorVersion = resultSet.getString(
"value");
989 closeResultSet(resultSet);
990 closeStatement(statement);
994 caseDBSchemaCreationVersion =
new CaseDbSchemaVersionNumber(Integer.parseInt(createdSchemaMajorVersion), Integer.parseInt(createdSchemaMinorVersion));
1007 if (dbPath.isEmpty()) {
1008 throw new IOException(
"Copying case database files is not supported for this type of case database");
1010 InputStream in = null;
1011 OutputStream out = null;
1014 InputStream inFile =
new FileInputStream(dbPath);
1015 in =
new BufferedInputStream(inFile);
1016 OutputStream outFile =
new FileOutputStream(newDBPath);
1017 out =
new BufferedOutputStream(outFile);
1018 int bytesRead = in.read();
1019 while (bytesRead != -1) {
1020 out.write(bytesRead);
1021 bytesRead = in.read();
1032 }
catch (IOException e) {
1033 logger.log(Level.WARNING,
"Could not close streams after db copy", e);
1042 private void logSQLiteJDBCDriverInfo() {
1044 SleuthkitCase.logger.info(String.format(
"sqlite-jdbc version %s loaded in %s mode",
1045 SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
1046 ?
"native" :
"pure-java"));
1047 }
catch (Exception ex) {
1048 SleuthkitCase.logger.log(Level.SEVERE,
"Error querying case database mode", ex);
1065 @SuppressWarnings(
"deprecation")
1066 private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection) throws SQLException, TskCoreException {
1067 if (schemaVersion.getMajor() != 2) {
1068 return schemaVersion;
1070 Statement statement = null;
1071 Statement statement2 = null;
1072 Statement updateStatement = null;
1073 ResultSet resultSet = null;
1076 statement = connection.createStatement();
1077 statement2 = connection.createStatement();
1080 statement.execute(
"CREATE TABLE tag_names (tag_name_id INTEGER PRIMARY KEY, display_name TEXT UNIQUE, description TEXT NOT NULL, color TEXT NOT NULL)");
1081 statement.execute(
"CREATE TABLE content_tags (tag_id INTEGER PRIMARY KEY, obj_id INTEGER NOT NULL, tag_name_id INTEGER NOT NULL, comment TEXT NOT NULL, begin_byte_offset INTEGER NOT NULL, end_byte_offset INTEGER NOT NULL)");
1082 statement.execute(
"CREATE TABLE blackboard_artifact_tags (tag_id INTEGER PRIMARY KEY, artifact_id INTEGER NOT NULL, tag_name_id INTEGER NOT NULL, comment TEXT NOT NULL)");
1085 statement.execute(
"CREATE TABLE reports (report_id INTEGER PRIMARY KEY, path TEXT NOT NULL, crtime INTEGER NOT NULL, src_module_name TEXT NOT NULL, report_name TEXT NOT NULL)");
1088 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN size INTEGER;");
1089 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN md5 TEXT;");
1090 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN display_name TEXT;");
1093 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN display_name TEXT;");
1096 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN meta_seq INTEGER;");
1101 statement.execute(
"ALTER TABLE blackboard_attributes ADD COLUMN artifact_type_id INTEGER NULL NOT NULL DEFAULT -1;");
1102 statement.execute(
"CREATE INDEX attribute_artifactTypeId ON blackboard_attributes(artifact_type_id);");
1103 statement.execute(
"CREATE INDEX attribute_valueText ON blackboard_attributes(value_text);");
1104 statement.execute(
"CREATE INDEX attribute_valueInt32 ON blackboard_attributes(value_int32);");
1105 statement.execute(
"CREATE INDEX attribute_valueInt64 ON blackboard_attributes(value_int64);");
1106 statement.execute(
"CREATE INDEX attribute_valueDouble ON blackboard_attributes(value_double);");
1107 resultSet = statement.executeQuery(
"SELECT attrs.artifact_id AS artifact_id, "
1108 +
"arts.artifact_type_id AS artifact_type_id "
1109 +
"FROM blackboard_attributes AS attrs "
1110 +
"INNER JOIN blackboard_artifacts AS arts "
1111 +
"WHERE attrs.artifact_id = arts.artifact_id;");
1112 updateStatement = connection.createStatement();
1113 while (resultSet.next()) {
1114 long artifactId = resultSet.getLong(
"artifact_id");
1115 int artifactTypeId = resultSet.getInt(
"artifact_type_id");
1116 updateStatement.executeUpdate(
1117 "UPDATE blackboard_attributes "
1118 +
"SET artifact_type_id = " + artifactTypeId
1119 +
" WHERE blackboard_attributes.artifact_id = " + artifactId +
";");
1124 Map<String, Long> tagNames =
new HashMap<>();
1125 long tagNameCounter = 1;
1129 resultSet = statement.executeQuery(
"SELECT * FROM \n"
1130 +
"(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, blackboard_attributes.value_text AS name\n"
1131 +
"FROM blackboard_artifacts INNER JOIN blackboard_attributes \n"
1132 +
"ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n"
1133 +
"WHERE blackboard_artifacts.artifact_type_id = "
1134 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1135 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
1136 +
") AS tagNames \n"
1138 +
"(SELECT tsk_files.obj_id as objId2, tsk_files.size AS fileSize \n"
1139 +
"FROM blackboard_artifacts INNER JOIN tsk_files \n"
1140 +
"ON blackboard_artifacts.obj_id = tsk_files.obj_id) AS fileData \n"
1141 +
"ON tagNames.objId = fileData.objId2 \n"
1143 +
"(SELECT value_text AS comment, artifact_id AS tagArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1144 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() +
") AS tagComments \n"
1145 +
"ON tagNames.artifactId = tagComments.tagArtifactId");
1147 while (resultSet.next()) {
1148 long objId = resultSet.getLong(
"objId");
1149 long fileSize = resultSet.getLong(
"fileSize");
1150 String tagName = resultSet.getString(
"name");
1151 String tagComment = resultSet.getString(
"comment");
1152 if (tagComment == null) {
1156 if (tagName != null && !tagName.isEmpty()) {
1159 if (tagNames.containsKey(tagName)) {
1160 tagNameIndex = tagNames.get(tagName);
1162 statement2.execute(
"INSERT INTO tag_names (display_name, description, color) "
1163 +
"VALUES(\"" + tagName +
"\", \"\", \"None\")");
1164 tagNames.put(tagName, tagNameCounter);
1165 tagNameIndex = tagNameCounter;
1169 statement2.execute(
"INSERT INTO content_tags (obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset) "
1170 +
"VALUES(" + objId +
", " + tagNameIndex +
", \"" + tagComment +
"\", 0, " + fileSize +
")");
1177 resultSet = statement.executeQuery(
"SELECT * FROM \n"
1178 +
"(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, "
1179 +
"blackboard_attributes.value_text AS name\n"
1180 +
"FROM blackboard_artifacts INNER JOIN blackboard_attributes \n"
1181 +
"ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n"
1182 +
"WHERE blackboard_artifacts.artifact_type_id = "
1183 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()
1184 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
1185 +
") AS tagNames \n"
1187 +
"(SELECT value_int64 AS taggedArtifactId, artifact_id AS associatedArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1188 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID() +
") AS tagArtifacts \n"
1189 +
"ON tagNames.artifactId = tagArtifacts.associatedArtifactId \n"
1191 +
"(SELECT value_text AS comment, artifact_id AS commentArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1192 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() +
") AS tagComments \n"
1193 +
"ON tagNames.artifactId = tagComments.commentArtifactId");
1195 while (resultSet.next()) {
1196 long artifactId = resultSet.getLong(
"taggedArtifactId");
1197 String tagName = resultSet.getString(
"name");
1198 String tagComment = resultSet.getString(
"comment");
1199 if (tagComment == null) {
1202 if (tagName != null && !tagName.isEmpty()) {
1205 if (tagNames.containsKey(tagName)) {
1206 tagNameIndex = tagNames.get(tagName);
1208 statement2.execute(
"INSERT INTO tag_names (display_name, description, color) "
1209 +
"VALUES(\"" + tagName +
"\", \"\", \"None\")");
1210 tagNames.put(tagName, tagNameCounter);
1211 tagNameIndex = tagNameCounter;
1215 statement2.execute(
"INSERT INTO blackboard_artifact_tags (artifact_id, tag_name_id, comment) "
1216 +
"VALUES(" + artifactId +
", " + tagNameIndex +
", \"" + tagComment +
"\")");
1222 "DELETE FROM blackboard_attributes WHERE artifact_id IN "
1223 +
"(SELECT artifact_id FROM blackboard_artifacts WHERE artifact_type_id = "
1224 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1225 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
");");
1227 "DELETE FROM blackboard_artifacts WHERE artifact_type_id = "
1228 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1229 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
";");
1231 return new CaseDbSchemaVersionNumber(3, 0);
1233 closeStatement(updateStatement);
1234 closeResultSet(resultSet);
1235 closeStatement(statement);
1236 closeStatement(statement2);
1254 private CaseDbSchemaVersionNumber updateFromSchema3toSchema4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1255 if (schemaVersion.getMajor() != 3) {
1256 return schemaVersion;
1259 Statement statement = null;
1260 ResultSet resultSet = null;
1261 Statement queryStatement = null;
1262 ResultSet queryResultSet = null;
1263 Statement updateStatement = null;
1268 statement = connection.createStatement();
1269 updateStatement = connection.createStatement();
1270 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN mime_type TEXT;");
1271 resultSet = statement.executeQuery(
"SELECT files.obj_id AS obj_id, attrs.value_text AS value_text "
1272 +
"FROM tsk_files AS files, blackboard_attributes AS attrs, blackboard_artifacts AS arts "
1273 +
"WHERE files.obj_id = arts.obj_id AND "
1274 +
"arts.artifact_id = attrs.artifact_id AND "
1275 +
"arts.artifact_type_id = 1 AND "
1276 +
"attrs.attribute_type_id = 62");
1277 while (resultSet.next()) {
1278 updateStatement.executeUpdate(
1280 +
"SET mime_type = '" + resultSet.getString(
"value_text") +
"' "
1281 +
"WHERE tsk_files.obj_id = " + resultSet.getInt(
"obj_id") +
";");
1286 statement.execute(
"ALTER TABLE blackboard_attribute_types ADD COLUMN value_type INTEGER NOT NULL DEFAULT -1;");
1287 resultSet = statement.executeQuery(
"SELECT * FROM blackboard_attribute_types AS types");
1288 while (resultSet.next()) {
1289 int attributeTypeId = resultSet.getInt(
"attribute_type_id");
1290 String attributeLabel = resultSet.getString(
"type_name");
1291 if (attributeTypeId < Blackboard.MIN_USER_DEFINED_TYPE_ID) {
1292 updateStatement.executeUpdate(
1293 "UPDATE blackboard_attribute_types "
1294 +
"SET value_type = " + ATTRIBUTE_TYPE.fromLabel(attributeLabel).getValueType().getType() +
" "
1295 +
"WHERE blackboard_attribute_types.attribute_type_id = " + attributeTypeId +
";");
1301 queryStatement = connection.createStatement();
1302 statement.execute(
"CREATE TABLE data_source_info (obj_id INTEGER PRIMARY KEY, device_id TEXT NOT NULL, time_zone TEXT NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id));");
1303 resultSet = statement.executeQuery(
"SELECT * FROM tsk_objects WHERE par_obj_id IS NULL");
1304 while (resultSet.next()) {
1305 long objectId = resultSet.getLong(
"obj_id");
1306 String timeZone =
"";
1307 queryResultSet = queryStatement.executeQuery(
"SELECT tzone FROM tsk_image_info WHERE obj_id = " + objectId);
1308 if (queryResultSet.next()) {
1309 timeZone = queryResultSet.getString(
"tzone");
1311 queryResultSet.close();
1312 updateStatement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone) "
1313 +
"VALUES(" + objectId +
", '" + UUID.randomUUID().toString() +
"' , '" + timeZone +
"');");
1327 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN data_source_obj_id BIGINT NOT NULL DEFAULT -1;");
1328 resultSet = statement.executeQuery(
"SELECT tsk_files.obj_id AS obj_id, par_obj_id FROM tsk_files, tsk_objects WHERE tsk_files.obj_id = tsk_objects.obj_id");
1329 while (resultSet.next()) {
1330 long fileId = resultSet.getLong(
"obj_id");
1331 long dataSourceId = getDataSourceObjectId(connection, fileId);
1332 updateStatement.executeUpdate(
"UPDATE tsk_files SET data_source_obj_id = " + dataSourceId +
" WHERE obj_id = " + fileId +
";");
1335 statement.execute(
"CREATE TABLE ingest_module_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
1336 statement.execute(
"CREATE TABLE ingest_job_status_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
1337 if (this.dbType.equals(DbType.SQLITE)) {
1338 statement.execute(
"CREATE TABLE ingest_modules (ingest_module_id INTEGER PRIMARY KEY, display_name TEXT NOT NULL, unique_name TEXT UNIQUE NOT NULL, type_id INTEGER NOT NULL, version TEXT NOT NULL, FOREIGN KEY(type_id) REFERENCES ingest_module_types(type_id));");
1339 statement.execute(
"CREATE TABLE ingest_jobs (ingest_job_id INTEGER PRIMARY KEY, obj_id BIGINT NOT NULL, host_name TEXT NOT NULL, start_date_time BIGINT NOT NULL, end_date_time BIGINT NOT NULL, status_id INTEGER NOT NULL, settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id));");
1341 statement.execute(
"CREATE TABLE ingest_modules (ingest_module_id BIGSERIAL PRIMARY KEY, display_name TEXT NOT NULL, unique_name TEXT UNIQUE NOT NULL, type_id INTEGER NOT NULL, version TEXT NOT NULL, FOREIGN KEY(type_id) REFERENCES ingest_module_types(type_id));");
1342 statement.execute(
"CREATE TABLE ingest_jobs (ingest_job_id BIGSERIAL PRIMARY KEY, obj_id BIGINT NOT NULL, host_name TEXT NOT NULL, start_date_time BIGINT NOT NULL, end_date_time BIGINT NOT NULL, status_id INTEGER NOT NULL, settings_dir TEXT, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(status_id) REFERENCES ingest_job_status_types(type_id));");
1345 statement.execute(
"CREATE TABLE ingest_job_modules (ingest_job_id INTEGER, ingest_module_id INTEGER, pipeline_position INTEGER, PRIMARY KEY(ingest_job_id, ingest_module_id), FOREIGN KEY(ingest_job_id) REFERENCES ingest_jobs(ingest_job_id), FOREIGN KEY(ingest_module_id) REFERENCES ingest_modules(ingest_module_id));");
1346 initIngestModuleTypes(connection);
1347 initIngestStatusTypes(connection);
1349 return new CaseDbSchemaVersionNumber(4, 0);
1352 closeResultSet(queryResultSet);
1353 closeStatement(queryStatement);
1354 closeStatement(updateStatement);
1355 closeResultSet(resultSet);
1356 closeStatement(statement);
1374 private CaseDbSchemaVersionNumber updateFromSchema4toSchema5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1375 if (schemaVersion.getMajor() != 4) {
1376 return schemaVersion;
1379 Statement statement = null;
1383 statement = connection.createStatement();
1384 statement.execute(
"CREATE TABLE review_statuses (review_status_id INTEGER PRIMARY KEY, review_status_name TEXT NOT NULL, display_name TEXT NOT NULL)");
1394 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
1397 statement.execute(
"CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL);");
1398 initEncodingTypes(connection);
1405 initReviewStatuses(connection);
1410 statement.execute(
"ALTER TABLE tsk_files_path ADD COLUMN encoding_type INTEGER NOT NULL DEFAULT 0;");
1412 return new CaseDbSchemaVersionNumber(5, 0);
1415 closeStatement(statement);
1433 private CaseDbSchemaVersionNumber updateFromSchema5toSchema6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1434 if (schemaVersion.getMajor() != 5) {
1435 return schemaVersion;
1442 Statement statement = null;
1443 ResultSet resultSet = null;
1449 statement = connection.createStatement();
1450 statement.execute(
"CREATE TABLE IF NOT EXISTS review_statuses (review_status_id INTEGER PRIMARY KEY, review_status_name TEXT NOT NULL, display_name TEXT NOT NULL)");
1452 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) AS count FROM review_statuses");
1454 if (resultSet.getLong(
"count") == 0) {
1463 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
1466 return new CaseDbSchemaVersionNumber(6, 0);
1469 closeResultSet(resultSet);
1470 closeStatement(statement);
1488 private CaseDbSchemaVersionNumber updateFromSchema6toSchema7(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1489 if (schemaVersion.getMajor() != 6) {
1490 return schemaVersion;
1496 Statement statement = null;
1497 Statement updstatement = null;
1498 ResultSet resultSet = null;
1501 statement = connection.createStatement();
1502 updstatement = connection.createStatement();
1503 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN extension TEXT");
1505 resultSet = connection.executeQuery(statement,
"SELECT obj_id,name FROM tsk_files");
1506 while (resultSet.next()) {
1507 long objID = resultSet.getLong(
"obj_id");
1508 String name = resultSet.getString(
"name");
1509 updstatement.executeUpdate(
"UPDATE tsk_files SET extension = '" +
escapeSingleQuotes(extractExtension(name)) +
"' "
1510 +
"WHERE obj_id = " + objID);
1513 statement.execute(
"CREATE INDEX file_extension ON tsk_files ( extension )");
1516 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN artifact_obj_id INTEGER NOT NULL DEFAULT -1");
1518 return new CaseDbSchemaVersionNumber(7, 0);
1521 closeResultSet(resultSet);
1522 closeStatement(statement);
1523 closeStatement(updstatement);
1541 private CaseDbSchemaVersionNumber updateFromSchema7toSchema7dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1542 if (schemaVersion.getMajor() != 7) {
1543 return schemaVersion;
1546 if (schemaVersion.getMinor() != 0) {
1547 return schemaVersion;
1553 Statement statement = null;
1554 ResultSet resultSet = null;
1557 statement = connection.createStatement();
1560 if (schemaVersion.getMinor() == 0) {
1562 statement.execute(
"ALTER TABLE tsk_db_info ADD COLUMN schema_minor_ver INTEGER DEFAULT 1");
1564 return new CaseDbSchemaVersionNumber(7, 1);
1567 closeResultSet(resultSet);
1568 closeStatement(statement);
1586 private CaseDbSchemaVersionNumber updateFromSchema7dot1toSchema7dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1587 if (schemaVersion.getMajor() != 7) {
1588 return schemaVersion;
1591 if (schemaVersion.getMinor() != 1) {
1592 return schemaVersion;
1595 Statement statement = null;
1596 Statement updstatement = null;
1597 ResultSet resultSet = null;
1601 statement = connection.createStatement();
1602 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN data_source_obj_id INTEGER NOT NULL DEFAULT -1");
1605 updstatement = connection.createStatement();
1606 resultSet = connection.executeQuery(statement,
"SELECT artifact_id, obj_id FROM blackboard_artifacts");
1607 while (resultSet.next()) {
1608 long artifact_id = resultSet.getLong(
"artifact_id");
1609 long obj_id = resultSet.getLong(
"obj_id");
1610 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
1611 updstatement.executeUpdate(
"UPDATE blackboard_artifacts SET data_source_obj_id = " + data_source_obj_id +
" "
1612 +
"WHERE artifact_id = " + artifact_id);
1614 closeResultSet(resultSet);
1615 closeStatement(statement);
1616 closeStatement(updstatement);
1621 statement = connection.createStatement();
1622 statement.execute(
"ALTER TABLE tag_names ADD COLUMN knownStatus INTEGER NOT NULL DEFAULT " + TskData.FileKnown.UNKNOWN.getFileKnownValue());
1625 if (this.dbType.equals(DbType.SQLITE)) {
1626 statement.execute(
"CREATE TABLE account_types (account_type_id INTEGER PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1627 statement.execute(
"CREATE TABLE accounts (account_id INTEGER PRIMARY KEY, account_type_id INTEGER NOT NULL, account_unique_identifier TEXT NOT NULL, UNIQUE(account_type_id, account_unique_identifier) , FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
1628 statement.execute(
"CREATE TABLE account_relationships (relationship_id INTEGER PRIMARY KEY, account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, relationship_source_obj_id INTEGER NOT NULL, date_time INTEGER, relationship_type INTEGER NOT NULL, data_source_obj_id INTEGER NOT NULL, UNIQUE(account1_id, account2_id, relationship_source_obj_id), FOREIGN KEY(account1_id) REFERENCES accounts(account_id), FOREIGN KEY(account2_id) REFERENCES accounts(account_id), FOREIGN KEY(relationship_source_obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id))");
1630 statement.execute(
"CREATE TABLE account_types (account_type_id BIGSERIAL PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1631 statement.execute(
"CREATE TABLE accounts (account_id BIGSERIAL PRIMARY KEY, account_type_id INTEGER NOT NULL, account_unique_identifier TEXT NOT NULL, UNIQUE(account_type_id, account_unique_identifier) , FOREIGN KEY(account_type_id) REFERENCES account_types(account_type_id))");
1632 statement.execute(
"CREATE TABLE account_relationships (relationship_id BIGSERIAL PRIMARY KEY, account1_id INTEGER NOT NULL, account2_id INTEGER NOT NULL, relationship_source_obj_id INTEGER NOT NULL, date_time BIGINT, relationship_type INTEGER NOT NULL, data_source_obj_id INTEGER NOT NULL, UNIQUE(account1_id, account2_id, relationship_source_obj_id), FOREIGN KEY(account1_id) REFERENCES accounts(account_id), FOREIGN KEY(account2_id) REFERENCES accounts(account_id), FOREIGN KEY(relationship_source_obj_id) REFERENCES tsk_objects(obj_id), FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id))");
1636 statement.execute(
"CREATE INDEX artifact_artifact_objID ON blackboard_artifacts(artifact_obj_id)");
1637 statement.execute(
"CREATE INDEX relationships_account1 ON account_relationships(account1_id)");
1638 statement.execute(
"CREATE INDEX relationships_account2 ON account_relationships(account2_id)");
1639 statement.execute(
"CREATE INDEX relationships_relationship_source_obj_id ON account_relationships(relationship_source_obj_id)");
1640 statement.execute(
"CREATE INDEX relationships_date_time ON account_relationships(date_time)");
1641 statement.execute(
"CREATE INDEX relationships_relationship_type ON account_relationships(relationship_type)");
1642 statement.execute(
"CREATE INDEX relationships_data_source_obj_id ON account_relationships(data_source_obj_id)");
1644 return new CaseDbSchemaVersionNumber(7, 2);
1646 closeResultSet(resultSet);
1647 closeStatement(statement);
1648 closeStatement(updstatement);
1666 private CaseDbSchemaVersionNumber updateFromSchema7dot2toSchema8dot0(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1667 if (schemaVersion.getMajor() != 7) {
1668 return schemaVersion;
1671 if (schemaVersion.getMinor() != 2) {
1672 return schemaVersion;
1675 Statement updateSchemaStatement = connection.createStatement();
1676 Statement getExistingReportsStatement = connection.createStatement();
1677 ResultSet resultSet = null;
1678 ResultSet existingReports = null;
1686 updateSchemaStatement.execute(
"ALTER TABLE reports RENAME TO old_reports");
1689 updateSchemaStatement.execute(
"CREATE TABLE reports (obj_id BIGSERIAL PRIMARY KEY, path TEXT NOT NULL, crtime INTEGER NOT NULL, src_module_name TEXT NOT NULL, report_name TEXT NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id))");
1692 existingReports = getExistingReportsStatement.executeQuery(
"SELECT * FROM old_reports");
1693 while (existingReports.next()) {
1694 String path = existingReports.getString(2);
1695 long crtime = existingReports.getInt(3);
1696 String sourceModule = existingReports.getString(4);
1697 String reportName = existingReports.getString(5);
1699 PreparedStatement insertObjectStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
1700 insertObjectStatement.clearParameters();
1701 insertObjectStatement.setNull(1, java.sql.Types.BIGINT);
1702 insertObjectStatement.setLong(2, TskData.ObjectType.REPORT.getObjectType());
1703 connection.executeUpdate(insertObjectStatement);
1704 resultSet = insertObjectStatement.getGeneratedKeys();
1705 if (!resultSet.next()) {
1706 throw new TskCoreException(String.format(
"Failed to INSERT report %s (%s) in tsk_objects table", reportName, path));
1708 long objectId = resultSet.getLong(1);
1711 PreparedStatement insertReportStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_REPORT);
1712 insertReportStatement.clearParameters();
1713 insertReportStatement.setLong(1, objectId);
1714 insertReportStatement.setString(2, path);
1715 insertReportStatement.setLong(3, crtime);
1716 insertReportStatement.setString(4, sourceModule);
1717 insertReportStatement.setString(5, reportName);
1718 connection.executeUpdate(insertReportStatement);
1722 updateSchemaStatement.execute(
"DROP TABLE old_reports");
1724 return new CaseDbSchemaVersionNumber(8, 0);
1726 closeResultSet(resultSet);
1727 closeResultSet(existingReports);
1728 closeStatement(updateSchemaStatement);
1729 closeStatement(getExistingReportsStatement);
1747 private CaseDbSchemaVersionNumber updateFromSchema8dot0toSchema8dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1748 if (schemaVersion.getMajor() != 8) {
1749 return schemaVersion;
1752 if (schemaVersion.getMinor() != 0) {
1753 return schemaVersion;
1758 try (Statement statement = connection.createStatement();) {
1760 if (this.dbType.equals(DbType.SQLITE)) {
1761 statement.execute(
"CREATE TABLE tsk_examiners (examiner_id INTEGER PRIMARY KEY, login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name) )");
1762 statement.execute(
"ALTER TABLE content_tags ADD COLUMN examiner_id INTEGER REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1763 statement.execute(
"ALTER TABLE blackboard_artifact_tags ADD COLUMN examiner_id INTEGER REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1765 statement.execute(
"CREATE TABLE tsk_examiners (examiner_id BIGSERIAL PRIMARY KEY, login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name))");
1766 statement.execute(
"ALTER TABLE content_tags ADD COLUMN examiner_id BIGINT REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1767 statement.execute(
"ALTER TABLE blackboard_artifact_tags ADD COLUMN examiner_id BIGINT REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1770 return new CaseDbSchemaVersionNumber(8, 1);
1789 private CaseDbSchemaVersionNumber updateFromSchema8dot1toSchema8dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1790 if (schemaVersion.getMajor() != 8) {
1791 return schemaVersion;
1794 if (schemaVersion.getMinor() != 1) {
1795 return schemaVersion;
1800 try (Statement statement = connection.createStatement();) {
1801 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN sha1 TEXT DEFAULT NULL");
1802 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN sha256 TEXT DEFAULT NULL");
1804 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_details TEXT");
1812 statement.execute(
"CREATE TABLE tsk_db_info_extended (name TEXT PRIMARY KEY, value TEXT NOT NULL)");
1813 ResultSet result = statement.executeQuery(
"SELECT tsk_ver FROM tsk_db_info");
1815 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + TSK_VERSION_KEY +
"', '" + result.getLong(
"tsk_ver") +
"')");
1816 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + SCHEMA_MAJOR_VERSION_KEY +
"', '8')");
1817 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + SCHEMA_MINOR_VERSION_KEY +
"', '2')");
1818 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + CREATION_SCHEMA_MAJOR_VERSION_KEY +
"', '0')");
1819 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + CREATION_SCHEMA_MINOR_VERSION_KEY +
"', '0')");
1821 String primaryKeyType;
1824 primaryKeyType =
"BIGSERIAL";
1827 primaryKeyType =
"INTEGER";
1830 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
1834 statement.execute(
"CREATE TABLE tsk_event_types ("
1835 +
" event_type_id " + primaryKeyType +
" PRIMARY KEY, "
1836 +
" display_name TEXT UNIQUE NOT NULL, "
1837 +
" super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
1838 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1839 +
" values( 0, 'Event Types', null)");
1840 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1841 +
" values(1, 'File System', 0)");
1842 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1843 +
" values(2, 'Web Activity', 0)");
1844 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1845 +
" values(3, 'Misc Types', 0)");
1846 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1847 +
" values(4, 'Modified', 1)");
1848 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1849 +
" values(5, 'Accessed', 1)");
1850 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1851 +
" values(6, 'Created', 1)");
1852 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1853 +
" values(7, 'Changed', 1)");
1856 statement.execute(
"CREATE TABLE tsk_event_descriptions ("
1857 +
" event_description_id " + primaryKeyType +
" PRIMARY KEY, "
1858 +
" full_description TEXT NOT NULL, "
1859 +
" med_description TEXT, "
1860 +
" short_description TEXT,"
1861 +
" data_source_obj_id BIGINT NOT NULL, "
1862 +
" file_obj_id BIGINT NOT NULL, "
1863 +
" artifact_id BIGINT, "
1864 +
" hash_hit INTEGER NOT NULL, "
1865 +
" tagged INTEGER NOT NULL, "
1866 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
1867 +
" FOREIGN KEY(file_obj_id) REFERENCES tsk_files(obj_id), "
1868 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
1871 statement.execute(
"CREATE TABLE tsk_events ( "
1872 +
" event_id " + primaryKeyType +
" PRIMARY KEY, "
1873 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
1874 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id) ,"
1875 +
" time INTEGER NOT NULL) "
1879 statement.execute(
"CREATE INDEX events_time ON tsk_events(time)");
1880 statement.execute(
"CREATE INDEX events_type ON tsk_events(event_type_id)");
1881 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
1882 statement.execute(
"CREATE INDEX events_file_obj_id ON tsk_event_descriptions(file_obj_id) ");
1883 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
1884 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
1885 return new CaseDbSchemaVersionNumber(8, 2);
1905 private CaseDbSchemaVersionNumber updateFromSchema8dot2toSchema8dot3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1906 if (schemaVersion.getMajor() != 8) {
1907 return schemaVersion;
1910 if (schemaVersion.getMinor() != 2) {
1911 return schemaVersion;
1916 ResultSet resultSet = null;
1918 try (Statement statement = connection.createStatement();) {
1923 String primaryKeyType;
1926 primaryKeyType =
"BIGSERIAL";
1929 primaryKeyType =
"INTEGER";
1932 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
1936 statement.execute(
"CREATE TABLE IF NOT EXISTS tsk_event_types ("
1937 +
" event_type_id " + primaryKeyType +
" PRIMARY KEY, "
1938 +
" display_name TEXT UNIQUE NOT NULL, "
1939 +
" super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
1941 resultSet = statement.executeQuery(
"SELECT * from tsk_event_types");
1945 if (!resultSet.next()) {
1947 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1948 +
" values( 0, 'Event Types', null)");
1949 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1950 +
" values(1, 'File System', 0)");
1951 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1952 +
" values(2, 'Web Activity', 0)");
1953 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1954 +
" values(3, 'Misc Types', 0)");
1955 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1956 +
" values(4, 'Modified', 1)");
1957 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1958 +
" values(5, 'Accessed', 1)");
1959 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1960 +
" values(6, 'Created', 1)");
1961 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
1962 +
" values(7, 'Changed', 1)");
1967 statement.execute(
"DROP TABLE IF EXISTS tsk_events");
1971 statement.execute(
"DROP TABLE IF EXISTS tsk_event_descriptions");
1974 statement.execute(
"CREATE TABLE tsk_event_descriptions ("
1975 +
" event_description_id " + primaryKeyType +
" PRIMARY KEY, "
1976 +
" full_description TEXT NOT NULL, "
1977 +
" med_description TEXT, "
1978 +
" short_description TEXT,"
1979 +
" data_source_obj_id BIGINT NOT NULL, "
1980 +
" file_obj_id BIGINT NOT NULL, "
1981 +
" artifact_id BIGINT, "
1982 +
" hash_hit INTEGER NOT NULL, "
1983 +
" tagged INTEGER NOT NULL, "
1984 +
" UNIQUE(full_description, file_obj_id, artifact_id), "
1985 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
1986 +
" FOREIGN KEY(file_obj_id) REFERENCES tsk_files(obj_id), "
1987 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
1991 statement.execute(
"CREATE TABLE tsk_events ( "
1992 +
" event_id " + primaryKeyType +
" PRIMARY KEY, "
1993 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
1994 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id) ,"
1995 +
" time INTEGER NOT NULL, "
1996 +
" UNIQUE (event_type_id, event_description_id, time))"
2000 statement.execute(
"UPDATE tsk_db_info_extended SET name = 'CREATION_SCHEMA_MAJOR_VERSION' WHERE name = 'CREATED_SCHEMA_MAJOR_VERSION'");
2001 statement.execute(
"UPDATE tsk_db_info_extended SET name = 'CREATION_SCHEMA_MINOR_VERSION' WHERE name = 'CREATED_SCHEMA_MINOR_VERSION'");
2003 return new CaseDbSchemaVersionNumber(8, 3);
2005 closeResultSet(resultSet);
2031 private CaseDbSchemaVersionNumber updateFromSchema8dot3toSchema8dot4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2032 if (schemaVersion.getMajor() != 8) {
2033 return schemaVersion;
2036 if (schemaVersion.getMinor() != 3) {
2037 return schemaVersion;
2040 Statement statement = connection.createStatement();
2041 ResultSet results = null;
2048 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
2054 results = statement.executeQuery(
"SELECT column_name FROM information_schema.columns "
2055 +
"WHERE table_name='tsk_event_descriptions' and column_name='file_obj_id'");
2056 if (results.next()) {
2058 statement.execute(
"ALTER TABLE tsk_event_descriptions "
2059 +
"RENAME COLUMN file_obj_id TO content_obj_id");
2063 statement.execute(
"CREATE TABLE temp_tsk_events ( "
2064 +
" event_id BIGSERIAL PRIMARY KEY, "
2065 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2066 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id),"
2067 +
" time BIGINT NOT NULL, "
2068 +
" UNIQUE (event_type_id, event_description_id, time))"
2072 statement.execute(
"INSERT INTO temp_tsk_events(event_id, event_type_id, "
2073 +
"event_description_id, time) SELECT * FROM tsk_events");
2076 statement.execute(
"DROP TABLE tsk_events");
2079 statement.execute(
"ALTER TABLE temp_tsk_events RENAME TO tsk_events");
2082 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
2083 statement.execute(
"CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id) ");
2084 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
2085 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
2086 statement.execute(
"CREATE INDEX events_time ON tsk_events(time) ");
2090 boolean hasMisnamedColumn =
false;
2091 results = statement.executeQuery(
"pragma table_info('tsk_event_descriptions')");
2092 while (results.next()) {
2093 if (results.getString(
"name") != null && results.getString(
"name").equals(
"file_obj_id")) {
2094 hasMisnamedColumn =
true;
2099 if (hasMisnamedColumn) {
2101 statement.execute(
"CREATE TABLE temp_tsk_event_descriptions ("
2102 +
" event_description_id INTEGER PRIMARY KEY, "
2103 +
" full_description TEXT NOT NULL, "
2104 +
" med_description TEXT, "
2105 +
" short_description TEXT,"
2106 +
" data_source_obj_id BIGINT NOT NULL, "
2107 +
" content_obj_id BIGINT NOT NULL, "
2108 +
" artifact_id BIGINT, "
2109 +
" hash_hit INTEGER NOT NULL, "
2110 +
" tagged INTEGER NOT NULL, "
2111 +
" UNIQUE(full_description, content_obj_id, artifact_id), "
2112 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
2113 +
" FOREIGN KEY(content_obj_id) REFERENCES tsk_files(obj_id), "
2114 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
2117 statement.execute(
"CREATE TABLE temp_tsk_events ( "
2118 +
" event_id INTEGER PRIMARY KEY, "
2119 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2120 +
" event_description_id BIGINT NOT NULL REFERENCES temp_tsk_event_descriptions(event_description_id),"
2121 +
" time INTEGER NOT NULL, "
2122 +
" UNIQUE (event_type_id, event_description_id, time))"
2126 statement.execute(
"INSERT INTO temp_tsk_event_descriptions(event_description_id, full_description, "
2127 +
"med_description, short_description, data_source_obj_id, content_obj_id, artifact_id, "
2128 +
"hash_hit, tagged) SELECT * FROM tsk_event_descriptions");
2130 statement.execute(
"INSERT INTO temp_tsk_events(event_id, event_type_id, "
2131 +
"event_description_id, time) SELECT * FROM tsk_events");
2134 statement.execute(
"DROP TABLE tsk_events");
2135 statement.execute(
"DROP TABLE tsk_event_descriptions");
2138 statement.execute(
"ALTER TABLE temp_tsk_event_descriptions RENAME TO tsk_event_descriptions");
2139 statement.execute(
"ALTER TABLE temp_tsk_events RENAME TO tsk_events");
2142 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
2143 statement.execute(
"CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id) ");
2144 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
2145 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
2146 statement.execute(
"CREATE INDEX events_time ON tsk_events(time) ");
2150 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
2154 if (this.dbType.equals(DbType.SQLITE)) {
2155 statement.execute(
"CREATE TABLE tsk_pool_info (obj_id INTEGER PRIMARY KEY, pool_type INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
2157 statement.execute(
"CREATE TABLE tsk_pool_info (obj_id BIGSERIAL PRIMARY KEY, pool_type INTEGER NOT NULL, FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE)");
2161 insertAccountTypeIfNotExists(statement,
"IMO",
"IMO");
2162 insertAccountTypeIfNotExists(statement,
"LINE",
"LINE");
2163 insertAccountTypeIfNotExists(statement,
"SKYPE",
"Skype");
2164 insertAccountTypeIfNotExists(statement,
"TANGO",
"Tango");
2165 insertAccountTypeIfNotExists(statement,
"TEXTNOW",
"TextNow");
2166 insertAccountTypeIfNotExists(statement,
"THREEMA",
"ThreeMa");
2167 insertAccountTypeIfNotExists(statement,
"VIBER",
"Viber");
2168 insertAccountTypeIfNotExists(statement,
"XENDER",
"Xender");
2169 insertAccountTypeIfNotExists(statement,
"ZAPYA",
"Zapya");
2170 insertAccountTypeIfNotExists(statement,
"SHAREIT",
"ShareIt");
2172 return new CaseDbSchemaVersionNumber(8, 4);
2174 closeResultSet(results);
2175 closeStatement(statement);
2180 private CaseDbSchemaVersionNumber updateFromSchema8dot4toSchema8dot5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2181 if (schemaVersion.getMajor() != 8) {
2182 return schemaVersion;
2185 if (schemaVersion.getMinor() != 4) {
2186 return schemaVersion;
2189 Statement statement = connection.createStatement();
2194 statement.execute(
"CREATE TABLE tsk_tag_sets (tag_set_id BIGSERIAL PRIMARY KEY, name TEXT UNIQUE)");
2195 statement.execute(
"ALTER TABLE tag_names ADD COLUMN tag_set_id BIGINT REFERENCES tsk_tag_sets(tag_set_id)");
2198 statement.execute(
"CREATE TABLE tsk_tag_sets (tag_set_id INTEGER PRIMARY KEY, name TEXT UNIQUE)");
2199 statement.execute(
"ALTER TABLE tag_names ADD COLUMN tag_set_id INTEGER REFERENCES tsk_tag_sets(tag_set_id)");
2203 statement.execute(
"ALTER TABLE tag_names ADD COLUMN rank INTEGER");
2211 String insertStmt =
"INSERT INTO tsk_tag_sets (name) VALUES ('Project VIC')";
2213 statement.execute(insertStmt, Statement.RETURN_GENERATED_KEYS);
2215 statement.execute(insertStmt);
2217 try (ResultSet resultSet = statement.getGeneratedKeys()) {
2218 if (resultSet != null && resultSet.next()) {
2219 int tagSetId = resultSet.getInt(1);
2221 String updateQuery =
"UPDATE tag_names SET tag_set_id = %d, color = '%s', rank = %d, display_name = '%s' WHERE display_name = '%s'";
2222 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Red", 1,
"Child Exploitation (Illegal)",
"CAT-1: Child Exploitation (Illegal)"));
2223 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Lime", 2,
"Child Exploitation (Non-Illegal/Age Difficult)",
"CAT-2: Child Exploitation (Non-Illegal/Age Difficult)"));
2224 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Yellow", 3,
"CGI/Animation (Child Exploitive)",
"CAT-3: CGI/Animation (Child Exploitive)"));
2225 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Purple", 4,
"Exemplar/Comparison (Internal Use Only)",
"CAT-4: Exemplar/Comparison (Internal Use Only)"));
2226 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Fuchsia", 5,
"Non-pertinent",
"CAT-5: Non-pertinent"));
2228 String
deleteContentTag =
"DELETE FROM content_tags WHERE tag_name_id IN (SELECT tag_name_id from tag_names WHERE display_name LIKE 'CAT-0: Uncategorized')";
2229 String deleteArtifactTag =
"DELETE FROM blackboard_artifact_tags WHERE tag_name_id IN (SELECT tag_name_id from tag_names WHERE display_name LIKE 'CAT-0: Uncategorized')";
2230 String deleteCat0 =
"DELETE FROM tag_names WHERE display_name = 'CAT-0: Uncategorized'";
2231 statement.executeUpdate(deleteContentTag);
2232 statement.executeUpdate(deleteArtifactTag);
2233 statement.executeUpdate(deleteCat0);
2236 throw new TskCoreException(
"Failed to retrieve the default tag_set_id from DB");
2246 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN data_source_obj_id BIGINT NOT NULL DEFAULT -1;");
2249 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN data_source_obj_id INTEGER NOT NULL DEFAULT -1;");
2252 Statement updateStatement = connection.createStatement();
2253 try (ResultSet resultSet = statement.executeQuery(
"SELECT obj_id FROM tsk_fs_info")) {
2254 while (resultSet.next()) {
2255 long fsId = resultSet.getLong(
"obj_id");
2256 long dataSourceId = getDataSourceObjectId(connection, fsId);
2257 updateStatement.executeUpdate(
"UPDATE tsk_fs_info SET data_source_obj_id = " + dataSourceId +
" WHERE obj_id = " + fsId +
";");
2260 closeStatement(updateStatement);
2263 return new CaseDbSchemaVersionNumber(8, 5);
2266 closeStatement(statement);
2271 private CaseDbSchemaVersionNumber updateFromSchema8dot5toSchema8dot6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2272 if (schemaVersion.getMajor() != 8) {
2273 return schemaVersion;
2276 if (schemaVersion.getMinor() != 5) {
2277 return schemaVersion;
2280 Statement statement = connection.createStatement();
2283 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN sha256 TEXT");
2285 return new CaseDbSchemaVersionNumber(8, 6);
2288 closeStatement(statement);
2293 @SuppressWarnings(
"deprecation")
2294 private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema9dot0(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection) throws SQLException, TskCoreException {
2295 if (schemaVersion.getMajor() != 8) {
2296 return schemaVersion;
2299 if (schemaVersion.getMinor() != 6) {
2300 return schemaVersion;
2303 Statement statement = connection.createStatement();
2306 String dateDataType =
"BIGINT";
2307 String bigIntDataType =
"BIGINT";
2308 String blobDataType =
"BYTEA";
2309 String primaryKeyType =
"BIGSERIAL";
2311 if (this.dbType.equals(DbType.SQLITE)) {
2312 dateDataType =
"INTEGER";
2313 bigIntDataType =
"INTEGER";
2314 blobDataType =
"BLOB";
2315 primaryKeyType =
"INTEGER";
2317 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN added_date_time " + dateDataType);
2318 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_settings TEXT");
2319 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_name TEXT");
2320 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_version TEXT");
2325 statement.execute(
"ALTER TABLE blackboard_artifact_types ADD COLUMN category_type INTEGER DEFAULT 0");
2326 String analysisTypeObjIdList
2327 = BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() +
", "
2328 + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() +
", "
2329 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
", "
2330 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() +
", "
2331 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
", "
2332 + BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() +
", "
2333 + BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() +
", "
2334 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() +
", "
2335 + BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED.getTypeID() +
", "
2336 + BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID() +
", "
2337 + BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() +
", "
2338 + BlackboardArtifact.ARTIFACT_TYPE.TSK_VERIFICATION_FAILED.getTypeID() +
", "
2339 + BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE.getTypeID() +
", "
2340 + BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() +
", "
2341 + BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_ACCOUNT_TYPE.getTypeID() +
", "
2342 + BlackboardArtifact.ARTIFACT_TYPE.TSK_YARA_HIT.getTypeID() +
", "
2343 + BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CATEGORIZATION.getTypeID();
2344 statement.execute(
"UPDATE blackboard_artifact_types SET category_type = " + BlackboardArtifact.Category.ANALYSIS_RESULT.getID()
2345 +
" WHERE artifact_type_id IN (" + analysisTypeObjIdList +
")");
2348 statement.execute(
"CREATE TABLE tsk_file_attributes (id " + primaryKeyType +
" PRIMARY KEY, "
2349 +
"obj_id " + bigIntDataType +
" NOT NULL, "
2350 +
"attribute_type_id " + bigIntDataType +
" NOT NULL, "
2351 +
"value_type INTEGER NOT NULL, value_byte " + blobDataType +
", "
2352 +
"value_text TEXT, value_int32 INTEGER, value_int64 " + bigIntDataType +
", value_double NUMERIC(20, 10), "
2353 +
"FOREIGN KEY(obj_id) REFERENCES tsk_files(obj_id) ON DELETE CASCADE, "
2354 +
"FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
2357 statement.execute(
"CREATE TABLE tsk_analysis_results (artifact_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2358 +
"conclusion TEXT, "
2359 +
"significance INTEGER NOT NULL, "
2367 +
"configuration TEXT, justification TEXT, "
2368 +
"ignore_score INTEGER DEFAULT 0 "
2371 statement.execute(
"CREATE TABLE tsk_aggregate_score( obj_id " + bigIntDataType +
" PRIMARY KEY, "
2372 +
"data_source_obj_id " + bigIntDataType +
", "
2373 +
"significance INTEGER NOT NULL, "
2376 +
"UNIQUE (obj_id),"
2377 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2378 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE "
2382 statement.execute(
"CREATE TABLE tsk_persons (id " + primaryKeyType +
" PRIMARY KEY, "
2383 +
"name TEXT NOT NULL, "
2384 +
"UNIQUE(name)) ");
2387 statement.execute(
"CREATE TABLE tsk_hosts (id " + primaryKeyType +
" PRIMARY KEY, "
2388 +
"name TEXT NOT NULL, "
2389 +
"db_status INTEGER DEFAULT 0, "
2390 +
"person_id INTEGER, "
2391 +
"merged_into " + bigIntDataType +
", "
2392 +
"FOREIGN KEY(person_id) REFERENCES tsk_persons(id) ON DELETE SET NULL, "
2393 +
"FOREIGN KEY(merged_into) REFERENCES tsk_hosts(id), "
2394 +
"UNIQUE(name)) ");
2397 statement.execute(
"CREATE TABLE tsk_os_account_realms (id " + primaryKeyType +
" PRIMARY KEY, "
2398 +
"realm_name TEXT DEFAULT NULL, "
2399 +
"realm_addr TEXT DEFAULT NULL, "
2400 +
"realm_signature TEXT NOT NULL, "
2401 +
"scope_host_id " + bigIntDataType +
" DEFAULT NULL, "
2402 +
"scope_confidence INTEGER, "
2403 +
"db_status INTEGER DEFAULT 0, "
2404 +
"merged_into " + bigIntDataType +
" DEFAULT NULL, "
2405 +
"UNIQUE(realm_signature), "
2406 +
"FOREIGN KEY(scope_host_id) REFERENCES tsk_hosts(id),"
2407 +
"FOREIGN KEY(merged_into) REFERENCES tsk_os_account_realms(id) )");
2412 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN host_id INTEGER REFERENCES tsk_hosts(id)");
2413 Statement updateStatement = connection.createStatement();
2414 try (ResultSet resultSet = statement.executeQuery(
"SELECT obj_id, device_id FROM data_source_info")) {
2415 Map<String, Long> hostMap =
new HashMap<>();
2417 while (resultSet.next()) {
2418 long objId = resultSet.getLong(
"obj_id");
2419 String deviceId = resultSet.getString(
"device_id");
2421 if (!hostMap.containsKey(deviceId)) {
2422 String hostName =
"Host " + hostIndex;
2423 updateStatement.execute(
"INSERT INTO tsk_hosts (name, db_status) VALUES ('" + hostName +
"', 0)");
2424 hostMap.put(deviceId, hostIndex);
2427 updateStatement.execute(
"UPDATE data_source_info SET host_id = " + hostMap.get(deviceId) +
" WHERE obj_id = " + objId);
2430 closeStatement(updateStatement);
2433 statement.execute(
"CREATE TABLE tsk_os_accounts (os_account_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2434 +
"login_name TEXT DEFAULT NULL, "
2435 +
"full_name TEXT DEFAULT NULL, "
2436 +
"realm_id " + bigIntDataType +
" NOT NULL, "
2437 +
"addr TEXT DEFAULT NULL, "
2438 +
"signature TEXT NOT NULL, "
2439 +
"status INTEGER, "
2441 +
"created_date " + bigIntDataType +
" DEFAULT NULL, "
2442 +
"db_status INTEGER DEFAULT 0, "
2443 +
"merged_into " + bigIntDataType +
" DEFAULT NULL, "
2444 +
"UNIQUE(signature, realm_id), "
2445 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2446 +
"FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id),"
2447 +
"FOREIGN KEY(merged_into) REFERENCES tsk_os_accounts(os_account_obj_id) )");
2449 statement.execute(
"CREATE TABLE tsk_os_account_attributes (id " + primaryKeyType +
" PRIMARY KEY, "
2450 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2451 +
"host_id " + bigIntDataType +
", "
2452 +
"source_obj_id " + bigIntDataType +
", "
2453 +
"attribute_type_id " + bigIntDataType +
" NOT NULL, "
2454 +
"value_type INTEGER NOT NULL, "
2455 +
"value_byte " + bigIntDataType +
", "
2456 +
"value_text TEXT, "
2457 +
"value_int32 INTEGER, value_int64 " + bigIntDataType +
", "
2458 +
"value_double NUMERIC(20, 10), "
2459 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), "
2460 +
"FOREIGN KEY(host_id) REFERENCES tsk_hosts(id), "
2461 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL, "
2462 +
"FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
2464 statement.execute(
"CREATE TABLE tsk_os_account_instances (id " + primaryKeyType +
" PRIMARY KEY, "
2465 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2466 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2467 +
"instance_type INTEGER NOT NULL, "
2468 +
"UNIQUE(os_account_obj_id, data_source_obj_id), "
2469 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), "
2470 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE )");
2472 statement.execute(
"CREATE TABLE tsk_data_artifacts ( "
2473 +
"artifact_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2474 +
"os_account_obj_id " + bigIntDataType +
", "
2475 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id)) ");
2478 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN owner_uid TEXT DEFAULT NULL");
2479 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN os_account_obj_id " + bigIntDataType +
" DEFAULT NULL REFERENCES tsk_os_accounts(os_account_obj_id) ");
2482 statement.execute(
"CREATE TABLE tsk_host_addresses (id " + primaryKeyType +
" PRIMARY KEY, "
2483 +
"address_type INTEGER NOT NULL, "
2484 +
"address TEXT NOT NULL, "
2485 +
"UNIQUE(address_type, address)) ");
2487 statement.execute(
"CREATE TABLE tsk_host_address_map (id " + primaryKeyType +
" PRIMARY KEY, "
2488 +
"host_id " + bigIntDataType +
" NOT NULL, "
2489 +
"addr_obj_id " + bigIntDataType +
" NOT NULL, "
2490 +
"source_obj_id " + bigIntDataType +
", "
2491 +
"time " + bigIntDataType +
", "
2492 +
"UNIQUE(host_id, addr_obj_id, time), "
2493 +
"FOREIGN KEY(host_id) REFERENCES tsk_hosts(id) ON DELETE CASCADE, "
2494 +
"FOREIGN KEY(addr_obj_id) REFERENCES tsk_host_addresses(id), "
2495 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL )");
2498 statement.execute(
"CREATE TABLE tsk_host_address_dns_ip_map (id " + primaryKeyType +
" PRIMARY KEY, "
2499 +
"dns_address_id " + bigIntDataType +
" NOT NULL, "
2500 +
"ip_address_id " + bigIntDataType +
" NOT NULL, "
2501 +
"source_obj_id " + bigIntDataType +
", "
2502 +
"time " + bigIntDataType +
", "
2503 +
"UNIQUE(dns_address_id, ip_address_id, time), "
2504 +
"FOREIGN KEY(dns_address_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE, "
2505 +
"FOREIGN KEY(ip_address_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE,"
2506 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL )");
2509 statement.execute(
"CREATE TABLE tsk_host_address_usage (id " + primaryKeyType +
" PRIMARY KEY, "
2510 +
"addr_obj_id " + bigIntDataType +
" NOT NULL, "
2511 +
"obj_id " + bigIntDataType +
" NOT NULL, "
2512 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2513 +
"UNIQUE(addr_obj_id, obj_id), "
2514 +
"FOREIGN KEY(addr_obj_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE, "
2515 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE )");
2517 return new CaseDbSchemaVersionNumber(9, 0);
2520 closeStatement(statement);
2525 private CaseDbSchemaVersionNumber updateFromSchema9dot0toSchema9dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2526 if (schemaVersion.getMajor() != 9) {
2527 return schemaVersion;
2530 if (schemaVersion.getMinor() != 0) {
2531 return schemaVersion;
2534 Statement statement = connection.createStatement();
2535 ResultSet results = null;
2543 results = statement.executeQuery(
"SELECT column_name FROM information_schema.columns "
2544 +
"WHERE table_name='tsk_analysis_results' and column_name='method_category'");
2545 if (results.next()) {
2547 statement.execute(
"ALTER TABLE tsk_analysis_results "
2548 +
"DROP COLUMN method_category");
2549 statement.execute(
"ALTER TABLE tsk_aggregate_score "
2550 +
"DROP COLUMN method_category");
2556 boolean hasMisnamedColumn =
false;
2557 results = statement.executeQuery(
"pragma table_info('tsk_analysis_results')");
2558 while (results.next()) {
2559 if (results.getString(
"name") != null && results.getString(
"name").equals(
"method_category")) {
2560 hasMisnamedColumn =
true;
2565 if (hasMisnamedColumn) {
2568 statement.execute(
"CREATE TABLE temp_tsk_analysis_results (artifact_obj_id INTEGER PRIMARY KEY, "
2569 +
"conclusion TEXT, "
2570 +
"significance INTEGER NOT NULL, "
2571 +
"configuration TEXT, justification TEXT, "
2572 +
"ignore_score INTEGER DEFAULT 0 "
2574 statement.execute(
"CREATE TABLE temp_tsk_aggregate_score( obj_id INTEGER PRIMARY KEY, "
2575 +
"data_source_obj_id INTEGER, "
2576 +
"significance INTEGER NOT NULL, "
2577 +
"UNIQUE (obj_id),"
2578 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2579 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE "
2583 statement.execute(
"INSERT INTO temp_tsk_analysis_results(artifact_obj_id, "
2584 +
"conclusion, justification, significance, configuration, ignore_score) "
2585 +
"SELECT artifact_obj_id, conclusion, justification, significance, configuration, ignore_score FROM tsk_analysis_results");
2586 statement.execute(
"INSERT INTO temp_tsk_aggregate_score(obj_id, "
2587 +
"data_source_obj_id, significance) "
2588 +
"SELECT obj_id, data_source_obj_id, significance FROM tsk_aggregate_score");
2591 statement.execute(
"DROP TABLE tsk_analysis_results");
2592 statement.execute(
"DROP TABLE tsk_aggregate_score");
2595 statement.execute(
"ALTER TABLE temp_tsk_analysis_results RENAME TO tsk_analysis_results");
2596 statement.execute(
"ALTER TABLE temp_tsk_aggregate_score RENAME TO tsk_aggregate_score");
2601 throw new TskCoreException(
"Unsupported database type: " +
getDatabaseType().toString());
2605 statement.execute(
"CREATE INDEX tsk_file_attributes_obj_id ON tsk_file_attributes(obj_id)");
2607 statement.execute(
"ALTER TABLE tsk_analysis_results ADD COLUMN priority INTEGER NOT NULL DEFAULT " + Score.Priority.NORMAL.getId());
2608 statement.execute(
"ALTER TABLE tsk_aggregate_score ADD COLUMN priority INTEGER NOT NULL DEFAULT " + Score.Priority.NORMAL.getId());
2610 statement.execute(
"UPDATE blackboard_artifact_types SET category_type = 1 WHERE artifact_type_id = 16");
2612 return new CaseDbSchemaVersionNumber(9, 1);
2614 closeResultSet(results);
2615 closeStatement(statement);
2633 private CaseDbSchemaVersionNumber updateFromSchema9dot1toSchema9dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2634 if (schemaVersion.getMajor() != 9) {
2635 return schemaVersion;
2638 if (schemaVersion.getMinor() != 1) {
2639 return schemaVersion;
2642 Statement updateSchemaStatement = connection.createStatement();
2643 ResultSet results = null;
2647 String bigIntDataType =
"BIGINT";
2648 String primaryKeyType =
"BIGSERIAL";
2650 if (this.dbType.equals(DbType.SQLITE)) {
2651 bigIntDataType =
"INTEGER";
2652 primaryKeyType =
"INTEGER";
2658 updateSchemaStatement.execute(
"ALTER TABLE tsk_os_account_instances RENAME TO old_tsk_os_account_instances");
2661 updateSchemaStatement.execute(
"CREATE TABLE tsk_os_account_instances (id " + primaryKeyType +
" PRIMARY KEY, "
2662 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2663 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2664 +
"instance_type INTEGER NOT NULL, "
2665 +
"UNIQUE(os_account_obj_id, data_source_obj_id, instance_type), "
2666 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE CASCADE, "
2667 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE ) ");
2670 updateSchemaStatement.execute(
"INSERT INTO tsk_os_account_instances(os_account_obj_id, "
2671 +
"data_source_obj_id, instance_type) SELECT os_account_obj_id, data_source_obj_id, instance_type FROM old_tsk_os_account_instances ORDER BY id ASC");
2674 updateSchemaStatement.execute(
"DROP TABLE old_tsk_os_account_instances");
2676 return new CaseDbSchemaVersionNumber(9, 2);
2678 closeResultSet(results);
2679 closeStatement(updateSchemaStatement);
2684 private CaseDbSchemaVersionNumber updateFromSchema9dot2toSchema9dot3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2685 if (schemaVersion.getMajor() != 9) {
2686 return schemaVersion;
2689 if (schemaVersion.getMinor() != 2) {
2690 return schemaVersion;
2693 Statement statement = connection.createStatement();
2697 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN sha1 TEXT");
2700 return new CaseDbSchemaVersionNumber(9, 3);
2703 closeStatement(statement);
2719 private void insertAccountTypeIfNotExists(Statement statement, String type_name, String display_name)
throws TskCoreException, SQLException {
2721 String insertSQL = String.format(
"INTO account_types(type_name, display_name) VALUES ('%s', '%s')", type_name, display_name);
2724 insertSQL =
"INSERT " + insertSQL +
" ON CONFLICT DO NOTHING";
2727 insertSQL =
"INSERT OR IGNORE " + insertSQL;
2730 throw new TskCoreException(
"Unknown DB Type: " +
getDatabaseType().name());
2732 statement.execute(insertSQL);
2742 static String extractExtension(
final String fileName) {
2744 int i = fileName.lastIndexOf(
".");
2746 if ((i > 0) && ((i + 1) < fileName.length())) {
2747 ext = fileName.substring(i + 1);
2758 return ext.toLowerCase();
2782 return CURRENT_DB_SCHEMA_VERSION;
2792 return caseDBSchemaCreationVersion;
2811 return dbBackupPath;
2838 return databaseName;
2858 rwLock.writeLock().lock();
2869 rwLock.writeLock().unlock();
2880 rwLock.readLock().lock();
2891 rwLock.readLock().unlock();
2911 }
catch (Exception ex) {
2912 throw new TskCoreException(
"Failed to open case database at " + dbPath, ex);
2942 return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()), databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDir, info.getDbType());
2943 }
catch (PropertyVetoException exp) {
2945 throw new TskCoreException(exp.getMessage(), exp);
2949 }
catch (Exception exp) {
2951 throw new TskCoreException(exp.getMessage(), exp);
2966 CaseDatabaseFactory factory =
new CaseDatabaseFactory(dbPath);
2967 factory.createCaseDatabase();
2971 }
catch (Exception ex) {
2972 throw new TskCoreException(
"Failed to create case database at " + dbPath, ex);
2992 String databaseName = createCaseDataBaseName(caseName);
3006 CaseDatabaseFactory factory =
new CaseDatabaseFactory(databaseName, info);
3007 factory.createCaseDatabase();
3010 return new SleuthkitCase(info.getHost(), Integer.parseInt(info.getPort()),
3011 databaseName, info.getUserName(), info.getPassword(), caseHandle, caseDirPath, info.getDbType());
3012 }
catch (PropertyVetoException exp) {
3014 throw new TskCoreException(exp.getMessage(), exp);
3015 }
catch (Exception exp) {
3017 throw new TskCoreException(exp.getMessage(), exp);
3030 private static String createCaseDataBaseName(String candidateDbName) {
3032 if (!candidateDbName.isEmpty()) {
3036 dbName = candidateDbName.replaceAll(
"[^\\p{ASCII}]",
"_");
3041 dbName = dbName.replaceAll(
"[\\p{Cntrl}]",
"_");
3046 dbName = dbName.replaceAll(
"[ /?:'\"\\\\]",
"_");
3051 dbName = dbName.toLowerCase();
3057 if ((dbName.length() > 0 && !(Character.isLetter(dbName.codePointAt(0))) && !(dbName.codePointAt(0) ==
'_'))) {
3058 dbName =
"_" + dbName;
3065 if (dbName.length() > MAX_DB_NAME_LEN_BEFORE_TIMESTAMP) {
3066 dbName = dbName.substring(0, MAX_DB_NAME_LEN_BEFORE_TIMESTAMP);
3078 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
3079 Date date =
new Date();
3080 dbName = dbName +
"_" + dateFormat.format(date);
3092 timelineEventsDisabled.set(
true);
3105 if (cachedCurrentExaminer != null) {
3106 return cachedCurrentExaminer;
3108 String loginName = System.getProperty(
"user.name");
3109 if (loginName == null || loginName.isEmpty()) {
3110 throw new TskCoreException(
"Failed to determine logged in user name.");
3113 ResultSet resultSet = null;
3114 CaseDbConnection connection = null;
3117 connection = connections.getConnection();
3118 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_EXAMINER_BY_LOGIN_NAME);
3119 statement.clearParameters();
3120 statement.setString(1, loginName);
3121 resultSet = connection.executeQuery(statement);
3122 if (resultSet.next()) {
3123 cachedCurrentExaminer =
new Examiner(resultSet.getLong(
"examiner_id"), resultSet.getString(
"login_name"), resultSet.getString(
"display_name"));
3124 return cachedCurrentExaminer;
3126 throw new TskCoreException(
"Error getting examaminer for name = " + loginName);
3129 }
catch (SQLException ex) {
3130 throw new TskCoreException(
"Error getting examaminer for name = " + loginName, ex);
3132 closeResultSet(resultSet);
3133 closeConnection(connection);
3148 Examiner getExaminerById(
long id)
throws TskCoreException {
3150 CaseDbConnection connection = null;
3151 ResultSet resultSet = null;
3154 connection = connections.getConnection();
3155 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_EXAMINER_BY_ID);
3156 statement.clearParameters();
3157 statement.setLong(1,
id);
3158 resultSet = connection.executeQuery(statement);
3159 if (resultSet.next()) {
3160 return new Examiner(resultSet.getLong(
"examiner_id"), resultSet.getString(
"login_name"), resultSet.getString(
"full_name"));
3162 throw new TskCoreException(
"Error getting examaminer for id = " +
id);
3164 }
catch (SQLException ex) {
3165 throw new TskCoreException(
"Error getting examaminer for id = " +
id, ex);
3167 closeResultSet(resultSet);
3168 closeConnection(connection);
3191 return this.caseHandle.initAddImageProcess(timeZone, addUnallocSpace, noFatFsOrphans, imageCopyPath,
this);
3203 CaseDbConnection connection = null;
3205 ResultSet rs = null;
3208 connection = connections.getConnection();
3209 s = connection.createStatement();
3210 rs = connection.executeQuery(s,
"SELECT obj_id, type FROM tsk_objects "
3211 +
"WHERE par_obj_id IS NULL");
3212 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
3214 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"),
ObjectType.
valueOf(rs.getShort(
"type"))));
3217 List<Content> rootObjs =
new ArrayList<Content>();
3218 for (ObjectInfo i : infos) {
3219 if (null != i.type) {
3230 throw new TskCoreException(
"Parentless object has wrong type to be a root (ABSTRACTFILE, but not VIRTUAL_DIRECTORY: " + i.type);
3242 throw new TskCoreException(
"Parentless object has wrong type to be a root: " + i.type);
3247 }
catch (SQLException ex) {
3248 throw new TskCoreException(
"Error getting root objects", ex);
3252 closeConnection(connection);
3268 List<Long> getDataSourceObjIds(String deviceId)
throws TskCoreException {
3271 synchronized (deviceIdToDatasourceObjIdMap) {
3272 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
3273 return new ArrayList<Long>(deviceIdToDatasourceObjIdMap.get(deviceId));
3276 CaseDbConnection connection = null;
3278 ResultSet rs = null;
3281 connection = connections.getConnection();
3282 s = connection.createStatement();
3283 rs = connection.executeQuery(s,
"SELECT obj_id FROM data_source_info WHERE device_id = '" + deviceId +
"'");
3284 List<Long> dataSourceObjIds =
new ArrayList<Long>();
3286 dataSourceObjIds.add(rs.getLong(
"obj_id"));
3289 long ds_obj_id = rs.getLong(
"obj_id");
3290 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
3291 deviceIdToDatasourceObjIdMap.get(deviceId).add(ds_obj_id);
3293 deviceIdToDatasourceObjIdMap.put(deviceId,
new HashSet<Long>(Arrays.asList(ds_obj_id)));
3296 return dataSourceObjIds;
3297 }
catch (SQLException ex) {
3298 throw new TskCoreException(
"Error getting data sources", ex);
3302 closeConnection(connection);
3325 CaseDbConnection connection = null;
3326 Statement statement = null;
3327 ResultSet resultSet = null;
3328 Statement statement2 = null;
3329 ResultSet resultSet2 = null;
3332 connection = connections.getConnection();
3333 statement = connection.createStatement();
3334 statement2 = connection.createStatement();
3335 resultSet = connection.executeQuery(statement,
3336 "SELECT ds.obj_id, ds.device_id, ds.time_zone, img.type, img.ssize, img.size, img.md5, img.sha1, img.sha256, img.display_name "
3337 +
"FROM data_source_info AS ds "
3338 +
"LEFT JOIN tsk_image_info AS img "
3339 +
"ON ds.obj_id = img.obj_id");
3341 List<DataSource> dataSourceList =
new ArrayList<DataSource>();
3344 while (resultSet.next()) {
3346 Long objectId = resultSet.getLong(
"obj_id");
3347 String deviceId = resultSet.getString(
"device_id");
3348 String timezone = resultSet.getString(
"time_zone");
3349 String type = resultSet.getString(
"type");
3357 resultSet2 = connection.executeQuery(statement2,
"SELECT name FROM tsk_files WHERE tsk_files.obj_id = " + objectId);
3358 String dsName = (resultSet2.next()) ? resultSet2.getString(
"name") :
"";
3366 String parentPath =
"/";
3367 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, dsName, dirType, metaType, dirFlag, metaFlags, timezone, null, null, null,
FileKnown.
UNKNOWN, parentPath);
3372 Long ssize = resultSet.getLong(
"ssize");
3373 Long size = resultSet.getLong(
"size");
3374 String md5 = resultSet.getString(
"md5");
3375 String sha1 = resultSet.getString(
"sha1");
3376 String sha256 = resultSet.getString(
"sha256");
3377 String name = resultSet.getString(
"display_name");
3379 List<String> imagePaths = imagePathsMap.get(objectId);
3381 if (imagePaths.size() > 0) {
3382 String path = imagePaths.get(0);
3383 name = (
new java.io.File(path)).getName();
3389 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name,
3390 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, size);
3393 dataSourceList.add(dataSource);
3396 return dataSourceList;
3398 }
catch (SQLException ex) {
3399 throw new TskCoreException(
"Error getting data sources", ex);
3401 closeResultSet(resultSet);
3402 closeStatement(statement);
3403 closeResultSet(resultSet2);
3404 closeStatement(statement2);
3405 closeConnection(connection);
3431 CaseDbConnection connection = null;
3432 Statement statement = null;
3433 ResultSet resultSet = null;
3434 Statement statement2 = null;
3435 ResultSet resultSet2 = null;
3438 connection = connections.getConnection();
3439 statement = connection.createStatement();
3440 statement2 = connection.createStatement();
3441 resultSet = connection.executeQuery(statement,
3442 "SELECT ds.device_id, ds.time_zone, img.type, img.ssize, img.size, img.md5, img.sha1, img.sha256, img.display_name "
3443 +
"FROM data_source_info AS ds "
3444 +
"LEFT JOIN tsk_image_info AS img "
3445 +
"ON ds.obj_id = img.obj_id "
3446 +
"WHERE ds.obj_id = " + objectId);
3447 if (resultSet.next()) {
3448 String deviceId = resultSet.getString(
"device_id");
3449 String timezone = resultSet.getString(
"time_zone");
3450 String type = resultSet.getString(
"type");
3458 resultSet2 = connection.executeQuery(statement2,
"SELECT name FROM tsk_files WHERE tsk_files.obj_id = " + objectId);
3459 String dsName = (resultSet2.next()) ? resultSet2.getString(
"name") :
"";
3466 String parentPath =
"/";
3467 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, dsName, dirType, metaType, dirFlag, metaFlags, timezone, null, null, null,
FileKnown.
UNKNOWN, parentPath);
3472 Long ssize = resultSet.getLong(
"ssize");
3473 Long size = resultSet.getLong(
"size");
3474 String md5 = resultSet.getString(
"md5");
3475 String sha1 = resultSet.getString(
"sha1");
3476 String sha256 = resultSet.getString(
"sha256");
3477 String name = resultSet.getString(
"display_name");
3479 List<String> imagePaths = getImagePathsById(objectId, connection);
3481 if (imagePaths.size() > 0) {
3482 String path = imagePaths.get(0);
3483 name = (
new java.io.File(path)).getName();
3489 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name,
3490 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, size);
3493 throw new TskDataException(String.format(
"There is no data source with obj_id = %d", objectId));
3495 }
catch (SQLException ex) {
3496 throw new TskCoreException(String.format(
"Error getting data source with obj_id = %d", objectId), ex);
3498 closeResultSet(resultSet);
3499 closeStatement(statement);
3500 closeResultSet(resultSet2);
3501 closeStatement(statement2);
3502 closeConnection(connection);
3523 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3524 artifacts.addAll(blackboard.getArtifactsByType(blackboard.
getArtifactType(artifactTypeID)));
3539 CaseDbConnection connection = null;
3540 ResultSet rs = null;
3543 connection = connections.getConnection();
3546 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_FROM_SOURCE);
3547 statement.clearParameters();
3548 statement.setLong(1, objId);
3549 rs = connection.executeQuery(statement);
3552 count = rs.getLong(
"count");
3555 }
catch (SQLException ex) {
3556 throw new TskCoreException(
"Error getting number of blackboard artifacts by content", ex);
3559 closeConnection(connection);
3575 CaseDbConnection connection = null;
3576 ResultSet rs = null;
3579 connection = connections.getConnection();
3582 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_OF_TYPE);
3583 statement.clearParameters();
3584 statement.setInt(1, artifactTypeID);
3585 rs = connection.executeQuery(statement);
3588 count = rs.getLong(
"count");
3591 }
catch (SQLException ex) {
3592 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
3595 closeConnection(connection);
3612 CaseDbConnection connection = null;
3613 ResultSet rs = null;
3616 connection = connections.getConnection();
3619 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_OF_TYPE_BY_DATA_SOURCE);
3620 statement.clearParameters();
3621 statement.setInt(2, artifactTypeID);
3622 statement.setLong(1, dataSourceID);
3623 rs = connection.executeQuery(statement);
3626 count = rs.getLong(
"count");
3629 }
catch (SQLException ex) {
3630 throw new TskCoreException(String.format(
"Error getting number of blackboard artifacts by type (%d) and data source (%d)", artifactTypeID, dataSourceID), ex);
3633 closeConnection(connection);
3657 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3658 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3659 +
"arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3660 +
"types.type_name AS type_name, types.display_name AS display_name, "
3661 +
" arts.review_status_id AS review_status_id "
3662 +
"FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3663 +
"WHERE arts.artifact_id = attrs.artifact_id "
3664 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3665 +
" AND attrs.value_text = '" + value +
"'"
3666 +
" AND types.artifact_type_id=arts.artifact_type_id"
3669 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3670 List<Long> dataArtifactObjIds =
new ArrayList<>();
3671 while (resultSet.next()) {
3674 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3676 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3680 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3681 if (!analysisArtifactObjIds.isEmpty()) {
3685 if (!dataArtifactObjIds.isEmpty()) {
3689 }
catch (SQLException ex) {
3690 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
3716 String valSubStr =
"%" + subString;
3717 if (startsWith ==
false) {
3722 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3723 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3724 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3725 +
" types.type_name AS type_name, types.display_name AS display_name, "
3726 +
" arts.review_status_id AS review_status_id "
3727 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3728 +
" WHERE arts.artifact_id = attrs.artifact_id "
3729 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3730 +
" AND LOWER(attrs.value_text) LIKE LOWER('" + valSubStr +
"')"
3731 +
" AND types.artifact_type_id=arts.artifact_type_id "
3733 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3734 List<Long> dataArtifactObjIds =
new ArrayList<>();
3735 while (resultSet.next()) {
3738 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3740 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3744 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3745 if (!analysisArtifactObjIds.isEmpty()) {
3749 if (!dataArtifactObjIds.isEmpty()) {
3753 }
catch (SQLException ex) {
3754 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
3778 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3779 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3780 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3781 +
" types.type_name AS type_name, types.display_name AS display_name, "
3782 +
" arts.review_status_id AS review_status_id "
3783 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3784 +
"WHERE arts.artifact_id = attrs.artifact_id "
3785 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3786 +
" AND attrs.value_int32 = " + value
3787 +
" AND types.artifact_type_id=arts.artifact_type_id "
3789 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3790 List<Long> dataArtifactObjIds =
new ArrayList<>();
3791 while (resultSet.next()) {
3794 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3796 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3800 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3801 if (!analysisArtifactObjIds.isEmpty()) {
3805 if (!dataArtifactObjIds.isEmpty()) {
3809 }
catch (SQLException ex) {
3810 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
3835 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3836 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3837 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3838 +
" types.type_name AS type_name, types.display_name AS display_name, "
3839 +
" arts.review_status_id AS review_status_id "
3840 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3841 +
" WHERE arts.artifact_id = attrs.artifact_id "
3842 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3843 +
" AND attrs.value_int64 = " + value
3844 +
" AND types.artifact_type_id=arts.artifact_type_id "
3846 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3847 List<Long> dataArtifactObjIds =
new ArrayList<>();
3848 while (resultSet.next()) {
3851 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3853 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3857 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3858 if (!analysisArtifactObjIds.isEmpty()) {
3862 if (!dataArtifactObjIds.isEmpty()) {
3866 }
catch (SQLException ex) {
3867 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
3892 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3893 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3894 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3895 +
" types.type_name AS type_name, types.display_name AS display_name, "
3896 +
" arts.review_status_id AS review_status_id "
3897 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3898 +
" WHERE arts.artifact_id = attrs.artifact_id "
3899 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3900 +
" AND attrs.value_double = " + value
3901 +
" AND types.artifact_type_id=arts.artifact_type_id "
3903 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3904 List<Long> dataArtifactObjIds =
new ArrayList<>();
3905 while (resultSet.next()) {
3908 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3910 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3914 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3915 if (!analysisArtifactObjIds.isEmpty()) {
3919 if (!dataArtifactObjIds.isEmpty()) {
3923 }
catch (SQLException ex) {
3924 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
3950 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
3951 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
3952 +
" arts.obj_id AS obj_id, arts.artifact_obj_id AS artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
3953 +
" types.type_name AS type_name, types.display_name AS display_name, "
3954 +
" arts.review_status_id AS review_status_id "
3955 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
3956 +
" WHERE arts.artifact_id = attrs.artifact_id "
3957 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
3958 +
" AND attrs.value_byte = " + value
3959 +
" AND types.artifact_type_id=arts.artifact_type_id "
3961 List<Long> analysisArtifactObjIds =
new ArrayList<>();
3962 List<Long> dataArtifactObjIds =
new ArrayList<>();
3963 while (resultSet.next()) {
3966 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3968 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
3972 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3973 if (!analysisArtifactObjIds.isEmpty()) {
3977 if (!dataArtifactObjIds.isEmpty()) {
3981 }
catch (SQLException ex) {
3982 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
3996 CaseDbConnection connection = null;
3998 ResultSet rs = null;
4001 connection = connections.getConnection();
4002 s = connection.createStatement();
4003 rs = connection.executeQuery(s,
"SELECT artifact_type_id, type_name, display_name, category_type FROM blackboard_artifact_types");
4007 rs.getString(
"type_name"), rs.getString(
"display_name"),
4010 return artifactTypes;
4011 }
catch (SQLException ex) {
4012 throw new TskCoreException(
"Error getting artifact types", ex);
4016 closeConnection(connection);
4030 String typeIdList =
"";
4037 String query =
"SELECT DISTINCT artifact_type_id FROM blackboard_artifacts "
4038 +
"WHERE artifact_type_id IN (" + typeIdList +
")";
4039 CaseDbConnection connection = null;
4041 ResultSet rs = null;
4044 connection = connections.getConnection();
4045 s = connection.createStatement();
4046 rs = connection.executeQuery(s, query);
4052 }
catch (SQLException ex) {
4053 throw new TskCoreException(
"Error getting artifact types in use", ex);
4057 closeConnection(connection);
4073 CaseDbConnection connection = null;
4075 ResultSet rs = null;
4078 connection = connections.getConnection();
4079 s = connection.createStatement();
4080 rs = connection.executeQuery(s,
4081 "SELECT DISTINCT arts.artifact_type_id AS artifact_type_id, "
4082 +
"types.type_name AS type_name, "
4083 +
"types.display_name AS display_name, "
4084 +
"types.category_type AS category_type "
4085 +
"FROM blackboard_artifact_types AS types "
4086 +
"INNER JOIN blackboard_artifacts AS arts "
4087 +
"ON arts.artifact_type_id = types.artifact_type_id");
4091 rs.getString(
"type_name"), rs.getString(
"display_name"),
4094 return uniqueArtifactTypes;
4095 }
catch (SQLException ex) {
4096 throw new TskCoreException(
"Error getting attribute types", ex);
4100 closeConnection(connection);
4113 CaseDbConnection connection = null;
4115 ResultSet rs = null;
4118 connection = connections.getConnection();
4119 s = connection.createStatement();
4120 rs = connection.executeQuery(s,
"SELECT attribute_type_id, type_name, display_name, value_type FROM blackboard_attribute_types");
4126 return attribute_types;
4127 }
catch (SQLException ex) {
4128 throw new TskCoreException(
"Error getting attribute types", ex);
4132 closeConnection(connection);
4149 CaseDbConnection connection = null;
4151 ResultSet rs = null;
4154 connection = connections.getConnection();
4155 s = connection.createStatement();
4156 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM blackboard_attribute_types");
4159 count = rs.getInt(
"count");
4162 }
catch (SQLException ex) {
4163 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
4167 closeConnection(connection);
4184 private long getArtifactsCountHelper(
int artifactTypeID,
long obj_id)
throws TskCoreException {
4185 CaseDbConnection connection = null;
4186 ResultSet rs = null;
4189 connection = connections.getConnection();
4192 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_BY_SOURCE_AND_TYPE);
4193 statement.clearParameters();
4194 statement.setLong(1, obj_id);
4195 statement.setInt(2, artifactTypeID);
4196 rs = connection.executeQuery(statement);
4199 count = rs.getLong(
"count");
4202 }
catch (SQLException ex) {
4203 throw new TskCoreException(
"Error getting blackboard artifact count", ex);
4206 closeConnection(connection);
4224 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4225 artifacts.addAll(blackboard.getArtifactsBySourceId(
getArtifactType(artifactTypeName), obj_id));
4242 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4243 artifacts.addAll(blackboard.getArtifactsBySourceId(blackboard.
getArtifactType(artifactTypeID), obj_id));
4276 int artifactTypeID = this.
getArtifactType(artifactTypeName).getTypeID();
4277 if (artifactTypeID == -1) {
4280 return getArtifactsCountHelper(artifactTypeID, obj_id);
4296 return getArtifactsCountHelper(artifactTypeID, obj_id);
4312 return getArtifactsCountHelper(artifactType.getTypeID(), obj_id);
4327 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4328 artifacts.addAll(blackboard.getArtifactsByType(
getArtifactType(artifactTypeName)));
4344 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4345 artifacts.addAll(blackboard.getArtifactsByType(blackboard.
getArtifactType(artifactType.getTypeID())));
4367 String dataArtifactJoin =
"tsk_data_artifacts AS datarts ON datarts.artifact_obj_id = arts.artifact_obj_id";
4368 String analysisResultJoin =
"tsk_analysis_results AS anresult ON anresult.artifact_obj_id = arts.artifact_obj_id";
4369 String dataArtifactColumns =
", datarts.os_account_obj_id AS os_account_obj_id";
4370 String analysResultColumns =
", anresult.conclusion AS conclusion, anresult.significance AS significance, anresult.priority AS priority, anresult.configuration AS configuration, anresult.justification AS justification ";
4372 String formatQuery =
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4373 +
"arts.obj_id AS obj_id, arts.artifact_obj_id as artifact_obj_id, arts.data_source_obj_id AS data_source_obj_id, arts.artifact_type_id AS artifact_type_id, "
4374 +
"types.type_name AS type_name, types.display_name AS display_name,"
4375 +
"arts.review_status_id AS review_status_id %s "
4376 +
"FROM blackboard_artifacts AS arts "
4377 +
"JOIN blackboard_attributes AS attrs ON arts.artifact_id = attrs.artifact_id "
4378 +
"JOIN blackboard_artifact_types AS types ON types.artifact_type_id = arts.artifact_type_id "
4380 +
"WHERE arts.artifact_id = attrs.artifact_id "
4381 +
"AND attrs.attribute_type_id = %d "
4382 +
" AND arts.artifact_type_id = %d "
4383 +
" AND attrs.value_text = '%s' "
4384 +
" AND types.artifact_type_id=arts.artifact_type_id "
4385 +
" AND arts.review_status_id != %d";
4387 String query = String.format(formatQuery,
4390 attrType.getTypeID(),
4391 artifactType.getTypeID(),
4396 try (CaseDbConnection connection = connections.getConnection(); Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, query)) {
4397 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4400 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
4402 osAccountObjId = null;
4405 artifacts.add(
new DataArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"),
4406 rs.getLong(
"artifact_obj_id"),
4407 rs.getObject(
"data_source_obj_id") != null ? rs.getLong(
"data_source_obj_id") : null,
4408 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
4411 artifacts.add(
new AnalysisResult(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"),
4412 rs.getLong(
"artifact_obj_id"),
4413 rs.getObject(
"data_source_obj_id") != null ? rs.getLong(
"data_source_obj_id") : null,
4414 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
4417 rs.getString(
"conclusion"), rs.getString(
"configuration"), rs.getString(
"justification")));
4421 }
catch (SQLException ex) {
4422 throw new TskCoreException(
"Error getting blackboard artifacts by artifact type and attribute. " + ex.getMessage(), ex);
4440 List<DataArtifact> dataArtifacts = blackboard.
getDataArtifactsWhere(
"artifacts.artifact_id = " + artifactID);
4441 if (!dataArtifacts.isEmpty()) {
4442 return dataArtifacts.get(0);
4445 List<AnalysisResult> analysisResults = blackboard.
getAnalysisResultsWhere(
"artifacts.artifact_id = " + artifactID);
4446 if (!analysisResults.isEmpty()) {
4447 return analysisResults.get(0);
4450 throw new TskCoreException(
"No blackboard artifact with id " + artifactID);
4463 try (CaseDbConnection connection = connections.getConnection();) {
4464 addBlackBoardAttribute(attr, artifactTypeId, connection);
4465 }
catch (SQLException ex) {
4466 throw new TskCoreException(
"Error adding blackboard attribute " + attr.toString(), ex);
4482 CaseDbConnection connection = null;
4485 connection = connections.getConnection();
4486 connection.beginTransaction();
4488 addBlackBoardAttribute(attr, artifactTypeId, connection);
4490 connection.commitTransaction();
4491 }
catch (SQLException ex) {
4492 rollbackTransaction(connection);
4493 throw new TskCoreException(
"Error adding blackboard attributes", ex);
4495 closeConnection(connection);
4500 void addBlackBoardAttribute(
BlackboardAttribute attr,
int artifactTypeId, CaseDbConnection connection)
throws SQLException, TskCoreException {
4501 PreparedStatement statement;
4502 switch (attr.getAttributeType().getValueType()) {
4505 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_STRING_ATTRIBUTE);
4506 statement.clearParameters();
4507 statement.setString(7, attr.getValueString());
4510 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_BYTE_ATTRIBUTE);
4511 statement.clearParameters();
4512 statement.setBytes(7, attr.getValueBytes());
4515 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_INT_ATTRIBUTE);
4516 statement.clearParameters();
4517 statement.setInt(7, attr.getValueInt());
4520 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
4521 statement.clearParameters();
4522 statement.setLong(7, attr.getValueLong());
4525 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_DOUBLE_ATTRIBUTE);
4526 statement.clearParameters();
4527 statement.setDouble(7, attr.getValueDouble());
4530 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
4531 statement.clearParameters();
4532 statement.setLong(7, attr.getValueLong());
4535 throw new TskCoreException(
"Unrecognized artifact attribute value type");
4537 statement.setLong(1, attr.getArtifactID());
4538 statement.setInt(2, artifactTypeId);
4539 statement.setString(3, attr.getSourcesCSV());
4540 statement.setString(4,
"");
4541 statement.setInt(5, attr.getAttributeType().getTypeID());
4542 statement.setLong(6, attr.getAttributeType().getValueType().getType());
4543 connection.executeUpdate(statement);
4546 void addFileAttribute(Attribute attr, CaseDbConnection connection)
throws SQLException, TskCoreException {
4547 PreparedStatement statement;
4548 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE_ATTRIBUTE, Statement.RETURN_GENERATED_KEYS);
4549 statement.clearParameters();
4551 statement.setLong(1, attr.getAttributeParentId());
4552 statement.setInt(2, attr.getAttributeType().getTypeID());
4553 statement.setLong(3, attr.getAttributeType().getValueType().getType());
4555 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE) {
4556 statement.setBytes(4, attr.getValueBytes());
4558 statement.setBytes(4, null);
4561 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING
4562 || attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON) {
4563 statement.setString(5, attr.getValueString());
4565 statement.setString(5, null);
4567 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER) {
4568 statement.setInt(6, attr.getValueInt());
4570 statement.setNull(6, java.sql.Types.INTEGER);
4573 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME
4574 || attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG) {
4575 statement.setLong(7, attr.getValueLong());
4577 statement.setNull(7, java.sql.Types.BIGINT);
4580 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE) {
4581 statement.setDouble(8, attr.getValueDouble());
4583 statement.setNull(8, java.sql.Types.DOUBLE);
4586 connection.executeUpdate(statement);
4587 try (ResultSet resultSet = statement.getGeneratedKeys()) {
4588 if (!resultSet.next()) {
4589 throw new TskCoreException(String.format(
"Failed to insert file attribute "
4590 +
"with id=%d. The expected key was not generated", attr.getId()));
4593 attr.setId(resultSet.getLong(1));
4607 String addSourceToArtifactAttribute(BlackboardAttribute attr, String source)
throws TskCoreException {
4615 if (null == source || source.isEmpty()) {
4616 throw new TskCoreException(
"Attempt to add null or empty source module name to artifact attribute");
4618 CaseDbConnection connection = null;
4620 Statement queryStmt = null;
4621 Statement updateStmt = null;
4622 ResultSet result = null;
4623 String newSources =
"";
4625 connection = connections.getConnection();
4626 connection.beginTransaction();
4627 String valueClause =
"";
4628 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType = attr.getAttributeType().getValueType();
4629 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
4630 switch (valueType) {
4636 valueClause =
" value_int32 = " + attr.getValueInt();
4640 valueClause =
" value_int64 = " + attr.getValueLong();
4643 valueClause =
" value_double = " + attr.getValueDouble();
4646 throw new TskCoreException(String.format(
"Unrecognized value type for attribute %s", attr.getDisplayString()));
4648 String query =
"SELECT source FROM blackboard_attributes WHERE"
4649 +
" artifact_id = " + attr.getArtifactID()
4650 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
4651 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
4652 +
" AND " + valueClause +
";";
4653 queryStmt = connection.createStatement();
4654 updateStmt = connection.createStatement();
4655 result = connection.executeQuery(queryStmt, query);
4662 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ATTR_BY_VALUE_BYTE);
4663 statement.clearParameters();
4664 statement.setLong(1, attr.getArtifactID());
4665 statement.setLong(2, attr.getAttributeType().getTypeID());
4666 statement.setBytes(3, attr.getValueBytes());
4667 result = connection.executeQuery(statement);
4669 while (result.next()) {
4670 String oldSources = result.getString(
"source");
4671 if (null != oldSources && !oldSources.isEmpty()) {
4672 Set<String> uniqueSources =
new HashSet<String>(Arrays.asList(oldSources.split(
",")));
4673 if (!uniqueSources.contains(source)) {
4674 newSources = oldSources +
"," + source;
4676 newSources = oldSources;
4679 newSources = source;
4681 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
4682 String update =
"UPDATE blackboard_attributes SET source = '" + newSources +
"' WHERE"
4683 +
" artifact_id = " + attr.getArtifactID()
4684 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
4685 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
4686 +
" AND " + valueClause +
";";
4687 connection.executeUpdate(updateStmt, update);
4694 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.UPDATE_ATTR_BY_VALUE_BYTE);
4695 statement.clearParameters();
4696 statement.setString(1, newSources);
4697 statement.setLong(2, attr.getArtifactID());
4698 statement.setLong(3, attr.getAttributeType().getTypeID());
4699 statement.setBytes(4, attr.getValueBytes());
4700 connection.executeUpdate(statement);
4703 connection.commitTransaction();
4705 }
catch (SQLException ex) {
4706 rollbackTransaction(connection);
4707 throw new TskCoreException(String.format(
"Error adding source module to attribute %s", attr.getDisplayString()), ex);
4709 closeResultSet(result);
4710 closeStatement(updateStmt);
4711 closeStatement(queryStmt);
4712 closeConnection(connection);
4736 throw new TskCoreException(
"Error adding artifact type: " + attrTypeString, ex);
4812 }
catch (BlackboardException ex) {
4813 throw new TskCoreException(
"Error getting or adding artifact type with name: " + artifactTypeName, ex);
4847 CaseDbConnection connection = null;
4849 ResultSet rs = null;
4852 connection = connections.getConnection();
4853 s = connection.createStatement();
4854 rs = connection.executeQuery(s,
"SELECT blackboard_attributes.artifact_id AS artifact_id, "
4855 +
"blackboard_attributes.source AS source, blackboard_attributes.context AS context, "
4856 +
"blackboard_attributes.attribute_type_id AS attribute_type_id, "
4857 +
"blackboard_attributes.value_type AS value_type, blackboard_attributes.value_byte AS value_byte, "
4858 +
"blackboard_attributes.value_text AS value_text, blackboard_attributes.value_int32 AS value_int32, "
4859 +
"blackboard_attributes.value_int64 AS value_int64, blackboard_attributes.value_double AS value_double "
4860 +
"FROM blackboard_attributes " + whereClause);
4861 ArrayList<BlackboardAttribute> matches =
new ArrayList<>();
4867 rs.getLong(
"artifact_id"),
4869 rs.getString(
"source"),
4870 rs.getString(
"context"),
4871 rs.getInt(
"value_int32"),
4872 rs.getLong(
"value_int64"),
4873 rs.getDouble(
"value_double"),
4874 rs.getString(
"value_text"),
4875 rs.getBytes(
"value_byte"), this
4880 }
catch (SQLException ex) {
4881 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
4885 closeConnection(connection);
4902 String query =
"SELECT blackboard_artifacts.artifact_id AS artifact_id, "
4903 +
"blackboard_artifacts.obj_id AS obj_id, blackboard_artifacts.artifact_obj_id AS artifact_obj_id, blackboard_artifacts.data_source_obj_id AS data_source_obj_id, blackboard_artifacts.artifact_type_id AS artifact_type_id, "
4904 +
"blackboard_artifacts.review_status_id AS review_status_id "
4905 +
"FROM blackboard_artifacts " + whereClause;
4907 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) {
4909 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4910 List<Long> dataArtifactObjIds =
new ArrayList<>();
4911 while (resultSet.next()) {
4914 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4916 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4920 ArrayList<BlackboardArtifact> matches =
new ArrayList<>();
4921 if (!analysisArtifactObjIds.isEmpty()) {
4925 if (!dataArtifactObjIds.isEmpty()) {
4930 }
catch (SQLException ex) {
4931 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
4955 throw new TskCoreException(
"Unknown artifact type for id: " + artifactTypeID);
4958 Category category = type.getCategory();
4959 if (category == null) {
4960 throw new TskCoreException(String.format(
"No category for %s (id: %d)",
4961 type.getDisplayName() == null ?
"<null>" : type.getDisplayName(),
4966 if (content == null) {
4967 throw new TskCoreException(
"No content found for object id: " + obj_id);
4971 case ANALYSIS_RESULT:
4973 .getAnalysisResult();
4977 throw new TskCoreException(
"Unknown category type: " + category.
getName());
4994 @SuppressWarnings(
"deprecation")
5015 @SuppressWarnings(
"deprecation")
5018 try (CaseDbConnection connection = connections.getConnection()) {
5019 return newBlackboardArtifact(artifactTypeID, obj_id, type.getTypeName(), type.getDisplayName(), data_source_obj_id, connection);
5024 private BlackboardArtifact
newBlackboardArtifact(
int artifact_type_id,
long obj_id, String artifactTypeName, String artifactDisplayName)
throws TskCoreException {
5025 try (CaseDbConnection connection = connections.getConnection()) {
5026 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
5027 return this.
newBlackboardArtifact(artifact_type_id, obj_id, artifactTypeName, artifactDisplayName, data_source_obj_id, connection);
5031 PreparedStatement createInsertArtifactStatement(
int artifact_type_id,
long obj_id,
long artifact_obj_id,
long data_source_obj_id, CaseDbConnection connection)
throws TskCoreException, SQLException {
5033 PreparedStatement statement;
5035 statement = connection.getPreparedStatement(PREPARED_STATEMENT.POSTGRESQL_INSERT_ARTIFACT, Statement.RETURN_GENERATED_KEYS);
5036 statement.clearParameters();
5037 statement.setLong(1, obj_id);
5038 statement.setLong(2, artifact_obj_id);
5039 statement.setLong(3, data_source_obj_id);
5040 statement.setInt(4, artifact_type_id);
5042 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_ARTIFACT, Statement.RETURN_GENERATED_KEYS);
5043 statement.clearParameters();
5044 this.nextArtifactId++;
5045 statement.setLong(1, this.nextArtifactId);
5046 statement.setLong(2, obj_id);
5047 statement.setLong(3, artifact_obj_id);
5048 statement.setLong(4, data_source_obj_id);
5049 statement.setInt(5, artifact_type_id);
5072 private BlackboardArtifact
newBlackboardArtifact(
int artifact_type_id,
long obj_id, String artifactTypeName, String artifactDisplayName,
long data_source_obj_id, CaseDbConnection connection)
throws TskCoreException {
5075 if (type.getCategory() == BlackboardArtifact.Category.ANALYSIS_RESULT) {
5076 return blackboard.
newAnalysisResult(type, obj_id, data_source_obj_id, Score.SCORE_UNKNOWN, null, null, null, Collections.emptyList()).getAnalysisResult();
5078 return blackboard.
newDataArtifact(type, obj_id, data_source_obj_id, Collections.emptyList(), null);
5080 }
catch (BlackboardException ex) {
5081 throw new TskCoreException(
"Error creating a blackboard artifact", ex);
5103 AnalysisResult newAnalysisResult(BlackboardArtifact.Type artifactType,
long objId, Long dataSourceObjId, Score score, String conclusion, String configuration, String justification, CaseDbConnection connection)
throws TskCoreException {
5105 if (artifactType.getCategory() != BlackboardArtifact.Category.ANALYSIS_RESULT) {
5106 throw new TskCoreException(String.format(
"Artifact type (name = %s) is not of the AnalysisResult category. ", artifactType.getTypeName()));
5113 long artifactObjId = addObject(objId, TskData.ObjectType.ARTIFACT.getObjectType(), connection);
5116 PreparedStatement insertArtifactstatement;
5117 ResultSet resultSet = null;
5119 insertArtifactstatement = createInsertArtifactStatement(artifactType.getTypeID(), objId, artifactObjId, dataSourceObjId, connection);
5120 connection.executeUpdate(insertArtifactstatement);
5121 resultSet = insertArtifactstatement.getGeneratedKeys();
5123 artifactID = resultSet.getLong(1);
5126 if (score.getSignificance() != Score.Significance.UNKNOWN
5127 || !StringUtils.isBlank(conclusion)
5128 || !StringUtils.isBlank(configuration)
5129 || !StringUtils.isBlank(justification)) {
5131 PreparedStatement analysisResultsStatement;
5133 analysisResultsStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_ANALYSIS_RESULT);
5134 analysisResultsStatement.clearParameters();
5136 analysisResultsStatement.setLong(1, artifactObjId);
5137 analysisResultsStatement.setString(2, (conclusion != null) ? conclusion :
"");
5138 analysisResultsStatement.setInt(3, score.getSignificance().getId());
5139 analysisResultsStatement.setInt(4, score.getPriority().getId());
5140 analysisResultsStatement.setString(5, (configuration != null) ? configuration :
"");
5141 analysisResultsStatement.setString(6, (justification != null) ? justification :
"");
5143 connection.executeUpdate(analysisResultsStatement);
5146 return new AnalysisResult(
this, artifactID, objId, artifactObjId, dataSourceObjId, artifactType.getTypeID(),
5147 artifactType.getTypeName(), artifactType.getDisplayName(),
5148 BlackboardArtifact.ReviewStatus.UNDECIDED,
true,
5149 score, (conclusion != null) ? conclusion :
"",
5150 (configuration != null) ? configuration :
"", (justification != null) ? justification :
"");
5153 closeResultSet(resultSet);
5156 }
catch (SQLException ex) {
5157 throw new TskCoreException(
"Error creating a analysis result", ex);
5175 boolean getContentHasChildren(Content content)
throws TskCoreException {
5176 CaseDbConnection connection = null;
5177 ResultSet rs = null;
5180 connection = connections.getConnection();
5183 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_CHILD_OBJECTS_BY_PARENT);
5184 statement.clearParameters();
5185 statement.setLong(1, content.getId());
5186 rs = connection.executeQuery(statement);
5187 boolean hasChildren =
false;
5189 hasChildren = rs.getInt(
"count") > 0;
5192 }
catch (SQLException e) {
5193 throw new TskCoreException(
"Error checking for children of parent " + content, e);
5196 closeConnection(connection);
5213 int getContentChildrenCount(Content content)
throws TskCoreException {
5215 if (!this.getHasChildren(content)) {
5219 CaseDbConnection connection = null;
5220 ResultSet rs = null;
5223 connection = connections.getConnection();
5226 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_CHILD_OBJECTS_BY_PARENT);
5227 statement.clearParameters();
5228 statement.setLong(1, content.getId());
5229 rs = connection.executeQuery(statement);
5230 int countChildren = -1;
5232 countChildren = rs.getInt(
"count");
5234 return countChildren;
5235 }
catch (SQLException e) {
5236 throw new TskCoreException(
"Error checking for children of parent " + content, e);
5239 closeConnection(connection);
5255 List<Content> getAbstractFileChildren(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
5256 CaseDbConnection connection = null;
5257 ResultSet rs = null;
5260 connection = connections.getConnection();
5262 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_PARENT_AND_TYPE);
5263 statement.clearParameters();
5264 long parentId = parent.getId();
5265 statement.setLong(1, parentId);
5266 statement.setShort(2, type.getFileType());
5267 rs = connection.executeQuery(statement);
5268 return fileChildren(rs, connection, parentId);
5269 }
catch (SQLException ex) {
5270 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5273 closeConnection(connection);
5287 List<Content> getAbstractFileChildren(Content parent)
throws TskCoreException {
5288 CaseDbConnection connection = null;
5289 ResultSet rs = null;
5292 connection = connections.getConnection();
5294 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_PARENT);
5295 statement.clearParameters();
5296 long parentId = parent.getId();
5297 statement.setLong(1, parentId);
5298 rs = connection.executeQuery(statement);
5299 return fileChildren(rs, connection, parentId);
5300 }
catch (SQLException ex) {
5301 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5304 closeConnection(connection);
5320 List<Long> getAbstractFileChildrenIds(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
5321 CaseDbConnection connection = null;
5322 ResultSet rs = null;
5325 connection = connections.getConnection();
5327 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_IDS_BY_PARENT_AND_TYPE);
5328 statement.clearParameters();
5329 statement.setLong(1, parent.getId());
5330 statement.setShort(2, type.getFileType());
5331 rs = connection.executeQuery(statement);
5332 List<Long> children =
new ArrayList<Long>();
5334 children.add(rs.getLong(
"obj_id"));
5337 }
catch (SQLException ex) {
5338 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5341 closeConnection(connection);
5355 List<Long> getAbstractFileChildrenIds(Content parent)
throws TskCoreException {
5356 CaseDbConnection connection = null;
5357 ResultSet rs = null;
5360 connection = connections.getConnection();
5362 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_IDS_BY_PARENT);
5363 statement.clearParameters();
5364 statement.setLong(1, parent.getId());
5365 rs = connection.executeQuery(statement);
5366 List<Long> children =
new ArrayList<Long>();
5368 children.add(rs.getLong(
"obj_id"));
5371 }
catch (SQLException ex) {
5372 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5375 closeConnection(connection);
5390 List<Long> getBlackboardArtifactChildrenIds(Content parent)
throws TskCoreException {
5391 CaseDbConnection connection = null;
5392 ResultSet rs = null;
5395 connection = connections.getConnection();
5397 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_OBJECTIDS_BY_PARENT);
5398 statement.clearParameters();
5399 statement.setLong(1, parent.getId());
5400 rs = connection.executeQuery(statement);
5401 List<Long> children =
new ArrayList<Long>();
5403 children.add(rs.getLong(
"obj_id"));
5406 }
catch (SQLException ex) {
5407 throw new TskCoreException(
"Error getting children for BlackboardArtifact", ex);
5410 closeConnection(connection);
5424 List<Content> getBlackboardArtifactChildren(Content parent)
throws TskCoreException {
5425 long parentId = parent.getId();
5426 List<Content> lc =
new ArrayList<>();
5428 lc.addAll(blackboard.getDataArtifactsBySource(parentId));
5440 Collection<ObjectInfo> getChildrenInfo(Content c)
throws TskCoreException {
5441 CaseDbConnection connection = null;
5443 ResultSet rs = null;
5446 connection = connections.getConnection();
5447 s = connection.createStatement();
5448 rs = connection.executeQuery(s,
"SELECT tsk_objects.obj_id AS obj_id, tsk_objects.type AS type "
5449 +
"FROM tsk_objects LEFT JOIN tsk_files "
5450 +
"ON tsk_objects.obj_id = tsk_files.obj_id "
5451 +
"WHERE tsk_objects.par_obj_id = " + c.getId()
5452 +
" ORDER BY tsk_objects.obj_id");
5453 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
5455 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type"))));
5458 }
catch (SQLException ex) {
5459 throw new TskCoreException(
"Error getting Children Info for Content", ex);
5463 closeConnection(connection);
5478 ObjectInfo getParentInfo(Content c)
throws TskCoreException {
5479 return getParentInfo(c.getId());
5492 ObjectInfo getParentInfo(
long contentId)
throws TskCoreException {
5494 CaseDbConnection connection = null;
5496 ResultSet rs = null;
5498 connection = connections.getConnection();
5499 s = connection.createStatement();
5500 rs = connection.executeQuery(s,
"SELECT parent.obj_id AS obj_id, parent.type AS type "
5501 +
"FROM tsk_objects AS parent INNER JOIN tsk_objects AS child "
5502 +
"ON child.par_obj_id = parent.obj_id "
5503 +
"WHERE child.obj_id = " + contentId);
5505 return new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type")));
5509 }
catch (SQLException ex) {
5510 throw new TskCoreException(
"Error getting Parent Info for Content: " + contentId, ex);
5514 closeConnection(connection);
5529 Directory getParentDirectory(FsContent fsc)
throws TskCoreException {
5534 ObjectInfo parentInfo = getParentInfo(fsc);
5535 if (parentInfo == null) {
5538 Directory parent = null;
5539 if (parentInfo.type == ObjectType.ABSTRACTFILE) {
5540 parent = getDirectoryById(parentInfo.id, fsc.getFileSystem());
5542 throw new TskCoreException(
"Parent of FsContent (id: " + fsc.getId() +
") has wrong type to be directory: " + parentInfo.type);
5561 Content content = frequentlyUsedContentMap.get(
id);
5562 if (null != content) {
5569 CaseDbConnection connection = null;
5571 ResultSet rs = null;
5574 connection = connections.getConnection();
5575 s = connection.createStatement();
5576 rs = connection.executeQuery(s,
"SELECT * FROM tsk_objects WHERE obj_id = " +
id +
" LIMIT 1");
5580 parentId = rs.getLong(
"par_obj_id");
5582 }
catch (SQLException ex) {
5583 throw new TskCoreException(
"Error getting Content by ID.", ex);
5587 closeConnection(connection);
5595 frequentlyUsedContentMap.put(
id, content);
5598 content = getVolumeSystemById(
id, parentId);
5601 content = getVolumeById(
id, parentId);
5602 frequentlyUsedContentMap.put(
id, content);
5605 content = getPoolById(
id, parentId);
5608 content = getFileSystemById(
id, parentId);
5609 frequentlyUsedContentMap.put(
id, content);
5620 frequentlyUsedContentMap.put(
id, content);
5649 String getFilePath(
long id) {
5651 String filePath = null;
5652 CaseDbConnection connection = null;
5653 ResultSet rs = null;
5656 connection = connections.getConnection();
5658 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_LOCAL_PATH_FOR_FILE);
5659 statement.clearParameters();
5660 statement.setLong(1,
id);
5661 rs = connection.executeQuery(statement);
5663 filePath = rs.getString(
"path");
5665 }
catch (SQLException | TskCoreException ex) {
5666 logger.log(Level.SEVERE,
"Error getting file path for file " +
id, ex);
5669 closeConnection(connection);
5682 TskData.EncodingType getEncodingType(
long id) {
5684 TskData.EncodingType type = TskData.EncodingType.NONE;
5685 CaseDbConnection connection = null;
5686 ResultSet rs = null;
5689 connection = connections.getConnection();
5690 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ENCODING_FOR_FILE);
5691 statement.clearParameters();
5692 statement.setLong(1,
id);
5693 rs = connection.executeQuery(statement);
5695 type = TskData.EncodingType.valueOf(rs.getInt(1));
5697 }
catch (SQLException | TskCoreException ex) {
5698 logger.log(Level.SEVERE,
"Error getting encoding type for file " +
id, ex);
5701 closeConnection(connection);
5715 String getFileParentPath(
long objectId, CaseDbConnection connection) {
5716 String parentPath = null;
5718 ResultSet rs = null;
5720 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_PATH_FOR_FILE);
5721 statement.clearParameters();
5722 statement.setLong(1, objectId);
5723 rs = connection.executeQuery(statement);
5725 parentPath = rs.getString(
"parent_path");
5727 }
catch (SQLException ex) {
5728 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
5744 String getFileName(
long objectId, CaseDbConnection connection) {
5745 String fileName = null;
5747 ResultSet rs = null;
5749 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_NAME);
5750 statement.clearParameters();
5751 statement.setLong(1, objectId);
5752 rs = connection.executeQuery(statement);
5754 fileName = rs.getString(
"name");
5756 }
catch (SQLException ex) {
5757 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
5775 DerivedFile.DerivedMethod getDerivedMethod(
long id)
throws TskCoreException {
5777 DerivedFile.DerivedMethod method = null;
5778 CaseDbConnection connection = null;
5779 ResultSet rs1 = null;
5780 ResultSet rs2 = null;
5783 connection = connections.getConnection();
5785 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_DERIVED_FILE);
5786 statement.clearParameters();
5787 statement.setLong(1,
id);
5788 rs1 = connection.executeQuery(statement);
5790 int method_id = rs1.getInt(
"derived_id");
5791 String rederive = rs1.getString(
"rederive");
5792 method =
new DerivedFile.DerivedMethod(method_id, rederive);
5793 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_DERIVATION_METHOD);
5794 statement.clearParameters();
5795 statement.setInt(1, method_id);
5796 rs2 = connection.executeQuery(statement);
5798 method.setToolName(rs2.getString(
"tool_name"));
5799 method.setToolVersion(rs2.getString(
"tool_version"));
5800 method.setOther(rs2.getString(
"other"));
5803 }
catch (SQLException e) {
5804 logger.log(Level.SEVERE,
"Error getting derived method for file: " +
id, e);
5806 closeResultSet(rs2);
5807 closeResultSet(rs1);
5808 closeConnection(connection);
5825 CaseDbConnection connection = connections.getConnection();
5829 closeConnection(connection);
5847 ResultSet rs = null;
5849 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_BY_ID);
5850 statement.clearParameters();
5851 statement.setLong(1, objectId);
5852 rs = connection.executeQuery(statement);
5853 List<AbstractFile> files = resultSetToAbstractFiles(rs, connection);
5854 if (files.size() > 0) {
5855 return files.get(0);
5859 }
catch (SQLException ex) {
5860 throw new TskCoreException(
"Error getting file by id, id = " + objectId, ex);
5880 CaseDbConnection connection = null;
5881 ResultSet rs = null;
5884 connection = connections.getConnection();
5887 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_ARTIFACT_TYPE_BY_ARTIFACT_OBJ_ID);
5888 statement.clearParameters();
5889 statement.setLong(1,
id);
5891 rs = connection.executeQuery(statement);
5893 throw new TskCoreException(
"Error getting artifacttype for artifact with artifact_obj_id = " +
id);
5898 switch (artifactType.getCategory()) {
5899 case ANALYSIS_RESULT:
5904 throw new TskCoreException(String.format(
"Unknown artifact category for artifact with artifact_obj_id = %d, and artifact type = %s",
id, artifactType.getTypeName()));
5907 }
catch (SQLException ex) {
5908 throw new TskCoreException(
"Error getting artifacts by artifact_obj_id, artifact_obj_id = " +
id, ex);
5911 closeConnection(connection);
5931 String query =
"SELECT artifact_type_id, artifact_obj_id FROM blackboard_artifacts WHERE artifact_id = " + id;
5934 try (CaseDbConnection connection = connections.getConnection();
5935 Statement statement = connection.createStatement();
5936 ResultSet resultSet = statement.executeQuery(query);) {
5937 if (resultSet != null && resultSet.next()) {
5939 long artifactObjId = resultSet.getLong(
"artifact_obj_id");
5940 switch (artifactType.getCategory()) {
5941 case ANALYSIS_RESULT:
5948 }
catch (SQLException ex) {
5949 throw new TskCoreException(
"Error getting artifacts by artifact id, artifact id = " +
id, ex);
5967 private long getFileSystemId(
long fileId, CaseDbConnection connection) {
5969 ResultSet rs = null;
5972 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_SYSTEM_BY_OBJECT);
5973 statement.clearParameters();
5974 statement.setLong(1, fileId);
5975 rs = connection.executeQuery(statement);
5977 ret = rs.getLong(
"fs_obj_id");
5982 }
catch (SQLException e) {
5983 logger.log(Level.SEVERE,
"Error checking file system id of a file, id = " + fileId, e);
6003 String query = String.format(
"SELECT COUNT(*) AS count FROM tsk_files WHERE obj_id = %d AND data_source_obj_id = %d", fileId, dataSource.getId());
6004 CaseDbConnection connection = null;
6005 Statement statement = null;
6006 ResultSet resultSet = null;
6009 connection = connections.getConnection();
6010 statement = connection.createStatement();
6011 resultSet = connection.executeQuery(statement, query);
6013 return (resultSet.getLong(
"count") > 0L);
6014 }
catch (SQLException ex) {
6015 throw new TskCoreException(String.format(
"Error executing query %s", query), ex);
6017 closeResultSet(resultSet);
6018 closeStatement(statement);
6019 closeConnection(connection);
6033 private static boolean containsLikeWildcard(String str) {
6037 return str.contains(
"%") || str.contains(
"_");
6052 public List<AbstractFile>
findFiles(
Content dataSource, String fileName)
throws TskCoreException {
6054 if (!containsLikeWildcard(fileName)) {
6058 List<AbstractFile> files =
new ArrayList<>();
6059 CaseDbConnection connection = null;
6060 ResultSet resultSet = null;
6063 connection = connections.getConnection();
6065 PreparedStatement statement;
6066 if (ext.isEmpty()) {
6067 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_DATA_SOURCE_AND_NAME);
6068 statement.clearParameters();
6069 statement.setString(1, fileName.toLowerCase());
6070 statement.setLong(2, dataSource.getId());
6072 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_EXTENSION_AND_DATA_SOURCE_AND_NAME);
6073 statement.clearParameters();
6074 statement.setString(1, ext);
6075 statement.setString(2, fileName.toLowerCase());
6076 statement.setLong(3, dataSource.getId());
6079 resultSet = connection.executeQuery(statement);
6080 files.addAll(resultSetToAbstractFiles(resultSet, connection));
6081 }
catch (SQLException e) {
6082 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles.exception.msg3.text"), e);
6084 closeResultSet(resultSet);
6085 closeConnection(connection);
6104 public List<AbstractFile>
findFiles(
Content dataSource, String fileName, String dirSubString)
throws TskCoreException {
6106 if (!containsLikeWildcard(fileName)) {
6110 List<AbstractFile> files =
new ArrayList<>();
6111 CaseDbConnection connection = null;
6112 ResultSet resultSet = null;
6115 connection = connections.getConnection();
6116 PreparedStatement statement;
6117 if (ext.isEmpty()) {
6118 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_DATA_SOURCE_AND_PARENT_PATH_AND_NAME);
6119 statement.clearParameters();
6120 statement.setString(1, fileName.toLowerCase());
6121 statement.setString(2,
"%" + dirSubString.toLowerCase() +
"%");
6122 statement.setLong(3, dataSource.getId());
6124 statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILES_BY_EXTENSION_AND_DATA_SOURCE_AND_PARENT_PATH_AND_NAME);
6125 statement.clearParameters();
6126 statement.setString(1, ext);
6127 statement.setString(2, fileName.toLowerCase());
6128 statement.setString(3,
"%" + dirSubString.toLowerCase() +
"%");
6129 statement.setLong(4, dataSource.getId());
6132 resultSet = connection.executeQuery(statement);
6133 files.addAll(resultSetToAbstractFiles(resultSet, connection));
6134 }
catch (SQLException e) {
6135 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles3.exception.msg3.text"), e);
6137 closeResultSet(resultSet);
6138 closeConnection(connection);
6163 if (null != localTrans) {
6166 }
catch (TskCoreException ex2) {
6167 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
6185 long addObject(
long parentId,
int objectType, CaseDbConnection connection)
throws SQLException {
6186 ResultSet resultSet = null;
6190 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
6191 statement.clearParameters();
6192 if (parentId != 0) {
6193 statement.setLong(1, parentId);
6195 statement.setNull(1, java.sql.Types.BIGINT);
6197 statement.setInt(2, objectType);
6198 connection.executeUpdate(statement);
6199 resultSet = statement.getGeneratedKeys();
6201 if (resultSet.next()) {
6202 if (parentId != 0) {
6203 setHasChildren(parentId);
6205 return resultSet.getLong(1);
6207 throw new SQLException(
"Error inserting object with parent " + parentId +
" into tsk_objects");
6210 closeResultSet(resultSet);
6233 if (transaction == null) {
6234 throw new TskCoreException(
"Passed null CaseDbTransaction");
6237 ResultSet resultSet = null;
6240 CaseDbConnection connection = transaction.getConnection();
6245 if (isRootDirectory((AbstractFile) parent, transaction)) {
6246 if (parent.
getName().isEmpty()) {
6249 parentPath =
"/" + parent.
getName() +
"/";
6252 parentPath = ((AbstractFile) parent).getParentPath() + parent.
getName() +
"/";
6266 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
6267 statement.clearParameters();
6268 statement.setLong(1, newObjId);
6271 Long fileSystemObjectId = null;
6272 if (0 != parentId) {
6273 fileSystemObjectId = this.getFileSystemId(parentId, connection);
6274 if (fileSystemObjectId != -1) {
6275 statement.setLong(2, fileSystemObjectId);
6277 statement.setNull(2, java.sql.Types.BIGINT);
6278 fileSystemObjectId = null;
6281 statement.setNull(2, java.sql.Types.BIGINT);
6285 statement.setString(3, directoryName);
6289 statement.setShort(5, (
short) 1);
6293 statement.setShort(6, dirType.
getValue());
6295 statement.setShort(7, metaType.
getValue());
6299 statement.setShort(8, dirFlag.
getValue());
6302 statement.setShort(9, metaFlags);
6305 statement.setLong(10, 0);
6308 statement.setNull(11, java.sql.Types.BIGINT);
6309 statement.setNull(12, java.sql.Types.BIGINT);
6310 statement.setNull(13, java.sql.Types.BIGINT);
6311 statement.setNull(14, java.sql.Types.BIGINT);
6313 statement.setNull(15, java.sql.Types.VARCHAR);
6314 statement.setNull(16, java.sql.Types.VARCHAR);
6315 statement.setNull(17, java.sql.Types.VARCHAR);
6318 statement.setNull(19, java.sql.Types.VARCHAR);
6321 statement.setString(20, parentPath);
6324 long dataSourceObjectId;
6325 if (0 == parentId) {
6326 dataSourceObjectId = newObjId;
6328 dataSourceObjectId = getDataSourceObjectId(connection, parentId);
6330 statement.setLong(21, dataSourceObjectId);
6333 statement.setString(22, null);
6335 statement.setString(23,
OsAccount.NO_OWNER_ID);
6336 statement.setNull(24, java.sql.Types.BIGINT);
6338 connection.executeUpdate(statement);
6340 return new VirtualDirectory(
this, newObjId, dataSourceObjectId, fileSystemObjectId, directoryName, dirType,
6343 }
catch (SQLException e) {
6344 throw new TskCoreException(
"Error creating virtual directory '" + directoryName +
"'", e);
6346 closeResultSet(resultSet);
6368 }
catch (TskCoreException ex) {
6371 }
catch (TskCoreException ex2) {
6372 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
6396 if (transaction == null) {
6397 throw new TskCoreException(
"Passed null CaseDbTransaction");
6400 ResultSet resultSet = null;
6403 CaseDbConnection connection = transaction.getConnection();
6406 if ((parent == null) || isRootDirectory(parent, transaction)) {
6419 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
6420 statement.clearParameters();
6421 statement.setLong(1, newObjId);
6424 statement.setNull(2, java.sql.Types.BIGINT);
6427 statement.setString(3, directoryName);
6431 statement.setShort(5, (
short) 1);
6435 statement.setShort(6, dirType.
getValue());
6437 statement.setShort(7, metaType.
getValue());
6441 statement.setShort(8, dirFlag.
getValue());
6444 statement.setShort(9, metaFlags);
6447 statement.setLong(10, 0);
6450 statement.setNull(11, java.sql.Types.BIGINT);
6451 statement.setNull(12, java.sql.Types.BIGINT);
6452 statement.setNull(13, java.sql.Types.BIGINT);
6453 statement.setNull(14, java.sql.Types.BIGINT);
6455 statement.setNull(15, java.sql.Types.VARCHAR);
6456 statement.setNull(16, java.sql.Types.VARCHAR);
6457 statement.setNull(17, java.sql.Types.VARCHAR);
6460 statement.setNull(19, java.sql.Types.VARCHAR);
6463 statement.setString(20, parentPath);
6466 long dataSourceObjectId = getDataSourceObjectId(connection, parentId);
6467 statement.setLong(21, dataSourceObjectId);
6470 statement.setString(22, null);
6472 statement.setString(23,
OsAccount.NO_OWNER_ID);
6473 statement.setNull(24, java.sql.Types.BIGINT);
6475 connection.executeUpdate(statement);
6477 return new LocalDirectory(
this, newObjId, dataSourceObjectId, directoryName, dirType,
6480 }
catch (SQLException e) {
6481 throw new TskCoreException(
"Error creating local directory '" + directoryName +
"'", e);
6483 closeResultSet(resultSet);
6532 Statement statement = null;
6534 CaseDbConnection connection = transaction.getConnection();
6547 statement = connection.createStatement();
6548 statement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone, host_id) "
6549 +
"VALUES(" + newObjId +
", '" + deviceId +
"', '" + timeZone +
"', " + host.getHostId() +
");");
6558 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE);
6559 preparedStatement.clearParameters();
6560 preparedStatement.setLong(1, newObjId);
6561 preparedStatement.setNull(2, java.sql.Types.BIGINT);
6562 preparedStatement.setString(3, rootDirectoryName);
6564 preparedStatement.setShort(5, (
short) 1);
6568 preparedStatement.setShort(7, metaType.
getValue());
6570 preparedStatement.setShort(8, dirFlag.
getValue());
6573 preparedStatement.setShort(9, metaFlags);
6574 preparedStatement.setLong(10, 0);
6575 preparedStatement.setNull(11, java.sql.Types.BIGINT);
6576 preparedStatement.setNull(12, java.sql.Types.BIGINT);
6577 preparedStatement.setNull(13, java.sql.Types.BIGINT);
6578 preparedStatement.setNull(14, java.sql.Types.BIGINT);
6579 preparedStatement.setNull(15, java.sql.Types.VARCHAR);
6580 preparedStatement.setNull(16, java.sql.Types.VARCHAR);
6581 preparedStatement.setNull(17, java.sql.Types.VARCHAR);
6583 preparedStatement.setNull(19, java.sql.Types.VARCHAR);
6584 String parentPath =
"/";
6585 preparedStatement.setString(20, parentPath);
6586 preparedStatement.setLong(21, newObjId);
6587 preparedStatement.setString(22, null);
6588 preparedStatement.setString(23,
OsAccount.NO_OWNER_ID);
6589 preparedStatement.setNull(24, java.sql.Types.BIGINT);
6592 connection.executeUpdate(preparedStatement);
6594 return new LocalFilesDataSource(
this, newObjId, newObjId, deviceId, rootDirectoryName, dirType, metaType, dirFlag, metaFlags, timeZone, null, null, null,
FileKnown.
UNKNOWN, parentPath);
6596 }
catch (SQLException ex) {
6597 throw new TskCoreException(String.format(
"Error creating local files data source with device id %s and directory name %s", deviceId, rootDirectoryName), ex);
6599 closeStatement(statement);
6623 String timezone, String md5, String sha1, String sha256,
6626 return addImage(type, sectorSize, size, displayName, imagePaths, timezone, md5, sha1, sha256, deviceId, null, transaction);
6650 String timezone, String md5, String sha1, String sha256,
6651 String deviceId,
Host host,
6653 Statement statement = null;
6656 CaseDbConnection connection = transaction.getConnection();
6661 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_IMAGE_INFO);
6662 preparedStatement.clearParameters();
6663 preparedStatement.setLong(1, newObjId);
6664 preparedStatement.setShort(2, (
short) type.getValue());
6665 preparedStatement.setLong(3, sectorSize);
6666 preparedStatement.setString(4, timezone);
6668 long savedSize = size < 0 ? 0 : size;
6669 preparedStatement.setLong(5, savedSize);
6670 preparedStatement.setString(6, md5);
6671 preparedStatement.setString(7, sha1);
6672 preparedStatement.setString(8, sha256);
6673 preparedStatement.setString(9, displayName);
6674 connection.executeUpdate(preparedStatement);
6677 for (
int i = 0; i < imagePaths.size(); i++) {
6678 preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_IMAGE_NAME);
6679 preparedStatement.clearParameters();
6680 preparedStatement.setLong(1, newObjId);
6681 preparedStatement.setString(2, imagePaths.get(i));
6682 preparedStatement.setLong(3, i);
6683 connection.executeUpdate(preparedStatement);
6687 String name = displayName;
6688 if (name == null || name.isEmpty()) {
6689 if (imagePaths.size() > 0) {
6690 String path = imagePaths.get(0);
6691 name = (
new java.io.File(path)).getName();
6699 if (name.isEmpty()) {
6707 preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_DATA_SOURCE_INFO);
6708 statement = connection.createStatement();
6709 preparedStatement.setLong(1, newObjId);
6710 preparedStatement.setString(2, deviceId);
6711 preparedStatement.setString(3, timezone);
6712 preparedStatement.setLong(4,
new Date().getTime());
6713 preparedStatement.setLong(5, host.getHostId());
6714 connection.executeUpdate(preparedStatement);
6717 return new Image(
this, newObjId, type.getValue(), deviceId, sectorSize, name,
6718 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, savedSize);
6719 }
catch (SQLException ex) {
6720 if (!imagePaths.isEmpty()) {
6721 throw new TskCoreException(String.format(
"Error adding image with path %s to database", imagePaths.get(0)), ex);
6723 throw new TskCoreException(String.format(
"Error adding image with display name %s to database", displayName), ex);
6726 closeStatement(statement);
6747 CaseDbConnection connection = transaction.getConnection();
6748 long newObjId = addObject(parentObjId,
TskData.
ObjectType.
VS.getObjectType(), connection);
6752 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_VS_INFO);
6753 preparedStatement.clearParameters();
6754 preparedStatement.setLong(1, newObjId);
6755 preparedStatement.setShort(2, (
short) type.getVsType());
6756 preparedStatement.setLong(3, imgOffset);
6757 preparedStatement.setLong(4, blockSize);
6758 connection.executeUpdate(preparedStatement);
6761 return new VolumeSystem(
this, newObjId,
"", type.getVsType(), imgOffset, blockSize);
6762 }
catch (SQLException ex) {
6763 throw new TskCoreException(String.format(
"Error creating volume system with parent ID %d and image offset %d",
6764 parentObjId, imgOffset), ex);
6783 public Volume addVolume(
long parentObjId,
long addr,
long start,
long length, String desc,
6787 CaseDbConnection connection = transaction.getConnection();
6792 PreparedStatement preparedStatement;
6794 preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_VS_PART_POSTGRESQL);
6796 preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_VS_PART_SQLITE);
6798 preparedStatement.clearParameters();
6799 preparedStatement.setLong(1, newObjId);
6800 preparedStatement.setLong(2, addr);
6801 preparedStatement.setLong(3, start);
6802 preparedStatement.setLong(4, length);
6803 preparedStatement.setString(5, desc);
6804 preparedStatement.setShort(6, (
short) flags);
6805 connection.executeUpdate(preparedStatement);
6808 return new Volume(
this, newObjId, addr, start, length, flags, desc);
6809 }
catch (SQLException ex) {
6810 throw new TskCoreException(String.format(
"Error creating volume with address %d and parent ID %d", addr, parentObjId), ex);
6828 CaseDbConnection connection = transaction.getConnection();
6833 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_POOL_INFO);
6834 preparedStatement.clearParameters();
6835 preparedStatement.setLong(1, newObjId);
6836 preparedStatement.setShort(2, type.getValue());
6837 connection.executeUpdate(preparedStatement);
6840 return new Pool(
this, newObjId, type.getName(), type.getValue());
6841 }
catch (SQLException ex) {
6842 throw new TskCoreException(String.format(
"Error creating pool with type %d and parent ID %d", type.getValue(), parentObjId), ex);
6865 long rootInum,
long firstInum,
long lastInum, String displayName,
6869 CaseDbConnection connection = transaction.getConnection();
6870 long newObjId = addObject(parentObjId,
TskData.
ObjectType.
FS.getObjectType(), connection);
6873 long dataSourceId = getDataSourceObjectId(connection, newObjId);
6877 PreparedStatement preparedStatement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FS_INFO);
6878 preparedStatement.clearParameters();
6879 preparedStatement.setLong(1, newObjId);
6880 preparedStatement.setLong(2, dataSourceId);
6881 preparedStatement.setLong(3, imgOffset);
6882 preparedStatement.setInt(4, type.getValue());
6883 preparedStatement.setLong(5, blockSize);
6884 preparedStatement.setLong(6, blockCount);
6885 preparedStatement.setLong(7, rootInum);
6886 preparedStatement.setLong(8, firstInum);
6887 preparedStatement.setLong(9, lastInum);
6888 preparedStatement.setString(10, displayName);
6889 connection.executeUpdate(preparedStatement);
6892 return new FileSystem(
this, newObjId, displayName, imgOffset, type, blockSize, blockCount, rootInum,
6893 firstInum, lastInum);
6894 }
catch (SQLException ex) {
6895 throw new TskCoreException(String.format(
"Error creating file system with image offset %d and parent ID %d",
6896 imgOffset, parentObjId), ex);
6927 long metaAddr,
int metaSeq,
6930 long ctime,
long crtime,
long atime,
long mtime,
6931 boolean isFile,
Content parent)
throws TskCoreException {
6937 metaAddr, metaSeq, attrType, attrId, dirFlag, metaFlags, size,
6938 ctime, crtime, atime, mtime, null, null, null, isFile, parent,
6940 Collections.emptyList(), transaction);
6944 return fileSystemFile;
6946 if (null != transaction) {
6949 }
catch (TskCoreException ex2) {
6950 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
6995 long metaAddr,
int metaSeq,
6998 long ctime,
long crtime,
long atime,
long mtime,
6999 String md5Hash, String sha256Hash, String mimeType,
7000 boolean isFile,
Content parent, String ownerUid,
7001 OsAccount osAccount, List<Attribute> fileAttributes,
7008 dirFlag, metaFlags, size,
7009 ctime, crtime, atime, mtime,
7010 md5Hash, sha256Hash, null,
7012 isFile, parent, ownerUid,
7013 osAccount, fileAttributes,