110public class SleuthkitCase {
112 private static final int MAX_DB_NAME_LEN_BEFORE_TIMESTAMP = 47;
117 private static final long BASE_ARTIFACT_ID = Long.MIN_VALUE;
118 private static final Logger logger = Logger.getLogger(SleuthkitCase.class.getName());
119 private static final ResourceBundle bundle = ResourceBundle.getBundle(
"org.sleuthkit.datamodel.Bundle");
120 private static final int IS_REACHABLE_TIMEOUT_MS = 1000;
121 private static final String SQL_ERROR_CONNECTION_GROUP =
"08";
123 private static final String SQL_CONNECTION_REJECTED =
"08004";
124 private static final String UNABLE_TO_VERIFY_SSL =
"08006";
126 private static final String SQL_ERROR_AUTHENTICATION_GROUP =
"28";
127 private static final String SQL_ERROR_PRIVILEGE_GROUP =
"42";
128 private static final String SQL_ERROR_RESOURCE_GROUP =
"53";
129 private static final String SQL_ERROR_LIMIT_GROUP =
"54";
130 private static final String SQL_ERROR_INTERNAL_GROUP =
"xx";
132 private static final Set<String> CORE_TABLE_NAMES = ImmutableSet.of(
134 "tsk_event_descriptions",
147 "tsk_files_derived_method",
150 "blackboard_artifact_tags",
151 "blackboard_artifacts",
152 "blackboard_attributes",
153 "blackboard_artifact_types",
154 "blackboard_attribute_types",
156 "file_encoding_types",
157 "file_collection_status_types",
158 "ingest_module_types",
159 "ingest_job_status_types",
162 "ingest_job_modules",
165 "account_relationships",
169 private static final Set<String> CORE_INDEX_NAMES = ImmutableSet.of(
173 "artifact_artifact_objID",
178 "relationships_account1",
179 "relationships_account2",
180 "relationships_relationship_source_obj_id",
181 "relationships_date_time",
182 "relationships_relationship_type",
183 "relationships_data_source_obj_id",
186 "events_data_source_obj_id",
187 "events_file_obj_id",
188 "events_artifact_id");
190 private static final String TSK_VERSION_KEY =
"TSK_VER";
191 private static final String SCHEMA_MAJOR_VERSION_KEY =
"SCHEMA_MAJOR_VERSION";
192 private static final String SCHEMA_MINOR_VERSION_KEY =
"SCHEMA_MINOR_VERSION";
193 private static final String CREATION_SCHEMA_MAJOR_VERSION_KEY =
"CREATION_SCHEMA_MAJOR_VERSION";
194 private static final String CREATION_SCHEMA_MINOR_VERSION_KEY =
"CREATION_SCHEMA_MINOR_VERSION";
197 static final String IMAGE_PASSWORD_KEY =
"imagePassword";
199 private final ConnectionPool connections;
200 private final Object carvedFileDirsLock =
new Object();
201 private final static int MAX_CARVED_FILES_PER_FOLDER = 2000;
202 private final Map<Long, CarvedFileDirInfo> rootIdsToCarvedFileDirs =
new HashMap<>();
203 private final Map<Long, FileSystem> fileSystemIdMap =
new HashMap<>();
204 private final List<ErrorObserver> sleuthkitCaseErrorObservers =
new ArrayList<>();
205 private final String databaseName;
206 private final String dbPath;
207 private final DbType dbType;
208 private final String caseDirPath;
210 private final String caseHandleIdentifier;
211 private String dbBackupPath;
212 private AtomicBoolean timelineEventsDisabled =
new AtomicBoolean(
false);
217 private final Object rootDirectoryMapLock =
new Object();
218 private final Map<RootDirectoryKey, Long> rootDirectoryMap =
new HashMap<>();
219 private final Cache<Long, Boolean> isRootDirectoryCache
220 = CacheBuilder.newBuilder().maximumSize(200000).expireAfterAccess(5, TimeUnit.MINUTES).build();
223 private final LockResources lockResources;
229 private final Map<Long, SparseBitSet> hasChildrenBitSetMap =
new HashMap<>();
231 private final ReentrantLock childrenBitSetLock =
new ReentrantLock();
233 private final CountDownLatch childrenBitSetInitLatch =
new CountDownLatch(1);
236 private long nextArtifactId;
241 private final ReentrantReadWriteLock rwLock =
new ReentrantReadWriteLock(
true);
256 private final Map<String, Set<Long>> deviceIdToDatasourceObjIdMap =
new HashMap<>();
258 private final EventBus eventBus =
new EventBus(
"SleuthkitCase-EventBus");
261 eventBus.register(listener);
265 eventBus.unregister(listener);
268 void fireTSKEvent(Object event) {
269 eventBus.post(event);
273 private final Map<Long, Content> frequentlyUsedContentMap =
new HashMap<>();
275 private Examiner cachedCurrentExaminer =
null;
278 Properties p =
new Properties(System.getProperties());
279 p.put(
"com.mchange.v2.log.MLog",
"com.mchange.v2.log.FallbackMLog");
280 p.put(
"com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL",
"SEVERE");
281 System.setProperties(p);
300 if (info.getHost() ==
null || info.getHost().isEmpty()) {
301 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingHostname"));
302 }
else if (info.getPort() ==
null || info.getPort().isEmpty()) {
303 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPort"));
304 }
else if (info.getUserName() ==
null || info.getUserName().isEmpty()) {
305 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingUsername"));
306 }
else if (info.getPassword() ==
null || info.getPassword().isEmpty()) {
307 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.MissingPassword"));
311 Class.forName(
"org.postgresql.Driver");
312 String connectionURL =
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres";
313 if (info.isSslEnabled()) {
314 if (info.isSslVerify()) {
315 if (info.getCustomSslValidationClassName().isBlank()) {
316 connectionURL += CaseDatabaseFactory.SSL_VERIFY_DEFAULT_URL;
319 connectionURL += CaseDatabaseFactory.getCustomPostrgesSslVerificationUrl(info.getCustomSslValidationClassName());
322 connectionURL += CaseDatabaseFactory.SSL_NONVERIFY_URL;
325 Connection conn = DriverManager.getConnection(connectionURL, info.getUserName(), info.getPassword());
329 }
catch (SQLException ex) {
331 String sqlState = ex.getSQLState().toLowerCase();
332 if (sqlState.startsWith(SQL_ERROR_CONNECTION_GROUP)) {
333 if (SQL_CONNECTION_REJECTED.equals(ex.getSQLState())) {
334 if (info.isSslEnabled()) {
335 result =
"Server rejected the SSL connection attempt. Check SSL configuration.";
337 result =
"Server rejected the connection attempt. Check server configuration.";
339 }
else if (UNABLE_TO_VERIFY_SSL.equals(ex.getSQLState())) {
340 result =
"Unable to verify SSL certificates. Check SSL configuration.";
343 if (InetAddress.getByName(info.getHost()).isReachable(IS_REACHABLE_TIMEOUT_MS)) {
345 result = bundle.getString(
"DatabaseConnectionCheck.Port");
347 result = bundle.getString(
"DatabaseConnectionCheck.HostnameOrPort");
349 }
catch (IOException | MissingResourceException any) {
351 result = bundle.getString(
"DatabaseConnectionCheck.Everything");
354 }
else if (sqlState.startsWith(SQL_ERROR_AUTHENTICATION_GROUP)) {
355 result = bundle.getString(
"DatabaseConnectionCheck.Authentication");
356 }
else if (sqlState.startsWith(SQL_ERROR_PRIVILEGE_GROUP)) {
357 result = bundle.getString(
"DatabaseConnectionCheck.Access");
358 }
else if (sqlState.startsWith(SQL_ERROR_RESOURCE_GROUP)) {
359 result = bundle.getString(
"DatabaseConnectionCheck.ServerDiskSpace");
360 }
else if (sqlState.startsWith(SQL_ERROR_LIMIT_GROUP)) {
361 result = bundle.getString(
"DatabaseConnectionCheck.ServerRestart");
362 }
else if (sqlState.startsWith(SQL_ERROR_INTERNAL_GROUP)) {
363 result = bundle.getString(
"DatabaseConnectionCheck.InternalServerIssue");
365 result = bundle.getString(
"DatabaseConnectionCheck.Connection");
368 }
catch (ClassNotFoundException ex) {
369 throw new TskCoreException(bundle.getString(
"DatabaseConnectionCheck.Installation"));
395 Class.forName(
"org.sqlite.JDBC");
396 this.dbPath = dbPath;
397 this.dbType = dbType;
399 this.caseDirPath = dbFile.getParentFile().getAbsolutePath();
400 this.databaseName = dbFile.
getName();
402 this.lockResources = lockingApplicationName ==
null
404 : LockResources.tryAcquireFileLock(this.caseDirPath, this.databaseName, lockingApplicationName);
406 this.connections =
new SQLiteConnections(dbPath, useWAL);
407 this.caseHandle = caseHandle;
408 this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier();
409 this.contentProvider = contentProvider;
411 logSQLiteJDBCDriverInfo();
425 private SleuthkitCase(CaseDbConnectionInfo info, String dbName, SleuthkitJNI.CaseDbHandle caseHandle, String caseDirPath, ContentStreamProvider contentProvider)
throws Exception {
427 this.databaseName = dbName;
428 this.dbType = info.getDbType();
429 this.caseDirPath = caseDirPath;
430 this.connections =
new PostgreSQLConnections(info, dbName);
431 this.caseHandle = caseHandle;
432 this.caseHandleIdentifier = caseHandle.getCaseDbIdentifier();
433 this.contentProvider = contentProvider;
434 this.lockResources =
null;
438 private void init() throws Exception {
439 blackboard =
new Blackboard(
this);
440 updateDatabaseSchema(
null);
441 try (CaseDbConnection connection = connections.getConnection()) {
442 blackboard.initBlackboardArtifactTypes(connection);
443 blackboard.initBlackboardAttributeTypes(connection);
444 initNextArtifactId(connection);
445 initIngestModuleTypes(connection);
446 initIngestStatusTypes(connection);
447 initReviewStatuses(connection);
448 initEncodingTypes(connection);
449 initCollectedStatusTypes(connection);
450 populateHasChildrenMap(
true);
451 updateExaminers(connection);
452 initDBSchemaCreationVersion(connection);
455 fileManager =
new FileManager(
this);
456 communicationsMgr =
new CommunicationsManager(
this);
457 timelineMgr =
new TimelineManager(
this);
458 dbAccessManager =
new CaseDbAccessManager(
this);
459 taggingMgr =
new TaggingManager(
this);
460 scoringManager =
new ScoringManager(
this);
461 osAccountRealmManager =
new OsAccountRealmManager(
this);
462 osAccountManager =
new OsAccountManager(
this);
463 hostManager =
new HostManager(
this);
464 personManager =
new PersonManager(
this);
465 hostAddressManager =
new HostAddressManager(
this);
475 ContentStreamProvider getContentProvider() {
476 return this.contentProvider;
484 static Set<String> getCoreTableNames() {
485 return Collections.unmodifiableSet(CORE_TABLE_NAMES);
493 static Set<String> getCoreIndexNames() {
494 return Collections.unmodifiableSet(CORE_INDEX_NAMES);
505 boolean getHasChildren(Content content) {
509 childrenBitSetInitLatch.await();
510 }
catch (InterruptedException ex) {
511 throw new AssertionError(
"Interrupted Exception awaiting Children bit set initialization", ex);
513 childrenBitSetLock.lock();
515 long objId = content.getId();
516 long mapIndex = objId / Integer.MAX_VALUE;
517 int mapValue = (int) (objId % Integer.MAX_VALUE);
519 if (hasChildrenBitSetMap.containsKey(mapIndex)) {
520 return hasChildrenBitSetMap.get(mapIndex).get(mapValue);
525 childrenBitSetLock.unlock();
534 private void setHasChildren(Long objId) {
535 setHasChildren(objId,
false);
543 private void setHasChildren(Long objId,
boolean initializing) {
547 childrenBitSetInitLatch.await();
549 }
catch (InterruptedException ex) {
550 throw new AssertionError(
"Interrupted Exception awaiting Children bit set initialization",ex);
553 childrenBitSetLock.lock();
555 long mapIndex = objId / Integer.MAX_VALUE;
556 int mapValue = (int) (objId % Integer.MAX_VALUE);
558 if (hasChildrenBitSetMap.containsKey(mapIndex)) {
559 hasChildrenBitSetMap.get(mapIndex).set(mapValue);
561 SparseBitSet bitSet =
new SparseBitSet();
562 bitSet.set(mapValue);
563 hasChildrenBitSetMap.put(mapIndex, bitSet);
566 childrenBitSetLock.unlock();
578 return communicationsMgr;
618 return dbAccessManager;
638 return scoringManager;
649 return osAccountRealmManager;
660 return osAccountManager;
682 return personManager;
693 return hostAddressManager;
705 private void initNextArtifactId(CaseDbConnection connection)
throws SQLException {
707 try (Statement statement = connection.createStatement()) {
708 ResultSet resultSet = connection.executeQuery(statement,
"SELECT MAX(artifact_id) AS max_artifact_id FROM blackboard_artifacts");
710 nextArtifactId = resultSet.getLong(
"max_artifact_id") + 1;
711 if (nextArtifactId == 1) {
712 nextArtifactId = BASE_ARTIFACT_ID;
726 private void initIngestModuleTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
727 Statement statement =
null;
728 ResultSet resultSet =
null;
731 statement = connection.createStatement();
732 for (IngestModuleType type : IngestModuleType.values()) {
734 String query =
"INSERT INTO ingest_module_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"')";
736 query +=
" ON CONFLICT ON CONSTRAINT ingest_module_types_pkey DO NOTHING";
738 statement.execute(query);
739 }
catch (SQLException ex) {
740 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_module_types WHERE type_id = " + type.ordinal() +
";");
742 if (resultSet.getLong(
"count") == 0) {
750 closeResultSet(resultSet);
751 closeStatement(statement);
763 private void initIngestStatusTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
764 Statement statement =
null;
765 ResultSet resultSet =
null;
768 statement = connection.createStatement();
769 for (IngestJobStatusType type : IngestJobStatusType.values()) {
771 String query =
"INSERT INTO ingest_job_status_types (type_id, type_name) VALUES (" + type.ordinal() +
", '" + type.toString() +
"')";
773 query +=
" ON CONFLICT ON CONSTRAINT ingest_job_status_types_pkey DO NOTHING";
775 statement.execute(query);
776 }
catch (SQLException ex) {
777 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM ingest_job_status_types WHERE type_id = " + type.ordinal() +
";");
779 if (resultSet.getLong(
"count") == 0) {
787 closeResultSet(resultSet);
788 closeStatement(statement);
799 private void initReviewStatuses(CaseDbConnection connection)
throws SQLException, TskCoreException {
800 Statement statement =
null;
801 ResultSet resultSet =
null;
804 statement = connection.createStatement();
805 for (BlackboardArtifact.ReviewStatus status : BlackboardArtifact.ReviewStatus.values()) {
807 String query =
"INSERT INTO review_statuses (review_status_id, review_status_name, display_name) "
808 +
"VALUES (" + status.getID() +
",'" + status.getName() +
"','" + status.getDisplayName() +
"')";
810 query +=
" ON CONFLICT ON CONSTRAINT review_statuses_pkey DO NOTHING";
812 statement.execute(query);
813 }
catch (SQLException ex) {
814 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM review_statuses WHERE review_status_id = " + status.getID());
816 if (resultSet.getLong(
"count") == 0) {
824 closeResultSet(resultSet);
825 closeStatement(statement);
837 private void initEncodingTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
838 Statement statement =
null;
839 ResultSet resultSet =
null;
842 statement = connection.createStatement();
843 for (TskData.EncodingType type : TskData.EncodingType.values()) {
845 String query =
"INSERT INTO file_encoding_types (encoding_type, name) VALUES (" + type.getType() +
" , '" + type.name() +
"')";
847 query +=
" ON CONFLICT ON CONSTRAINT file_encoding_types_pkey DO NOTHING";
849 statement.execute(query);
850 }
catch (SQLException ex) {
851 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM file_encoding_types WHERE encoding_type = " + type.getType());
853 if (resultSet.getLong(
"count") == 0) {
861 closeResultSet(resultSet);
862 closeStatement(statement);
874 private void initCollectedStatusTypes(CaseDbConnection connection)
throws SQLException, TskCoreException {
875 Statement statement =
null;
876 ResultSet resultSet =
null;
879 statement = connection.createStatement();
880 for (TskData.CollectedStatus type : TskData.CollectedStatus.values()) {
882 String query =
"INSERT INTO file_collection_status_types (collection_status_type, name) VALUES (" + type.getType() +
" , '" + type.name() +
"')";
884 query +=
" ON CONFLICT ON CONSTRAINT file_collection_status_types_pkey DO NOTHING";
886 statement.execute(query);
887 }
catch (SQLException ex) {
888 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) as count FROM file_collection_status_types WHERE collection_status_type = " + type.getType());
890 if (resultSet.getLong(
"count") == 0) {
898 closeResultSet(resultSet);
899 closeStatement(statement);
912 private void updateExaminers(CaseDbConnection connection)
throws SQLException, TskCoreException {
914 String loginName = System.getProperty(
"user.name");
915 if (loginName.isEmpty()) {
916 logger.log(Level.SEVERE,
"Cannot determine logged in user name");
922 PreparedStatement statement;
931 throw new TskCoreException(
"Unknown DB Type: " +
getDatabaseType().name());
933 statement.clearParameters();
934 statement.setString(1, loginName);
935 connection.executeUpdate(statement);
936 }
catch (SQLException ex) {
937 throw new TskCoreException(
"Error inserting row in tsk_examiners. login name: " + loginName, ex);
948 private void populateHasChildrenMap(
boolean async)
throws TskCoreException {
950 Runnable childrenBitSetLockInitRunnable = () -> {
957 childrenBitSetLock.lock();
964 long timestamp = System.currentTimeMillis();
966 Statement statement =
null;
967 ResultSet resultSet =
null;
969 try (CaseDbConnection neoConnection = connections.getConnection()) {
970 statement = neoConnection.createStatement();
971 String query =
"select distinct par_obj_id from tsk_objects";
972 if (dbType == DbType.POSTGRESQL) {
973 query =
"select distinct ON (par_obj_id) par_obj_id from tsk_objects";
976 resultSet = statement.executeQuery(query);
981 while (resultSet.next()) {
982 setHasChildren(resultSet.getLong(
"par_obj_id"),
true);
985 long delay = System.currentTimeMillis() - timestamp;
986 logger.log(Level.INFO,
"Time to initialize parent node cache: {0} ms", delay);
987 }
catch (SQLException ex) {
988 logger.log(Level.SEVERE,
"Error populating parent node cache", ex);
990 throw new AssertionError(
"Error populating parent node cache",ex);
991 }
catch (TskCoreException ex) {
992 logger.log(Level.SEVERE,
"Error acquiring connection", ex);
993 throw new AssertionError(
"Error acquiring connection",ex);
995 closeResultSet(resultSet);
996 closeStatement(statement);
998 childrenBitSetLock.unlock();
1000 childrenBitSetInitLatch.countDown();
1005 CompletableFuture.runAsync(childrenBitSetLockInitRunnable);
1007 childrenBitSetLockInitRunnable.run();
1017 void addDataSourceToHasChildrenMap() throws TskCoreException {
1020 childrenBitSetInitLatch.await();
1021 }
catch (InterruptedException ex) {
1022 throw new AssertionError(
"Interrupted Exception awaiting Children bit set initialization", ex);
1024 populateHasChildrenMap(
false);
1036 private void updateDatabaseSchema(String dbPath)
throws Exception {
1037 CaseDbConnection connection =
null;
1038 ResultSet resultSet =
null;
1039 Statement statement =
null;
1042 connection = connections.getConnection();
1043 connection.beginTransaction();
1045 boolean hasMinorVersion =
false;
1046 ResultSet columns = connection.getConnection().getMetaData().getColumns(
null,
null,
"tsk_db_info",
"schema%");
1047 while (columns.next()) {
1048 if (columns.getString(
"COLUMN_NAME").equals(
"schema_minor_ver")) {
1049 hasMinorVersion =
true;
1054 int dbSchemaMajorVersion;
1055 int dbSchemaMinorVersion = 0;
1057 statement = connection.createStatement();
1058 resultSet = connection.executeQuery(statement,
"SELECT schema_ver"
1059 + (hasMinorVersion ?
", schema_minor_ver" :
"")
1060 +
" FROM tsk_db_info");
1061 if (resultSet.next()) {
1062 dbSchemaMajorVersion = resultSet.getInt(
"schema_ver");
1063 if (hasMinorVersion) {
1065 dbSchemaMinorVersion = resultSet.getInt(
"schema_minor_ver");
1068 throw new TskCoreException();
1070 CaseDbSchemaVersionNumber dbSchemaVersion =
new CaseDbSchemaVersionNumber(dbSchemaMajorVersion, dbSchemaMinorVersion);
1077 if (
false == CURRENT_DB_SCHEMA_VERSION.isCompatible(dbSchemaVersion)) {
1079 throw new TskUnsupportedSchemaVersionException(
1080 "Unsupported DB schema version " + dbSchemaVersion +
", the highest supported schema version is " + CURRENT_DB_SCHEMA_VERSION.getMajor() +
".X");
1081 }
else if (dbSchemaVersion.compareTo(CURRENT_DB_SCHEMA_VERSION) < 0) {
1084 if (
null != dbPath) {
1087 String backupFilePath = dbPath +
".schemaVer" + dbSchemaVersion.toString() +
".backup";
1089 dbBackupPath = backupFilePath;
1096 dbSchemaVersion = updateFromSchema2toSchema3(dbSchemaVersion, connection);
1097 dbSchemaVersion = updateFromSchema3toSchema4(dbSchemaVersion, connection);
1098 dbSchemaVersion = updateFromSchema4toSchema5(dbSchemaVersion, connection);
1099 dbSchemaVersion = updateFromSchema5toSchema6(dbSchemaVersion, connection);
1100 dbSchemaVersion = updateFromSchema6toSchema7(dbSchemaVersion, connection);
1101 dbSchemaVersion = updateFromSchema7toSchema7dot1(dbSchemaVersion, connection);
1102 dbSchemaVersion = updateFromSchema7dot1toSchema7dot2(dbSchemaVersion, connection);
1103 dbSchemaVersion = updateFromSchema7dot2toSchema8dot0(dbSchemaVersion, connection);
1104 dbSchemaVersion = updateFromSchema8dot0toSchema8dot1(dbSchemaVersion, connection);
1105 dbSchemaVersion = updateFromSchema8dot1toSchema8dot2(dbSchemaVersion, connection);
1106 dbSchemaVersion = updateFromSchema8dot2toSchema8dot3(dbSchemaVersion, connection);
1107 dbSchemaVersion = updateFromSchema8dot3toSchema8dot4(dbSchemaVersion, connection);
1108 dbSchemaVersion = updateFromSchema8dot4toSchema8dot5(dbSchemaVersion, connection);
1109 dbSchemaVersion = updateFromSchema8dot5toSchema8dot6(dbSchemaVersion, connection);
1110 dbSchemaVersion = updateFromSchema8dot6toSchema9dot0(dbSchemaVersion, connection);
1111 dbSchemaVersion = updateFromSchema9dot0toSchema9dot1(dbSchemaVersion, connection);
1112 dbSchemaVersion = updateFromSchema9dot1toSchema9dot2(dbSchemaVersion, connection);
1113 dbSchemaVersion = updateFromSchema9dot2toSchema9dot3(dbSchemaVersion, connection);
1114 dbSchemaVersion = updateFromSchema9dot3toSchema9dot4(dbSchemaVersion, connection);
1115 dbSchemaVersion = updateFromSchema9dot4toSchema9dot5(dbSchemaVersion, connection);
1116 dbSchemaVersion = updateFromSchema9dot5toSchema9dot6(dbSchemaVersion, connection);
1119 statement = connection.createStatement();
1120 connection.executeUpdate(statement,
"UPDATE tsk_db_info SET schema_ver = " + dbSchemaVersion.getMajor() +
", schema_minor_ver = " + dbSchemaVersion.getMinor());
1121 connection.executeUpdate(statement,
"UPDATE tsk_db_info_extended SET value = " + dbSchemaVersion.getMajor() +
" WHERE name = '" + SCHEMA_MAJOR_VERSION_KEY +
"'");
1122 connection.executeUpdate(statement,
"UPDATE tsk_db_info_extended SET value = " + dbSchemaVersion.getMinor() +
" WHERE name = '" + SCHEMA_MINOR_VERSION_KEY +
"'");
1127 connection.commitTransaction();
1128 }
catch (Exception ex) {
1129 rollbackTransaction(connection);
1132 closeResultSet(resultSet);
1133 closeStatement(statement);
1134 closeConnection(connection);
1146 private void initDBSchemaCreationVersion(CaseDbConnection connection)
throws SQLException {
1148 Statement statement =
null;
1149 ResultSet resultSet =
null;
1150 String createdSchemaMajorVersion =
"0";
1151 String createdSchemaMinorVersion =
"0";
1154 statement = connection.createStatement();
1155 resultSet = connection.executeQuery(statement,
"SELECT name, value FROM tsk_db_info_extended");
1156 while (resultSet.next()) {
1157 String name = resultSet.getString(
"name");
1158 if (name.equals(CREATION_SCHEMA_MAJOR_VERSION_KEY) || name.equals(
"CREATED_SCHEMA_MAJOR_VERSION")) {
1159 createdSchemaMajorVersion = resultSet.getString(
"value");
1160 }
else if (name.equals(CREATION_SCHEMA_MINOR_VERSION_KEY) || name.equals(
"CREATED_SCHEMA_MINOR_VERSION")) {
1161 createdSchemaMinorVersion = resultSet.getString(
"value");
1166 closeResultSet(resultSet);
1167 closeStatement(statement);
1171 caseDBSchemaCreationVersion =
new CaseDbSchemaVersionNumber(Integer.parseInt(createdSchemaMajorVersion), Integer.parseInt(createdSchemaMinorVersion));
1184 if (dbPath.isEmpty()) {
1185 throw new IOException(
"Copying case database files is not supported for this type of case database");
1189 try(InputStream inFile =
new FileInputStream(dbPath);
1190 InputStream in =
new BufferedInputStream(inFile);
1191 OutputStream outFile =
new FileOutputStream(newDBPath);
1192 OutputStream out =
new BufferedOutputStream(outFile);) {
1194 int bytesRead = in.read();
1195 while (bytesRead != -1) {
1196 out.write(bytesRead);
1197 bytesRead = in.read();
1207 private void logSQLiteJDBCDriverInfo() {
1209 SleuthkitCase.logger.info(String.format(
"sqlite-jdbc version %s loaded in %s mode",
1210 SQLiteJDBCLoader.getVersion(), SQLiteJDBCLoader.isNativeMode()
1211 ?
"native" :
"pure-java"));
1212 }
catch (Exception ex) {
1213 SleuthkitCase.logger.log(Level.SEVERE,
"Error querying case database mode", ex);
1230 @SuppressWarnings(
"deprecation")
1231 private CaseDbSchemaVersionNumber updateFromSchema2toSchema3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection) throws SQLException, TskCoreException {
1232 if (schemaVersion.getMajor() != 2) {
1233 return schemaVersion;
1235 Statement statement =
null;
1236 Statement statement2 =
null;
1237 Statement updateStatement =
null;
1238 ResultSet resultSet =
null;
1241 statement = connection.createStatement();
1242 statement2 = connection.createStatement();
1245 statement.execute(
"CREATE TABLE tag_names (tag_name_id INTEGER PRIMARY KEY, display_name TEXT UNIQUE, description TEXT NOT NULL, color TEXT NOT NULL)");
1246 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)");
1247 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)");
1250 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)");
1253 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN size INTEGER;");
1254 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN md5 TEXT;");
1255 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN display_name TEXT;");
1258 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN display_name TEXT;");
1261 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN meta_seq INTEGER;");
1266 statement.execute(
"ALTER TABLE blackboard_attributes ADD COLUMN artifact_type_id INTEGER NULL NOT NULL DEFAULT -1;");
1267 statement.execute(
"CREATE INDEX attribute_artifactTypeId ON blackboard_attributes(artifact_type_id);");
1268 statement.execute(
"CREATE INDEX attribute_valueText ON blackboard_attributes(value_text);");
1269 statement.execute(
"CREATE INDEX attribute_valueInt32 ON blackboard_attributes(value_int32);");
1270 statement.execute(
"CREATE INDEX attribute_valueInt64 ON blackboard_attributes(value_int64);");
1271 statement.execute(
"CREATE INDEX attribute_valueDouble ON blackboard_attributes(value_double);");
1272 resultSet = statement.executeQuery(
"SELECT attrs.artifact_id AS artifact_id, "
1273 +
"arts.artifact_type_id AS artifact_type_id "
1274 +
"FROM blackboard_attributes AS attrs "
1275 +
"INNER JOIN blackboard_artifacts AS arts "
1276 +
"WHERE attrs.artifact_id = arts.artifact_id;");
1277 updateStatement = connection.createStatement();
1278 while (resultSet.next()) {
1279 long artifactId = resultSet.getLong(
"artifact_id");
1280 int artifactTypeId = resultSet.getInt(
"artifact_type_id");
1281 updateStatement.executeUpdate(
1282 "UPDATE blackboard_attributes "
1283 +
"SET artifact_type_id = " + artifactTypeId
1284 +
" WHERE blackboard_attributes.artifact_id = " + artifactId +
";");
1289 Map<String, Long> tagNames =
new HashMap<>();
1290 long tagNameCounter = 1;
1294 resultSet = statement.executeQuery(
"SELECT * FROM \n"
1295 +
"(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, blackboard_attributes.value_text AS name\n"
1296 +
"FROM blackboard_artifacts INNER JOIN blackboard_attributes \n"
1297 +
"ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n"
1298 +
"WHERE blackboard_artifacts.artifact_type_id = "
1299 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1300 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
1301 +
") AS tagNames \n"
1303 +
"(SELECT tsk_files.obj_id as objId2, tsk_files.size AS fileSize \n"
1304 +
"FROM blackboard_artifacts INNER JOIN tsk_files \n"
1305 +
"ON blackboard_artifacts.obj_id = tsk_files.obj_id) AS fileData \n"
1306 +
"ON tagNames.objId = fileData.objId2 \n"
1308 +
"(SELECT value_text AS comment, artifact_id AS tagArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1309 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() +
") AS tagComments \n"
1310 +
"ON tagNames.artifactId = tagComments.tagArtifactId");
1312 while (resultSet.next()) {
1313 long objId = resultSet.getLong(
"objId");
1314 long fileSize = resultSet.getLong(
"fileSize");
1315 String tagName = resultSet.getString(
"name");
1316 String tagComment = resultSet.getString(
"comment");
1317 if (tagComment ==
null) {
1321 if (tagName !=
null && !tagName.isEmpty()) {
1324 if (tagNames.containsKey(tagName)) {
1325 tagNameIndex = tagNames.get(tagName);
1327 statement2.execute(
"INSERT INTO tag_names (display_name, description, color) "
1328 +
"VALUES(\"" + tagName +
"\", \"\", \"None\")");
1329 tagNames.put(tagName, tagNameCounter);
1330 tagNameIndex = tagNameCounter;
1334 statement2.execute(
"INSERT INTO content_tags (obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset) "
1335 +
"VALUES(" + objId +
", " + tagNameIndex +
", \"" + tagComment +
"\", 0, " + fileSize +
")");
1342 resultSet = statement.executeQuery(
"SELECT * FROM \n"
1343 +
"(SELECT blackboard_artifacts.obj_id AS objId, blackboard_attributes.artifact_id AS artifactId, "
1344 +
"blackboard_attributes.value_text AS name\n"
1345 +
"FROM blackboard_artifacts INNER JOIN blackboard_attributes \n"
1346 +
"ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id \n"
1347 +
"WHERE blackboard_artifacts.artifact_type_id = "
1348 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID()
1349 +
" AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAG_NAME.getTypeID()
1350 +
") AS tagNames \n"
1352 +
"(SELECT value_int64 AS taggedArtifactId, artifact_id AS associatedArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1353 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TAGGED_ARTIFACT.getTypeID() +
") AS tagArtifacts \n"
1354 +
"ON tagNames.artifactId = tagArtifacts.associatedArtifactId \n"
1356 +
"(SELECT value_text AS comment, artifact_id AS commentArtifactId FROM blackboard_attributes WHERE attribute_type_id = "
1357 + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT.getTypeID() +
") AS tagComments \n"
1358 +
"ON tagNames.artifactId = tagComments.commentArtifactId");
1360 while (resultSet.next()) {
1361 long artifactId = resultSet.getLong(
"taggedArtifactId");
1362 String tagName = resultSet.getString(
"name");
1363 String tagComment = resultSet.getString(
"comment");
1364 if (tagComment ==
null) {
1367 if (tagName !=
null && !tagName.isEmpty()) {
1370 if (tagNames.containsKey(tagName)) {
1371 tagNameIndex = tagNames.get(tagName);
1373 statement2.execute(
"INSERT INTO tag_names (display_name, description, color) "
1374 +
"VALUES(\"" + tagName +
"\", \"\", \"None\")");
1375 tagNames.put(tagName, tagNameCounter);
1376 tagNameIndex = tagNameCounter;
1380 statement2.execute(
"INSERT INTO blackboard_artifact_tags (artifact_id, tag_name_id, comment) "
1381 +
"VALUES(" + artifactId +
", " + tagNameIndex +
", \"" + tagComment +
"\")");
1387 "DELETE FROM blackboard_attributes WHERE artifact_id IN "
1388 +
"(SELECT artifact_id FROM blackboard_artifacts WHERE artifact_type_id = "
1389 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1390 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
");");
1392 "DELETE FROM blackboard_artifacts WHERE artifact_type_id = "
1393 + ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID()
1394 +
" OR artifact_type_id = " + ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
";");
1396 return new CaseDbSchemaVersionNumber(3, 0);
1398 closeStatement(updateStatement);
1399 closeResultSet(resultSet);
1400 closeStatement(statement);
1401 closeStatement(statement2);
1419 private CaseDbSchemaVersionNumber updateFromSchema3toSchema4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1420 if (schemaVersion.getMajor() != 3) {
1421 return schemaVersion;
1424 Statement statement =
null;
1425 ResultSet resultSet =
null;
1426 Statement queryStatement =
null;
1427 ResultSet queryResultSet =
null;
1428 Statement updateStatement =
null;
1433 statement = connection.createStatement();
1434 updateStatement = connection.createStatement();
1435 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN mime_type TEXT;");
1436 resultSet = statement.executeQuery(
"SELECT files.obj_id AS obj_id, attrs.value_text AS value_text "
1437 +
"FROM tsk_files AS files, blackboard_attributes AS attrs, blackboard_artifacts AS arts "
1438 +
"WHERE files.obj_id = arts.obj_id AND "
1439 +
"arts.artifact_id = attrs.artifact_id AND "
1440 +
"arts.artifact_type_id = 1 AND "
1441 +
"attrs.attribute_type_id = 62");
1442 while (resultSet.next()) {
1443 updateStatement.executeUpdate(
1445 +
"SET mime_type = '" + resultSet.getString(
"value_text") +
"' "
1446 +
"WHERE tsk_files.obj_id = " + resultSet.getInt(
"obj_id") +
";");
1451 statement.execute(
"ALTER TABLE blackboard_attribute_types ADD COLUMN value_type INTEGER NOT NULL DEFAULT -1;");
1452 resultSet = statement.executeQuery(
"SELECT * FROM blackboard_attribute_types AS types");
1453 while (resultSet.next()) {
1454 int attributeTypeId = resultSet.getInt(
"attribute_type_id");
1455 String attributeLabel = resultSet.getString(
"type_name");
1456 if (attributeTypeId < Blackboard.MIN_USER_DEFINED_TYPE_ID) {
1457 updateStatement.executeUpdate(
1458 "UPDATE blackboard_attribute_types "
1459 +
"SET value_type = " + ATTRIBUTE_TYPE.fromLabel(attributeLabel).getValueType().getType() +
" "
1460 +
"WHERE blackboard_attribute_types.attribute_type_id = " + attributeTypeId +
";");
1466 queryStatement = connection.createStatement();
1467 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));");
1468 resultSet = statement.executeQuery(
"SELECT * FROM tsk_objects WHERE par_obj_id IS NULL");
1469 while (resultSet.next()) {
1470 long objectId = resultSet.getLong(
"obj_id");
1471 String timeZone =
"";
1472 queryResultSet = queryStatement.executeQuery(
"SELECT tzone FROM tsk_image_info WHERE obj_id = " + objectId);
1473 if (queryResultSet.next()) {
1474 timeZone = queryResultSet.getString(
"tzone");
1476 queryResultSet.close();
1477 updateStatement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone) "
1478 +
"VALUES(" + objectId +
", '" + UUID.randomUUID().toString() +
"' , '" + timeZone +
"');");
1492 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN data_source_obj_id BIGINT NOT NULL DEFAULT -1;");
1493 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");
1494 while (resultSet.next()) {
1495 long fileId = resultSet.getLong(
"obj_id");
1496 long dataSourceId = getDataSourceObjectId(connection, fileId);
1497 updateStatement.executeUpdate(
"UPDATE tsk_files SET data_source_obj_id = " + dataSourceId +
" WHERE obj_id = " + fileId +
";");
1500 statement.execute(
"CREATE TABLE ingest_module_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
1501 statement.execute(
"CREATE TABLE ingest_job_status_types (type_id INTEGER PRIMARY KEY, type_name TEXT NOT NULL)");
1502 if (this.dbType.equals(DbType.SQLITE)) {
1503 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));");
1504 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));");
1506 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));");
1507 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));");
1510 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));");
1511 initIngestModuleTypes(connection);
1512 initIngestStatusTypes(connection);
1514 return new CaseDbSchemaVersionNumber(4, 0);
1517 closeResultSet(queryResultSet);
1518 closeStatement(queryStatement);
1519 closeStatement(updateStatement);
1520 closeResultSet(resultSet);
1521 closeStatement(statement);
1539 private CaseDbSchemaVersionNumber updateFromSchema4toSchema5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1540 if (schemaVersion.getMajor() != 4) {
1541 return schemaVersion;
1544 Statement statement =
null;
1548 statement = connection.createStatement();
1549 statement.execute(
"CREATE TABLE review_statuses (review_status_id INTEGER PRIMARY KEY, review_status_name TEXT NOT NULL, display_name TEXT NOT NULL)");
1559 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
1562 statement.execute(
"CREATE TABLE file_encoding_types (encoding_type INTEGER PRIMARY KEY, name TEXT NOT NULL);");
1563 initEncodingTypes(connection);
1570 initReviewStatuses(connection);
1575 statement.execute(
"ALTER TABLE tsk_files_path ADD COLUMN encoding_type INTEGER NOT NULL DEFAULT 0;");
1577 return new CaseDbSchemaVersionNumber(5, 0);
1580 closeStatement(statement);
1598 private CaseDbSchemaVersionNumber updateFromSchema5toSchema6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1599 if (schemaVersion.getMajor() != 5) {
1600 return schemaVersion;
1607 Statement statement =
null;
1608 ResultSet resultSet =
null;
1614 statement = connection.createStatement();
1615 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)");
1617 resultSet = connection.executeQuery(statement,
"SELECT COUNT(*) AS count FROM review_statuses");
1619 if (resultSet.getLong(
"count") == 0) {
1628 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN review_status_id INTEGER NOT NULL DEFAULT " + BlackboardArtifact.ReviewStatus.UNDECIDED.getID());
1631 return new CaseDbSchemaVersionNumber(6, 0);
1634 closeResultSet(resultSet);
1635 closeStatement(statement);
1653 private CaseDbSchemaVersionNumber updateFromSchema6toSchema7(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1654 if (schemaVersion.getMajor() != 6) {
1655 return schemaVersion;
1661 Statement statement =
null;
1662 Statement updstatement =
null;
1663 ResultSet resultSet =
null;
1666 statement = connection.createStatement();
1667 updstatement = connection.createStatement();
1668 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN extension TEXT");
1670 resultSet = connection.executeQuery(statement,
"SELECT obj_id,name FROM tsk_files");
1671 while (resultSet.next()) {
1672 long objID = resultSet.getLong(
"obj_id");
1673 String name = resultSet.getString(
"name");
1674 updstatement.executeUpdate(
"UPDATE tsk_files SET extension = '" +
escapeSingleQuotes(extractExtension(name)) +
"' "
1675 +
"WHERE obj_id = " + objID);
1678 statement.execute(
"CREATE INDEX file_extension ON tsk_files ( extension )");
1681 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN artifact_obj_id INTEGER NOT NULL DEFAULT -1");
1683 return new CaseDbSchemaVersionNumber(7, 0);
1686 closeResultSet(resultSet);
1687 closeStatement(statement);
1688 closeStatement(updstatement);
1706 private CaseDbSchemaVersionNumber updateFromSchema7toSchema7dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1707 if (schemaVersion.getMajor() != 7) {
1708 return schemaVersion;
1711 if (schemaVersion.getMinor() != 0) {
1712 return schemaVersion;
1718 Statement statement =
null;
1719 ResultSet resultSet =
null;
1722 statement = connection.createStatement();
1725 if (schemaVersion.getMinor() == 0) {
1727 statement.execute(
"ALTER TABLE tsk_db_info ADD COLUMN schema_minor_ver INTEGER DEFAULT 1");
1729 return new CaseDbSchemaVersionNumber(7, 1);
1732 closeResultSet(resultSet);
1733 closeStatement(statement);
1751 private CaseDbSchemaVersionNumber updateFromSchema7dot1toSchema7dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1752 if (schemaVersion.getMajor() != 7) {
1753 return schemaVersion;
1756 if (schemaVersion.getMinor() != 1) {
1757 return schemaVersion;
1760 Statement statement =
null;
1761 Statement updstatement =
null;
1762 ResultSet resultSet =
null;
1766 statement = connection.createStatement();
1767 statement.execute(
"ALTER TABLE blackboard_artifacts ADD COLUMN data_source_obj_id INTEGER NOT NULL DEFAULT -1");
1770 updstatement = connection.createStatement();
1771 resultSet = connection.executeQuery(statement,
"SELECT artifact_id, obj_id FROM blackboard_artifacts");
1772 while (resultSet.next()) {
1773 long artifact_id = resultSet.getLong(
"artifact_id");
1774 long obj_id = resultSet.getLong(
"obj_id");
1775 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
1776 updstatement.executeUpdate(
"UPDATE blackboard_artifacts SET data_source_obj_id = " + data_source_obj_id +
" "
1777 +
"WHERE artifact_id = " + artifact_id);
1779 closeResultSet(resultSet);
1780 closeStatement(statement);
1781 closeStatement(updstatement);
1786 statement = connection.createStatement();
1787 statement.execute(
"ALTER TABLE tag_names ADD COLUMN knownStatus INTEGER NOT NULL DEFAULT " + TskData.FileKnown.UNKNOWN.getFileKnownValue());
1790 if (this.dbType.equals(DbType.SQLITE)) {
1791 statement.execute(
"CREATE TABLE account_types (account_type_id INTEGER PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1792 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))");
1793 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))");
1795 statement.execute(
"CREATE TABLE account_types (account_type_id BIGSERIAL PRIMARY KEY, type_name TEXT UNIQUE NOT NULL, display_name TEXT NOT NULL)");
1796 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))");
1797 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))");
1801 statement.execute(
"CREATE INDEX artifact_artifact_objID ON blackboard_artifacts(artifact_obj_id)");
1802 statement.execute(
"CREATE INDEX relationships_account1 ON account_relationships(account1_id)");
1803 statement.execute(
"CREATE INDEX relationships_account2 ON account_relationships(account2_id)");
1804 statement.execute(
"CREATE INDEX relationships_relationship_source_obj_id ON account_relationships(relationship_source_obj_id)");
1805 statement.execute(
"CREATE INDEX relationships_date_time ON account_relationships(date_time)");
1806 statement.execute(
"CREATE INDEX relationships_relationship_type ON account_relationships(relationship_type)");
1807 statement.execute(
"CREATE INDEX relationships_data_source_obj_id ON account_relationships(data_source_obj_id)");
1809 return new CaseDbSchemaVersionNumber(7, 2);
1811 closeResultSet(resultSet);
1812 closeStatement(statement);
1813 closeStatement(updstatement);
1831 private CaseDbSchemaVersionNumber updateFromSchema7dot2toSchema8dot0(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1832 if (schemaVersion.getMajor() != 7) {
1833 return schemaVersion;
1836 if (schemaVersion.getMinor() != 2) {
1837 return schemaVersion;
1840 Statement updateSchemaStatement = connection.createStatement();
1841 Statement getExistingReportsStatement = connection.createStatement();
1842 ResultSet resultSet =
null;
1843 ResultSet existingReports =
null;
1851 updateSchemaStatement.execute(
"ALTER TABLE reports RENAME TO old_reports");
1854 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))");
1857 existingReports = getExistingReportsStatement.executeQuery(
"SELECT * FROM old_reports");
1858 while (existingReports.next()) {
1859 String path = existingReports.getString(2);
1860 long crtime = existingReports.getInt(3);
1861 String sourceModule = existingReports.getString(4);
1862 String reportName = existingReports.getString(5);
1865 insertObjectStatement.clearParameters();
1866 insertObjectStatement.setNull(1, java.sql.Types.BIGINT);
1867 insertObjectStatement.setLong(2, TskData.ObjectType.REPORT.getObjectType());
1868 connection.executeUpdate(insertObjectStatement);
1869 resultSet = insertObjectStatement.getGeneratedKeys();
1870 if (!resultSet.next()) {
1871 throw new TskCoreException(String.format(
"Failed to INSERT report %s (%s) in tsk_objects table", reportName, path));
1873 long objectId = resultSet.getLong(1);
1877 insertReportStatement.clearParameters();
1878 insertReportStatement.setLong(1, objectId);
1879 insertReportStatement.setString(2, path);
1880 insertReportStatement.setLong(3, crtime);
1881 insertReportStatement.setString(4, sourceModule);
1882 insertReportStatement.setString(5, reportName);
1883 connection.executeUpdate(insertReportStatement);
1887 updateSchemaStatement.execute(
"DROP TABLE old_reports");
1889 return new CaseDbSchemaVersionNumber(8, 0);
1891 closeResultSet(resultSet);
1892 closeResultSet(existingReports);
1893 closeStatement(updateSchemaStatement);
1894 closeStatement(getExistingReportsStatement);
1912 private CaseDbSchemaVersionNumber updateFromSchema8dot0toSchema8dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1913 if (schemaVersion.getMajor() != 8) {
1914 return schemaVersion;
1917 if (schemaVersion.getMinor() != 0) {
1918 return schemaVersion;
1923 try (Statement statement = connection.createStatement();) {
1925 if (this.dbType.equals(DbType.SQLITE)) {
1926 statement.execute(
"CREATE TABLE tsk_examiners (examiner_id INTEGER PRIMARY KEY, login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name) )");
1927 statement.execute(
"ALTER TABLE content_tags ADD COLUMN examiner_id INTEGER REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1928 statement.execute(
"ALTER TABLE blackboard_artifact_tags ADD COLUMN examiner_id INTEGER REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1930 statement.execute(
"CREATE TABLE tsk_examiners (examiner_id BIGSERIAL PRIMARY KEY, login_name TEXT NOT NULL, display_name TEXT, UNIQUE(login_name))");
1931 statement.execute(
"ALTER TABLE content_tags ADD COLUMN examiner_id BIGINT REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1932 statement.execute(
"ALTER TABLE blackboard_artifact_tags ADD COLUMN examiner_id BIGINT REFERENCES tsk_examiners(examiner_id) DEFAULT NULL");
1935 return new CaseDbSchemaVersionNumber(8, 1);
1954 private CaseDbSchemaVersionNumber updateFromSchema8dot1toSchema8dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
1955 if (schemaVersion.getMajor() != 8) {
1956 return schemaVersion;
1959 if (schemaVersion.getMinor() != 1) {
1960 return schemaVersion;
1965 try (Statement statement = connection.createStatement();) {
1966 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN sha1 TEXT DEFAULT NULL");
1967 statement.execute(
"ALTER TABLE tsk_image_info ADD COLUMN sha256 TEXT DEFAULT NULL");
1969 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_details TEXT");
1977 statement.execute(
"CREATE TABLE tsk_db_info_extended (name TEXT PRIMARY KEY, value TEXT NOT NULL)");
1978 ResultSet result = statement.executeQuery(
"SELECT tsk_ver FROM tsk_db_info");
1980 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + TSK_VERSION_KEY +
"', '" + result.getLong(
"tsk_ver") +
"')");
1981 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + SCHEMA_MAJOR_VERSION_KEY +
"', '8')");
1982 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + SCHEMA_MINOR_VERSION_KEY +
"', '2')");
1983 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + CREATION_SCHEMA_MAJOR_VERSION_KEY +
"', '0')");
1984 statement.execute(
"INSERT INTO tsk_db_info_extended (name, value) VALUES ('" + CREATION_SCHEMA_MINOR_VERSION_KEY +
"', '0')");
1986 String primaryKeyType;
1989 primaryKeyType =
"BIGSERIAL";
1992 primaryKeyType =
"INTEGER";
1995 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
1999 statement.execute(
"CREATE TABLE tsk_event_types ("
2000 +
" event_type_id " + primaryKeyType +
" PRIMARY KEY, "
2001 +
" display_name TEXT UNIQUE NOT NULL, "
2002 +
" super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
2003 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2004 +
" values( 0, 'Event Types', null)");
2005 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2006 +
" values(1, 'File System', 0)");
2007 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2008 +
" values(2, 'Web Activity', 0)");
2009 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2010 +
" values(3, 'Misc Types', 0)");
2011 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2012 +
" values(4, 'Modified', 1)");
2013 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2014 +
" values(5, 'Accessed', 1)");
2015 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2016 +
" values(6, 'Created', 1)");
2017 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2018 +
" values(7, 'Changed', 1)");
2021 statement.execute(
"CREATE TABLE tsk_event_descriptions ("
2022 +
" event_description_id " + primaryKeyType +
" PRIMARY KEY, "
2023 +
" full_description TEXT NOT NULL, "
2024 +
" med_description TEXT, "
2025 +
" short_description TEXT,"
2026 +
" data_source_obj_id BIGINT NOT NULL, "
2027 +
" file_obj_id BIGINT NOT NULL, "
2028 +
" artifact_id BIGINT, "
2029 +
" hash_hit INTEGER NOT NULL, "
2030 +
" tagged INTEGER NOT NULL, "
2031 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
2032 +
" FOREIGN KEY(file_obj_id) REFERENCES tsk_files(obj_id), "
2033 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
2036 statement.execute(
"CREATE TABLE tsk_events ( "
2037 +
" event_id " + primaryKeyType +
" PRIMARY KEY, "
2038 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2039 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id) ,"
2040 +
" time INTEGER NOT NULL) "
2044 statement.execute(
"CREATE INDEX events_time ON tsk_events(time)");
2045 statement.execute(
"CREATE INDEX events_type ON tsk_events(event_type_id)");
2046 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
2047 statement.execute(
"CREATE INDEX events_file_obj_id ON tsk_event_descriptions(file_obj_id) ");
2048 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
2049 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
2050 return new CaseDbSchemaVersionNumber(8, 2);
2070 private CaseDbSchemaVersionNumber updateFromSchema8dot2toSchema8dot3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2071 if (schemaVersion.getMajor() != 8) {
2072 return schemaVersion;
2075 if (schemaVersion.getMinor() != 2) {
2076 return schemaVersion;
2081 ResultSet resultSet =
null;
2083 try (Statement statement = connection.createStatement();) {
2088 String primaryKeyType;
2091 primaryKeyType =
"BIGSERIAL";
2094 primaryKeyType =
"INTEGER";
2097 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
2101 statement.execute(
"CREATE TABLE IF NOT EXISTS tsk_event_types ("
2102 +
" event_type_id " + primaryKeyType +
" PRIMARY KEY, "
2103 +
" display_name TEXT UNIQUE NOT NULL, "
2104 +
" super_type_id INTEGER REFERENCES tsk_event_types(event_type_id) )");
2106 resultSet = statement.executeQuery(
"SELECT * from tsk_event_types");
2110 if (!resultSet.next()) {
2112 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2113 +
" values( 0, 'Event Types', null)");
2114 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2115 +
" values(1, 'File System', 0)");
2116 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2117 +
" values(2, 'Web Activity', 0)");
2118 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2119 +
" values(3, 'Misc Types', 0)");
2120 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2121 +
" values(4, 'Modified', 1)");
2122 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2123 +
" values(5, 'Accessed', 1)");
2124 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2125 +
" values(6, 'Created', 1)");
2126 statement.execute(
"insert into tsk_event_types(event_type_id, display_name, super_type_id)"
2127 +
" values(7, 'Changed', 1)");
2132 statement.execute(
"DROP TABLE IF EXISTS tsk_events");
2136 statement.execute(
"DROP TABLE IF EXISTS tsk_event_descriptions");
2139 statement.execute(
"CREATE TABLE tsk_event_descriptions ("
2140 +
" event_description_id " + primaryKeyType +
" PRIMARY KEY, "
2141 +
" full_description TEXT NOT NULL, "
2142 +
" med_description TEXT, "
2143 +
" short_description TEXT,"
2144 +
" data_source_obj_id BIGINT NOT NULL, "
2145 +
" file_obj_id BIGINT NOT NULL, "
2146 +
" artifact_id BIGINT, "
2147 +
" hash_hit INTEGER NOT NULL, "
2148 +
" tagged INTEGER NOT NULL, "
2149 +
" UNIQUE(full_description, file_obj_id, artifact_id), "
2150 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
2151 +
" FOREIGN KEY(file_obj_id) REFERENCES tsk_files(obj_id), "
2152 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
2156 statement.execute(
"CREATE TABLE tsk_events ( "
2157 +
" event_id " + primaryKeyType +
" PRIMARY KEY, "
2158 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2159 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id) ,"
2160 +
" time INTEGER NOT NULL, "
2161 +
" UNIQUE (event_type_id, event_description_id, time))"
2165 statement.execute(
"UPDATE tsk_db_info_extended SET name = 'CREATION_SCHEMA_MAJOR_VERSION' WHERE name = 'CREATED_SCHEMA_MAJOR_VERSION'");
2166 statement.execute(
"UPDATE tsk_db_info_extended SET name = 'CREATION_SCHEMA_MINOR_VERSION' WHERE name = 'CREATED_SCHEMA_MINOR_VERSION'");
2168 return new CaseDbSchemaVersionNumber(8, 3);
2170 closeResultSet(resultSet);
2196 private CaseDbSchemaVersionNumber updateFromSchema8dot3toSchema8dot4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2197 if (schemaVersion.getMajor() != 8) {
2198 return schemaVersion;
2201 if (schemaVersion.getMinor() != 3) {
2202 return schemaVersion;
2205 Statement statement = connection.createStatement();
2206 ResultSet results =
null;
2213 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
2219 results = statement.executeQuery(
"SELECT column_name FROM information_schema.columns "
2220 +
"WHERE table_name='tsk_event_descriptions' and column_name='file_obj_id'");
2221 if (results.next()) {
2223 statement.execute(
"ALTER TABLE tsk_event_descriptions "
2224 +
"RENAME COLUMN file_obj_id TO content_obj_id");
2228 statement.execute(
"CREATE TABLE temp_tsk_events ( "
2229 +
" event_id BIGSERIAL PRIMARY KEY, "
2230 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2231 +
" event_description_id BIGINT NOT NULL REFERENCES tsk_event_descriptions(event_description_id),"
2232 +
" time BIGINT NOT NULL, "
2233 +
" UNIQUE (event_type_id, event_description_id, time))"
2237 statement.execute(
"INSERT INTO temp_tsk_events(event_id, event_type_id, "
2238 +
"event_description_id, time) SELECT * FROM tsk_events");
2241 statement.execute(
"DROP TABLE tsk_events");
2244 statement.execute(
"ALTER TABLE temp_tsk_events RENAME TO tsk_events");
2247 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
2248 statement.execute(
"CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id) ");
2249 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
2250 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
2251 statement.execute(
"CREATE INDEX events_time ON tsk_events(time) ");
2255 boolean hasMisnamedColumn =
false;
2256 results = statement.executeQuery(
"pragma table_info('tsk_event_descriptions')");
2257 while (results.next()) {
2258 if (results.getString(
"name") !=
null && results.getString(
"name").equals(
"file_obj_id")) {
2259 hasMisnamedColumn =
true;
2264 if (hasMisnamedColumn) {
2266 statement.execute(
"CREATE TABLE temp_tsk_event_descriptions ("
2267 +
" event_description_id INTEGER PRIMARY KEY, "
2268 +
" full_description TEXT NOT NULL, "
2269 +
" med_description TEXT, "
2270 +
" short_description TEXT,"
2271 +
" data_source_obj_id BIGINT NOT NULL, "
2272 +
" content_obj_id BIGINT NOT NULL, "
2273 +
" artifact_id BIGINT, "
2274 +
" hash_hit INTEGER NOT NULL, "
2275 +
" tagged INTEGER NOT NULL, "
2276 +
" UNIQUE(full_description, content_obj_id, artifact_id), "
2277 +
" FOREIGN KEY(data_source_obj_id) REFERENCES data_source_info(obj_id), "
2278 +
" FOREIGN KEY(content_obj_id) REFERENCES tsk_files(obj_id), "
2279 +
" FOREIGN KEY(artifact_id) REFERENCES blackboard_artifacts(artifact_id))"
2282 statement.execute(
"CREATE TABLE temp_tsk_events ( "
2283 +
" event_id INTEGER PRIMARY KEY, "
2284 +
" event_type_id BIGINT NOT NULL REFERENCES tsk_event_types(event_type_id) ,"
2285 +
" event_description_id BIGINT NOT NULL REFERENCES temp_tsk_event_descriptions(event_description_id),"
2286 +
" time INTEGER NOT NULL, "
2287 +
" UNIQUE (event_type_id, event_description_id, time))"
2291 statement.execute(
"INSERT INTO temp_tsk_event_descriptions(event_description_id, full_description, "
2292 +
"med_description, short_description, data_source_obj_id, content_obj_id, artifact_id, "
2293 +
"hash_hit, tagged) SELECT * FROM tsk_event_descriptions");
2295 statement.execute(
"INSERT INTO temp_tsk_events(event_id, event_type_id, "
2296 +
"event_description_id, time) SELECT * FROM tsk_events");
2299 statement.execute(
"DROP TABLE tsk_events");
2300 statement.execute(
"DROP TABLE tsk_event_descriptions");
2303 statement.execute(
"ALTER TABLE temp_tsk_event_descriptions RENAME TO tsk_event_descriptions");
2304 statement.execute(
"ALTER TABLE temp_tsk_events RENAME TO tsk_events");
2307 statement.execute(
"CREATE INDEX events_data_source_obj_id ON tsk_event_descriptions(data_source_obj_id) ");
2308 statement.execute(
"CREATE INDEX events_content_obj_id ON tsk_event_descriptions(content_obj_id) ");
2309 statement.execute(
"CREATE INDEX events_artifact_id ON tsk_event_descriptions(artifact_id) ");
2310 statement.execute(
"CREATE INDEX events_sub_type_time ON tsk_events(event_type_id, time) ");
2311 statement.execute(
"CREATE INDEX events_time ON tsk_events(time) ");
2315 throw new TskCoreException(
"Unsupported data base type: " +
getDatabaseType().toString());
2319 if (this.dbType.equals(DbType.SQLITE)) {
2320 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)");
2322 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)");
2326 insertAccountTypeIfNotExists(statement,
"IMO",
"IMO");
2327 insertAccountTypeIfNotExists(statement,
"LINE",
"LINE");
2328 insertAccountTypeIfNotExists(statement,
"SKYPE",
"Skype");
2329 insertAccountTypeIfNotExists(statement,
"TANGO",
"Tango");
2330 insertAccountTypeIfNotExists(statement,
"TEXTNOW",
"TextNow");
2331 insertAccountTypeIfNotExists(statement,
"THREEMA",
"ThreeMa");
2332 insertAccountTypeIfNotExists(statement,
"VIBER",
"Viber");
2333 insertAccountTypeIfNotExists(statement,
"XENDER",
"Xender");
2334 insertAccountTypeIfNotExists(statement,
"ZAPYA",
"Zapya");
2335 insertAccountTypeIfNotExists(statement,
"SHAREIT",
"ShareIt");
2337 return new CaseDbSchemaVersionNumber(8, 4);
2339 closeResultSet(results);
2340 closeStatement(statement);
2345 private CaseDbSchemaVersionNumber updateFromSchema8dot4toSchema8dot5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2346 if (schemaVersion.getMajor() != 8) {
2347 return schemaVersion;
2350 if (schemaVersion.getMinor() != 4) {
2351 return schemaVersion;
2354 Statement statement = connection.createStatement();
2359 statement.execute(
"CREATE TABLE tsk_tag_sets (tag_set_id BIGSERIAL PRIMARY KEY, name TEXT UNIQUE)");
2360 statement.execute(
"ALTER TABLE tag_names ADD COLUMN tag_set_id BIGINT REFERENCES tsk_tag_sets(tag_set_id)");
2363 statement.execute(
"CREATE TABLE tsk_tag_sets (tag_set_id INTEGER PRIMARY KEY, name TEXT UNIQUE)");
2364 statement.execute(
"ALTER TABLE tag_names ADD COLUMN tag_set_id INTEGER REFERENCES tsk_tag_sets(tag_set_id)");
2368 statement.execute(
"ALTER TABLE tag_names ADD COLUMN rank INTEGER");
2376 String insertStmt =
"INSERT INTO tsk_tag_sets (name) VALUES ('Project VIC')";
2378 statement.execute(insertStmt, Statement.RETURN_GENERATED_KEYS);
2380 statement.execute(insertStmt);
2382 try (ResultSet resultSet = statement.getGeneratedKeys()) {
2383 if (resultSet !=
null && resultSet.next()) {
2384 int tagSetId = resultSet.getInt(1);
2386 String updateQuery =
"UPDATE tag_names SET tag_set_id = %d, color = '%s', rank = %d, display_name = '%s' WHERE display_name = '%s'";
2387 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Red", 1,
"Child Exploitation (Illegal)",
"CAT-1: Child Exploitation (Illegal)"));
2388 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Lime", 2,
"Child Exploitation (Non-Illegal/Age Difficult)",
"CAT-2: Child Exploitation (Non-Illegal/Age Difficult)"));
2389 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Yellow", 3,
"CGI/Animation (Child Exploitive)",
"CAT-3: CGI/Animation (Child Exploitive)"));
2390 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Purple", 4,
"Exemplar/Comparison (Internal Use Only)",
"CAT-4: Exemplar/Comparison (Internal Use Only)"));
2391 statement.executeUpdate(String.format(updateQuery, tagSetId,
"Fuchsia", 5,
"Non-pertinent",
"CAT-5: Non-pertinent"));
2393 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')";
2394 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')";
2395 String deleteCat0 =
"DELETE FROM tag_names WHERE display_name = 'CAT-0: Uncategorized'";
2397 statement.executeUpdate(deleteArtifactTag);
2398 statement.executeUpdate(deleteCat0);
2401 throw new TskCoreException(
"Failed to retrieve the default tag_set_id from DB");
2411 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN data_source_obj_id BIGINT NOT NULL DEFAULT -1;");
2414 statement.execute(
"ALTER TABLE tsk_fs_info ADD COLUMN data_source_obj_id INTEGER NOT NULL DEFAULT -1;");
2417 Statement updateStatement = connection.createStatement();
2418 try (ResultSet resultSet = statement.executeQuery(
"SELECT obj_id FROM tsk_fs_info")) {
2419 while (resultSet.next()) {
2420 long fsId = resultSet.getLong(
"obj_id");
2421 long dataSourceId = getDataSourceObjectId(connection, fsId);
2422 updateStatement.executeUpdate(
"UPDATE tsk_fs_info SET data_source_obj_id = " + dataSourceId +
" WHERE obj_id = " + fsId +
";");
2425 closeStatement(updateStatement);
2428 return new CaseDbSchemaVersionNumber(8, 5);
2431 closeStatement(statement);
2436 private CaseDbSchemaVersionNumber updateFromSchema8dot5toSchema8dot6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2437 if (schemaVersion.getMajor() != 8) {
2438 return schemaVersion;
2441 if (schemaVersion.getMinor() != 5) {
2442 return schemaVersion;
2445 Statement statement = connection.createStatement();
2448 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN sha256 TEXT");
2450 return new CaseDbSchemaVersionNumber(8, 6);
2453 closeStatement(statement);
2458 @SuppressWarnings(
"deprecation")
2459 private CaseDbSchemaVersionNumber updateFromSchema8dot6toSchema9dot0(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection) throws SQLException, TskCoreException {
2460 if (schemaVersion.getMajor() != 8) {
2461 return schemaVersion;
2464 if (schemaVersion.getMinor() != 6) {
2465 return schemaVersion;
2468 Statement statement = connection.createStatement();
2471 String dateDataType =
"BIGINT";
2472 String bigIntDataType =
"BIGINT";
2473 String blobDataType =
"BYTEA";
2474 String primaryKeyType =
"BIGSERIAL";
2476 if (this.dbType.equals(DbType.SQLITE)) {
2477 dateDataType =
"INTEGER";
2478 bigIntDataType =
"INTEGER";
2479 blobDataType =
"BLOB";
2480 primaryKeyType =
"INTEGER";
2482 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN added_date_time " + dateDataType);
2483 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_settings TEXT");
2484 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_name TEXT");
2485 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN acquisition_tool_version TEXT");
2490 statement.execute(
"ALTER TABLE blackboard_artifact_types ADD COLUMN category_type INTEGER DEFAULT 0");
2491 String analysisTypeObjIdList
2492 = BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() +
", "
2493 + BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT.getTypeID() +
", "
2494 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT.getTypeID() +
", "
2495 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_FILE.getTypeID() +
", "
2496 + BlackboardArtifact.ARTIFACT_TYPE.TSK_TAG_ARTIFACT.getTypeID() +
", "
2497 + BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_DETECTED.getTypeID() +
", "
2498 + BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID() +
", "
2499 + BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID() +
", "
2500 + BlackboardArtifact.ARTIFACT_TYPE.TSK_FACE_DETECTED.getTypeID() +
", "
2501 + BlackboardArtifact.ARTIFACT_TYPE.TSK_ENCRYPTION_SUSPECTED.getTypeID() +
", "
2502 + BlackboardArtifact.ARTIFACT_TYPE.TSK_OBJECT_DETECTED.getTypeID() +
", "
2503 + BlackboardArtifact.ARTIFACT_TYPE.TSK_VERIFICATION_FAILED.getTypeID() +
", "
2504 + BlackboardArtifact.ARTIFACT_TYPE.TSK_DATA_SOURCE_USAGE.getTypeID() +
", "
2505 + BlackboardArtifact.ARTIFACT_TYPE.TSK_USER_CONTENT_SUSPECTED.getTypeID() +
", "
2506 + BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_ACCOUNT_TYPE.getTypeID() +
", "
2507 + BlackboardArtifact.ARTIFACT_TYPE.TSK_YARA_HIT.getTypeID() +
", "
2508 + BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CATEGORIZATION.getTypeID();
2509 statement.execute(
"UPDATE blackboard_artifact_types SET category_type = " + BlackboardArtifact.Category.ANALYSIS_RESULT.getID()
2510 +
" WHERE artifact_type_id IN (" + analysisTypeObjIdList +
")");
2513 statement.execute(
"CREATE TABLE tsk_file_attributes (id " + primaryKeyType +
" PRIMARY KEY, "
2514 +
"obj_id " + bigIntDataType +
" NOT NULL, "
2515 +
"attribute_type_id " + bigIntDataType +
" NOT NULL, "
2516 +
"value_type INTEGER NOT NULL, value_byte " + blobDataType +
", "
2517 +
"value_text TEXT, value_int32 INTEGER, value_int64 " + bigIntDataType +
", value_double NUMERIC(20, 10), "
2518 +
"FOREIGN KEY(obj_id) REFERENCES tsk_files(obj_id) ON DELETE CASCADE, "
2519 +
"FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
2522 statement.execute(
"CREATE TABLE tsk_analysis_results (artifact_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2523 +
"conclusion TEXT, "
2524 +
"significance INTEGER NOT NULL, "
2532 +
"configuration TEXT, justification TEXT, "
2533 +
"ignore_score INTEGER DEFAULT 0 "
2536 statement.execute(
"CREATE TABLE tsk_aggregate_score( obj_id " + bigIntDataType +
" PRIMARY KEY, "
2537 +
"data_source_obj_id " + bigIntDataType +
", "
2538 +
"significance INTEGER NOT NULL, "
2541 +
"UNIQUE (obj_id),"
2542 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2543 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE "
2547 statement.execute(
"CREATE TABLE tsk_persons (id " + primaryKeyType +
" PRIMARY KEY, "
2548 +
"name TEXT NOT NULL, "
2549 +
"UNIQUE(name)) ");
2552 statement.execute(
"CREATE TABLE tsk_hosts (id " + primaryKeyType +
" PRIMARY KEY, "
2553 +
"name TEXT NOT NULL, "
2554 +
"db_status INTEGER DEFAULT 0, "
2555 +
"person_id INTEGER, "
2556 +
"merged_into " + bigIntDataType +
", "
2557 +
"FOREIGN KEY(person_id) REFERENCES tsk_persons(id) ON DELETE SET NULL, "
2558 +
"FOREIGN KEY(merged_into) REFERENCES tsk_hosts(id), "
2559 +
"UNIQUE(name)) ");
2562 statement.execute(
"CREATE TABLE tsk_os_account_realms (id " + primaryKeyType +
" PRIMARY KEY, "
2563 +
"realm_name TEXT DEFAULT NULL, "
2564 +
"realm_addr TEXT DEFAULT NULL, "
2565 +
"realm_signature TEXT NOT NULL, "
2566 +
"scope_host_id " + bigIntDataType +
" DEFAULT NULL, "
2567 +
"scope_confidence INTEGER, "
2568 +
"db_status INTEGER DEFAULT 0, "
2569 +
"merged_into " + bigIntDataType +
" DEFAULT NULL, "
2570 +
"UNIQUE(realm_signature), "
2571 +
"FOREIGN KEY(scope_host_id) REFERENCES tsk_hosts(id),"
2572 +
"FOREIGN KEY(merged_into) REFERENCES tsk_os_account_realms(id) )");
2577 statement.execute(
"ALTER TABLE data_source_info ADD COLUMN host_id INTEGER REFERENCES tsk_hosts(id)");
2578 Statement updateStatement = connection.createStatement();
2579 try (ResultSet resultSet = statement.executeQuery(
"SELECT obj_id, device_id FROM data_source_info")) {
2580 Map<String, Long> hostMap =
new HashMap<>();
2582 while (resultSet.next()) {
2583 long objId = resultSet.getLong(
"obj_id");
2584 String deviceId = resultSet.getString(
"device_id");
2586 if (!hostMap.containsKey(deviceId)) {
2587 String hostName =
"Host " + hostIndex;
2588 updateStatement.execute(
"INSERT INTO tsk_hosts (name, db_status) VALUES ('" + hostName +
"', 0)");
2589 hostMap.put(deviceId, hostIndex);
2592 updateStatement.execute(
"UPDATE data_source_info SET host_id = " + hostMap.get(deviceId) +
" WHERE obj_id = " + objId);
2595 closeStatement(updateStatement);
2598 statement.execute(
"CREATE TABLE tsk_os_accounts (os_account_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2599 +
"login_name TEXT DEFAULT NULL, "
2600 +
"full_name TEXT DEFAULT NULL, "
2601 +
"realm_id " + bigIntDataType +
" NOT NULL, "
2602 +
"addr TEXT DEFAULT NULL, "
2603 +
"signature TEXT NOT NULL, "
2604 +
"status INTEGER, "
2606 +
"created_date " + bigIntDataType +
" DEFAULT NULL, "
2607 +
"db_status INTEGER DEFAULT 0, "
2608 +
"merged_into " + bigIntDataType +
" DEFAULT NULL, "
2609 +
"UNIQUE(signature, realm_id), "
2610 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2611 +
"FOREIGN KEY(realm_id) REFERENCES tsk_os_account_realms(id),"
2612 +
"FOREIGN KEY(merged_into) REFERENCES tsk_os_accounts(os_account_obj_id) )");
2614 statement.execute(
"CREATE TABLE tsk_os_account_attributes (id " + primaryKeyType +
" PRIMARY KEY, "
2615 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2616 +
"host_id " + bigIntDataType +
", "
2617 +
"source_obj_id " + bigIntDataType +
", "
2618 +
"attribute_type_id " + bigIntDataType +
" NOT NULL, "
2619 +
"value_type INTEGER NOT NULL, "
2620 +
"value_byte " + bigIntDataType +
", "
2621 +
"value_text TEXT, "
2622 +
"value_int32 INTEGER, value_int64 " + bigIntDataType +
", "
2623 +
"value_double NUMERIC(20, 10), "
2624 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), "
2625 +
"FOREIGN KEY(host_id) REFERENCES tsk_hosts(id), "
2626 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL, "
2627 +
"FOREIGN KEY(attribute_type_id) REFERENCES blackboard_attribute_types(attribute_type_id))");
2629 statement.execute(
"CREATE TABLE tsk_os_account_instances (id " + primaryKeyType +
" PRIMARY KEY, "
2630 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2631 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2632 +
"instance_type INTEGER NOT NULL, "
2633 +
"UNIQUE(os_account_obj_id, data_source_obj_id), "
2634 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id), "
2635 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE )");
2637 statement.execute(
"CREATE TABLE tsk_data_artifacts ( "
2638 +
"artifact_obj_id " + bigIntDataType +
" PRIMARY KEY, "
2639 +
"os_account_obj_id " + bigIntDataType +
", "
2640 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id)) ");
2643 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN owner_uid TEXT DEFAULT NULL");
2644 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN os_account_obj_id " + bigIntDataType +
" DEFAULT NULL REFERENCES tsk_os_accounts(os_account_obj_id) ");
2647 statement.execute(
"CREATE TABLE tsk_host_addresses (id " + primaryKeyType +
" PRIMARY KEY, "
2648 +
"address_type INTEGER NOT NULL, "
2649 +
"address TEXT NOT NULL, "
2650 +
"UNIQUE(address_type, address)) ");
2652 statement.execute(
"CREATE TABLE tsk_host_address_map (id " + primaryKeyType +
" PRIMARY KEY, "
2653 +
"host_id " + bigIntDataType +
" NOT NULL, "
2654 +
"addr_obj_id " + bigIntDataType +
" NOT NULL, "
2655 +
"source_obj_id " + bigIntDataType +
", "
2656 +
"time " + bigIntDataType +
", "
2657 +
"UNIQUE(host_id, addr_obj_id, time), "
2658 +
"FOREIGN KEY(host_id) REFERENCES tsk_hosts(id) ON DELETE CASCADE, "
2659 +
"FOREIGN KEY(addr_obj_id) REFERENCES tsk_host_addresses(id), "
2660 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL )");
2663 statement.execute(
"CREATE TABLE tsk_host_address_dns_ip_map (id " + primaryKeyType +
" PRIMARY KEY, "
2664 +
"dns_address_id " + bigIntDataType +
" NOT NULL, "
2665 +
"ip_address_id " + bigIntDataType +
" NOT NULL, "
2666 +
"source_obj_id " + bigIntDataType +
", "
2667 +
"time " + bigIntDataType +
", "
2668 +
"UNIQUE(dns_address_id, ip_address_id, time), "
2669 +
"FOREIGN KEY(dns_address_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE, "
2670 +
"FOREIGN KEY(ip_address_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE,"
2671 +
"FOREIGN KEY(source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE SET NULL )");
2674 statement.execute(
"CREATE TABLE tsk_host_address_usage (id " + primaryKeyType +
" PRIMARY KEY, "
2675 +
"addr_obj_id " + bigIntDataType +
" NOT NULL, "
2676 +
"obj_id " + bigIntDataType +
" NOT NULL, "
2677 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2678 +
"UNIQUE(addr_obj_id, obj_id), "
2679 +
"FOREIGN KEY(addr_obj_id) REFERENCES tsk_host_addresses(id) ON DELETE CASCADE, "
2680 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE )");
2682 return new CaseDbSchemaVersionNumber(9, 0);
2685 closeStatement(statement);
2690 private CaseDbSchemaVersionNumber updateFromSchema9dot0toSchema9dot1(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2691 if (schemaVersion.getMajor() != 9) {
2692 return schemaVersion;
2695 if (schemaVersion.getMinor() != 0) {
2696 return schemaVersion;
2699 Statement statement = connection.createStatement();
2700 ResultSet results =
null;
2708 results = statement.executeQuery(
"SELECT column_name FROM information_schema.columns "
2709 +
"WHERE table_name='tsk_analysis_results' and column_name='method_category'");
2710 if (results.next()) {
2712 statement.execute(
"ALTER TABLE tsk_analysis_results "
2713 +
"DROP COLUMN method_category");
2714 statement.execute(
"ALTER TABLE tsk_aggregate_score "
2715 +
"DROP COLUMN method_category");
2721 boolean hasMisnamedColumn =
false;
2722 results = statement.executeQuery(
"pragma table_info('tsk_analysis_results')");
2723 while (results.next()) {
2724 if (results.getString(
"name") !=
null && results.getString(
"name").equals(
"method_category")) {
2725 hasMisnamedColumn =
true;
2730 if (hasMisnamedColumn) {
2733 statement.execute(
"CREATE TABLE temp_tsk_analysis_results (artifact_obj_id INTEGER PRIMARY KEY, "
2734 +
"conclusion TEXT, "
2735 +
"significance INTEGER NOT NULL, "
2736 +
"configuration TEXT, justification TEXT, "
2737 +
"ignore_score INTEGER DEFAULT 0 "
2739 statement.execute(
"CREATE TABLE temp_tsk_aggregate_score( obj_id INTEGER PRIMARY KEY, "
2740 +
"data_source_obj_id INTEGER, "
2741 +
"significance INTEGER NOT NULL, "
2742 +
"UNIQUE (obj_id),"
2743 +
"FOREIGN KEY(obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE, "
2744 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE "
2748 statement.execute(
"INSERT INTO temp_tsk_analysis_results(artifact_obj_id, "
2749 +
"conclusion, justification, significance, configuration, ignore_score) "
2750 +
"SELECT artifact_obj_id, conclusion, justification, significance, configuration, ignore_score FROM tsk_analysis_results");
2751 statement.execute(
"INSERT INTO temp_tsk_aggregate_score(obj_id, "
2752 +
"data_source_obj_id, significance) "
2753 +
"SELECT obj_id, data_source_obj_id, significance FROM tsk_aggregate_score");
2756 statement.execute(
"DROP TABLE tsk_analysis_results");
2757 statement.execute(
"DROP TABLE tsk_aggregate_score");
2760 statement.execute(
"ALTER TABLE temp_tsk_analysis_results RENAME TO tsk_analysis_results");
2761 statement.execute(
"ALTER TABLE temp_tsk_aggregate_score RENAME TO tsk_aggregate_score");
2766 throw new TskCoreException(
"Unsupported database type: " +
getDatabaseType().toString());
2770 statement.execute(
"CREATE INDEX tsk_file_attributes_obj_id ON tsk_file_attributes(obj_id)");
2772 statement.execute(
"ALTER TABLE tsk_analysis_results ADD COLUMN priority INTEGER NOT NULL DEFAULT " + Score.Priority.NORMAL.getId());
2773 statement.execute(
"ALTER TABLE tsk_aggregate_score ADD COLUMN priority INTEGER NOT NULL DEFAULT " + Score.Priority.NORMAL.getId());
2775 statement.execute(
"UPDATE blackboard_artifact_types SET category_type = 1 WHERE artifact_type_id = 16");
2777 return new CaseDbSchemaVersionNumber(9, 1);
2779 closeResultSet(results);
2780 closeStatement(statement);
2798 private CaseDbSchemaVersionNumber updateFromSchema9dot1toSchema9dot2(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2799 if (schemaVersion.getMajor() != 9) {
2800 return schemaVersion;
2803 if (schemaVersion.getMinor() != 1) {
2804 return schemaVersion;
2807 Statement updateSchemaStatement = connection.createStatement();
2808 ResultSet results =
null;
2812 String bigIntDataType =
"BIGINT";
2813 String primaryKeyType =
"BIGSERIAL";
2815 if (this.dbType.equals(DbType.SQLITE)) {
2816 bigIntDataType =
"INTEGER";
2817 primaryKeyType =
"INTEGER";
2823 updateSchemaStatement.execute(
"ALTER TABLE tsk_os_account_instances RENAME TO old_tsk_os_account_instances");
2826 updateSchemaStatement.execute(
"CREATE TABLE tsk_os_account_instances (id " + primaryKeyType +
" PRIMARY KEY, "
2827 +
"os_account_obj_id " + bigIntDataType +
" NOT NULL, "
2828 +
"data_source_obj_id " + bigIntDataType +
" NOT NULL, "
2829 +
"instance_type INTEGER NOT NULL, "
2830 +
"UNIQUE(os_account_obj_id, data_source_obj_id, instance_type), "
2831 +
"FOREIGN KEY(os_account_obj_id) REFERENCES tsk_os_accounts(os_account_obj_id) ON DELETE CASCADE, "
2832 +
"FOREIGN KEY(data_source_obj_id) REFERENCES tsk_objects(obj_id) ON DELETE CASCADE ) ");
2835 updateSchemaStatement.execute(
"INSERT INTO tsk_os_account_instances(os_account_obj_id, "
2836 +
"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");
2839 updateSchemaStatement.execute(
"DROP TABLE old_tsk_os_account_instances");
2841 return new CaseDbSchemaVersionNumber(9, 2);
2843 closeResultSet(results);
2844 closeStatement(updateSchemaStatement);
2849 private CaseDbSchemaVersionNumber updateFromSchema9dot2toSchema9dot3(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2850 if (schemaVersion.getMajor() != 9) {
2851 return schemaVersion;
2854 if (schemaVersion.getMinor() != 2) {
2855 return schemaVersion;
2858 Statement statement = connection.createStatement();
2862 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN sha1 TEXT");
2865 return new CaseDbSchemaVersionNumber(9, 3);
2868 closeStatement(statement);
2873 private CaseDbSchemaVersionNumber updateFromSchema9dot3toSchema9dot4(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2874 if (schemaVersion.getMajor() != 9) {
2875 return schemaVersion;
2878 if (schemaVersion.getMinor() != 3) {
2879 return schemaVersion;
2882 Statement statement = connection.createStatement();
2886 statement.execute(
"CREATE TABLE file_collection_status_types (collection_status_type INTEGER PRIMARY KEY, name TEXT NOT NULL);");
2887 initCollectedStatusTypes(connection);
2890 statement.execute(
"ALTER TABLE tsk_files ADD COLUMN collected INTEGER NOT NULL DEFAULT " +
2891 TskData.CollectedStatus.UNKNOWN.getType() +
";");
2893 return new CaseDbSchemaVersionNumber(9, 4);
2896 closeStatement(statement);
2901 private CaseDbSchemaVersionNumber updateFromSchema9dot4toSchema9dot5(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2902 if (schemaVersion.getMajor() != 9) {
2903 return schemaVersion;
2906 if (schemaVersion.getMinor() != 4) {
2907 return schemaVersion;
2910 Statement statement = connection.createStatement();
2914 statement.execute(
"CREATE INDEX tsk_os_accounts_login_name_idx ON tsk_os_accounts(login_name, db_status, realm_id)");
2915 statement.execute(
"CREATE INDEX tsk_os_accounts_addr_idx ON tsk_os_accounts(addr, db_status, realm_id)");
2916 statement.execute(
"CREATE INDEX tsk_os_account_realms_realm_name_idx ON tsk_os_account_realms(realm_name)");
2917 statement.execute(
"CREATE INDEX tsk_os_account_realms_realm_addr_idx ON tsk_os_account_realms(realm_addr)");
2919 return new CaseDbSchemaVersionNumber(9, 5);
2922 closeStatement(statement);
2927 private CaseDbSchemaVersionNumber updateFromSchema9dot5toSchema9dot6(CaseDbSchemaVersionNumber schemaVersion, CaseDbConnection connection)
throws SQLException, TskCoreException {
2928 if (schemaVersion.getMajor() != 9) {
2929 return schemaVersion;
2932 if (schemaVersion.getMinor() != 5) {
2933 return schemaVersion;
2936 String insertSQL =
"";
2939 insertSQL =
"CREATE INDEX tsk_files_datasrc_md5_size_partial_index ON tsk_files(data_source_obj_id, md5, size) WHERE md5 IS NOT NULL AND size > 0";
2942 insertSQL =
"CREATE INDEX tsk_files_datasrc_md5_size_index ON tsk_files(data_source_obj_id, md5, size)";
2945 throw new TskCoreException(
"Unknown DB Type: " +
getDatabaseType().name());
2948 Statement statement = connection.createStatement();
2952 statement.execute(insertSQL);
2954 return new CaseDbSchemaVersionNumber(9, 6);
2957 closeStatement(statement);
2973 private void insertAccountTypeIfNotExists(Statement statement, String type_name, String display_name)
throws TskCoreException, SQLException {
2975 String insertSQL = String.format(
"INTO account_types(type_name, display_name) VALUES ('%s', '%s')", type_name, display_name);
2978 insertSQL =
"INSERT " + insertSQL +
" ON CONFLICT DO NOTHING";
2981 insertSQL =
"INSERT OR IGNORE " + insertSQL;
2984 throw new TskCoreException(
"Unknown DB Type: " +
getDatabaseType().name());
2986 statement.execute(insertSQL);
2996 static String extractExtension(
final String fileName) {
2998 int i = fileName.lastIndexOf(
".");
3000 if ((i > 0) && ((i + 1) < fileName.length())) {
3001 ext = fileName.substring(i + 1);
3012 return ext.toLowerCase();
3036 return CURRENT_DB_SCHEMA_VERSION;
3046 return caseDBSchemaCreationVersion;
3065 return dbBackupPath;
3116 return databaseName;
3136 rwLock.writeLock().lock();
3147 rwLock.writeLock().unlock();
3158 rwLock.readLock().lock();
3169 rwLock.readLock().unlock();
3198 return openCase(dbPath, contentProvider,
null);
3215 return openCase(dbPath, contentProvider,
null,
false);
3238 return new SleuthkitCase(dbPath, caseHandle,
DbType.
SQLITE, contentProvider, lockingApplicationName, useWAL);
3242 }
catch (Exception ex) {
3243 throw new TskCoreException(
"Failed to open case database at " + dbPath, ex);
3262 return openCase(databaseName, info, caseDir,
null);
3293 return new SleuthkitCase(info, databaseName, caseHandle, caseDir, contentProvider);
3294 }
catch (PropertyVetoException exp) {
3300 }
catch (Exception exp) {
3331 return newCase(dbPath, contentProvider,
null);
3351 return newCase(dbPath, contentProvider,
null,
false);
3377 CaseDatabaseFactory factory =
new CaseDatabaseFactory(dbPath);
3378 factory.createCaseDatabase();
3381 return new SleuthkitCase(dbPath, caseHandle,
DbType.
SQLITE, contentProvider, lockingApplicationName, useWAL);
3382 }
catch (Exception ex) {
3383 throw new TskCoreException(
"Failed to create case database at " + dbPath, ex);
3403 return newCase(caseName, info, caseDirPath,
null);
3425 String databaseName = createCaseDataBaseName(caseName);
3439 CaseDatabaseFactory factory =
new CaseDatabaseFactory(databaseName, info);
3440 factory.createCaseDatabase();
3443 return new SleuthkitCase(info, databaseName, caseHandle, caseDirPath, contentProvider);
3444 }
catch (PropertyVetoException exp) {
3447 }
catch (Exception exp) {
3462 private static String createCaseDataBaseName(String candidateDbName) {
3464 if (!candidateDbName.isEmpty()) {
3468 dbName = candidateDbName.replaceAll(
"[^\\p{ASCII}]",
"_");
3473 dbName = dbName.replaceAll(
"[\\p{Cntrl}]",
"_");
3478 dbName = dbName.replaceAll(
"[ /?:'\"\\\\]",
"_");
3483 dbName = dbName.toLowerCase();
3489 if ((dbName.length() > 0 && !(Character.isLetter(dbName.codePointAt(0))) && !(dbName.codePointAt(0) ==
'_'))) {
3490 dbName =
"_" + dbName;
3497 if (dbName.length() > MAX_DB_NAME_LEN_BEFORE_TIMESTAMP) {
3498 dbName = dbName.substring(0, MAX_DB_NAME_LEN_BEFORE_TIMESTAMP);
3510 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
3511 Date date =
new Date();
3512 dbName = dbName +
"_" + dateFormat.format(date);
3524 timelineEventsDisabled.set(
true);
3537 if (cachedCurrentExaminer !=
null) {
3538 return cachedCurrentExaminer;
3540 String loginName = System.getProperty(
"user.name");
3541 if (loginName ==
null || loginName.isEmpty()) {
3545 ResultSet resultSet =
null;
3546 CaseDbConnection connection =
null;
3549 connection = connections.getConnection();
3551 statement.clearParameters();
3552 statement.setString(1, loginName);
3553 resultSet = connection.executeQuery(statement);
3554 if (resultSet.next()) {
3555 cachedCurrentExaminer =
new Examiner(resultSet.getLong(
"examiner_id"), resultSet.getString(
"login_name"), resultSet.getString(
"display_name"));
3556 return cachedCurrentExaminer;
3558 throw new TskCoreException(
"Error getting examaminer for name = " + loginName);
3561 }
catch (SQLException ex) {
3562 throw new TskCoreException(
"Error getting examaminer for name = " + loginName, ex);
3564 closeResultSet(resultSet);
3565 closeConnection(connection);
3582 CaseDbConnection connection =
null;
3583 ResultSet resultSet =
null;
3586 connection = connections.getConnection();
3587 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_EXAMINER_BY_ID);
3588 statement.clearParameters();
3589 statement.setLong(1,
id);
3590 resultSet = connection.executeQuery(statement);
3591 if (resultSet.next()) {
3592 return new Examiner(resultSet.getLong(
"examiner_id"), resultSet.getString(
"login_name"), resultSet.getString(
"full_name"));
3594 throw new TskCoreException(
"Error getting examaminer for id = " +
id);
3596 }
catch (SQLException ex) {
3597 throw new TskCoreException(
"Error getting examaminer for id = " +
id, ex);
3599 closeResultSet(resultSet);
3600 closeConnection(connection);
3623 return makeAddImageProcess(timeZone, addUnallocSpace, noFatFsOrphans, imageCopyPath,
null);
3647 return this.caseHandle.initAddImageProcess(timeZone, addUnallocSpace, noFatFsOrphans, imageCopyPath, password,
this);
3659 CaseDbConnection connection =
null;
3661 ResultSet rs =
null;
3664 connection = connections.getConnection();
3665 s = connection.createStatement();
3666 rs = connection.executeQuery(s,
"SELECT obj_id, type FROM tsk_objects "
3667 +
"WHERE par_obj_id IS NULL");
3668 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
3670 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"),
ObjectType.
valueOf(rs.getShort(
"type"))));
3673 List<Content> rootObjs =
new ArrayList<Content>();
3674 for (ObjectInfo i : infos) {
3675 if (
null != i.type) {
3686 throw new TskCoreException(
"Parentless object has wrong type to be a root (ABSTRACTFILE, but not VIRTUAL_DIRECTORY: " + i.type);
3698 throw new TskCoreException(
"Parentless object has wrong type to be a root: " + i.type);
3703 }
catch (SQLException ex) {
3708 closeConnection(connection);
3727 synchronized (deviceIdToDatasourceObjIdMap) {
3728 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
3729 return new ArrayList<Long>(deviceIdToDatasourceObjIdMap.get(deviceId));
3732 CaseDbConnection connection =
null;
3734 ResultSet rs =
null;
3737 connection = connections.getConnection();
3738 s = connection.createStatement();
3739 rs = connection.executeQuery(s,
"SELECT obj_id FROM data_source_info WHERE device_id = '" + deviceId +
"'");
3740 List<Long> dataSourceObjIds =
new ArrayList<Long>();
3742 dataSourceObjIds.add(rs.getLong(
"obj_id"));
3745 long ds_obj_id = rs.getLong(
"obj_id");
3746 if (deviceIdToDatasourceObjIdMap.containsKey(deviceId)) {
3747 deviceIdToDatasourceObjIdMap.get(deviceId).add(ds_obj_id);
3749 deviceIdToDatasourceObjIdMap.put(deviceId,
new HashSet<Long>(Arrays.asList(ds_obj_id)));
3752 return dataSourceObjIds;
3753 }
catch (SQLException ex) {
3754 throw new TskCoreException(
"Error getting data sources", ex);
3758 closeConnection(connection);
3781 CaseDbConnection connection =
null;
3782 Statement statement =
null;
3783 ResultSet resultSet =
null;
3784 Statement statement2 =
null;
3785 ResultSet resultSet2 =
null;
3788 connection = connections.getConnection();
3789 statement = connection.createStatement();
3790 statement2 = connection.createStatement();
3791 resultSet = connection.executeQuery(statement,
3792 "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 "
3793 +
"FROM data_source_info AS ds "
3794 +
"LEFT JOIN tsk_image_info AS img "
3795 +
"ON ds.obj_id = img.obj_id");
3797 List<DataSource> dataSourceList =
new ArrayList<DataSource>();
3800 while (resultSet.next()) {
3802 Long objectId = resultSet.getLong(
"obj_id");
3803 String deviceId = resultSet.getString(
"device_id");
3804 String timezone = resultSet.getString(
"time_zone");
3805 String type = resultSet.getString(
"type");
3813 resultSet2 = connection.executeQuery(statement2,
"SELECT name FROM tsk_files WHERE tsk_files.obj_id = " + objectId);
3814 String dsName = (resultSet2.next()) ? resultSet2.getString(
"name") :
"";
3822 String parentPath =
"/";
3823 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, dsName, dirType, metaType, dirFlag, metaFlags, timezone,
null,
null,
null,
FileKnown.
UNKNOWN, parentPath);
3828 Long ssize = resultSet.getLong(
"ssize");
3829 Long size = resultSet.getLong(
"size");
3830 String md5 = resultSet.getString(
"md5");
3831 String sha1 = resultSet.getString(
"sha1");
3832 String sha256 = resultSet.getString(
"sha256");
3833 String name = resultSet.getString(
"display_name");
3835 List<String> imagePaths = imagePathsMap.get(objectId);
3837 if (imagePaths.size() > 0) {
3838 String path = imagePaths.get(0);
3839 name = (
new java.io.File(path)).getName();
3845 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name,
3846 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, size);
3849 dataSourceList.add(dataSource);
3852 return dataSourceList;
3854 }
catch (SQLException ex) {
3857 closeResultSet(resultSet);
3858 closeStatement(statement);
3859 closeResultSet(resultSet2);
3860 closeStatement(statement2);
3861 closeConnection(connection);
3887 CaseDbConnection connection =
null;
3888 Statement statement =
null;
3889 ResultSet resultSet =
null;
3890 Statement statement2 =
null;
3891 ResultSet resultSet2 =
null;
3894 connection = connections.getConnection();
3895 statement = connection.createStatement();
3896 statement2 = connection.createStatement();
3897 resultSet = connection.executeQuery(statement,
3898 "SELECT ds.device_id, ds.time_zone, img.type, img.ssize, img.size, img.md5, img.sha1, img.sha256, img.display_name "
3899 +
"FROM data_source_info AS ds "
3900 +
"LEFT JOIN tsk_image_info AS img "
3901 +
"ON ds.obj_id = img.obj_id "
3902 +
"WHERE ds.obj_id = " + objectId);
3903 if (resultSet.next()) {
3904 String deviceId = resultSet.getString(
"device_id");
3905 String timezone = resultSet.getString(
"time_zone");
3906 String type = resultSet.getString(
"type");
3914 resultSet2 = connection.executeQuery(statement2,
"SELECT name FROM tsk_files WHERE tsk_files.obj_id = " + objectId);
3915 String dsName = (resultSet2.next()) ? resultSet2.getString(
"name") :
"";
3922 String parentPath =
"/";
3923 dataSource =
new LocalFilesDataSource(
this, objectId, objectId, deviceId, dsName, dirType, metaType, dirFlag, metaFlags, timezone,
null,
null,
null,
FileKnown.
UNKNOWN, parentPath);
3928 Long ssize = resultSet.getLong(
"ssize");
3929 Long size = resultSet.getLong(
"size");
3930 String md5 = resultSet.getString(
"md5");
3931 String sha1 = resultSet.getString(
"sha1");
3932 String sha256 = resultSet.getString(
"sha256");
3933 String name = resultSet.getString(
"display_name");
3935 List<String> imagePaths = getImagePathsById(objectId, connection);
3937 if (imagePaths.size() > 0) {
3938 String path = imagePaths.get(0);
3939 name = (
new java.io.File(path)).getName();
3945 dataSource =
new Image(
this, objectId, Long.valueOf(type), deviceId, ssize, name,
3946 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, size);
3949 throw new TskDataException(String.format(
"There is no data source with obj_id = %d", objectId));
3951 }
catch (SQLException ex) {
3952 throw new TskCoreException(String.format(
"Error getting data source with obj_id = %d", objectId), ex);
3954 closeResultSet(resultSet);
3955 closeStatement(statement);
3956 closeResultSet(resultSet2);
3957 closeStatement(statement2);
3958 closeConnection(connection);
3979 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
3980 artifacts.addAll(blackboard.getArtifactsByType(blackboard.getArtifactType(artifactTypeID)));
3995 CaseDbConnection connection =
null;
3996 ResultSet rs =
null;
3999 connection = connections.getConnection();
4003 statement.clearParameters();
4004 statement.setLong(1, objId);
4005 rs = connection.executeQuery(statement);
4008 count = rs.getLong(
"count");
4011 }
catch (SQLException ex) {
4012 throw new TskCoreException(
"Error getting number of blackboard artifacts by content", ex);
4015 closeConnection(connection);
4031 CaseDbConnection connection =
null;
4032 ResultSet rs =
null;
4035 connection = connections.getConnection();
4039 statement.clearParameters();
4040 statement.setInt(1, artifactTypeID);
4041 rs = connection.executeQuery(statement);
4044 count = rs.getLong(
"count");
4047 }
catch (SQLException ex) {
4048 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
4051 closeConnection(connection);
4068 CaseDbConnection connection =
null;
4069 ResultSet rs =
null;
4072 connection = connections.getConnection();
4076 statement.clearParameters();
4077 statement.setInt(2, artifactTypeID);
4078 statement.setLong(1, dataSourceID);
4079 rs = connection.executeQuery(statement);
4082 count = rs.getLong(
"count");
4085 }
catch (SQLException ex) {
4086 throw new TskCoreException(String.format(
"Error getting number of blackboard artifacts by type (%d) and data source (%d)", artifactTypeID, dataSourceID), ex);
4089 closeConnection(connection);
4113 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4114 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4115 +
"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, "
4116 +
"types.type_name AS type_name, types.display_name AS display_name, "
4117 +
" arts.review_status_id AS review_status_id "
4118 +
"FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4119 +
"WHERE arts.artifact_id = attrs.artifact_id "
4120 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4121 +
" AND attrs.value_text = '" + value +
"'"
4122 +
" AND types.artifact_type_id=arts.artifact_type_id"
4125 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4126 List<Long> dataArtifactObjIds =
new ArrayList<>();
4127 while (resultSet.next()) {
4130 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4132 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4136 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4137 if (!analysisArtifactObjIds.isEmpty()) {
4141 if (!dataArtifactObjIds.isEmpty()) {
4145 }
catch (SQLException ex) {
4146 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
4172 String valSubStr =
"%" + subString;
4173 if (startsWith ==
false) {
4178 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4179 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4180 +
" 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, "
4181 +
" types.type_name AS type_name, types.display_name AS display_name, "
4182 +
" arts.review_status_id AS review_status_id "
4183 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4184 +
" WHERE arts.artifact_id = attrs.artifact_id "
4185 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4186 +
" AND LOWER(attrs.value_text) LIKE LOWER('" + valSubStr +
"')"
4187 +
" AND types.artifact_type_id=arts.artifact_type_id "
4189 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4190 List<Long> dataArtifactObjIds =
new ArrayList<>();
4191 while (resultSet.next()) {
4194 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4196 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4200 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4201 if (!analysisArtifactObjIds.isEmpty()) {
4205 if (!dataArtifactObjIds.isEmpty()) {
4209 }
catch (SQLException ex) {
4210 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
4234 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4235 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4236 +
" 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, "
4237 +
" types.type_name AS type_name, types.display_name AS display_name, "
4238 +
" arts.review_status_id AS review_status_id "
4239 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4240 +
"WHERE arts.artifact_id = attrs.artifact_id "
4241 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4242 +
" AND attrs.value_int32 = " + value
4243 +
" AND types.artifact_type_id=arts.artifact_type_id "
4245 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4246 List<Long> dataArtifactObjIds =
new ArrayList<>();
4247 while (resultSet.next()) {
4250 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4252 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4256 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4257 if (!analysisArtifactObjIds.isEmpty()) {
4261 if (!dataArtifactObjIds.isEmpty()) {
4265 }
catch (SQLException ex) {
4266 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
4291 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4292 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4293 +
" 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, "
4294 +
" types.type_name AS type_name, types.display_name AS display_name, "
4295 +
" arts.review_status_id AS review_status_id "
4296 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4297 +
" WHERE arts.artifact_id = attrs.artifact_id "
4298 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4299 +
" AND attrs.value_int64 = " + value
4300 +
" AND types.artifact_type_id=arts.artifact_type_id "
4302 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4303 List<Long> dataArtifactObjIds =
new ArrayList<>();
4304 while (resultSet.next()) {
4307 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4309 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4313 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4314 if (!analysisArtifactObjIds.isEmpty()) {
4318 if (!dataArtifactObjIds.isEmpty()) {
4322 }
catch (SQLException ex) {
4323 throw new TskCoreException(
"Error getting blackboard artifacts by attribute. " + ex.getMessage(), ex);
4348 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4349 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4350 +
" 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, "
4351 +
" types.type_name AS type_name, types.display_name AS display_name, "
4352 +
" arts.review_status_id AS review_status_id "
4353 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4354 +
" WHERE arts.artifact_id = attrs.artifact_id "
4355 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4356 +
" AND attrs.value_double = " + value
4357 +
" AND types.artifact_type_id=arts.artifact_type_id "
4359 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4360 List<Long> dataArtifactObjIds =
new ArrayList<>();
4361 while (resultSet.next()) {
4364 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4366 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4370 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4371 if (!analysisArtifactObjIds.isEmpty()) {
4375 if (!dataArtifactObjIds.isEmpty()) {
4379 }
catch (SQLException ex) {
4380 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
4406 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement();
4407 ResultSet resultSet = connection.executeQuery(statement,
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4408 +
" 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, "
4409 +
" types.type_name AS type_name, types.display_name AS display_name, "
4410 +
" arts.review_status_id AS review_status_id "
4411 +
" FROM blackboard_artifacts AS arts, blackboard_attributes AS attrs, blackboard_artifact_types AS types "
4412 +
" WHERE arts.artifact_id = attrs.artifact_id "
4413 +
" AND attrs.attribute_type_id = " + attrType.getTypeID()
4414 +
" AND attrs.value_byte = " + value
4415 +
" AND types.artifact_type_id=arts.artifact_type_id "
4417 List<Long> analysisArtifactObjIds =
new ArrayList<>();
4418 List<Long> dataArtifactObjIds =
new ArrayList<>();
4419 while (resultSet.next()) {
4422 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4424 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
4428 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4429 if (!analysisArtifactObjIds.isEmpty()) {
4433 if (!dataArtifactObjIds.isEmpty()) {
4437 }
catch (SQLException ex) {
4438 throw new TskCoreException(
"Error getting blackboard artifacts by attribute", ex);
4452 CaseDbConnection connection =
null;
4454 ResultSet rs =
null;
4457 connection = connections.getConnection();
4458 s = connection.createStatement();
4459 rs = connection.executeQuery(s,
"SELECT artifact_type_id, type_name, display_name, category_type FROM blackboard_artifact_types");
4463 rs.getString(
"type_name"), rs.getString(
"display_name"),
4466 return artifactTypes;
4467 }
catch (SQLException ex) {
4472 closeConnection(connection);
4486 String typeIdList =
"";
4493 String query =
"SELECT DISTINCT artifact_type_id FROM blackboard_artifacts "
4494 +
"WHERE artifact_type_id IN (" + typeIdList +
")";
4495 CaseDbConnection connection =
null;
4497 ResultSet rs =
null;
4500 connection = connections.getConnection();
4501 s = connection.createStatement();
4502 rs = connection.executeQuery(s, query);
4508 }
catch (SQLException ex) {
4513 closeConnection(connection);
4529 CaseDbConnection connection =
null;
4531 ResultSet rs =
null;
4534 connection = connections.getConnection();
4535 s = connection.createStatement();
4536 rs = connection.executeQuery(s,
4537 "SELECT DISTINCT arts.artifact_type_id AS artifact_type_id, "
4538 +
"types.type_name AS type_name, "
4539 +
"types.display_name AS display_name, "
4540 +
"types.category_type AS category_type "
4541 +
"FROM blackboard_artifact_types AS types "
4542 +
"INNER JOIN blackboard_artifacts AS arts "
4543 +
"ON arts.artifact_type_id = types.artifact_type_id");
4547 rs.getString(
"type_name"), rs.getString(
"display_name"),
4550 return uniqueArtifactTypes;
4551 }
catch (SQLException ex) {
4556 closeConnection(connection);
4569 CaseDbConnection connection =
null;
4571 ResultSet rs =
null;
4574 connection = connections.getConnection();
4575 s = connection.createStatement();
4576 rs = connection.executeQuery(s,
"SELECT attribute_type_id, type_name, display_name, value_type FROM blackboard_attribute_types");
4582 return attribute_types;
4583 }
catch (SQLException ex) {
4588 closeConnection(connection);
4605 CaseDbConnection connection =
null;
4607 ResultSet rs =
null;
4610 connection = connections.getConnection();
4611 s = connection.createStatement();
4612 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM blackboard_attribute_types");
4615 count = rs.getInt(
"count");
4618 }
catch (SQLException ex) {
4619 throw new TskCoreException(
"Error getting number of blackboard artifacts by type", ex);
4623 closeConnection(connection);
4640 private long getArtifactsCountHelper(
int artifactTypeID,
long obj_id)
throws TskCoreException {
4641 CaseDbConnection connection =
null;
4642 ResultSet rs =
null;
4645 connection = connections.getConnection();
4648 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.COUNT_ARTIFACTS_BY_SOURCE_AND_TYPE);
4649 statement.clearParameters();
4650 statement.setLong(1, obj_id);
4651 statement.setInt(2, artifactTypeID);
4652 rs = connection.executeQuery(statement);
4655 count = rs.getLong(
"count");
4658 }
catch (SQLException ex) {
4659 throw new TskCoreException(
"Error getting blackboard artifact count", ex);
4662 closeConnection(connection);
4680 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4681 artifacts.addAll(blackboard.getArtifactsBySourceId(
getArtifactType(artifactTypeName), obj_id));
4698 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4699 artifacts.addAll(blackboard.getArtifactsBySourceId(blackboard.getArtifactType(artifactTypeID), obj_id));
4732 int artifactTypeID = this.
getArtifactType(artifactTypeName).getTypeID();
4733 if (artifactTypeID == -1) {
4736 return getArtifactsCountHelper(artifactTypeID, obj_id);
4752 return getArtifactsCountHelper(artifactTypeID, obj_id);
4768 return getArtifactsCountHelper(artifactType.getTypeID(), obj_id);
4783 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4784 artifacts.addAll(blackboard.getArtifactsByType(
getArtifactType(artifactTypeName)));
4800 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4801 artifacts.addAll(blackboard.getArtifactsByType(blackboard.getArtifactType(artifactType.getTypeID())));
4823 String dataArtifactJoin =
"tsk_data_artifacts AS datarts ON datarts.artifact_obj_id = arts.artifact_obj_id";
4824 String analysisResultJoin =
"tsk_analysis_results AS anresult ON anresult.artifact_obj_id = arts.artifact_obj_id";
4825 String dataArtifactColumns =
", datarts.os_account_obj_id AS os_account_obj_id";
4826 String analysResultColumns =
", anresult.conclusion AS conclusion, anresult.significance AS significance, anresult.priority AS priority, anresult.configuration AS configuration, anresult.justification AS justification ";
4828 String formatQuery =
"SELECT DISTINCT arts.artifact_id AS artifact_id, "
4829 +
"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, "
4830 +
"types.type_name AS type_name, types.display_name AS display_name,"
4831 +
"arts.review_status_id AS review_status_id %s "
4832 +
"FROM blackboard_artifacts AS arts "
4833 +
"JOIN blackboard_attributes AS attrs ON arts.artifact_id = attrs.artifact_id "
4834 +
"JOIN blackboard_artifact_types AS types ON types.artifact_type_id = arts.artifact_type_id "
4836 +
"WHERE arts.artifact_id = attrs.artifact_id "
4837 +
"AND attrs.attribute_type_id = %d "
4838 +
" AND arts.artifact_type_id = %d "
4839 +
" AND attrs.value_text = '%s' "
4840 +
" AND types.artifact_type_id=arts.artifact_type_id "
4841 +
" AND arts.review_status_id != %d";
4843 String query = String.format(formatQuery,
4846 attrType.getTypeID(),
4847 artifactType.getTypeID(),
4852 try (CaseDbConnection connection = connections.getConnection(); Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, query)) {
4853 ArrayList<BlackboardArtifact> artifacts =
new ArrayList<>();
4856 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
4858 osAccountObjId =
null;
4861 artifacts.add(
new DataArtifact(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"),
4862 rs.getLong(
"artifact_obj_id"),
4863 rs.getObject(
"data_source_obj_id") !=
null ? rs.getLong(
"data_source_obj_id") :
null,
4864 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
4867 artifacts.add(
new AnalysisResult(
this, rs.getLong(
"artifact_id"), rs.getLong(
"obj_id"),
4868 rs.getLong(
"artifact_obj_id"),
4869 rs.getObject(
"data_source_obj_id") !=
null ? rs.getLong(
"data_source_obj_id") :
null,
4870 rs.getInt(
"artifact_type_id"), rs.getString(
"type_name"), rs.getString(
"display_name"),
4873 rs.getString(
"conclusion"), rs.getString(
"configuration"), rs.getString(
"justification")));
4877 }
catch (SQLException ex) {
4878 throw new TskCoreException(
"Error getting blackboard artifacts by artifact type and attribute. " + ex.getMessage(), ex);
4896 List<DataArtifact> dataArtifacts = blackboard.getDataArtifactsWhere(
"artifacts.artifact_id = " + artifactID);
4897 if (!dataArtifacts.isEmpty()) {
4898 return dataArtifacts.get(0);
4901 List<AnalysisResult> analysisResults = blackboard.getAnalysisResultsWhere(
"artifacts.artifact_id = " + artifactID);
4902 if (!analysisResults.isEmpty()) {
4903 return analysisResults.get(0);
4906 throw new TskCoreException(
"No blackboard artifact with id " + artifactID);
4919 try (CaseDbConnection connection = connections.getConnection();) {
4920 addBlackBoardAttribute(attr, artifactTypeId, connection);
4921 }
catch (SQLException ex) {
4922 throw new TskCoreException(
"Error adding blackboard attribute " + attr.toString(), ex);
4938 CaseDbConnection connection =
null;
4941 connection = connections.getConnection();
4942 connection.beginTransaction();
4944 addBlackBoardAttribute(attr, artifactTypeId, connection);
4946 connection.commitTransaction();
4947 }
catch (SQLException ex) {
4948 rollbackTransaction(connection);
4951 closeConnection(connection);
4957 PreparedStatement statement;
4958 switch (attr.getAttributeType().getValueType()) {
4961 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_STRING_ATTRIBUTE);
4962 statement.clearParameters();
4963 statement.setString(7, attr.getValueString());
4966 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_BYTE_ATTRIBUTE);
4967 statement.clearParameters();
4968 statement.setBytes(7, attr.getValueBytes());
4971 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_INT_ATTRIBUTE);
4972 statement.clearParameters();
4973 statement.setInt(7, attr.getValueInt());
4976 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
4977 statement.clearParameters();
4978 statement.setLong(7, attr.getValueLong());
4981 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_DOUBLE_ATTRIBUTE);
4982 statement.clearParameters();
4983 statement.setDouble(7, attr.getValueDouble());
4986 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_LONG_ATTRIBUTE);
4987 statement.clearParameters();
4988 statement.setLong(7, attr.getValueLong());
4993 statement.setLong(1, attr.getArtifactID());
4994 statement.setInt(2, artifactTypeId);
4995 statement.setString(3, attr.getSourcesCSV());
4996 statement.setString(4,
"");
4997 statement.setInt(5, attr.getAttributeType().getTypeID());
4998 statement.setLong(6, attr.getAttributeType().getValueType().getType());
4999 connection.executeUpdate(statement);
5002 void addFileAttribute(Attribute attr, CaseDbConnection connection)
throws SQLException, TskCoreException {
5003 PreparedStatement statement;
5004 statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_FILE_ATTRIBUTE, Statement.RETURN_GENERATED_KEYS);
5005 statement.clearParameters();
5007 statement.setLong(1, attr.getAttributeParentId());
5008 statement.setInt(2, attr.getAttributeType().getTypeID());
5009 statement.setLong(3, attr.getAttributeType().getValueType().getType());
5011 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE) {
5012 statement.setBytes(4, attr.getValueBytes());
5014 statement.setBytes(4,
null);
5017 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.STRING
5018 || attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.JSON) {
5019 statement.setString(5, attr.getValueString());
5021 statement.setString(5,
null);
5023 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.INTEGER) {
5024 statement.setInt(6, attr.getValueInt());
5026 statement.setNull(6, java.sql.Types.INTEGER);
5029 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DATETIME
5030 || attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.LONG) {
5031 statement.setLong(7, attr.getValueLong());
5033 statement.setNull(7, java.sql.Types.BIGINT);
5036 if (attr.getAttributeType().getValueType() == TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.DOUBLE) {
5037 statement.setDouble(8, attr.getValueDouble());
5039 statement.setNull(8, java.sql.Types.DOUBLE);
5042 connection.executeUpdate(statement);
5043 try (ResultSet resultSet = statement.getGeneratedKeys()) {
5044 if (!resultSet.next()) {
5045 throw new TskCoreException(String.format(
"Failed to insert file attribute "
5046 +
"with id=%d. The expected key was not generated", attr.getId()));
5049 attr.setId(resultSet.getLong(1));
5063 String addSourceToArtifactAttribute(BlackboardAttribute attr, String source)
throws TskCoreException {
5071 if (
null == source || source.isEmpty()) {
5072 throw new TskCoreException(
"Attempt to add null or empty source module name to artifact attribute");
5074 CaseDbConnection connection =
null;
5076 Statement queryStmt =
null;
5077 Statement updateStmt =
null;
5078 ResultSet result =
null;
5079 String newSources =
"";
5081 connection = connections.getConnection();
5082 connection.beginTransaction();
5083 String valueClause =
"";
5084 BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE valueType = attr.getAttributeType().getValueType();
5085 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
5086 switch (valueType) {
5092 valueClause =
" value_int32 = " + attr.getValueInt();
5096 valueClause =
" value_int64 = " + attr.getValueLong();
5099 valueClause =
" value_double = " + attr.getValueDouble();
5102 throw new TskCoreException(String.format(
"Unrecognized value type for attribute %s", attr.getDisplayString()));
5104 String query =
"SELECT source FROM blackboard_attributes WHERE"
5105 +
" artifact_id = " + attr.getArtifactID()
5106 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
5107 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
5108 +
" AND " + valueClause +
";";
5109 queryStmt = connection.createStatement();
5110 updateStmt = connection.createStatement();
5111 result = connection.executeQuery(queryStmt, query);
5119 statement.clearParameters();
5120 statement.setLong(1, attr.getArtifactID());
5121 statement.setLong(2, attr.getAttributeType().getTypeID());
5122 statement.setBytes(3, attr.getValueBytes());
5123 result = connection.executeQuery(statement);
5125 while (result.next()) {
5126 String oldSources = result.getString(
"source");
5127 if (
null != oldSources && !oldSources.isEmpty()) {
5128 Set<String> uniqueSources =
new HashSet<String>(Arrays.asList(oldSources.split(
",")));
5129 if (!uniqueSources.contains(source)) {
5130 newSources = oldSources +
"," + source;
5132 newSources = oldSources;
5135 newSources = source;
5137 if (BlackboardAttribute.TSK_BLACKBOARD_ATTRIBUTE_VALUE_TYPE.BYTE != valueType) {
5138 String update =
"UPDATE blackboard_attributes SET source = '" + newSources +
"' WHERE"
5139 +
" artifact_id = " + attr.getArtifactID()
5140 +
" AND attribute_type_id = " + attr.getAttributeType().getTypeID()
5141 +
" AND value_type = " + attr.getAttributeType().getValueType().getType()
5142 +
" AND " + valueClause +
";";
5143 connection.executeUpdate(updateStmt, update);
5151 statement.clearParameters();
5152 statement.setString(1, newSources);
5153 statement.setLong(2, attr.getArtifactID());
5154 statement.setLong(3, attr.getAttributeType().getTypeID());
5155 statement.setBytes(4, attr.getValueBytes());
5156 connection.executeUpdate(statement);
5159 connection.commitTransaction();
5161 }
catch (SQLException ex) {
5162 rollbackTransaction(connection);
5163 throw new TskCoreException(String.format(
"Error adding source module to attribute %s", attr.getDisplayString()), ex);
5165 closeResultSet(result);
5166 closeStatement(updateStmt);
5167 closeStatement(queryStmt);
5168 closeConnection(connection);
5190 return blackboard.getOrAddAttributeType(attrTypeString, valueType, displayName);
5192 throw new TskCoreException(
"Error adding artifact type: " + attrTypeString, ex);
5209 return blackboard.getAttributeType(attrTypeName);
5225 return blackboard.getArtifactType(artTypeName);
5268 }
catch (BlackboardException ex) {
5269 throw new TskCoreException(
"Error getting or adding artifact type with name: " + artifactTypeName, ex);
5286 return blackboard.getBlackboardAttributes(artifact);
5303 CaseDbConnection connection =
null;
5305 ResultSet rs =
null;
5308 connection = connections.getConnection();
5309 s = connection.createStatement();
5310 rs = connection.executeQuery(s,
"SELECT blackboard_attributes.artifact_id AS artifact_id, "
5311 +
"blackboard_attributes.source AS source, blackboard_attributes.context AS context, "
5312 +
"blackboard_attributes.attribute_type_id AS attribute_type_id, "
5313 +
"blackboard_attributes.value_type AS value_type, blackboard_attributes.value_byte AS value_byte, "
5314 +
"blackboard_attributes.value_text AS value_text, blackboard_attributes.value_int32 AS value_int32, "
5315 +
"blackboard_attributes.value_int64 AS value_int64, blackboard_attributes.value_double AS value_double "
5316 +
"FROM blackboard_attributes " + whereClause);
5317 ArrayList<BlackboardAttribute> matches =
new ArrayList<>();
5321 type = blackboard.getAttributeType(rs.getInt(
"attribute_type_id"));
5323 rs.getLong(
"artifact_id"),
5325 rs.getString(
"source"),
5326 rs.getString(
"context"),
5327 rs.getInt(
"value_int32"),
5328 rs.getLong(
"value_int64"),
5329 rs.getDouble(
"value_double"),
5330 rs.getString(
"value_text"),
5331 rs.getBytes(
"value_byte"),
this
5336 }
catch (SQLException ex) {
5337 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
5341 closeConnection(connection);
5358 String query =
"SELECT blackboard_artifacts.artifact_id AS artifact_id, "
5359 +
"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, "
5360 +
"blackboard_artifacts.review_status_id AS review_status_id "
5361 +
"FROM blackboard_artifacts " + whereClause;
5363 try (CaseDbConnection connection = connections.getConnection(); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(query)) {
5365 List<Long> analysisArtifactObjIds =
new ArrayList<>();
5366 List<Long> dataArtifactObjIds =
new ArrayList<>();
5367 while (resultSet.next()) {
5370 analysisArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
5372 dataArtifactObjIds.add(resultSet.getLong(
"artifact_obj_id"));
5376 ArrayList<BlackboardArtifact> matches =
new ArrayList<>();
5377 if (!analysisArtifactObjIds.isEmpty()) {
5381 if (!dataArtifactObjIds.isEmpty()) {
5386 }
catch (SQLException ex) {
5387 throw new TskCoreException(
"Error getting attributes using this where clause: " + whereClause, ex);
5411 throw new TskCoreException(
"Unknown artifact type for id: " + artifactTypeID);
5414 Category category = type.getCategory();
5415 if (category ==
null) {
5417 type.getDisplayName() ==
null ?
"<null>" : type.getDisplayName(),
5422 if (content ==
null) {
5427 case ANALYSIS_RESULT:
5450 @SuppressWarnings(
"deprecation")
5471 @SuppressWarnings(
"deprecation")
5474 try (CaseDbConnection connection = connections.getConnection()) {
5475 return newBlackboardArtifact(artifactTypeID, obj_id, type.getTypeName(), type.getDisplayName(), data_source_obj_id, connection);
5480 private BlackboardArtifact
newBlackboardArtifact(
int artifact_type_id,
long obj_id, String artifactTypeName, String artifactDisplayName)
throws TskCoreException {
5481 try (CaseDbConnection connection = connections.getConnection()) {
5482 long data_source_obj_id = getDataSourceObjectId(connection, obj_id);
5483 return this.
newBlackboardArtifact(artifact_type_id, obj_id, artifactTypeName, artifactDisplayName, data_source_obj_id, connection);
5487 PreparedStatement createInsertArtifactStatement(
int artifact_type_id,
long obj_id,
long artifact_obj_id,
long data_source_obj_id, CaseDbConnection connection)
throws TskCoreException, SQLException {
5489 PreparedStatement statement;
5490 if (dbType == DbType.POSTGRESQL) {
5491 statement = connection.getPreparedStatement(PREPARED_STATEMENT.POSTGRESQL_INSERT_ARTIFACT, Statement.RETURN_GENERATED_KEYS);
5492 statement.clearParameters();
5493 statement.setLong(1, obj_id);
5494 statement.setLong(2, artifact_obj_id);
5495 statement.setLong(3, data_source_obj_id);
5496 statement.setInt(4, artifact_type_id);
5499 statement.clearParameters();
5500 this.nextArtifactId++;
5501 statement.setLong(1, this.nextArtifactId);
5502 statement.setLong(2, obj_id);
5503 statement.setLong(3, artifact_obj_id);
5504 statement.setLong(4, data_source_obj_id);
5505 statement.setInt(5, artifact_type_id);
5528 private BlackboardArtifact
newBlackboardArtifact(
int artifact_type_id,
long obj_id, String artifactTypeName, String artifactDisplayName,
long data_source_obj_id, CaseDbConnection connection)
throws TskCoreException {
5529 BlackboardArtifact.Type type = blackboard.getArtifactType(artifact_type_id);
5531 if (type.getCategory() == BlackboardArtifact.Category.ANALYSIS_RESULT) {
5532 return blackboard.newAnalysisResult(type, obj_id, data_source_obj_id, Score.SCORE_UNKNOWN,
null,
null,
null, Collections.emptyList()).getAnalysisResult();
5534 return blackboard.newDataArtifact(type, obj_id, data_source_obj_id, Collections.emptyList(),
null);
5536 }
catch (BlackboardException ex) {
5537 throw new TskCoreException(
"Error creating a blackboard artifact", ex);
5559 AnalysisResult newAnalysisResult(BlackboardArtifact.Type artifactType,
long objId, Long dataSourceObjId, Score score, String conclusion, String configuration, String justification, CaseDbConnection connection)
throws TskCoreException {
5561 if (artifactType.getCategory() != BlackboardArtifact.Category.ANALYSIS_RESULT) {
5562 throw new TskCoreException(String.format(
"Artifact type (name = %s) is not of the AnalysisResult category. ", artifactType.getTypeName()));
5569 long artifactObjId = addObject(objId, TskData.ObjectType.ARTIFACT.getObjectType(), connection);
5572 PreparedStatement insertArtifactstatement;
5573 ResultSet resultSet =
null;
5575 insertArtifactstatement = createInsertArtifactStatement(artifactType.getTypeID(), objId, artifactObjId, dataSourceObjId, connection);
5576 connection.executeUpdate(insertArtifactstatement);
5577 resultSet = insertArtifactstatement.getGeneratedKeys();
5579 artifactID = resultSet.getLong(1);
5582 if (score.getSignificance() != Score.Significance.UNKNOWN
5583 || !StringUtils.isBlank(conclusion)
5584 || !StringUtils.isBlank(configuration)
5585 || !StringUtils.isBlank(justification)) {
5587 PreparedStatement analysisResultsStatement;
5590 analysisResultsStatement.clearParameters();
5592 analysisResultsStatement.setLong(1, artifactObjId);
5593 analysisResultsStatement.setString(2, (conclusion !=
null) ? conclusion :
"");
5594 analysisResultsStatement.setInt(3, score.getSignificance().getId());
5595 analysisResultsStatement.setInt(4, score.getPriority().getId());
5596 analysisResultsStatement.setString(5, (configuration !=
null) ? configuration :
"");
5597 analysisResultsStatement.setString(6, (justification !=
null) ? justification :
"");
5599 connection.executeUpdate(analysisResultsStatement);
5602 return new AnalysisResult(
this, artifactID, objId, artifactObjId, dataSourceObjId, artifactType.getTypeID(),
5603 artifactType.getTypeName(), artifactType.getDisplayName(),
5604 BlackboardArtifact.ReviewStatus.UNDECIDED,
true,
5605 score, (conclusion !=
null) ? conclusion :
"",
5606 (configuration !=
null) ? configuration :
"", (justification !=
null) ? justification :
"");
5609 closeResultSet(resultSet);
5612 }
catch (SQLException ex) {
5613 throw new TskCoreException(
"Error creating a analysis result", ex);
5631 boolean getContentHasChildren(Content content)
throws TskCoreException {
5632 CaseDbConnection connection =
null;
5633 ResultSet rs =
null;
5636 connection = connections.getConnection();
5640 statement.clearParameters();
5641 statement.setLong(1, content.getId());
5642 rs = connection.executeQuery(statement);
5643 boolean hasChildren =
false;
5645 hasChildren = rs.getInt(
"count") > 0;
5648 }
catch (SQLException e) {
5649 throw new TskCoreException(
"Error checking for children of parent " + content, e);
5652 closeConnection(connection);
5669 int getContentChildrenCount(Content content)
throws TskCoreException {
5671 if (!this.getHasChildren(content)) {
5675 CaseDbConnection connection =
null;
5676 ResultSet rs =
null;
5679 connection = connections.getConnection();
5683 statement.clearParameters();
5684 statement.setLong(1, content.getId());
5685 rs = connection.executeQuery(statement);
5686 int countChildren = -1;
5688 countChildren = rs.getInt(
"count");
5690 return countChildren;
5691 }
catch (SQLException e) {
5692 throw new TskCoreException(
"Error checking for children of parent " + content, e);
5695 closeConnection(connection);
5719 int getAbstractFileChildrenCountByType(Content content, List<TSK_FS_NAME_TYPE_ENUM> types)
throws TskCoreException {
5721 if (!this.getHasChildren(content)) {
5725 if (types ==
null || types.isEmpty()) {
5729 CaseDbConnection connection =
null;
5730 ResultSet rs =
null;
5733 connection = connections.getConnection();
5736 StringBuilder inClause =
new StringBuilder(
"?");
5737 for (
int i = 1; i < types.size(); i++) {
5738 inClause.append(
", ?");
5741 String sql =
"SELECT COUNT(*) AS count "
5742 +
"FROM tsk_objects "
5743 +
"INNER JOIN tsk_files ON tsk_objects.obj_id = tsk_files.obj_id "
5744 +
"WHERE (tsk_objects.par_obj_id = ? AND tsk_files.dir_type IN (" + inClause.toString() +
"))";
5746 PreparedStatement statement = connection.getConnection().prepareStatement(sql);
5747 statement.clearParameters();
5748 statement.setLong(1, content.getId());
5750 for (
int i = 0; i < types.size(); i++) {
5751 statement.setInt(i + 2, types.get(i).getValue());
5754 rs = connection.executeQuery(statement);
5755 int countChildren = -1;
5757 countChildren = rs.getInt(
"count");
5759 return countChildren;
5760 }
catch (SQLException e) {
5761 throw new TskCoreException(
"Error checking for children of parent " + content, e);
5764 closeConnection(connection);
5780 List<Content> getAbstractFileChildren(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
5781 CaseDbConnection connection =
null;
5782 ResultSet rs =
null;
5785 connection = connections.getConnection();
5788 statement.clearParameters();
5789 long parentId = parent.getId();
5790 statement.setLong(1, parentId);
5791 statement.setShort(2, type.getFileType());
5792 rs = connection.executeQuery(statement);
5793 return fileChildren(rs, connection, parentId);
5794 }
catch (SQLException ex) {
5795 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5798 closeConnection(connection);
5812 List<Content> getAbstractFileChildren(Content parent)
throws TskCoreException {
5813 CaseDbConnection connection =
null;
5814 ResultSet rs =
null;
5817 connection = connections.getConnection();
5820 statement.clearParameters();
5821 long parentId = parent.getId();
5822 statement.setLong(1, parentId);
5823 rs = connection.executeQuery(statement);
5824 return fileChildren(rs, connection, parentId);
5825 }
catch (SQLException ex) {
5826 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5829 closeConnection(connection);
5845 List<Long> getAbstractFileChildrenIds(Content parent, TSK_DB_FILES_TYPE_ENUM type)
throws TskCoreException {
5846 CaseDbConnection connection =
null;
5847 ResultSet rs =
null;
5850 connection = connections.getConnection();
5853 statement.clearParameters();
5854 statement.setLong(1, parent.getId());
5855 statement.setShort(2, type.getFileType());
5856 rs = connection.executeQuery(statement);
5857 List<Long> children =
new ArrayList<Long>();
5859 children.add(rs.getLong(
"obj_id"));
5862 }
catch (SQLException ex) {
5863 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5866 closeConnection(connection);
5880 List<Long> getAbstractFileChildrenIds(Content parent)
throws TskCoreException {
5881 CaseDbConnection connection =
null;
5882 ResultSet rs =
null;
5885 connection = connections.getConnection();
5888 statement.clearParameters();
5889 statement.setLong(1, parent.getId());
5890 rs = connection.executeQuery(statement);
5891 List<Long> children =
new ArrayList<Long>();
5893 children.add(rs.getLong(
"obj_id"));
5896 }
catch (SQLException ex) {
5897 throw new TskCoreException(
"Error getting AbstractFile children for Content", ex);
5900 closeConnection(connection);
5915 List<Long> getBlackboardArtifactChildrenIds(Content parent)
throws TskCoreException {
5916 CaseDbConnection connection =
null;
5917 ResultSet rs =
null;
5920 connection = connections.getConnection();
5923 statement.clearParameters();
5924 statement.setLong(1, parent.getId());
5925 rs = connection.executeQuery(statement);
5926 List<Long> children =
new ArrayList<Long>();
5928 children.add(rs.getLong(
"obj_id"));
5931 }
catch (SQLException ex) {
5932 throw new TskCoreException(
"Error getting children for BlackboardArtifact", ex);
5935 closeConnection(connection);
5949 List<Content> getBlackboardArtifactChildren(Content parent)
throws TskCoreException {
5950 long parentId = parent.getId();
5951 List<Content> lc =
new ArrayList<>();
5952 lc.addAll(blackboard.getAnalysisResults(parentId));
5953 lc.addAll(blackboard.getDataArtifactsBySource(parentId));
5965 Collection<ObjectInfo> getChildrenInfo(Content c)
throws TskCoreException {
5966 CaseDbConnection connection =
null;
5968 ResultSet rs =
null;
5971 connection = connections.getConnection();
5972 s = connection.createStatement();
5973 rs = connection.executeQuery(s,
"SELECT tsk_objects.obj_id AS obj_id, tsk_objects.type AS type "
5974 +
"FROM tsk_objects LEFT JOIN tsk_files "
5975 +
"ON tsk_objects.obj_id = tsk_files.obj_id "
5976 +
"WHERE tsk_objects.par_obj_id = " + c.getId()
5977 +
" ORDER BY tsk_objects.obj_id");
5978 Collection<ObjectInfo> infos =
new ArrayList<ObjectInfo>();
5980 infos.add(
new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type"))));
5983 }
catch (SQLException ex) {
5984 throw new TskCoreException(
"Error getting Children Info for Content", ex);
5988 closeConnection(connection);
6003 ObjectInfo getParentInfo(Content c)
throws TskCoreException {
6004 return getParentInfo(c.getId());
6017 ObjectInfo getParentInfo(
long contentId)
throws TskCoreException {
6019 CaseDbConnection connection =
null;
6021 ResultSet rs =
null;
6023 connection = connections.getConnection();
6024 s = connection.createStatement();
6025 rs = connection.executeQuery(s,
"SELECT parent.obj_id AS obj_id, parent.type AS type "
6026 +
"FROM tsk_objects AS parent INNER JOIN tsk_objects AS child "
6027 +
"ON child.par_obj_id = parent.obj_id "
6028 +
"WHERE child.obj_id = " + contentId);
6030 return new ObjectInfo(rs.getLong(
"obj_id"), ObjectType.valueOf(rs.getShort(
"type")));
6034 }
catch (SQLException ex) {
6035 throw new TskCoreException(
"Error getting Parent Info for Content: " + contentId, ex);
6039 closeConnection(connection);
6054 Directory getParentDirectory(FsContent fsc)
throws TskCoreException {
6059 ObjectInfo parentInfo = getParentInfo(fsc);
6060 if (parentInfo ==
null) {
6063 Directory parent =
null;
6064 if (parentInfo.type == ObjectType.ABSTRACTFILE) {
6065 parent = getDirectoryById(parentInfo.id, fsc.getFileSystem());
6067 throw new TskCoreException(
"Parent of FsContent (id: " + fsc.getId() +
") has wrong type to be directory: " + parentInfo.type);
6086 Content content = frequentlyUsedContentMap.get(
id);
6087 if (
null != content) {
6094 CaseDbConnection connection =
null;
6096 ResultSet rs =
null;
6099 connection = connections.getConnection();
6100 s = connection.createStatement();
6101 rs = connection.executeQuery(s,
"SELECT * FROM tsk_objects WHERE obj_id = " +
id +
" LIMIT 1");
6105 parentId = rs.getLong(
"par_obj_id");
6107 }
catch (SQLException ex) {
6112 closeConnection(connection);
6120 frequentlyUsedContentMap.put(
id, content);
6123 content = getVolumeSystemById(
id, parentId);
6126 content = getVolumeById(
id, parentId);
6127 frequentlyUsedContentMap.put(
id, content);
6130 content = getPoolById(
id, parentId);
6133 content = getFileSystemById(
id, parentId);
6134 frequentlyUsedContentMap.put(
id, content);
6145 frequentlyUsedContentMap.put(
id, content);
6158 content = hostAddressManager.getHostAddress(
id);
6174 String getFilePath(
long id) {
6176 String filePath =
null;
6177 CaseDbConnection connection =
null;
6178 ResultSet rs =
null;
6181 connection = connections.getConnection();
6183 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_LOCAL_PATH_FOR_FILE);
6184 statement.clearParameters();
6185 statement.setLong(1,
id);
6186 rs = connection.executeQuery(statement);
6188 filePath = rs.getString(
"path");
6190 }
catch (SQLException | TskCoreException ex) {
6191 logger.log(Level.SEVERE,
"Error getting file path for file " +
id, ex);
6194 closeConnection(connection);
6207 TskData.EncodingType getEncodingType(
long id) {
6209 TskData.EncodingType type = TskData.EncodingType.NONE;
6210 CaseDbConnection connection =
null;
6211 ResultSet rs =
null;
6214 connection = connections.getConnection();
6216 statement.clearParameters();
6217 statement.setLong(1,
id);
6218 rs = connection.executeQuery(statement);
6220 type = TskData.EncodingType.valueOf(rs.getInt(1));
6222 }
catch (SQLException | TskCoreException ex) {
6223 logger.log(Level.SEVERE,
"Error getting encoding type for file " +
id, ex);
6226 closeConnection(connection);
6240 String getFileParentPath(
long objectId, CaseDbConnection connection) {
6241 String parentPath =
null;
6243 ResultSet rs =
null;
6246 statement.clearParameters();
6247 statement.setLong(1, objectId);
6248 rs = connection.executeQuery(statement);
6250 parentPath = rs.getString(
"parent_path");
6252 }
catch (SQLException ex) {
6253 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
6269 String getFileName(
long objectId, CaseDbConnection connection) {
6270 String fileName =
null;
6272 ResultSet rs =
null;
6275 statement.clearParameters();
6276 statement.setLong(1, objectId);
6277 rs = connection.executeQuery(statement);
6279 fileName = rs.getString(
"name");
6281 }
catch (SQLException ex) {
6282 logger.log(Level.SEVERE,
"Error getting file parent_path for file " + objectId, ex);
6300 DerivedFile.DerivedMethod getDerivedMethod(
long id)
throws TskCoreException {
6302 DerivedFile.DerivedMethod method =
null;
6303 CaseDbConnection connection =
null;
6304 ResultSet rs1 =
null;
6305 ResultSet rs2 =
null;
6308 connection = connections.getConnection();
6311 statement.clearParameters();
6312 statement.setLong(1,
id);
6313 rs1 = connection.executeQuery(statement);
6315 int method_id = rs1.getInt(
"derived_id");
6316 String rederive = rs1.getString(
"rederive");
6317 method =
new DerivedFile.DerivedMethod(method_id, rederive);
6319 statement.clearParameters();
6320 statement.setInt(1, method_id);
6321 rs2 = connection.executeQuery(statement);
6323 method.setToolName(rs2.getString(
"tool_name"));
6324 method.setToolVersion(rs2.getString(
"tool_version"));
6325 method.setOther(rs2.getString(
"other"));
6328 }
catch (SQLException e) {
6329 logger.log(Level.SEVERE,
"Error getting derived method for file: " +
id, e);
6331 closeResultSet(rs2);
6332 closeResultSet(rs1);
6333 closeConnection(connection);
6350 CaseDbConnection connection = connections.getConnection();
6354 closeConnection(connection);
6372 ResultSet rs =
null;
6374 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_BY_ID);
6375 statement.clearParameters();
6376 statement.setLong(1, objectId);
6377 rs = connection.executeQuery(statement);
6378 List<AbstractFile> files = resultSetToAbstractFiles(rs, connection);
6379 if (files.size() > 0) {
6380 return files.get(0);
6384 }
catch (SQLException ex) {
6385 throw new TskCoreException(
"Error getting file by id, id = " + objectId, ex);
6405 CaseDbConnection connection =
null;
6406 ResultSet rs =
null;
6409 connection = connections.getConnection();
6413 statement.clearParameters();
6414 statement.setLong(1,
id);
6416 rs = connection.executeQuery(statement);
6418 throw new TskCoreException(
"Error getting artifacttype for artifact with artifact_obj_id = " +
id);
6423 switch (artifactType.getCategory()) {
6424 case ANALYSIS_RESULT:
6425 return blackboard.getAnalysisResultById(
id);
6427 return blackboard.getDataArtifactById(
id);
6429 throw new TskCoreException(String.format(
"Unknown artifact category for artifact with artifact_obj_id = %d, and artifact type = %s",
id, artifactType.getTypeName()));
6432 }
catch (SQLException ex) {
6433 throw new TskCoreException(
"Error getting artifacts by artifact_obj_id, artifact_obj_id = " +
id, ex);
6436 closeConnection(connection);
6456 String query =
"SELECT artifact_type_id, artifact_obj_id FROM blackboard_artifacts WHERE artifact_id = " + id;
6459 try (CaseDbConnection connection = connections.getConnection();
6460 Statement statement = connection.createStatement();
6461 ResultSet resultSet = statement.executeQuery(query);) {
6462 if (resultSet !=
null && resultSet.next()) {
6464 long artifactObjId = resultSet.getLong(
"artifact_obj_id");
6465 switch (artifactType.getCategory()) {
6466 case ANALYSIS_RESULT:
6467 return blackboard.getAnalysisResultById(artifactObjId);
6469 return blackboard.getDataArtifactById(artifactObjId);
6473 }
catch (SQLException ex) {
6474 throw new TskCoreException(
"Error getting artifacts by artifact id, artifact id = " +
id, ex);
6492 private long getFileSystemId(
long fileId, CaseDbConnection connection) {
6494 ResultSet rs =
null;
6497 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.SELECT_FILE_SYSTEM_BY_OBJECT);
6498 statement.clearParameters();
6499 statement.setLong(1, fileId);
6500 rs = connection.executeQuery(statement);
6502 ret = rs.getLong(
"fs_obj_id");
6507 }
catch (SQLException e) {
6508 logger.log(Level.SEVERE,
"Error checking file system id of a file, id = " + fileId, e);
6528 String query = String.format(
"SELECT COUNT(*) AS count FROM tsk_files WHERE obj_id = %d AND data_source_obj_id = %d", fileId, dataSource.getId());
6529 CaseDbConnection connection =
null;
6530 Statement statement =
null;
6531 ResultSet resultSet =
null;
6534 connection = connections.getConnection();
6535 statement = connection.createStatement();
6536 resultSet = connection.executeQuery(statement, query);
6538 return (resultSet.getLong(
"count") > 0L);
6539 }
catch (SQLException ex) {
6540 throw new TskCoreException(String.format(
"Error executing query %s", query), ex);
6542 closeResultSet(resultSet);
6543 closeStatement(statement);
6544 closeConnection(connection);
6558 private static boolean containsLikeWildcard(String str) {
6562 return str.contains(
"%") || str.contains(
"_");
6579 if (!containsLikeWildcard(fileName)) {
6580 ext = SleuthkitCase.extractExtension(fileName);
6583 List<AbstractFile> files =
new ArrayList<>();
6584 CaseDbConnection connection =
null;
6585 ResultSet resultSet =
null;
6588 connection = connections.getConnection();
6590 PreparedStatement statement;
6591 if (ext.isEmpty()) {
6593 statement.clearParameters();
6594 statement.setString(1, fileName.toLowerCase());
6595 statement.setLong(2, dataSource.getId());
6598 statement.clearParameters();
6599 statement.setString(1, ext);
6600 statement.setString(2, fileName.toLowerCase());
6601 statement.setLong(3, dataSource.getId());
6604 resultSet = connection.executeQuery(statement);
6605 files.addAll(resultSetToAbstractFiles(resultSet, connection));
6606 }
catch (SQLException e) {
6607 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles.exception.msg3.text"), e);
6609 closeResultSet(resultSet);
6610 closeConnection(connection);
6631 if (!containsLikeWildcard(fileName)) {
6632 ext = SleuthkitCase.extractExtension(fileName);
6635 List<AbstractFile> files =
new ArrayList<>();
6636 CaseDbConnection connection =
null;
6637 ResultSet resultSet =
null;
6640 connection = connections.getConnection();
6641 PreparedStatement statement;
6642 if (ext.isEmpty()) {
6644 statement.clearParameters();
6645 statement.setString(1, fileName.toLowerCase());
6646 statement.setString(2,
"%" + dirSubString.toLowerCase() +
"%");
6647 statement.setLong(3, dataSource.getId());
6650 statement.clearParameters();
6651 statement.setString(1, ext);
6652 statement.setString(2, fileName.toLowerCase());
6653 statement.setString(3,
"%" + dirSubString.toLowerCase() +
"%");
6654 statement.setLong(4, dataSource.getId());
6657 resultSet = connection.executeQuery(statement);
6658 files.addAll(resultSetToAbstractFiles(resultSet, connection));
6659 }
catch (SQLException e) {
6660 throw new TskCoreException(bundle.getString(
"SleuthkitCase.findFiles3.exception.msg3.text"), e);
6662 closeResultSet(resultSet);
6663 closeConnection(connection);
6688 if (
null != localTrans) {
6692 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
6710 long addObject(
long parentId,
int objectType, CaseDbConnection connection)
throws SQLException {
6711 ResultSet resultSet =
null;
6715 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.INSERT_OBJECT, Statement.RETURN_GENERATED_KEYS);
6716 statement.clearParameters();
6717 if (parentId != 0) {
6718 statement.setLong(1, parentId);
6720 statement.setNull(1, java.sql.Types.BIGINT);
6722 statement.setInt(2, objectType);
6723 connection.executeUpdate(statement);
6724 resultSet = statement.getGeneratedKeys();
6726 if (resultSet.next()) {
6727 if (parentId != 0) {
6728 setHasChildren(parentId);
6730 return resultSet.getLong(1);
6732 throw new SQLException(
"Error inserting object with parent " + parentId +
" into tsk_objects");
6735 closeResultSet(resultSet);
6758 if (transaction ==
null) {
6762 ResultSet resultSet =
null;
6765 CaseDbConnection connection = transaction.getConnection();
6770 if (isRootDirectory((
AbstractFile) parent, transaction)) {
6771 if (parent.
getName().isEmpty()) {
6774 parentPath =
"/" + parent.
getName() +
"/";
6792 statement.clearParameters();
6793 statement.setLong(1, newObjId);
6796 Long fileSystemObjectId =
null;
6797 if (0 != parentId) {
6798 fileSystemObjectId = this.getFileSystemId(parentId, connection);
6799 if (fileSystemObjectId != -1) {
6800 statement.setLong(2, fileSystemObjectId);
6802 statement.setNull(2, java.sql.Types.BIGINT);
6803 fileSystemObjectId =
null;
6806 statement.setNull(2, java.sql.Types.BIGINT);
6810 statement.setString(3, directoryName);
6814 statement.setShort(5, (
short) 1);
6818 statement.setShort(6, dirType.
getValue());
6820 statement.setShort(7, metaType.
getValue());
6824 statement.setShort(8, dirFlag.
getValue());
6827 statement.setShort(9, metaFlags);
6830 statement.setLong(10, 0);
6833 statement.setNull(11, java.sql.Types.BIGINT);
6834 statement.setNull(12, java.sql.Types.BIGINT);
6835 statement.setNull(13, java.sql.Types.BIGINT);
6836 statement.setNull(14, java.sql.Types.BIGINT);
6838 statement.setNull(15, java.sql.Types.VARCHAR);
6839 statement.setNull(16, java.sql.Types.VARCHAR);
6840 statement.setNull(17, java.sql.Types.VARCHAR);
6843 statement.setNull(19, java.sql.Types.VARCHAR);
6846 statement.setString(20, parentPath);
6849 long dataSourceObjectId;
6850 if (0 == parentId) {
6851 dataSourceObjectId = newObjId;
6853 dataSourceObjectId = getDataSourceObjectId(connection, parentId);
6855 statement.setLong(21, dataSourceObjectId);
6858 statement.setString(22,
null);
6860 statement.setString(23,
OsAccount.NO_OWNER_ID);
6861 statement.setNull(24, java.sql.Types.BIGINT);
6864 connection.executeUpdate(statement);
6866 return new VirtualDirectory(
this, newObjId, dataSourceObjectId, fileSystemObjectId, directoryName, dirType,
6869 }
catch (SQLException e) {
6870 throw new TskCoreException(
"Error creating virtual directory '" + directoryName +
"'", e);
6872 closeResultSet(resultSet);
6898 logger.log(Level.SEVERE, String.format(
"Failed to rollback transaction after exception: %s", ex.getMessage()), ex2);
6922 if (transaction ==
null) {
6926 ResultSet resultSet =
null;
6929 CaseDbConnection connection = transaction.getConnection();
6932 if ((parent ==
null) || isRootDirectory(parent, transaction)) {
6946 statement.clearParameters();
6947 statement.setLong(1, newObjId);
6950 statement.setNull(2, java.sql.Types.BIGINT);
6953 statement.setString(3, directoryName);
6957 statement.setShort(5, (
short) 1);
6961 statement.setShort(6, dirType.
getValue());
6963 statement.setShort(7, metaType.
getValue());
6967 statement.setShort(8, dirFlag.
getValue());
6970 statement.setShort(9, metaFlags);
6973 statement.setLong(10, 0);
6976 statement.setNull(11, java.sql.Types.BIGINT);
6977 statement.setNull(12, java.sql.Types.BIGINT);
6978 statement.setNull(13, java.sql.Types.BIGINT);
6979 statement.setNull(14, java.sql.Types.BIGINT);
6981 statement.setNull(15, java.sql.Types.VARCHAR);
6982 statement.setNull(16, java.sql.Types.VARCHAR);
6983 statement.setNull(17, java.sql.Types.VARCHAR);
6986 statement.setNull(19, java.sql.Types.VARCHAR);
6989 statement.setString(20, parentPath);
6992 long dataSourceObjectId = getDataSourceObjectId(connection, parentId);
6993 statement.setLong(21, dataSourceObjectId);
6996 statement.setString(22,
null);
6998 statement.setString(23,
OsAccount.NO_OWNER_ID);
6999 statement.setNull(24, java.sql.Types.BIGINT);
7002 connection.executeUpdate(statement);
7004 return new LocalDirectory(
this, newObjId, dataSourceObjectId, directoryName, dirType,
7007 }
catch (SQLException e) {
7008 throw new TskCoreException(
"Error creating local directory '" + directoryName +
"'", e);
7010 closeResultSet(resultSet);
7059 Statement statement =
null;
7061 CaseDbConnection connection = transaction.getConnection();
7074 statement = connection.createStatement();
7075 statement.executeUpdate(
"INSERT INTO data_source_info (obj_id, device_id, time_zone, host_id) "
7076 +
"VALUES(" + newObjId +
", '" + deviceId +
"', '" + timeZone +
"', " + host.getHostId() +
");");
7086 preparedStatement.clearParameters();
7087 preparedStatement.setLong(1, newObjId);
7088 preparedStatement.setNull(2, java.sql.Types.BIGINT);
7089 preparedStatement.setString(3, rootDirectoryName);
7091 preparedStatement.setShort(5, (
short) 1);
7095 preparedStatement.setShort(7, metaType.
getValue());
7097 preparedStatement.setShort(8, dirFlag.
getValue());
7100 preparedStatement.setShort(9, metaFlags);
7101 preparedStatement.setLong(10, 0);
7102 preparedStatement.setNull(11, java.sql.Types.BIGINT);
7103 preparedStatement.setNull(12, java.sql.Types.BIGINT);
7104 preparedStatement.setNull(13, java.sql.Types.BIGINT);
7105 preparedStatement.setNull(14, java.sql.Types.BIGINT);
7106 preparedStatement.setNull(15, java.sql.Types.VARCHAR);
7107 preparedStatement.setNull(16, java.sql.Types.VARCHAR);
7108 preparedStatement.setNull(17, java.sql.Types.VARCHAR);
7110 preparedStatement.setNull(19, java.sql.Types.VARCHAR);
7111 String parentPath =
"/";
7112 preparedStatement.setString(20, parentPath);
7113 preparedStatement.setLong(21, newObjId);
7114 preparedStatement.setString(22,
null);
7115 preparedStatement.setString(23,
OsAccount.NO_OWNER_ID);
7116 preparedStatement.setNull(24, java.sql.Types.BIGINT);
7120 connection.executeUpdate(preparedStatement);
7122 return new LocalFilesDataSource(
this, newObjId, newObjId, deviceId, rootDirectoryName, dirType, metaType, dirFlag, metaFlags, timeZone,
null,
null,
null,
FileKnown.
UNKNOWN, parentPath);
7124 }
catch (SQLException ex) {
7125 throw new TskCoreException(String.format(
"Error creating local files data source with device id %s and directory name %s", deviceId, rootDirectoryName), ex);
7127 closeStatement(statement);
7151 String timezone, String md5, String sha1, String sha256,
7154 return addImage(type, sectorSize, size, displayName, imagePaths, timezone, md5, sha1, sha256, deviceId,
null, transaction);
7178 String timezone, String md5, String sha1, String sha256,
7179 String deviceId,
Host host,
7182 return addImage(type, sectorSize, size, displayName, imagePaths, timezone, md5, sha1, sha256, deviceId, host,
null, transaction);
7208 String timezone, String md5, String sha1, String sha256,
7209 String deviceId,
Host host, String password,
7211 Statement statement =
null;
7214 CaseDbConnection connection = transaction.getConnection();
7220 preparedStatement.clearParameters();
7221 preparedStatement.setLong(1, newObjId);
7222 preparedStatement.setShort(2, (
short) type.getValue());
7223 preparedStatement.setLong(3, sectorSize);
7224 preparedStatement.setString(4, timezone);
7226 long savedSize = size < 0 ? 0 : size;
7227 preparedStatement.setLong(5, savedSize);
7228 preparedStatement.setString(6, md5);
7229 preparedStatement.setString(7, sha1);
7230 preparedStatement.setString(8, sha256);
7231 preparedStatement.setString(9, displayName);
7232 connection.executeUpdate(preparedStatement);
7235 for (
int i = 0; i < imagePaths.size(); i++) {
7237 preparedStatement.clearParameters();
7238 preparedStatement.setLong(1, newObjId);
7239 preparedStatement.setString(2, imagePaths.get(i));
7240 preparedStatement.setLong(3, i);
7241 connection.executeUpdate(preparedStatement);
7245 String name = displayName;
7246 if (name ==
null || name.isEmpty()) {
7247 if (imagePaths.size() > 0) {
7248 String path = imagePaths.get(0);
7249 name = (
new java.io.File(path)).getName();
7257 if (name.isEmpty()) {
7264 Map<String, Object> acquisitionToolMap =
new HashMap<>();
7265 if (password !=
null) {
7266 acquisitionToolMap.put(IMAGE_PASSWORD_KEY, password);
7268 String acquisitionToolJson = (
new Gson()).toJson(acquisitionToolMap);
7272 statement = connection.createStatement();
7273 preparedStatement.setLong(1, newObjId);
7274 preparedStatement.setString(2, deviceId);
7275 preparedStatement.setString(3, timezone);
7276 preparedStatement.setLong(4,
new Date().getTime());
7277 preparedStatement.setLong(5, host.getHostId());
7278 preparedStatement.setString(6, acquisitionToolJson);
7279 connection.executeUpdate(preparedStatement);
7282 return new Image(
this, newObjId, type.getValue(), deviceId, sectorSize, name,
7283 imagePaths.toArray(
new String[imagePaths.size()]), timezone, md5, sha1, sha256, savedSize);
7284 }
catch (SQLException ex) {
7285 if (!imagePaths.isEmpty()) {
7286 throw new TskCoreException(String.format(
"Error adding image with path %s to database", imagePaths.get(0)), ex);
7288 throw new TskCoreException(String.format(
"Error adding image with display name %s to database", displayName), ex);
7291 closeStatement(statement);
7312 CaseDbConnection connection = transaction.getConnection();
7313 long newObjId = addObject(parentObjId,
TskData.
ObjectType.
VS.getObjectType(), connection);
7318 preparedStatement.clearParameters();
7319 preparedStatement.setLong(1, newObjId);
7320 preparedStatement.setShort(2, (
short) type.getVsType());
7321 preparedStatement.setLong(3, imgOffset);
7322 preparedStatement.setLong(4, blockSize);
7323 connection.executeUpdate(preparedStatement);
7326 return new VolumeSystem(
this, newObjId,
"", type.getVsType(), imgOffset, blockSize);
7327 }
catch (SQLException ex) {
7328 throw new TskCoreException(String.format(
"Error creating volume system with parent ID %d and image offset %d",
7329 parentObjId, imgOffset), ex);
7348 public Volume addVolume(
long parentObjId,
long addr,
long start,
long length, String desc,
7352 CaseDbConnection connection = transaction.getConnection();
7357 PreparedStatement preparedStatement;
7363 preparedStatement.clearParameters();
7364 preparedStatement.setLong(1, newObjId);
7365 preparedStatement.setLong(2, addr);
7366 preparedStatement.setLong(3, start);
7367 preparedStatement.setLong(4, length);
7368 preparedStatement.setString(5, desc);
7369 preparedStatement.setShort(6, (
short) flags);
7370 connection.executeUpdate(preparedStatement);
7373 return new Volume(
this, newObjId, addr, start, length, flags, desc);
7374 }
catch (SQLException ex) {
7375 throw new TskCoreException(String.format(
"Error creating volume with address %d and parent ID %d", addr, parentObjId), ex);
7393 CaseDbConnection connection = transaction.getConnection();
7399 preparedStatement.clearParameters();
7400 preparedStatement.setLong(1, newObjId);
7401 preparedStatement.setShort(2, type.getValue());
7402 connection.executeUpdate(preparedStatement);
7405 return new Pool(
this, newObjId, type.getName(), type.getValue());
7406 }
catch (SQLException ex) {
7407 throw new TskCoreException(String.format(
"Error creating pool with type %d and parent ID %d", type.getValue(), parentObjId), ex);
7430 long rootInum,
long firstInum,
long lastInum, String displayName,
7434 CaseDbConnection connection = transaction.getConnection();
7435 long newObjId = addObject(parentObjId,
TskData.
ObjectType.
FS.getObjectType(), connection);
7438 long dataSourceId = getDataSourceObjectId(connection, newObjId);
7443 preparedStatement.clearParameters();
7444 preparedStatement.setLong(1, newObjId);
7445 preparedStatement.setLong(2, dataSourceId);
7446 preparedStatement.setLong(3, imgOffset);
7447 preparedStatement.setInt(4, type.getValue());
7448 preparedStatement.setLong(5, blockSize);
7449 preparedStatement.setLong(6, blockCount);
7450 preparedStatement.setLong(7, rootInum);
7451 preparedStatement.setLong(8, firstInum);
7452 preparedStatement.setLong(9, lastInum);
7453 preparedStatement.setString(10, displayName);
7454 connection.executeUpdate(preparedStatement);
7457 return new FileSystem(
this, newObjId, displayName, imgOffset, type, blockSize, blockCount, rootInum,
7458 firstInum, lastInum);
7459 }
catch (SQLException ex) {
7460 throw new TskCoreException(String.format(
"Error creating file system with image offset %d and parent ID %d",
7461 imgOffset, parentObjId), ex);
7492 long metaAddr,
int metaSeq,
7495 long ctime,
long crtime,
long atime,
long mtime,
7502 metaAddr, metaSeq, attrType, attrId, dirFlag, metaFlags, size,
7503 ctime, crtime, atime, mtime,
null,
null,
null, isFile, parent,
7505 Collections.emptyList(), transaction);
7509 return fileSystemFile;
7511 if (
null != transaction) {
7515 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
7560 long metaAddr,
int metaSeq,
7563 long ctime,
long crtime,
long atime,
long mtime,
7564 String md5Hash, String sha256Hash, String mimeType,
7565 boolean isFile,
Content parent, String ownerUid,
7566 OsAccount osAccount, List<Attribute> fileAttributes,
7573 dirFlag, metaFlags, size,
7574 ctime, crtime, atime, mtime,
7575 md5Hash, sha256Hash,
null,
7577 isFile, parent, ownerUid,
7578 osAccount, fileAttributes,
7623 long metaAddr,
int metaSeq,
7626 long ctime,
long crtime,
long atime,
long mtime,
7627 String md5Hash, String sha256Hash, String sha1Hash,
7628 String mimeType,
boolean isFile,
7629 Content parent, String ownerUid,
7630 OsAccount osAccount, List<Attribute> fileAttributes,
7636 dirFlag, metaFlags, size,
7637 ctime, crtime, atime, mtime,
7638 md5Hash, sha256Hash, sha1Hash,
7640 isFile, parent, ownerUid,
7687 long metaAddr,
int metaSeq,
7690 long ctime,
long crtime,
long atime,
long mtime,
7691 String md5Hash, String sha256Hash, String sha1Hash,
7692 String mimeType,
boolean isFile,
7693 Content parent, String ownerUid,
7695 List<Attribute> fileAttributes,
7699 Statement queryStatement =
null;
7700 String parentPath =
"/";
7702 CaseDbConnection connection = transaction.getConnection();
7710 if (isRootDirectory(parentFile, transaction)) {
7713 parentPath = parentFile.
getParentPath() + parent.getName() +
"/";
7720 statement.clearParameters();
7721 statement.setLong(1, objectId);
7722 statement.setLong(2, fsObjId);
7723 statement.setLong(3, dataSourceObjId);
7724 statement.setShort(4, (
short) attrType.getValue());
7725 statement.setInt(5, attrId);
7726 statement.setString(6, fileName);
7727 statement.setLong(7, metaAddr);
7728 statement.setInt(8, metaSeq);
7730 statement.setShort(10, (
short) 1);
7732 statement.setShort(11, dirType.
getValue());
7734 statement.setShort(12, metaType.
getValue());
7735 statement.setShort(13, dirFlag.getValue());
7736 statement.setShort(14, metaFlags);
7737 statement.setLong(15, size < 0 ? 0 : size);
7738 statement.setLong(16, ctime);
7739 statement.setLong(17, crtime);
7740 statement.setLong(18, atime);
7741 statement.setLong(19, mtime);
7742 statement.setString(20, md5Hash);
7743 statement.setString(21, sha256Hash);
7744 statement.setString(22, sha1Hash);
7745 statement.setString(23, mimeType);
7746 statement.setString(24, parentPath);
7747 final String extension = extractExtension(fileName);
7748 statement.setString(25, extension);
7749 statement.setString(26, ownerUid);
7750 if (
null != osAccount) {
7751 statement.setLong(27, osAccount.getId());
7753 statement.setNull(27, java.sql.Types.BIGINT);
7755 statement.setLong(28, collected.getType());
7757 connection.executeUpdate(statement);
7759 Long osAccountId = (osAccount !=
null) ? osAccount.getId() :
null;
7760 DerivedFile derivedFile =
new DerivedFile(
this, objectId, dataSourceObjId, fsObjId, fileName, dirType, metaType, dirFlag, metaFlags,
7761 size, ctime, crtime, atime, mtime, md5Hash, sha256Hash, sha1Hash,
null, parentPath,
null, parent.getId(), mimeType,
null, extension, ownerUid, osAccountId);
7763 if (!timelineEventsDisabled.get()) {
7764 timelineManager.addEventsForNewFile(derivedFile, connection);
7767 for (
Attribute fileAttribute : fileAttributes) {
7768 fileAttribute.setAttributeParentId(objectId);
7769 fileAttribute.setCaseDatabase(
this);
7770 addFileAttribute(fileAttribute, connection);
7773 if (osAccount !=
null) {
7777 return new org.sleuthkit.datamodel.File(
this, objectId, dataSourceObjId, fsObjId,
7778 attrType, attrId, fileName, metaAddr, metaSeq,
7779 dirType, metaType, dirFlag, metaFlags,
7780 size, ctime, crtime, atime, mtime,
7781 (
short) 0, 0, 0, md5Hash, sha256Hash, sha1Hash,
null, parentPath, mimeType,
7782 extension, ownerUid, osAccountId, collected, fileAttributes);
7784 }
catch (SQLException ex) {
7785 throw new TskCoreException(String.format(
"Failed to INSERT file system file %s (%s) with parent id %d in tsk_files table", fileName, parentPath, parent.getId()), ex);
7787 closeStatement(queryStatement);
7800 CaseDbConnection connection =
null;
7802 ResultSet rs =
null;
7805 connection = connections.getConnection();
7806 s = connection.createStatement();
7807 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE"
7809 +
" AND obj_id = data_source_obj_id"
7810 +
" ORDER BY dir_type, LOWER(name)");
7811 List<VirtualDirectory> virtDirRootIds =
new ArrayList<VirtualDirectory>();
7813 virtDirRootIds.add(virtualDirectory(rs, connection));
7815 return virtDirRootIds;
7816 }
catch (SQLException ex) {
7817 throw new TskCoreException(
"Error getting local files virtual folder id", ex);
7821 closeConnection(connection);
7839 assert (
null != fileRanges);
7840 if (
null == fileRanges) {
7844 assert (
null != parent);
7845 if (
null == parent) {
7851 parentPath = ((
AbstractFile) parent).getParentPath() + parent.getName() +
'/';
7857 Statement statement =
null;
7858 ResultSet resultSet =
null;
7862 CaseDbConnection connection = transaction.getConnection();
7865 Long fileSystemObjectId;
7866 if (0 != parent.getId()) {
7867 fileSystemObjectId = this.getFileSystemId(parent.getId(), connection);
7868 if (fileSystemObjectId == -1) {
7869 fileSystemObjectId =
null;
7872 fileSystemObjectId =
null;
7875 List<LayoutFile> fileRangeLayoutFiles =
new ArrayList<>();
7883 long end_byte_in_parent = fileRange.getByteStart() + fileRange.getByteLen() - 1;
7894 prepStmt.clearParameters();
7895 prepStmt.setLong(1, fileRangeId);
7896 if (fileSystemObjectId !=
null) {
7897 prepStmt.setLong(2, fileSystemObjectId);
7899 prepStmt.setNull(2, java.sql.Types.BIGINT);
7901 prepStmt.setString(3,
"Unalloc_" + parent.getId() +
"_" + fileRange.getByteStart() +
"_" + end_byte_in_parent);
7903 prepStmt.setNull(5, java.sql.Types.BIGINT);
7908 prepStmt.setLong(10, fileRange.getByteLen());
7909 prepStmt.setNull(11, java.sql.Types.BIGINT);
7910 prepStmt.setNull(12, java.sql.Types.BIGINT);
7911 prepStmt.setNull(13, java.sql.Types.BIGINT);
7912 prepStmt.setNull(14, java.sql.Types.BIGINT);
7913 prepStmt.setNull(15, java.sql.Types.VARCHAR);
7914 prepStmt.setNull(16, java.sql.Types.VARCHAR);
7915 prepStmt.setNull(17, java.sql.Types.VARCHAR);
7918 prepStmt.setNull(19, java.sql.Types.VARCHAR);
7919 prepStmt.setString(20, parentPath);
7920 prepStmt.setLong(21, parent.getId());
7923 prepStmt.setString(22,
null);
7925 prepStmt.setString(23,
OsAccount.NO_OWNER_ID);
7926 prepStmt.setNull(24, java.sql.Types.BIGINT);
7929 connection.executeUpdate(prepStmt);
7937 prepStmt.clearParameters();
7938 prepStmt.setLong(1, fileRangeId);
7939 prepStmt.setLong(2, fileRange.getByteStart());
7940 prepStmt.setLong(3, fileRange.getByteLen());
7941 prepStmt.setLong(4, fileRange.getSequence());
7942 connection.executeUpdate(prepStmt);
7947 fileRangeLayoutFiles.add(
new LayoutFile(
this,
7951 Long.toString(fileRange.getSequence()),
7957 fileRange.getByteLen(),
7961 parent.getUniquePath(),
7969 return fileRangeLayoutFiles;
7971 }
catch (SQLException ex) {
7972 throw new TskCoreException(
"Failed to add layout files to case database", ex);
7974 closeResultSet(resultSet);
7975 closeStatement(statement);
7977 if (
null != transaction) {
7981 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
7993 private class CarvedFileDirInfo {
7996 AtomicInteger count;
7999 this.currentFolder = currentFolder;
8000 count =
new AtomicInteger(0);
8003 CarvedFileDirInfo(VirtualDirectory currentFolder,
int count) {
8004 this.currentFolder = currentFolder;
8005 this.count =
new AtomicInteger(count);
8015 return count.get() >= MAX_CARVED_FILES_PER_FOLDER;
8021 void incrementFileCounter() {
8022 count.incrementAndGet();
8035 private CarvedFileDirInfo getMostRecentCarvedDirInfo(VirtualDirectory carvedFilesBaseDir)
throws TskCoreException {
8036 VirtualDirectory mostRecentDir =
null;
8037 for (Content child : carvedFilesBaseDir.getChildren()) {
8038 if (isValidCarvedFileSubfolder(child)) {
8039 if (mostRecentDir ==
null
8040 || (mostRecentDir.getId() < child.getId())) {
8041 mostRecentDir = (VirtualDirectory) child;
8046 if (mostRecentDir !=
null) {
8047 return new CarvedFileDirInfo(mostRecentDir, mostRecentDir.getChildrenCount());
8060 private boolean isValidCarvedFileSubfolder(Content subfolder) {
8061 if (!(subfolder instanceof VirtualDirectory)) {
8064 return subfolder.
getName().matches(
"^[0-9]+$");
8080 private CarvedFileDirInfo createCarvedFilesSubfolder(Content carvedFilesBaseDir, CarvedFileDirInfo currentSubfolderInfo)
throws TskCoreException {
8082 if (currentSubfolderInfo !=
null) {
8084 int currentIndex = Integer.parseInt(currentSubfolderInfo.currentFolder.getName());
8085 nextIndex = currentIndex + 1;
8086 }
catch (NumberFormatException ex) {
8087 throw new TskCoreException(
"Unexpected name format for carved files subdirectory with ID: " + currentSubfolderInfo.currentFolder.getId() +
" (" + currentSubfolderInfo.currentFolder.getName() +
")", ex);
8091 VirtualDirectory carvedFilesSubdir =
addVirtualDirectory(carvedFilesBaseDir.getId(), Integer.toString(nextIndex));
8092 return new CarvedFileDirInfo(carvedFilesSubdir);
8107 assert (
null != carvingResult);
8108 if (
null == carvingResult) {
8111 assert (
null != carvingResult.getParent());
8112 if (
null == carvingResult.getParent()) {
8115 assert (
null != carvingResult.getCarvedFiles());
8116 if (
null == carvingResult.getCarvedFiles()) {
8120 Statement statement =
null;
8121 ResultSet resultSet =
null;
8131 while (
null != root) {
8145 CarvedFileDirInfo carvedFilesDirInfo =
null;
8146 synchronized (carvedFileDirsLock) {
8148 carvedFilesDirInfo = rootIdsToCarvedFileDirs.get(root.
getId());
8149 if (carvedFilesDirInfo !=
null) {
8150 carvedFilesDirInfo.incrementFileCounter();
8153 if (carvedFilesDirInfo.isFull()) {
8154 carvedFilesDirInfo = createCarvedFilesSubfolder(carvedFilesDirInfo.currentFolder.getParent(), carvedFilesDirInfo);
8158 if (
null == carvedFilesDirInfo) {
8159 List<Content> rootChildren;
8161 rootChildren = ((
FileSystem) root).getRootDirectory().getChildren();
8165 for (
Content child : rootChildren) {
8171 carvedFilesDirInfo = getMostRecentCarvedDirInfo(baseDir);
8174 if (carvedFilesDirInfo ==
null) {
8175 carvedFilesDirInfo = createCarvedFilesSubfolder(baseDir,
null);
8179 if (carvedFilesDirInfo.isFull()) {
8180 carvedFilesDirInfo = createCarvedFilesSubfolder(baseDir, carvedFilesDirInfo);
8183 rootIdsToCarvedFileDirs.put(root.
getId(), carvedFilesDirInfo);
8187 if (carvedFilesDirInfo ==
null) {
8191 long parId = root.
getId();
8195 parId = rootDir.
getId();
8198 carvedFilesDirInfo = createCarvedFilesSubfolder(carvedFilesBaseDir,
null);
8199 rootIdsToCarvedFileDirs.put(root.
getId(), carvedFilesDirInfo);
8210 CaseDbConnection connection = transaction.getConnection();
8211 String parentPath = getFileParentPath(carvedFilesDirInfo.currentFolder.getId(), connection) + carvedFilesDirInfo.currentFolder.getName() +
"/";
8212 List<LayoutFile> carvedFiles =
new ArrayList<>();
8219 if (carvedFilesDirInfo.isFull()) {
8225 synchronized (carvedFileDirsLock) {
8227 carvedFilesDirInfo = rootIdsToCarvedFileDirs.get(root.
getId());
8228 if (carvedFilesDirInfo.isFull()) {
8229 carvedFilesDirInfo = createCarvedFilesSubfolder(carvedFilesBaseDir, carvedFilesDirInfo);
8230 rootIdsToCarvedFileDirs.put(root.
getId(), carvedFilesDirInfo);
8231 carvedFilesDir = carvedFilesDirInfo.currentFolder;
8237 connection = transaction.getConnection();
8238 parentPath = getFileParentPath(carvedFilesDir.
getId(), connection) + carvedFilesDir.
getName() +
"/";
8241 carvedFilesDirInfo.incrementFileCounter();
8260 prepStmt.clearParameters();
8261 prepStmt.setLong(1, carvedFileId);
8262 Long fileSystemObjectId;
8264 prepStmt.setLong(2, root.
getId());
8265 fileSystemObjectId = root.
getId();
8267 prepStmt.setNull(2, java.sql.Types.BIGINT);
8268 fileSystemObjectId =
null;
8270 prepStmt.setString(3, carvedFile.getName());
8272 prepStmt.setShort(5, (
short) 1);
8277 prepStmt.setLong(10, carvedFile.getSizeInBytes());
8278 prepStmt.setNull(11, java.sql.Types.BIGINT);
8279 prepStmt.setNull(12, java.sql.Types.BIGINT);
8280 prepStmt.setNull(13, java.sql.Types.BIGINT);
8281 prepStmt.setNull(14, java.sql.Types.BIGINT);
8282 prepStmt.setNull(15, java.sql.Types.VARCHAR);
8283 prepStmt.setNull(16, java.sql.Types.VARCHAR);
8284 prepStmt.setNull(17, java.sql.Types.VARCHAR);
8287 prepStmt.setNull(19, java.sql.Types.VARCHAR);
8288 prepStmt.setString(20, parentPath);
8290 prepStmt.setString(22, extractExtension(carvedFile.getName()));
8292 prepStmt.setString(23,
OsAccount.NO_OWNER_ID);
8293 prepStmt.setNull(24, java.sql.Types.BIGINT);
8296 connection.executeUpdate(prepStmt);
8304 for (
TskFileRange tskFileRange : carvedFile.getLayoutInParent()) {
8305 prepStmt.clearParameters();
8306 prepStmt.setLong(1, carvedFileId);
8307 prepStmt.setLong(2, tskFileRange.getByteStart());
8308 prepStmt.setLong(3, tskFileRange.getByteLen());
8309 prepStmt.setLong(4, tskFileRange.getSequence());
8310 connection.executeUpdate(prepStmt);
8320 carvedFile.getName(),
8326 carvedFile.getSizeInBytes(),
8340 }
catch (SQLException ex) {
8341 throw new TskCoreException(
"Failed to add carved files to case database", ex);
8343 closeResultSet(resultSet);
8344 closeStatement(statement);
8346 if (
null != transaction) {
8350 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
8387 long size,
long ctime,
long crtime,
long atime,
long mtime,
8388 boolean isFile,
Content parentObj,
8389 String rederiveDetails, String toolName, String toolVersion,
8394 size, ctime, crtime, atime, mtime,
8396 rederiveDetails, toolName, toolVersion,
8397 otherDetails, encodingType, transaction);
8407 long size,
long ctime,
long crtime,
long atime,
long mtime,
8408 boolean isFile,
Content parentObj,
8409 String rederiveDetails, String toolName, String toolVersion,
8412 localPath = localPath.replaceAll(
"^[/\\\\]+",
"");
8416 CaseDbConnection connection = transaction.getConnection();
8418 final long parentId = parentObj.getId();
8419 String parentPath =
"";
8421 parentPath = parentObj.getUniquePath() +
'/' + parentObj.getName() +
'/';
8423 parentPath = ((
AbstractFile) parentObj).getParentPath() + parentObj.getName() +
'/';
8436 statement.clearParameters();
8437 statement.setLong(1, newObjId);
8440 Long fsObjId = this.getFileSystemId(parentId, connection);
8441 if (fsObjId != -1) {
8442 statement.setLong(2, fsObjId);
8445 statement.setNull(2, java.sql.Types.BIGINT);
8447 statement.setString(3, fileName);
8451 statement.setShort(5, (
short) 1);
8455 statement.setShort(6, dirType.
getValue());
8457 statement.setShort(7, metaType.
getValue());
8461 statement.setShort(8, dirFlag.
getValue());
8464 statement.setShort(9, metaFlags);
8468 long savedSize = size < 0 ? 0 : size;
8469 statement.setLong(10, savedSize);
8473 statement.setLong(11, ctime);
8474 statement.setLong(12, crtime);
8475 statement.setLong(13, atime);
8476 statement.setLong(14, mtime);
8478 statement.setNull(15, java.sql.Types.VARCHAR);
8479 statement.setNull(16, java.sql.Types.VARCHAR);
8480 statement.setNull(17, java.sql.Types.VARCHAR);
8483 statement.setNull(19, java.sql.Types.VARCHAR);
8486 statement.setString(20, parentPath);
8489 long dataSourceObjId = getDataSourceObjectId(connection, parentObj);
8490 statement.setLong(21, dataSourceObjId);
8491 final String extension = extractExtension(fileName);
8493 statement.setString(22, extension);
8495 statement.setString(23,
OsAccount.NO_OWNER_ID);
8496 statement.setNull(24, java.sql.Types.BIGINT);
8499 connection.executeUpdate(statement);
8502 addFilePath(connection, newObjId, localPath, encodingType);
8504 DerivedFile derivedFile =
new DerivedFile(
this, newObjId, dataSourceObjId, fsObjId, fileName, dirType, metaType, dirFlag, metaFlags,
8505 savedSize, ctime, crtime, atime, mtime,
null,
null,
null,
null, parentPath, localPath, parentId,
null, encodingType, extension,
OsAccount.NO_OWNER_ID,
OsAccount.NO_ACCOUNT);
8507 if (!timelineEventsDisabled.get()) {
8508 timelineManager.addEventsForNewFile(derivedFile, connection);
8513 }
catch (SQLException ex) {
8514 throw new TskCoreException(
"Failed to add derived file to case database", ex);
8549 long size,
long ctime,
long crtime,
long atime,
long mtime,
8550 boolean isFile, String mimeType,
8551 String rederiveDetails, String toolName, String toolVersion,
8560 size, ctime, crtime, atime, mtime,
8562 rederiveDetails, toolName, toolVersion,
8563 otherDetails, encodingType, parentObj, trans);
8567 if (trans !=
null) {
8575 long size,
long ctime,
long crtime,
long atime,
long mtime,
8576 boolean isFile, String mimeType,
8577 String rederiveDetails, String toolName, String toolVersion,
8582 localPath = localPath.replaceAll(
"^[/\\\\]+",
"");
8584 ResultSet rs =
null;
8586 final long parentId = parentObj.getId();
8587 String parentPath =
"";
8589 parentPath = parentObj.getUniquePath() +
'/' + parentObj.getName() +
'/';
8591 parentPath = ((
AbstractFile) parentObj).getParentPath() + parentObj.getName() +
'/';
8596 statement.clearParameters();
8603 statement.setShort(2, dirType.
getValue());
8605 statement.setShort(3, metaType.
getValue());
8609 statement.setShort(4, dirFlag.
getValue());
8612 statement.setShort(5, metaFlags);
8616 long savedSize = size < 0 ? 0 : size;
8617 statement.setLong(6, savedSize);
8621 statement.setLong(7, ctime);
8622 statement.setLong(8, crtime);
8623 statement.setLong(9, atime);
8624 statement.setLong(10, mtime);
8625 statement.setString(11, mimeType);
8626 statement.setString(12, String.valueOf(derivedFile.getId()));
8627 trans.getConnection().executeUpdate(statement);
8630 updateFilePath(trans.getConnection(), derivedFile.getId(), localPath, encodingType);
8632 long dataSourceObjId = getDataSourceObjectId(trans.getConnection(), parentObj);
8633 Long fileSystemObjId = derivedFile.getFileSystemObjectId().orElse(
null);
8634 final String extension = extractExtension(derivedFile.getName());
8635 return new DerivedFile(
this, derivedFile.getId(), dataSourceObjId, fileSystemObjId, derivedFile.getName(), dirType, metaType, dirFlag, metaFlags,
8636 savedSize, ctime, crtime, atime, mtime,
null,
null,
null,
null, parentPath, localPath, parentId,
null, encodingType, extension,
8637 derivedFile.getOwnerUid().orElse(
null), derivedFile.getOsAccountObjectId().orElse(
null));
8638 }
catch (SQLException ex) {
8639 throw new TskCoreException(
"Failed to add derived file to case database", ex);
8665 long size,
long ctime,
long crtime,
long atime,
long mtime,
8671 LocalFile created =
addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime, isFile, encodingType, parent, localTrans);
8676 if (
null != localTrans) {
8680 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
8711 long size,
long ctime,
long crtime,
long atime,
long mtime,
8716 size, ctime, crtime, atime, mtime,
8718 isFile, encodingType,
8719 parent, transaction);
8751 long size,
long ctime,
long crtime,
long atime,
long mtime,
8752 String md5, String sha256,
FileKnown known, String mimeType,
8756 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime,
8757 md5, sha256, known, mimeType, isFile, encodingType,
8793 long size,
long ctime,
long crtime,
long atime,
long mtime,
8794 String md5, String sha256,
FileKnown known, String mimeType,
8799 size, ctime, crtime, atime, mtime,
8800 md5, sha256,
null, known, mimeType,
8801 isFile, encodingType, osAccountId, ownerAccount,
8802 parent, transaction);
8839 long size,
long ctime,
long crtime,
long atime,
long mtime,
8840 String md5, String sha256, String sha1Hash,
FileKnown known, String mimeType,
8843 CaseDbConnection connection = transaction.getConnection();
8844 Statement queryStatement =
null;
8857 statement.clearParameters();
8858 statement.setLong(1, objectId);
8859 statement.setNull(2, java.sql.Types.BIGINT);
8860 statement.setString(3, fileName);
8862 statement.setShort(5, (
short) 1);
8864 statement.setShort(6, dirType.
getValue());
8866 statement.setShort(7, metaType.
getValue());
8868 statement.setShort(8, dirFlag.
getValue());
8870 statement.setShort(9, metaFlags);
8872 long savedSize = size < 0 ? 0 : size;
8873 statement.setLong(10, savedSize);
8874 statement.setLong(11, ctime);
8875 statement.setLong(12, crtime);
8876 statement.setLong(13, atime);
8877 statement.setLong(14, mtime);
8878 statement.setString(15, md5);
8879 statement.setString(16, sha256);
8880 statement.setString(17, sha1Hash);
8882 if (known !=
null) {
8883 statement.setByte(18, known.getFileKnownValue());
8887 statement.setString(19, mimeType);
8889 long dataSourceObjId;
8893 if (isRootDirectory(parentFile, transaction)) {
8896 parentPath = parentFile.
getParentPath() + parent.getName() +
"/";
8901 dataSourceObjId = getDataSourceObjectId(connection, parent);
8903 statement.setString(20, parentPath);
8904 statement.setLong(21, dataSourceObjId);
8905 final String extension = extractExtension(fileName);
8906 statement.setString(22, extension);
8908 if (ownerAccount !=
null) {
8909 statement.setString(23, ownerAccount);
8911 statement.setNull(23, java.sql.Types.VARCHAR);
8914 if (osAccountId !=
null) {
8915 statement.setLong(24, osAccountId);
8917 statement.setNull(24, java.sql.Types.BIGINT);
8922 connection.executeUpdate(statement);
8923 addFilePath(connection, objectId, localPath, encodingType);
8933 ctime, crtime, atime, mtime,
8934 mimeType, md5, sha256, sha1Hash, known,
8935 parent.getId(), parentPath,
8938 encodingType, extension,
8939 ownerAccount, osAccountId);
8940 if (!timelineEventsDisabled.get()) {
8945 }
catch (SQLException ex) {
8946 throw new TskCoreException(String.format(
"Failed to INSERT local file %s (%s) with parent id %d in tsk_files table", fileName, localPath, parent.getId()), ex);
8948 closeStatement(queryStatement);
8957 private class RootDirectoryKey {
8959 private long dataSourceId;
8960 private Long fileSystemId;
8962 RootDirectoryKey(
long dataSourceId, Long fileSystemId) {
8963 this.dataSourceId = dataSourceId;
8964 this.fileSystemId = fileSystemId;
8968 public int hashCode() {
8970 hash = 41 * hash + Objects.hashCode(dataSourceId);
8971 hash = 41 * hash + Objects.hashCode(fileSystemId);
8976 public boolean equals(Object obj) {
8983 if (getClass() != obj.getClass()) {
8987 RootDirectoryKey otherKey = (RootDirectoryKey) obj;
8988 if (dataSourceId != otherKey.dataSourceId) {
8992 if (fileSystemId !=
null) {
8993 return fileSystemId.equals(otherKey.fileSystemId);
8995 return (otherKey.fileSystemId ==
null);
9011 private boolean isRootDirectory(AbstractFile file,
CaseDbTransaction transaction)
throws TskCoreException {
9016 Long fsObjId =
null;
9017 if (file instanceof FsContent) {
9018 fsObjId = ((FsContent) file).getFileSystemId();
9020 RootDirectoryKey key =
new RootDirectoryKey(file.getDataSourceObjectId(), fsObjId);
9021 synchronized (rootDirectoryMapLock) {
9022 if (rootDirectoryMap.containsKey(key)) {
9023 return rootDirectoryMap.get(key).equals(file.getId());
9030 Boolean isRoot = isRootDirectoryCache.getIfPresent(file.getId());
9031 if (isRoot !=
null) {
9035 CaseDbConnection connection = transaction.getConnection();
9036 Statement statement =
null;
9037 ResultSet resultSet =
null;
9040 String query = String.format(
"SELECT ParentRow.type AS parent_type, ParentRow.obj_id AS parent_object_id "
9041 +
"FROM tsk_objects ParentRow JOIN tsk_objects ChildRow ON ChildRow.par_obj_id = ParentRow.obj_id "
9042 +
"WHERE ChildRow.obj_id = %s;", file.getId());
9044 statement = connection.createStatement();
9045 resultSet = statement.executeQuery(query);
9046 if (resultSet.next()) {
9047 long parentId = resultSet.getLong(
"parent_object_id");
9048 if (parentId == 0) {
9051 int type = resultSet.getInt(
"parent_type");
9052 boolean result = type == TskData.ObjectType.IMG.getObjectType()
9053 || type == TskData.ObjectType.VS.getObjectType()
9054 || type == TskData.ObjectType.VOL.getObjectType()
9055 || type == TskData.ObjectType.FS.getObjectType();
9056 if (result ==
true) {
9057 synchronized (rootDirectoryMapLock) {
9059 rootDirectoryMap.put(key, file.getId());
9062 isRootDirectoryCache.put(file.getId(), result);
9067 synchronized (rootDirectoryMapLock) {
9068 rootDirectoryMap.put(key, file.getId());
9070 isRootDirectoryCache.put(file.getId(),
true);
9075 }
catch (SQLException ex) {
9076 throw new TskCoreException(String.format(
"Failed to lookup parent of file (%s) with id %d", file.getName(), file.getId()), ex);
9078 closeResultSet(resultSet);
9079 closeStatement(statement);
9105 long ctime,
long crtime,
long atime,
long mtime,
9106 List<TskFileRange> fileRanges,
9109 if (
null == parent) {
9115 parentPath = ((
AbstractFile) parent).getParentPath() + parent.getName() +
'/';
9121 Statement statement =
null;
9122 ResultSet resultSet =
null;
9125 CaseDbConnection connection = transaction.getConnection();
9142 prepStmt.clearParameters();
9143 prepStmt.setLong(1, newFileId);
9146 Long fileSystemObjectId;
9147 if (0 != parent.getId()) {
9148 fileSystemObjectId = this.getFileSystemId(parent.getId(), connection);
9149 if (fileSystemObjectId != -1) {
9150 prepStmt.setLong(2, fileSystemObjectId);
9152 prepStmt.setNull(2, java.sql.Types.BIGINT);
9153 fileSystemObjectId =
null;
9156 prepStmt.setNull(2, java.sql.Types.BIGINT);
9157 fileSystemObjectId =
null;
9159 prepStmt.setString(3, fileName);
9161 prepStmt.setShort(5, (
short) 0);
9164 prepStmt.setShort(8, dirFlag.getValue());
9165 prepStmt.setShort(9, metaFlag.getValue());
9167 long savedSize = size < 0 ? 0 : size;
9168 prepStmt.setLong(10, savedSize);
9169 prepStmt.setLong(11, ctime);
9170 prepStmt.setLong(12, crtime);
9171 prepStmt.setLong(13, atime);
9172 prepStmt.setLong(14, mtime);
9173 prepStmt.setNull(15, java.sql.Types.VARCHAR);
9174 prepStmt.setNull(16, java.sql.Types.VARCHAR);
9175 prepStmt.setNull(17, java.sql.Types.VARCHAR);
9178 prepStmt.setNull(19, java.sql.Types.VARCHAR);
9179 prepStmt.setString(20, parentPath);
9180 prepStmt.setLong(21, parent.getDataSource().getId());
9182 prepStmt.setString(22, extractExtension(fileName));
9184 prepStmt.setString(23,
OsAccount.NO_OWNER_ID);
9185 prepStmt.setNull(24, java.sql.Types.BIGINT);
9188 connection.executeUpdate(prepStmt);
9197 prepStmt.clearParameters();
9198 prepStmt.setLong(1, newFileId);
9199 prepStmt.setLong(2, tskFileRange.getByteStart());
9200 prepStmt.setLong(3, tskFileRange.getByteLen());
9201 prepStmt.setLong(4, tskFileRange.getSequence());
9202 connection.executeUpdate(prepStmt);
9210 parent.getDataSource().getId(),
9217 metaFlag.getValue(),
9219 ctime, crtime, atime, mtime,
9231 }
catch (SQLException ex) {
9232 throw new TskCoreException(
"Failed to add layout file " + fileName +
" to case database", ex);
9234 closeResultSet(resultSet);
9235 closeStatement(statement);
9237 if (
null != transaction) {
9241 logger.log(Level.SEVERE,
"Failed to rollback transaction after exception", ex2);
9257 if (content ==
null) {
9260 if (content instanceof AbstractFile) {
9261 return ((AbstractFile) content).getDataSourceObjectId();
9263 return getDataSourceObjectId(connection, content.getId());
9279 private long getDataSourceObjectId(CaseDbConnection connection,
long objectId)
throws TskCoreException {
9281 Statement statement =
null;
9282 ResultSet resultSet =
null;
9284 statement = connection.createStatement();
9285 long dataSourceObjId;
9286 long ancestorId = objectId;
9288 dataSourceObjId = ancestorId;
9289 String query = String.format(
"SELECT par_obj_id FROM tsk_objects WHERE obj_id = %s;", ancestorId);
9290 resultSet = statement.executeQuery(query);
9291 if (resultSet.next()) {
9292 ancestorId = resultSet.getLong(
"par_obj_id");
9294 throw new TskCoreException(String.format(
"tsk_objects table is corrupt, SQL query returned no result: %s", query));
9298 }
while (0 != ancestorId);
9299 return dataSourceObjId;
9300 }
catch (SQLException ex) {
9301 throw new TskCoreException(String.format(
"Error finding root data source for object (obj_id = %d)", objectId), ex);
9303 closeResultSet(resultSet);
9304 closeStatement(statement);
9320 private void addFilePath(CaseDbConnection connection,
long objId, String path, TskData.EncodingType type)
throws SQLException {
9322 statement.clearParameters();
9323 statement.setLong(1, objId);
9324 statement.setString(2, path);
9325 statement.setInt(3, type.getType());
9326 connection.executeUpdate(statement);
9340 private void updateFilePath(CaseDbConnection connection,
long objId, String path, TskData.EncodingType type)
throws SQLException {
9342 statement.clearParameters();
9343 statement.setString(1, path);
9344 statement.setInt(2, type.getType());
9345 statement.setLong(3, objId);
9346 connection.executeUpdate(statement);
9364 if (!containsLikeWildcard(fileName)) {
9365 ext = SleuthkitCase.extractExtension(fileName);
9368 CaseDbConnection connection =
null;
9369 ResultSet rs =
null;
9370 long parentId = parentFile.getId();
9374 connection = connections.getConnection();
9376 PreparedStatement statement;
9377 if (ext.isEmpty()) {
9379 statement.clearParameters();
9380 statement.setLong(1, parentId);
9381 statement.setString(2, fileName);
9384 statement.clearParameters();
9385 statement.setString(1, ext);
9386 statement.setLong(2, parentId);
9387 statement.setString(3, fileName);
9390 rs = connection.executeQuery(statement);
9391 return resultSetToAbstractFiles(rs, connection);
9392 }
catch (SQLException ex) {
9393 throw new TskCoreException(
"Error getting AbstractFile children with name=" + fileName +
" for Content parent with ID=" + parentFile.getId(), ex);
9396 closeConnection(connection);
9413 CaseDbConnection connection =
null;
9415 ResultSet rs =
null;
9418 connection = connections.getConnection();
9419 s = connection.createStatement();
9420 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files WHERE " + sqlWhereClause);
9422 return rs.getLong(
"count");
9423 }
catch (SQLException e) {
9424 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.countFilesWhere().", e);
9428 closeConnection(connection);
9451 CaseDbConnection connection =
null;
9453 ResultSet rs =
null;
9456 connection = connections.getConnection();
9457 s = connection.createStatement();
9458 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE " + sqlWhereClause);
9459 return resultSetToAbstractFiles(rs, connection);
9460 }
catch (SQLException e) {
9461 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findAllFilesWhere(): " + sqlWhereClause, e);
9465 closeConnection(connection);
9489 String queryTemplate =
"SELECT tsk_files.* FROM tsk_files JOIN tsk_objects ON tsk_objects.obj_id = tsk_files.obj_id WHERE par_obj_id = %d AND %s";
9491 try (CaseDbConnection connection = connections.getConnection()) {
9492 String query = String.format(queryTemplate, parentId, sqlWhereClause);
9493 try (Statement s = connection.createStatement(); ResultSet rs = connection.executeQuery(s, query)) {
9494 return resultSetToAbstractFiles(rs, connection);
9495 }
catch (SQLException ex) {
9496 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findAllFilesInFolderWhere(): " + query, ex);
9516 CaseDbConnection connection =
null;
9518 ResultSet rs =
null;
9521 connection = connections.getConnection();
9522 s = connection.createStatement();
9523 rs = connection.executeQuery(s,
"SELECT obj_id FROM tsk_files WHERE " + sqlWhereClause);
9524 List<Long> ret =
new ArrayList<>();
9526 ret.add(rs.getLong(
"obj_id"));
9529 }
catch (SQLException e) {
9530 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findAllFileIdsWhere(): " + sqlWhereClause, e);
9534 closeConnection(connection);
9557 int lastSlash = path.lastIndexOf(
'/');
9560 if (lastSlash == path.length()) {
9561 path = path.substring(0, lastSlash - 1);
9562 lastSlash = path.lastIndexOf(
'/');
9565 String parentPath = path.substring(0, lastSlash);
9566 String fileName = path.substring(lastSlash);
9568 return findFiles(dataSource, fileName, parentPath);
9582 CaseDbConnection connection =
null;
9584 ResultSet rs =
null;
9587 connection = connections.getConnection();
9588 s = connection.createStatement();
9589 rs = connection.executeQuery(s,
"SELECT * FROM tsk_file_layout WHERE obj_id = " +
id +
" ORDER BY sequence");
9590 List<TskFileRange> ranges =
new ArrayList<TskFileRange>();
9593 rs.getLong(
"byte_len"), rs.getLong(
"sequence"));
9597 }
catch (SQLException ex) {
9598 throw new TskCoreException(
"Error getting TskFileLayoutRanges by id, id = " +
id, ex);
9602 closeConnection(connection);
9618 CaseDbConnection connection =
null;
9620 ResultSet rs =
null;
9623 connection = connections.getConnection();
9624 s = connection.createStatement();
9625 rs = connection.executeQuery(s,
"SELECT tsk_image_info.type, tsk_image_info.ssize, tsk_image_info.tzone, tsk_image_info.size, tsk_image_info.md5, tsk_image_info.sha1, tsk_image_info.sha256, tsk_image_info.display_name, data_source_info.device_id, tsk_image_names.name "
9626 +
"FROM tsk_image_info "
9627 +
"INNER JOIN data_source_info ON tsk_image_info.obj_id = data_source_info.obj_id "
9628 +
"LEFT JOIN tsk_image_names ON tsk_image_names.obj_id = data_source_info.obj_id "
9629 +
"WHERE tsk_image_info.obj_id = " +
id);
9631 List<String> imagePaths =
new ArrayList<>();
9632 long type, ssize, size;
9633 String tzone, md5, sha1, sha256, name, device_id, imagePath;
9636 imagePath = rs.getString(
"name");
9637 if (imagePath !=
null) {
9638 imagePaths.add(imagePath);
9640 type = rs.getLong(
"type");
9641 ssize = rs.getLong(
"ssize");
9642 tzone = rs.getString(
"tzone");
9643 size = rs.getLong(
"size");
9644 md5 = rs.getString(
"md5");
9645 sha1 = rs.getString(
"sha1");
9646 sha256 = rs.getString(
"sha256");
9647 name = rs.getString(
"display_name");
9649 if (imagePaths.size() > 0) {
9650 String path = imagePaths.get(0);
9651 name = (
new java.io.File(path)).getName();
9656 device_id = rs.getString(
"device_id");
9663 imagePath = rs.getString(
"name");
9664 if (imagePath !=
null) {
9665 imagePaths.add(imagePath);
9669 return new Image(
this,
id, type, device_id, ssize, name,
9670 imagePaths.toArray(
new String[imagePaths.size()]), tzone, md5, sha1, sha256, size);
9671 }
catch (SQLException ex) {
9676 closeConnection(connection);
9693 CaseDbConnection connection =
null;
9695 ResultSet rs =
null;
9698 connection = connections.getConnection();
9699 s = connection.createStatement();
9700 rs = connection.executeQuery(s,
"SELECT * FROM tsk_vs_info "
9701 +
"where obj_id = " +
id);
9703 long type = rs.getLong(
"vs_type");
9704 long imgOffset = rs.getLong(
"img_offset");
9705 long blockSize = rs.getLong(
"block_size");
9707 vs.setParent(parent);
9710 throw new TskCoreException(
"No volume system found for id:" +
id);
9712 }
catch (SQLException ex) {
9713 throw new TskCoreException(
"Error getting Volume System by ID.", ex);
9717 closeConnection(connection);
9730 VolumeSystem getVolumeSystemById(
long id,
long parentId)
throws TskCoreException {
9731 VolumeSystem vs = getVolumeSystemById(
id,
null);
9732 vs.setParentId(parentId);
9747 FileSystem getFileSystemById(
long id, Image parent)
throws TskCoreException {
9748 return getFileSystemByIdHelper(
id, parent);
9759 FileSystem getFileSystemById(
long id,
long parentId)
throws TskCoreException {
9761 FileSystem fs = getFileSystemById(
id, vol);
9762 fs.setParentId(parentId);
9777 FileSystem getFileSystemById(
long id, Volume parent)
throws TskCoreException {
9778 return getFileSystemByIdHelper(
id, parent);
9792 Pool getPoolById(
long id, Content parent)
throws TskCoreException {
9793 return getPoolByIdHelper(
id, parent);
9804 Pool getPoolById(
long id,
long parentId)
throws TskCoreException {
9805 Pool pool = getPoolById(
id,
null);
9806 pool.setParentId(parentId);
9821 private Pool getPoolByIdHelper(
long id, Content parent)
throws TskCoreException {
9824 try (CaseDbConnection connection = connections.getConnection();
9825 Statement s = connection.createStatement();
9826 ResultSet rs = connection.executeQuery(s,
"SELECT * FROM tsk_pool_info "
9827 +
"where obj_id = " +
id);) {
9829 Pool pool =
new Pool(
this, rs.getLong(
"obj_id"), TskData.TSK_POOL_TYPE_ENUM.valueOf(rs.getLong(
"pool_type")).getName(), rs.getLong(
"pool_type"));
9830 pool.setParent(parent);
9834 throw new TskCoreException(
"No pool found for ID:" +
id);
9836 }
catch (SQLException ex) {
9837 throw new TskCoreException(
"Error getting Pool by ID", ex);
9854 private FileSystem getFileSystemByIdHelper(
long id, Content parent)
throws TskCoreException {
9858 synchronized (fileSystemIdMap) {
9859 if (fileSystemIdMap.containsKey(
id)) {
9860 return fileSystemIdMap.get(
id);
9863 CaseDbConnection connection =
null;
9865 ResultSet rs =
null;
9868 connection = connections.getConnection();
9869 s = connection.createStatement();
9870 rs = connection.executeQuery(s,
"SELECT * FROM tsk_fs_info "
9871 +
"where obj_id = " +
id);
9873 TskData.TSK_FS_TYPE_ENUM fsType = TskData.TSK_FS_TYPE_ENUM.valueOf(rs.getInt(
"fs_type"));
9874 FileSystem fs =
new FileSystem(
this, rs.getLong(
"obj_id"),
"", rs.getLong(
"img_offset"),
9875 fsType, rs.getLong(
"block_size"), rs.getLong(
"block_count"),
9876 rs.getLong(
"root_inum"), rs.getLong(
"first_inum"), rs.getLong(
"last_inum"));
9877 fs.setParent(parent);
9879 synchronized (fileSystemIdMap) {
9880 fileSystemIdMap.put(
id, fs);
9884 throw new TskCoreException(
"No file system found for id:" +
id);
9886 }
catch (SQLException ex) {
9887 throw new TskCoreException(
"Error getting File System by ID", ex);
9891 closeConnection(connection);
9907 Volume getVolumeById(
long id, VolumeSystem parent)
throws TskCoreException {
9908 CaseDbConnection connection =
null;
9910 ResultSet rs =
null;
9913 connection = connections.getConnection();
9914 s = connection.createStatement();
9915 rs = connection.executeQuery(s,
"SELECT * FROM tsk_vs_parts "
9916 +
"where obj_id = " +
id);
9927 description = rs.getString(
"desc");
9928 }
catch (Exception ex) {
9929 description = rs.getString(
"descr");
9931 Volume vol =
new Volume(
this, rs.getLong(
"obj_id"), rs.getLong(
"addr"),
9932 rs.getLong(
"start"), rs.getLong(
"length"), rs.getLong(
"flags"),
9934 vol.setParent(parent);
9937 throw new TskCoreException(
"No volume found for id:" +
id);
9939 }
catch (SQLException ex) {
9940 throw new TskCoreException(
"Error getting Volume by ID", ex);
9944 closeConnection(connection);
9957 Volume getVolumeById(
long id,
long parentId)
throws TskCoreException {
9958 Volume vol = getVolumeById(
id,
null);
9959 vol.setParentId(parentId);
9974 Directory getDirectoryById(
long id, FileSystem parentFs)
throws TskCoreException {
9975 CaseDbConnection connection =
null;
9977 ResultSet rs =
null;
9980 connection = connections.getConnection();
9981 s = connection.createStatement();
9982 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files "
9983 +
"WHERE obj_id = " +
id);
9984 Directory temp =
null;
9986 final short type = rs.getShort(
"type");
9987 if (type == TSK_DB_FILES_TYPE_ENUM.FS.getFileType()) {
9988 if (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
9989 || rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()) {
9990 temp = directory(rs, parentFs);
9992 }
else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()) {
9993 throw new TskCoreException(
"Expecting an FS-type directory, got virtual, id: " +
id);
9996 throw new TskCoreException(
"No Directory found for id:" +
id);
9999 }
catch (SQLException ex) {
10000 throw new TskCoreException(
"Error getting Directory by ID", ex);
10002 closeResultSet(rs);
10004 closeConnection(connection);
10019 List<FileSystem> fileSystems =
new ArrayList<>();
10020 String queryStr =
"SELECT * FROM tsk_fs_info WHERE data_source_obj_id = " + image.getId();
10022 CaseDbConnection connection =
null;
10023 Statement s =
null;
10024 ResultSet rs =
null;
10027 connection = connections.getConnection();
10028 s = connection.createStatement();
10029 rs = connection.executeQuery(s, queryStr);
10030 while (rs.next()) {
10033 fsType, rs.getLong(
"block_size"), rs.getLong(
"block_count"),
10034 rs.getLong(
"root_inum"), rs.getLong(
"first_inum"), rs.getLong(
"last_inum"));
10035 fs.setParent(
null);
10036 fileSystems.add(fs);
10038 }
catch (SQLException ex) {
10039 throw new TskCoreException(
"Error looking up files systems. Query: " + queryStr, ex);
10041 closeResultSet(rs);
10043 closeConnection(connection);
10046 return fileSystems;
10060 Collection<ObjectInfo> childInfos = getChildrenInfo(img);
10061 List<Content> children =
new ArrayList<Content>();
10062 for (ObjectInfo info : childInfos) {
10063 if (
null != info.type) {
10064 switch (info.type) {
10066 children.add(getVolumeSystemById(info.id, img));
10069 children.add(getPoolById(info.id, img));
10072 children.add(getFileSystemById(info.id, img));
10090 throw new TskCoreException(
"Image has child of invalid type: " + info.type);
10107 List<Long> getImageChildrenIds(Image img)
throws TskCoreException {
10108 Collection<ObjectInfo> childInfos = getChildrenInfo(img);
10109 List<Long> children =
new ArrayList<Long>();
10110 for (ObjectInfo info : childInfos) {
10111 if (info.type == ObjectType.VS
10112 || info.type == ObjectType.POOL
10113 || info.type == ObjectType.FS
10114 || info.type == ObjectType.ABSTRACTFILE
10115 || info.type == ObjectType.ARTIFACT) {
10116 children.add(info.id);
10117 }
else if (info.type == ObjectType.REPORT) {
10120 throw new TskCoreException(
"Image has child of invalid type: " + info.type);
10136 List<Content> getPoolChildren(Pool pool)
throws TskCoreException {
10137 Collection<ObjectInfo> childInfos = getChildrenInfo(pool);
10138 List<Content> children =
new ArrayList<Content>();
10139 for (ObjectInfo info : childInfos) {
10140 if (
null != info.type) {
10141 switch (info.type) {
10143 children.add(getVolumeSystemById(info.id, pool));
10158 throw new TskCoreException(
"Pool has child of invalid type: " + info.type);
10175 List<Long> getPoolChildrenIds(Pool pool)
throws TskCoreException {
10176 Collection<ObjectInfo> childInfos = getChildrenInfo(pool);
10177 List<Long> children =
new ArrayList<Long>();
10178 for (ObjectInfo info : childInfos) {
10179 if (info.type == ObjectType.VS || info.type == ObjectType.ABSTRACTFILE || info.type == ObjectType.ARTIFACT) {
10180 children.add(info.id);
10182 throw new TskCoreException(
"Pool has child of invalid type: " + info.type);
10198 List<Content> getVolumeSystemChildren(VolumeSystem vs)
throws TskCoreException {
10199 Collection<ObjectInfo> childInfos = getChildrenInfo(vs);
10200 List<Content> children =
new ArrayList<Content>();
10201 for (ObjectInfo info : childInfos) {
10202 if (
null != info.type) {
10203 switch (info.type) {
10205 children.add(getVolumeById(info.id, vs));
10220 throw new TskCoreException(
"VolumeSystem has child of invalid type: " + info.type);
10237 List<Long> getVolumeSystemChildrenIds(VolumeSystem vs)
throws TskCoreException {
10238 Collection<ObjectInfo> childInfos = getChildrenInfo(vs);
10239 List<Long> children =
new ArrayList<Long>();
10240 for (ObjectInfo info : childInfos) {
10241 if (info.type == ObjectType.VOL || info.type == ObjectType.ABSTRACTFILE || info.type == ObjectType.ARTIFACT) {
10242 children.add(info.id);
10244 throw new TskCoreException(
"VolumeSystem has child of invalid type: " + info.type);
10260 List<Content> getVolumeChildren(Volume vol)
throws TskCoreException {
10261 Collection<ObjectInfo> childInfos = getChildrenInfo(vol);
10262 List<Content> children =
new ArrayList<Content>();
10263 for (ObjectInfo info : childInfos) {
10264 if (
null != info.type) {
10265 switch (info.type) {
10267 children.add(getPoolById(info.id, vol));
10270 children.add(getFileSystemById(info.id, vol));
10285 throw new TskCoreException(
"Volume has child of invalid type: " + info.type);
10302 List<Long> getVolumeChildrenIds(Volume vol)
throws TskCoreException {
10303 final Collection<ObjectInfo> childInfos = getChildrenInfo(vol);
10304 final List<Long> children =
new ArrayList<Long>();
10305 for (ObjectInfo info : childInfos) {
10306 if (info.type == ObjectType.FS || info.type == ObjectType.ABSTRACTFILE || info.type == ObjectType.ARTIFACT) {
10307 children.add(info.id);
10309 throw new TskCoreException(
"Volume has child of invalid type: " + info.type);
10329 return addImageInfo(deviceObjId, imageFilePaths, timeZone,
null);
10347 return addImageInfo(deviceObjId, imageFilePaths, timeZone, host,
null);
10368 long imageId = this.caseHandle.addImageInfo(deviceObjId, imageFilePaths, timeZone, host, password,
this);
10382 CaseDbConnection connection =
null;
10383 Statement s1 =
null;
10384 ResultSet rs1 =
null;
10387 connection = connections.getConnection();
10388 s1 = connection.createStatement();
10389 rs1 = connection.executeQuery(s1,
"SELECT tsk_image_info.obj_id, tsk_image_names.name FROM tsk_image_info "
10390 +
"LEFT JOIN tsk_image_names ON tsk_image_info.obj_id = tsk_image_names.obj_id");
10391 Map<Long, List<String>> imgPaths =
new LinkedHashMap<Long, List<String>>();
10392 while (rs1.next()) {
10393 long obj_id = rs1.getLong(
"obj_id");
10394 String name = rs1.getString(
"name");
10395 List<String> imagePaths = imgPaths.get(obj_id);
10396 if (imagePaths ==
null) {
10397 List<String> paths =
new ArrayList<String>();
10398 if (name !=
null) {
10401 imgPaths.put(obj_id, paths);
10403 if (name !=
null) {
10404 imagePaths.add(name);
10409 }
catch (SQLException ex) {
10412 closeResultSet(rs1);
10413 closeStatement(s1);
10414 closeConnection(connection);
10430 private List<String> getImagePathsById(
long objectId, CaseDbConnection connection)
throws TskCoreException {
10431 List<String> imagePaths =
new ArrayList<>();
10433 Statement statement =
null;
10434 ResultSet resultSet =
null;
10436 statement = connection.createStatement();
10437 resultSet = connection.executeQuery(statement,
"SELECT name FROM tsk_image_names WHERE tsk_image_names.obj_id = " + objectId);
10438 while (resultSet.next()) {
10439 imagePaths.add(resultSet.getString(
"name"));
10441 }
catch (SQLException ex) {
10442 throw new TskCoreException(String.format(
"Error getting image names with obj_id = %d", objectId), ex);
10444 closeResultSet(resultSet);
10445 closeStatement(statement);
10459 CaseDbConnection connection =
null;
10460 Statement s =
null;
10461 ResultSet rs =
null;
10464 connection = connections.getConnection();
10465 s = connection.createStatement();
10466 rs = connection.executeQuery(s,
"SELECT obj_id FROM tsk_image_info");
10467 Collection<Long> imageIDs =
new ArrayList<Long>();
10468 while (rs.next()) {
10469 imageIDs.add(rs.getLong(
"obj_id"));
10471 List<Image> images =
new ArrayList<Image>();
10472 for (
long id : imageIDs) {
10476 }
catch (SQLException ex) {
10479 closeResultSet(rs);
10481 closeConnection(connection);
10501 transaction =
null;
10503 if (transaction !=
null) {
10524 statement.clearParameters();
10525 statement.setLong(1, objId);
10526 trans.getConnection().executeUpdate(statement);
10527 for (
int i = 0; i < paths.size(); i++) {
10529 statement.clearParameters();
10530 statement.setLong(1, objId);
10531 statement.setString(2, paths.get(i));
10532 statement.setLong(3, i);
10533 trans.getConnection().executeUpdate(statement);
10535 }
catch (SQLException ex) {
10558 Host hostToDelete =
null;
10562 if (major > 9 || (major == 9 && minor >= 1)) {
10564 if (
getHostManager().getDataSourcesForHost(hostToDelete).size() != 1) {
10565 hostToDelete =
null;
10569 CaseDbConnection connection =
null;
10570 Statement statement;
10573 connection = connections.getConnection();
10574 statement = connection.createStatement();
10575 connection.beginTransaction();
10578 statement.execute(
"DELETE FROM tsk_objects WHERE obj_id = " + dataSourceObjectId);
10581 String accountSql =
"DELETE FROM accounts WHERE account_id in (SELECT account_id FROM accounts "
10582 +
"WHERE account_id NOT IN (SELECT account1_id FROM account_relationships) "
10583 +
"AND account_id NOT IN (SELECT account2_id FROM account_relationships))";
10584 statement.execute(accountSql);
10588 if (hostToDelete !=
null) {
10589 statement.execute(
"DELETE FROM tsk_hosts WHERE id = " + hostToDelete.
getHostId());
10592 String deleteOsAcctObjectsQuery =
"DELETE FROM tsk_objects "
10593 +
"WHERE type=" + TskData.ObjectType.OS_ACCOUNT.getObjectType() +
" "
10594 +
"AND obj_id NOT IN (SELECT os_account_obj_id FROM tsk_os_accounts WHERE os_account_obj_id IS NOT NULL)";
10595 statement.execute(deleteOsAcctObjectsQuery);
10598 connection.commitTransaction();
10599 }
catch (SQLException ex) {
10600 rollbackTransaction(connection);
10601 throw new TskCoreException(
"Error deleting data source.", ex);
10603 closeConnection(connection);
10633 List<AbstractFile> resultSetToAbstractFiles(ResultSet rs, CaseDbConnection connection)
throws SQLException {
10634 ArrayList<AbstractFile> results =
new ArrayList<AbstractFile>();
10636 while (rs.next()) {
10637 final short type = rs.getShort(
"type");
10638 if (type == TSK_DB_FILES_TYPE_ENUM.FS.getFileType()
10639 && (rs.getShort(
"meta_type") != TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue())) {
10641 if (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()) {
10642 result = directory(rs,
null);
10644 result = file(rs,
null);
10646 results.add(result);
10647 }
else if (type == TSK_DB_FILES_TYPE_ENUM.VIRTUAL_DIR.getFileType()
10648 || (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue())) {
10649 final VirtualDirectory virtDir = virtualDirectory(rs, connection);
10650 results.add(virtDir);
10651 }
else if (type == TSK_DB_FILES_TYPE_ENUM.LOCAL_DIR.getFileType()) {
10652 final LocalDirectory localDir = localDirectory(rs);
10653 results.add(localDir);
10654 }
else if (type == TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS.getFileType()
10655 || type == TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS.getFileType()
10656 || type == TSK_DB_FILES_TYPE_ENUM.CARVED.getFileType()
10657 || type == TSK_DB_FILES_TYPE_ENUM.LAYOUT_FILE.getFileType()) {
10658 TSK_DB_FILES_TYPE_ENUM atype = TSK_DB_FILES_TYPE_ENUM.valueOf(type);
10659 String parentPath = rs.getString(
"parent_path");
10660 if (parentPath ==
null) {
10664 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
10665 if (rs.wasNull()) {
10666 osAccountObjId =
null;
10669 LayoutFile lf =
new LayoutFile(
this,
10670 rs.getLong(
"obj_id"),
10671 rs.getLong(
"data_source_obj_id"),
10672 rs.getLong(
"fs_obj_id"),
10673 rs.getString(
"name"),
10675 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")), TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10676 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
10677 rs.getLong(
"size"),
10678 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
10679 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10680 FileKnown.valueOf(rs.getByte(
"known")), parentPath,
10681 rs.getString(
"mime_type"),
10682 rs.getString(
"owner_uid"), osAccountObjId);
10684 }
else if (type == TSK_DB_FILES_TYPE_ENUM.DERIVED.getFileType()) {
10685 final DerivedFile df;
10686 df = derivedFile(rs, connection, AbstractContent.UNKNOWN_ID);
10688 }
else if (type == TSK_DB_FILES_TYPE_ENUM.LOCAL.getFileType()) {
10689 final LocalFile lf;
10690 lf = localFile(rs, connection, AbstractContent.UNKNOWN_ID);
10692 }
else if (type == TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType()) {
10693 final SlackFile sf = slackFile(rs,
null);
10697 }
catch (SQLException e) {
10698 logger.log(Level.SEVERE,
"Error getting abstract files from result set", e);
10716 org.sleuthkit.datamodel.File file(ResultSet rs, FileSystem fs)
throws SQLException {
10717 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
10718 if (rs.wasNull()) {
10719 osAccountObjId =
null;
10722 org.sleuthkit.datamodel.File f =
new org.sleuthkit.datamodel.File(
this, rs.getLong(
"obj_id"),
10723 rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
10724 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
10725 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
10726 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10727 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10728 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
10729 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
10730 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
10731 (
short) rs.getInt(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
10732 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10733 FileKnown.valueOf(rs.getByte(
"known")),
10734 rs.getString(
"parent_path"), rs.getString(
"mime_type"), rs.getString(
"extension"), rs.getString(
"owner_uid"),
10735 osAccountObjId, TskData.CollectedStatus.valueOf(rs.getInt(
"collected")), Collections.emptyList());
10736 f.setFileSystem(fs);
10751 Directory directory(ResultSet rs, FileSystem fs)
throws SQLException {
10752 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
10753 if (rs.wasNull()) {
10754 osAccountObjId =
null;
10757 Directory dir =
new Directory(
this, rs.getLong(
"obj_id"), rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
10758 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
10759 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
10760 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10761 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10762 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
10763 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
10764 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
10765 rs.getShort(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
10766 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10767 FileKnown.valueOf(rs.getByte(
"known")),
10768 rs.getString(
"parent_path"), rs.getString(
"owner_uid"), osAccountObjId);
10769 dir.setFileSystem(fs);
10783 VirtualDirectory virtualDirectory(ResultSet rs, CaseDbConnection connection)
throws SQLException {
10784 String parentPath = rs.getString(
"parent_path");
10785 if (parentPath ==
null) {
10789 long objId = rs.getLong(
"obj_id");
10790 long dsObjId = rs.getLong(
"data_source_obj_id");
10791 if (objId == dsObjId) {
10793 String deviceId =
"";
10794 String timeZone =
"";
10795 Statement s =
null;
10796 ResultSet rsDataSourceInfo =
null;
10800 s = connection.createStatement();
10801 rsDataSourceInfo = connection.executeQuery(s,
"SELECT device_id, time_zone FROM data_source_info WHERE obj_id = " + objId);
10802 if (rsDataSourceInfo.next()) {
10803 deviceId = rsDataSourceInfo.getString(
"device_id");
10804 timeZone = rsDataSourceInfo.getString(
"time_zone");
10806 }
catch (SQLException ex) {
10807 logger.log(Level.SEVERE,
"Error data source info for datasource id " + objId, ex);
10809 closeResultSet(rsDataSourceInfo);
10814 return new LocalFilesDataSource(
this,
10817 rs.getString(
"name"),
10818 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10819 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10820 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
10821 rs.getShort(
"meta_flags"),
10823 rs.getString(
"md5"),
10824 rs.getString(
"sha256"),
10825 rs.getString(
"sha1"),
10826 FileKnown.valueOf(rs.getByte(
"known")),
10829 final VirtualDirectory vd =
new VirtualDirectory(
this,
10831 rs.getLong(
"fs_obj_id"),
10832 rs.getString(
"name"),
10833 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10834 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10835 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
10836 rs.getShort(
"meta_flags"), rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10837 FileKnown.valueOf(rs.getByte(
"known")), parentPath);
10851 LocalDirectory localDirectory(ResultSet rs)
throws SQLException {
10852 String parentPath = rs.getString(
"parent_path");
10853 if (parentPath ==
null) {
10856 final LocalDirectory ld =
new LocalDirectory(
this, rs.getLong(
"obj_id"),
10857 rs.getLong(
"data_source_obj_id"), rs.getString(
"name"),
10858 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10859 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10860 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
10861 rs.getShort(
"meta_flags"), rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10862 FileKnown.valueOf(rs.getByte(
"known")), parentPath);
10879 private DerivedFile derivedFile(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
10880 boolean hasLocalPath = rs.getBoolean(
"has_path");
10881 long objId = rs.getLong(
"obj_id");
10882 String localPath =
null;
10883 TskData.EncodingType encodingType = TskData.EncodingType.NONE;
10884 if (hasLocalPath) {
10885 ResultSet rsFilePath =
null;
10889 statement.clearParameters();
10890 statement.setLong(1, objId);
10891 rsFilePath = connection.executeQuery(statement);
10892 if (rsFilePath.next()) {
10893 localPath = rsFilePath.getString(
"path");
10894 encodingType = TskData.EncodingType.valueOf(rsFilePath.getInt(
"encoding_type"));
10896 }
catch (SQLException ex) {
10897 logger.log(Level.SEVERE,
"Error getting encoding type for file " + objId, ex);
10899 closeResultSet(rsFilePath);
10903 String parentPath = rs.getString(
"parent_path");
10904 if (parentPath ==
null) {
10908 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
10909 if (rs.wasNull()) {
10910 osAccountObjId =
null;
10913 final DerivedFile df =
new DerivedFile(
this, objId, rs.getLong(
"data_source_obj_id"),
10914 rs.getLong(
"fs_obj_id"),
10915 rs.getString(
"name"),
10916 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10917 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10918 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
10919 rs.getLong(
"size"),
10920 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
10921 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10922 FileKnown.valueOf(rs.getByte(
"known")),
10923 parentPath, localPath, parentId, rs.getString(
"mime_type"),
10924 encodingType, rs.getString(
"extension"),
10925 rs.getString(
"owner_uid"), osAccountObjId);
10942 private LocalFile localFile(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
10943 long objId = rs.getLong(
"obj_id");
10944 String localPath =
null;
10945 TskData.EncodingType encodingType = TskData.EncodingType.NONE;
10946 if (rs.getBoolean(
"has_path")) {
10947 ResultSet rsFilePath =
null;
10951 statement.clearParameters();
10952 statement.setLong(1, objId);
10953 rsFilePath = connection.executeQuery(statement);
10954 if (rsFilePath.next()) {
10955 localPath = rsFilePath.getString(
"path");
10956 encodingType = TskData.EncodingType.valueOf(rsFilePath.getInt(
"encoding_type"));
10958 }
catch (SQLException ex) {
10959 logger.log(Level.SEVERE,
"Error getting encoding type for file " + objId, ex);
10961 closeResultSet(rsFilePath);
10965 String parentPath = rs.getString(
"parent_path");
10966 if (
null == parentPath) {
10969 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
10970 if (rs.wasNull()) {
10971 osAccountObjId =
null;
10974 LocalFile file =
new LocalFile(
this, objId, rs.getString(
"name"),
10975 TSK_DB_FILES_TYPE_ENUM.valueOf(rs.getShort(
"type")),
10976 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
10977 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
10978 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
10979 rs.getLong(
"size"),
10980 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
10981 rs.getString(
"mime_type"), rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
10982 FileKnown.valueOf(rs.getByte(
"known")),
10983 parentId, parentPath, rs.getLong(
"data_source_obj_id"),
10984 localPath, encodingType, rs.getString(
"extension"),
10985 rs.getString(
"owner_uid"), osAccountObjId);
11000 org.sleuthkit.datamodel.SlackFile slackFile(ResultSet rs, FileSystem fs)
throws SQLException {
11001 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
11002 if (rs.wasNull()) {
11003 osAccountObjId =
null;
11005 org.sleuthkit.datamodel.SlackFile f =
new org.sleuthkit.datamodel.SlackFile(
this, rs.getLong(
"obj_id"),
11006 rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
11007 TskData.TSK_FS_ATTR_TYPE_ENUM.valueOf(rs.getShort(
"attr_type")),
11008 rs.getInt(
"attr_id"), rs.getString(
"name"), rs.getLong(
"meta_addr"), rs.getInt(
"meta_seq"),
11009 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
11010 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
11011 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")),
11012 rs.getShort(
"meta_flags"), rs.getLong(
"size"),
11013 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
11014 (
short) rs.getInt(
"mode"), rs.getInt(
"uid"), rs.getInt(
"gid"),
11015 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
11016 FileKnown.valueOf(rs.getByte(
"known")),
11017 rs.getString(
"parent_path"), rs.getString(
"mime_type"), rs.getString(
"extension"),
11018 rs.getString(
"owner_uid"), osAccountObjId);
11019 f.setFileSystem(fs);
11034 List<Content> fileChildren(ResultSet rs, CaseDbConnection connection,
long parentId)
throws SQLException {
11035 List<Content> children =
new ArrayList<Content>();
11037 while (rs.next()) {
11038 TskData.TSK_DB_FILES_TYPE_ENUM type = TskData.TSK_DB_FILES_TYPE_ENUM.valueOf(rs.getShort(
"type"));
11040 if (
null != type) {
11043 if (rs.getShort(
"meta_type") != TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()) {
11045 if (rs.getShort(
"meta_type") == TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()) {
11046 result = directory(rs,
null);
11048 result = file(rs,
null);
11050 children.add(result);
11052 VirtualDirectory virtDir = virtualDirectory(rs, connection);
11053 children.add(virtDir);
11057 VirtualDirectory virtDir = virtualDirectory(rs, connection);
11058 children.add(virtDir);
11061 LocalDirectory localDir = localDirectory(rs);
11062 children.add(localDir);
11064 case UNALLOC_BLOCKS:
11065 case UNUSED_BLOCKS:
11067 case LAYOUT_FILE: {
11068 String parentPath = rs.getString(
"parent_path");
11069 if (parentPath ==
null) {
11072 Long osAccountObjId = rs.getLong(
"os_account_obj_id");
11073 if (rs.wasNull()) {
11074 osAccountObjId =
null;
11076 final LayoutFile lf =
new LayoutFile(
this, rs.getLong(
"obj_id"),
11077 rs.getLong(
"data_source_obj_id"), rs.getLong(
"fs_obj_id"),
11078 rs.getString(
"name"), type,
11079 TSK_FS_NAME_TYPE_ENUM.valueOf(rs.getShort(
"dir_type")),
11080 TSK_FS_META_TYPE_ENUM.valueOf(rs.getShort(
"meta_type")),
11081 TSK_FS_NAME_FLAG_ENUM.valueOf(rs.getShort(
"dir_flags")), rs.getShort(
"meta_flags"),
11082 rs.getLong(
"size"),
11083 rs.getLong(
"ctime"), rs.getLong(
"crtime"), rs.getLong(
"atime"), rs.getLong(
"mtime"),
11084 rs.getString(
"md5"), rs.getString(
"sha256"), rs.getString(
"sha1"),
11085 FileKnown.valueOf(rs.getByte(
"known")), parentPath, rs.getString(
"mime_type"),
11086 rs.getString(
"owner_uid"), osAccountObjId);
11091 final DerivedFile df = derivedFile(rs, connection, parentId);
11095 final LocalFile lf = localFile(rs, connection, parentId);
11100 final SlackFile sf = slackFile(rs,
null);
11170 return connections.getConnection();
11180 String getCaseHandleIdentifier() {
11181 return caseHandleIdentifier;
11184 @SuppressWarnings(
"deprecation")
11201 connections.close();
11203 logger.log(Level.SEVERE,
"Error closing database connection pool.", ex);
11206 fileSystemIdMap.clear();
11209 if (this.caseHandle !=
null) {
11210 this.caseHandle.free();
11211 this.caseHandle =
null;
11214 logger.log(Level.SEVERE,
"Error freeing case handle.", ex);
11219 if (this.lockResources !=
null) {
11221 this.lockResources.close();
11222 }
catch (Exception ex) {
11223 logger.log(Level.SEVERE,
"Error closing lock resources.", ex);
11241 long id = file.getId();
11242 FileKnown currentKnown = file.getKnown();
11243 if (currentKnown.compareTo(fileKnown) > 0) {
11247 try (CaseDbConnection connection = connections.getConnection();
11248 Statement statement = connection.createStatement();) {
11249 connection.executeUpdate(statement,
"UPDATE tsk_files "
11250 +
"SET known='" + fileKnown.getFileKnownValue() +
"' "
11251 +
"WHERE obj_id=" +
id);
11253 file.setKnown(fileKnown);
11254 }
catch (SQLException ex) {
11272 try (CaseDbConnection connection = connections.getConnection();) {
11274 preparedStatement.clearParameters();
11275 preparedStatement.setString(1, name);
11276 preparedStatement.setLong(2, objId);
11277 connection.executeUpdate(preparedStatement);
11278 }
catch (SQLException ex) {
11279 throw new TskCoreException(String.format(
"Error updating while the name for object ID %d to %s", objId, name), ex);
11293 void setImageName(String name,
long objId)
throws TskCoreException {
11295 try (CaseDbConnection connection = connections.getConnection();) {
11296 PreparedStatement preparedStatement = connection.getPreparedStatement(SleuthkitCase.PREPARED_STATEMENT.UPDATE_IMAGE_NAME);
11297 preparedStatement.clearParameters();
11298 preparedStatement.setString(1, name);
11299 preparedStatement.setLong(2, objId);
11300 connection.executeUpdate(preparedStatement);
11301 }
catch (SQLException ex) {
11302 throw new TskCoreException(String.format(
"Error updating while the name for object ID %d to %s", objId, name), ex);
11322 void setImageSizes(Image image,
long totalSize,
long sectorSize)
throws TskCoreException {
11325 try (CaseDbConnection connection = connections.getConnection();) {
11326 PreparedStatement preparedStatement = connection.getPreparedStatement(SleuthkitCase.PREPARED_STATEMENT.UPDATE_IMAGE_SIZES);
11327 preparedStatement.clearParameters();
11328 preparedStatement.setLong(1, totalSize);
11329 preparedStatement.setLong(2, sectorSize);
11330 preparedStatement.setLong(3, image.getId());
11331 connection.executeUpdate(preparedStatement);
11332 }
catch (SQLException ex) {
11333 throw new TskCoreException(String.format(
"Error updating image sizes to %d and sector size to %d for object ID %d ", totalSize, sectorSize, image.getId()), ex);
11354 public void updateFile(
long fileObjId,
long size,
long mtime,
long atime,
long ctime,
long crtime, String userSid, Long osAcctObjId)
throws TskCoreException {
11356 String updateString =
"UPDATE tsk_files SET size = ?, mtime = ?, atime = ?, ctime = ?, crtime = ?, "
11357 +
" owner_uid = ?, os_account_obj_id = ? WHERE obj_id = ?";
11360 try (CaseDbConnection connection = connections.getConnection();
11361 PreparedStatement preparedStatement = connection.getPreparedStatement(updateString, Statement.NO_GENERATED_KEYS);) {
11363 preparedStatement.clearParameters();
11365 preparedStatement.setLong(1, size);
11366 preparedStatement.setLong(2, mtime);
11367 preparedStatement.setLong(3, atime);
11368 preparedStatement.setLong(4, ctime);
11369 preparedStatement.setLong(5, crtime);
11370 preparedStatement.setString(6, userSid);
11372 if (osAcctObjId !=
null) {
11373 preparedStatement.setLong(7, osAcctObjId);
11375 preparedStatement.setNull(7, java.sql.Types.BIGINT);
11378 preparedStatement.setLong(8, fileObjId);
11380 connection.executeUpdate(preparedStatement);
11381 }
catch (SQLException ex) {
11382 throw new TskCoreException(String.format(
"Error updating file (obj_id = %s)", fileObjId), ex);
11399 try (CaseDbConnection connection = connections.getConnection();
11400 Statement statement = connection.createStatement()) {
11401 connection.executeUpdate(statement, String.format(
"UPDATE tsk_files SET mime_type = '%s' WHERE obj_id = %d", mimeType, file.getId()));
11402 file.setMIMEType(mimeType);
11403 }
catch (SQLException ex) {
11404 throw new TskCoreException(String.format(
"Error setting MIME type for file (obj_id = %s)", file.getId()), ex);
11423 short metaFlag = file.getMetaFlagsAsInt();
11432 try (CaseDbConnection connection = connections.getConnection();
11433 Statement statement = connection.createStatement();) {
11434 connection.executeUpdate(statement, String.format(
"UPDATE tsk_files SET meta_flags = '%d', dir_flags = '%d' WHERE obj_id = %d", newMetaFlgs, newDirFlags, file.getId()));
11441 }
catch (SQLException ex) {
11442 throw new TskCoreException(String.format(
"Error setting unalloc meta flag for file (obj_id = %s)", file.getId()), ex);
11458 if (md5Hash ==
null) {
11461 long id = file.
getId();
11463 try (CaseDbConnection connection = connections.getConnection();) {
11464 PreparedStatement statement = connection.getPreparedStatement(PREPARED_STATEMENT.UPDATE_FILE_MD5);
11465 statement.clearParameters();
11466 statement.setString(1, md5Hash.toLowerCase());
11467 statement.setLong(2,
id);
11468 connection.executeUpdate(statement);
11470 }
catch (SQLException ex) {
11471 throw new TskCoreException(
"Error setting MD5 hash", ex);
11486 void setMd5ImageHash(Image img, String md5Hash)
throws TskCoreException {
11487 if (md5Hash ==
null) {
11490 long id = img.getId();
11492 try (CaseDbConnection connection = connections.getConnection();) {
11494 statement.clearParameters();
11495 statement.setString(1, md5Hash.toLowerCase());
11496 statement.setLong(2,
id);
11497 connection.executeUpdate(statement);
11498 }
catch (SQLException ex) {
11499 throw new TskCoreException(
"Error setting MD5 hash", ex);
11515 String getMd5ImageHash(Image img)
throws TskCoreException {
11516 long id = img.getId();
11517 CaseDbConnection connection =
null;
11518 ResultSet rs =
null;
11522 connection = connections.getConnection();
11525 statement.clearParameters();
11526 statement.setLong(1,
id);
11527 rs = connection.executeQuery(statement);
11529 hash = rs.getString(
"md5");
11532 }
catch (SQLException ex) {
11533 throw new TskCoreException(
"Error getting MD5 hash", ex);
11535 closeResultSet(rs);
11536 closeConnection(connection);
11550 void setSha1ImageHash(Image img, String sha1Hash)
throws TskCoreException {
11551 if (sha1Hash ==
null) {
11554 long id = img.getId();
11556 try (CaseDbConnection connection = connections.getConnection();) {
11558 statement.clearParameters();
11559 statement.setString(1, sha1Hash.toLowerCase());
11560 statement.setLong(2,
id);
11561 connection.executeUpdate(statement);
11562 }
catch (SQLException ex) {
11563 throw new TskCoreException(
"Error setting SHA1 hash", ex);
11579 String getSha1ImageHash(Image img)
throws TskCoreException {
11580 long id = img.getId();
11581 CaseDbConnection connection =
null;
11582 ResultSet rs =
null;
11586 connection = connections.getConnection();
11589 statement.clearParameters();
11590 statement.setLong(1,
id);
11591 rs = connection.executeQuery(statement);
11593 hash = rs.getString(
"sha1");
11596 }
catch (SQLException ex) {
11597 throw new TskCoreException(
"Error getting SHA1 hash", ex);
11599 closeResultSet(rs);
11600 closeConnection(connection);
11614 void setSha256ImageHash(Image img, String sha256Hash)
throws TskCoreException {
11615 if (sha256Hash ==
null) {
11618 long id = img.getId();
11620 try (CaseDbConnection connection = connections.getConnection();) {
11622 statement.clearParameters();
11623 statement.setString(1, sha256Hash.toLowerCase());
11624 statement.setLong(2,
id);
11625 connection.executeUpdate(statement);
11626 }
catch (SQLException ex) {
11627 throw new TskCoreException(
"Error setting SHA256 hash", ex);
11643 String getSha256ImageHash(Image img)
throws TskCoreException {
11644 long id = img.getId();
11645 CaseDbConnection connection =
null;
11646 ResultSet rs =
null;
11650 connection = connections.getConnection();
11653 statement.clearParameters();
11654 statement.setLong(1,
id);
11655 rs = connection.executeQuery(statement);
11657 hash = rs.getString(
"sha256");
11660 }
catch (SQLException ex) {
11661 throw new TskCoreException(
"Error setting SHA256 hash", ex);
11663 closeResultSet(rs);
11664 closeConnection(connection);
11677 void setAcquisitionDetails(DataSource datasource, String details)
throws TskCoreException {
11679 long id = datasource.getId();
11681 try (CaseDbConnection connection = connections.getConnection();) {
11683 statement.clearParameters();
11684 statement.setString(1, details);
11685 statement.setLong(2,
id);
11686 connection.executeUpdate(statement);
11687 }
catch (SQLException ex) {
11688 throw new TskCoreException(
"Error setting acquisition details", ex);
11705 void setAcquisitionToolDetails(DataSource datasource, String name, String version, String settings)
throws TskCoreException {
11707 long id = datasource.getId();
11709 try (CaseDbConnection connection = connections.getConnection();) {
11711 statement.clearParameters();
11712 statement.setString(1, settings);
11713 statement.setString(2, name);
11714 statement.setString(3, version);
11715 statement.setLong(4,
id);
11716 connection.executeUpdate(statement);
11717 }
catch (SQLException ex) {
11718 throw new TskCoreException(
"Error setting acquisition details", ex);
11733 void setAcquisitionDetails(
long dataSourceId, String details,
CaseDbTransaction trans)
throws TskCoreException {
11735 CaseDbConnection connection = trans.getConnection();
11737 statement.clearParameters();
11738 statement.setString(1, details);
11739 statement.setLong(2, dataSourceId);
11740 connection.executeUpdate(statement);
11741 }
catch (SQLException ex) {
11742 throw new TskCoreException(
"Error setting acquisition details", ex);
11755 String getAcquisitionDetails(DataSource datasource)
throws TskCoreException {
11756 long id = datasource.getId();
11757 CaseDbConnection connection =
null;
11758 ResultSet rs =
null;
11762 connection = connections.getConnection();
11765 statement.clearParameters();
11766 statement.setLong(1,
id);
11767 rs = connection.executeQuery(statement);
11769 hash = rs.getString(
"acquisition_details");
11772 }
catch (SQLException ex) {
11773 throw new TskCoreException(
"Error setting acquisition details", ex);
11775 closeResultSet(rs);
11776 closeConnection(connection);
11791 String getDataSourceInfoString(DataSource datasource, String columnName)
throws TskCoreException {
11792 long id = datasource.getId();
11793 CaseDbConnection connection =
null;
11794 ResultSet rs =
null;
11795 String returnValue =
"";
11798 connection = connections.getConnection();
11801 statement.clearParameters();
11802 statement.setLong(1,
id);
11803 rs = connection.executeQuery(statement);
11805 returnValue = rs.getString(columnName);
11807 return returnValue;
11808 }
catch (SQLException ex) {
11809 throw new TskCoreException(
"Error setting acquisition details", ex);
11811 closeResultSet(rs);
11812 closeConnection(connection);
11827 Long getDataSourceInfoLong(DataSource datasource, String columnName)
throws TskCoreException {
11828 long id = datasource.getId();
11829 CaseDbConnection connection =
null;
11830 ResultSet rs =
null;
11831 Long returnValue =
null;
11834 connection = connections.getConnection();
11837 statement.clearParameters();
11838 statement.setLong(1,
id);
11839 rs = connection.executeQuery(statement);
11841 returnValue = rs.getLong(columnName);
11843 return returnValue;
11844 }
catch (SQLException ex) {
11845 throw new TskCoreException(
"Error setting acquisition details", ex);
11847 closeResultSet(rs);
11848 closeConnection(connection);
11864 if (newStatus ==
null) {
11868 try (CaseDbConnection connection = connections.getConnection();
11869 Statement statement = connection.createStatement();) {
11870 connection.executeUpdate(statement,
"UPDATE blackboard_artifacts "
11871 +
" SET review_status_id=" + newStatus.getID()
11872 +
" WHERE blackboard_artifacts.artifact_id = " + artifact.getArtifactID());
11873 }
catch (SQLException ex) {
11891 CaseDbConnection connection =
null;
11892 Statement s =
null;
11893 ResultSet rs =
null;
11896 connection = connections.getConnection();
11897 s = connection.createStatement();
11898 Short contentShort = contentType.getValue();
11899 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files WHERE meta_type = '" + contentShort.toString() +
"'");
11902 count = rs.getInt(
"count");
11905 }
catch (SQLException ex) {
11908 closeResultSet(rs);
11910 closeConnection(connection);
11924 String escapedText =
null;
11925 if (text !=
null) {
11926 escapedText = text.replaceAll(
"'",
"''");
11928 return escapedText;
11939 if (md5Hash ==
null) {
11943 CaseDbConnection connection =
null;
11944 Statement s =
null;
11945 ResultSet rs =
null;
11948 connection = connections.getConnection();
11949 s = connection.createStatement();
11950 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE "
11951 +
" md5 = '" + md5Hash.toLowerCase() +
"' "
11953 return resultSetToAbstractFiles(rs, connection);
11955 logger.log(Level.WARNING,
"Error querying database.", ex);
11957 closeResultSet(rs);
11959 closeConnection(connection);
11972 boolean allFilesAreHashed =
false;
11974 CaseDbConnection connection =
null;
11975 Statement s =
null;
11976 ResultSet rs =
null;
11979 connection = connections.getConnection();
11980 s = connection.createStatement();
11981 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files "
11983 +
"AND md5 IS NULL "
11984 +
"AND size > '0'");
11985 if (rs.next() && rs.getInt(
"count") == 0) {
11986 allFilesAreHashed =
true;
11989 logger.log(Level.WARNING,
"Failed to query whether all files have MD5 hashes", ex);
11991 closeResultSet(rs);
11993 closeConnection(connection);
11996 return allFilesAreHashed;
12008 CaseDbConnection connection =
null;
12009 Statement s =
null;
12010 ResultSet rs =
null;
12012 connection = connections.getConnection();
12013 s = connection.createStatement();
12014 rs = connection.executeQuery(s,
"SELECT COUNT(*) AS count FROM tsk_files "
12015 +
"WHERE md5 IS NOT NULL "
12016 +
"AND size > '0'");
12018 count = rs.getInt(
"count");
12021 logger.log(Level.WARNING,
"Failed to query for all the files.", ex);
12023 closeResultSet(rs);
12025 closeConnection(connection);
12041 CaseDbConnection connection =
null;
12042 ResultSet resultSet =
null;
12045 connection = connections.getConnection();
12049 resultSet = connection.executeQuery(statement);
12050 ArrayList<TagName> tagNames =
new ArrayList<>();
12051 while (resultSet.next()) {
12052 tagNames.add(
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12054 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank")));
12057 }
catch (SQLException ex) {
12058 throw new TskCoreException(
"Error selecting rows from tag_names table", ex);
12060 closeResultSet(resultSet);
12061 closeConnection(connection);
12077 CaseDbConnection connection =
null;
12078 ResultSet resultSet =
null;
12081 connection = connections.getConnection();
12085 resultSet = connection.executeQuery(statement);
12086 ArrayList<TagName> tagNames =
new ArrayList<>();
12087 while (resultSet.next()) {
12088 tagNames.add(
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12090 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank")));
12093 }
catch (SQLException ex) {
12094 throw new TskCoreException(
"Error selecting rows from tag_names table", ex);
12096 closeResultSet(resultSet);
12097 closeConnection(connection);
12116 ArrayList<TagName> tagNames =
new ArrayList<>();
12122 CaseDbConnection connection =
null;
12123 ResultSet resultSet =
null;
12126 connection = connections.getConnection();
12129 statement.setLong(1, dsObjId);
12130 statement.setLong(2, dsObjId);
12131 resultSet = connection.executeQuery(statement);
12132 while (resultSet.next()) {
12133 tagNames.add(
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12135 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank")));
12138 }
catch (SQLException ex) {
12139 throw new TskCoreException(
"Failed to get tag names in use for data source objID : " + dsObjId, ex);
12141 closeResultSet(resultSet);
12142 closeConnection(connection);
12161 @SuppressWarnings(
"deprecation")
12203 return taggingMgr.addContentTag(content, tagName, comment, beginByteOffset, endByteOffset).getAddedTag();
12216 statement.clearParameters();
12217 statement.setLong(1, tag.getId());
12218 trans.getConnection().executeUpdate(statement);
12221 Long contentId = tag.getContent() !=
null ? tag.getContent().getId() :
null;
12222 Long dataSourceId = tag.getContent() !=
null && tag.getContent().getDataSource() !=
null
12223 ? tag.getContent().getDataSource().getId()
12226 this.
getScoringManager().updateAggregateScoreAfterDeletion(contentId, dataSourceId, trans);
12230 }
catch (SQLException ex) {
12231 throw new TskCoreException(
"Error deleting row from content_tags table (id = " + tag.getId() +
")", ex);
12233 if (trans !=
null) {
12248 CaseDbConnection connection =
null;
12249 ResultSet resultSet =
null;
12252 connection = connections.getConnection();
12259 resultSet = connection.executeQuery(statement);
12260 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
12261 while (resultSet.next()) {
12262 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12264 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12266 tags.add(
new ContentTag(resultSet.getLong(
"tag_id"), content, tagName, resultSet.getString(
"comment"),
12267 resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"), resultSet.getString(
"login_name")));
12270 }
catch (SQLException ex) {
12271 throw new TskCoreException(
"Error selecting rows from content_tags table", ex);
12273 closeResultSet(resultSet);
12274 closeConnection(connection);
12290 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12293 CaseDbConnection connection =
null;
12294 ResultSet resultSet =
null;
12297 connection = connections.getConnection();
12301 statement.clearParameters();
12302 statement.setLong(1, tagName.getId());
12303 resultSet = connection.executeQuery(statement);
12304 if (resultSet.next()) {
12305 return resultSet.getLong(
"count");
12307 throw new TskCoreException(
"Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")");
12309 }
catch (SQLException ex) {
12310 throw new TskCoreException(
"Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")", ex);
12312 closeResultSet(resultSet);
12313 closeConnection(connection);
12335 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12339 CaseDbConnection connection =
null;
12340 ResultSet resultSet =
null;
12343 connection = connections.getConnection();
12349 statement.clearParameters();
12350 statement.setLong(1, tagName.getId());
12351 statement.setLong(2, dsObjId);
12353 resultSet = connection.executeQuery(statement);
12354 if (resultSet.next()) {
12355 return resultSet.getLong(
"count");
12357 throw new TskCoreException(
"Error getting content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")" +
" for dsObjId = " + dsObjId);
12359 }
catch (SQLException ex) {
12360 throw new TskCoreException(
"Failed to get content_tags row count for tag_name_id = " + tagName.getId() +
"data source objID : " + dsObjId, ex);
12362 closeResultSet(resultSet);
12363 closeConnection(connection);
12380 CaseDbConnection connection =
null;
12381 ResultSet resultSet =
null;
12385 connection = connections.getConnection();
12393 statement.clearParameters();
12394 statement.setLong(1, contentTagID);
12395 resultSet = connection.executeQuery(statement);
12397 while (resultSet.next()) {
12398 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12400 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12402 resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"), resultSet.getString(
"login_name"));
12406 }
catch (SQLException ex) {
12407 throw new TskCoreException(
"Error getting content tag with id = " + contentTagID, ex);
12409 closeResultSet(resultSet);
12410 closeConnection(connection);
12428 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12431 CaseDbConnection connection =
null;
12432 ResultSet resultSet =
null;
12435 connection = connections.getConnection();
12442 statement.clearParameters();
12443 statement.setLong(1, tagName.getId());
12444 resultSet = connection.executeQuery(statement);
12445 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
12446 while (resultSet.next()) {
12448 tagName, resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"), resultSet.getString(
"login_name"));
12453 }
catch (SQLException ex) {
12454 throw new TskCoreException(
"Error getting content_tags rows (tag_name_id = " + tagName.getId() +
")", ex);
12456 closeResultSet(resultSet);
12457 closeConnection(connection);
12478 CaseDbConnection connection =
null;
12479 ResultSet resultSet =
null;
12482 connection = connections.getConnection();
12507 statement.clearParameters();
12508 statement.setLong(1, tagName.getId());
12509 statement.setLong(2, dsObjId);
12510 statement.setLong(3, tagName.getId());
12511 statement.setLong(4, dsObjId);
12512 resultSet = connection.executeQuery(statement);
12513 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
12514 while (resultSet.next()) {
12516 tagName, resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"), resultSet.getString(
"login_name"));
12521 }
catch (SQLException ex) {
12522 throw new TskCoreException(
"Failed to get content_tags row count for tag_name_id = " + tagName.getId() +
" data source objID : " + dsObjId, ex);
12524 closeResultSet(resultSet);
12525 closeConnection(connection);
12542 CaseDbConnection connection =
null;
12543 ResultSet resultSet =
null;
12546 connection = connections.getConnection();
12554 statement.clearParameters();
12555 statement.setLong(1, content.getId());
12556 resultSet = connection.executeQuery(statement);
12557 ArrayList<ContentTag> tags =
new ArrayList<ContentTag>();
12558 while (resultSet.next()) {
12559 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12561 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12563 resultSet.getString(
"comment"), resultSet.getLong(
"begin_byte_offset"), resultSet.getLong(
"end_byte_offset"), resultSet.getString(
"login_name"));
12567 }
catch (SQLException ex) {
12568 throw new TskCoreException(
"Error getting content tags data for content (obj_id = " + content.getId() +
")", ex);
12570 closeResultSet(resultSet);
12571 closeConnection(connection);
12592 return taggingMgr.addArtifactTag(artifact, tagName, comment).getAddedTag();
12605 statement.clearParameters();
12606 statement.setLong(1, tag.getId());
12607 trans.getConnection().executeUpdate(statement);
12610 Long artifactObjId = tag.getArtifact().getId();
12611 Long dataSourceId = tag.getContent() !=
null && tag.getContent().getDataSource() !=
null
12612 ? tag.getContent().getDataSource().getId()
12615 this.
getScoringManager().updateAggregateScoreAfterDeletion(artifactObjId, dataSourceId, trans);
12619 }
catch (SQLException ex) {
12620 throw new TskCoreException(
"Error deleting row from blackboard_artifact_tags table (id = " + tag.getId() +
")", ex);
12622 if (trans !=
null) {
12638 CaseDbConnection connection =
null;
12639 ResultSet resultSet =
null;
12642 connection = connections.getConnection();
12649 resultSet = connection.executeQuery(statement);
12650 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<>();
12651 while (resultSet.next()) {
12652 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12654 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12658 artifact, content, tagName, resultSet.getString(
"comment"), resultSet.getString(
"login_name"));
12662 }
catch (SQLException ex) {
12663 throw new TskCoreException(
"Error selecting rows from blackboard_artifact_tags table", ex);
12665 closeResultSet(resultSet);
12666 closeConnection(connection);
12682 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12685 CaseDbConnection connection =
null;
12686 ResultSet resultSet =
null;
12689 connection = connections.getConnection();
12693 statement.clearParameters();
12694 statement.setLong(1, tagName.getId());
12695 resultSet = connection.executeQuery(statement);
12696 if (resultSet.next()) {
12697 return resultSet.getLong(
"count");
12699 throw new TskCoreException(
"Error getting blackboard_artifact_tags row count for tag name (tag_name_id = " + tagName.getId() +
")");
12701 }
catch (SQLException ex) {
12702 throw new TskCoreException(
"Error getting blackboard artifact_content_tags row count for tag name (tag_name_id = " + tagName.getId() +
")", ex);
12704 closeResultSet(resultSet);
12705 closeConnection(connection);
12726 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12730 CaseDbConnection connection =
null;
12731 ResultSet resultSet =
null;
12734 connection = connections.getConnection();
12740 statement.clearParameters();
12741 statement.setLong(1, tagName.getId());
12742 statement.setLong(2, dsObjId);
12743 resultSet = connection.executeQuery(statement);
12744 if (resultSet.next()) {
12745 return resultSet.getLong(
"count");
12747 throw new TskCoreException(
"Error getting blackboard_artifact_tags row count for tag name (tag_name_id = " + tagName.getId() +
")" +
" for dsObjId = " + dsObjId);
12749 }
catch (SQLException ex) {
12750 throw new TskCoreException(
"Failed to get blackboard_artifact_tags row count for tag_name_id = " + tagName.getId() +
"data source objID : " + dsObjId, ex);
12752 closeResultSet(resultSet);
12753 closeConnection(connection);
12770 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12773 CaseDbConnection connection =
null;
12774 ResultSet resultSet =
null;
12777 connection = connections.getConnection();
12784 statement.clearParameters();
12785 statement.setLong(1, tagName.getId());
12786 resultSet = connection.executeQuery(statement);
12787 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<BlackboardArtifactTag>();
12788 while (resultSet.next()) {
12792 artifact, content, tagName, resultSet.getString(
"comment"), resultSet.getString(
"login_name"));
12796 }
catch (SQLException ex) {
12797 throw new TskCoreException(
"Error getting blackboard artifact tags data (tag_name_id = " + tagName.getId() +
")", ex);
12799 closeResultSet(resultSet);
12800 closeConnection(connection);
12821 if (tagName.getId() ==
Tag.ID_NOT_SET) {
12825 CaseDbConnection connection =
null;
12826 ResultSet resultSet =
null;
12829 connection = connections.getConnection();
12838 statement.clearParameters();
12839 statement.setLong(1, tagName.getId());
12840 statement.setLong(2, dsObjId);
12841 resultSet = connection.executeQuery(statement);
12842 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<BlackboardArtifactTag>();
12843 while (resultSet.next()) {
12847 artifact, content, tagName, resultSet.getString(
"comment"), resultSet.getString(
"login_name"));
12851 }
catch (SQLException ex) {
12852 throw new TskCoreException(
"Failed to get blackboard_artifact_tags row count for tag_name_id = " + tagName.getId() +
"data source objID : " + dsObjId, ex);
12854 closeResultSet(resultSet);
12855 closeConnection(connection);
12874 CaseDbConnection connection =
null;
12875 ResultSet resultSet =
null;
12879 connection = connections.getConnection();
12887 statement.clearParameters();
12888 statement.setLong(1, artifactTagID);
12889 resultSet = connection.executeQuery(statement);
12891 while (resultSet.next()) {
12892 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12894 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12898 artifact, content, tagName, resultSet.getString(
"comment"), resultSet.getString(
"login_name"));
12902 }
catch (SQLException ex) {
12903 throw new TskCoreException(
"Error getting blackboard artifact tag with id = " + artifactTagID, ex);
12905 closeResultSet(resultSet);
12906 closeConnection(connection);
12925 CaseDbConnection connection =
null;
12926 ResultSet resultSet =
null;
12929 connection = connections.getConnection();
12937 statement.clearParameters();
12938 statement.setLong(1, artifact.getArtifactID());
12939 resultSet = connection.executeQuery(statement);
12940 ArrayList<BlackboardArtifactTag> tags =
new ArrayList<>();
12941 while (resultSet.next()) {
12942 TagName tagName =
new TagName(resultSet.getLong(
"tag_name_id"), resultSet.getString(
"display_name"),
12944 TskData.
TagType.
valueOf(resultSet.getByte(
"knownStatus")), resultSet.getLong(
"tag_set_id"), resultSet.getInt(
"rank"));
12947 artifact, content, tagName, resultSet.getString(
"comment"), resultSet.getString(
"login_name"));
12951 }
catch (SQLException ex) {
12952 throw new TskCoreException(
"Error getting blackboard artifact tags data (artifact_id = " + artifact.getArtifactID() +
")", ex);
12954 closeResultSet(resultSet);
12955 closeConnection(connection);
12970 try (CaseDbConnection connection = connections.getConnection();) {
12973 statement.clearParameters();
12974 statement.setString(1, newPath);
12975 statement.setLong(2, objectId);
12976 connection.executeUpdate(statement);
12977 }
catch (SQLException ex) {
12978 throw new TskCoreException(
"Error updating image path in database for object " + objectId, ex);
12998 return addReport(localPath, sourceModuleName, reportName,
null);
13019 String relativePath =
"";
13020 long createTime = 0;
13021 String localPathLower = localPath.toLowerCase();
13023 if (localPathLower.startsWith(
"http")) {
13024 relativePath = localPathLower;
13025 createTime = System.currentTimeMillis() / 1000;
13036 int length =
new File(casePathLower).toURI().relativize(
new File(localPathLower).toURI()).getPath().length();
13037 relativePath =
new File(localPath.substring(localPathLower.length() - length)).getPath();
13038 }
catch (IllegalArgumentException ex) {
13039 String errorMessage = String.format(
"Local path %s not in the database directory or one of its subdirectories", localPath);
13044 java.io.File tempFile =
new java.io.File(localPath);
13046 createTime = tempFile.lastModified() / 1000;
13047 }
catch (Exception ex) {
13048 throw new TskCoreException(
"Could not get create time for report at " + localPath, ex);
13054 try (CaseDbConnection connection = connections.getConnection();) {
13057 long parentObjId = 0;
13058 if (parent !=
null) {
13059 parentObjId = parent.getId();
13065 statement.clearParameters();
13066 statement.setLong(1, objectId);
13067 statement.setString(2, relativePath);
13068 statement.setLong(3, createTime);
13069 statement.setString(4, sourceModuleName);
13070 statement.setString(5, reportName);
13071 connection.executeUpdate(statement);
13072 return new Report(
this, objectId, localPath, createTime, sourceModuleName, reportName, parent);
13073 }
catch (SQLException ex) {
13074 throw new TskCoreException(
"Error adding report " + localPath +
" to reports table", ex);
13089 CaseDbConnection connection =
null;
13090 ResultSet resultSet =
null;
13091 ResultSet parentResultSet =
null;
13092 PreparedStatement statement =
null;
13093 Statement parentStatement =
null;
13096 connection = connections.getConnection();
13100 parentStatement = connection.createStatement();
13101 resultSet = connection.executeQuery(statement);
13102 ArrayList<Report> reports =
new ArrayList<Report>();
13103 while (resultSet.next()) {
13104 String localpath = resultSet.getString(
"path");
13105 if (localpath.toLowerCase().startsWith(
"http") ==
false) {
13107 localpath = Paths.get(
getDbDirPath(), localpath).normalize().toString();
13112 long reportId = resultSet.getLong(
"obj_id");
13113 String parentQuery = String.format(
"SELECT * FROM tsk_objects WHERE obj_id = %s;", reportId);
13114 parentResultSet = parentStatement.executeQuery(parentQuery);
13115 if (parentResultSet.next()) {
13116 long parentId = parentResultSet.getLong(
"par_obj_id");
13119 parentResultSet.
close();
13121 reports.add(
new Report(
this,
13124 resultSet.getLong(
"crtime"),
13125 resultSet.getString(
"src_module_name"),
13126 resultSet.getString(
"report_name"),
13130 }
catch (SQLException ex) {
13133 closeResultSet(resultSet);
13134 closeResultSet(parentResultSet);
13135 closeStatement(statement);
13136 closeStatement(parentStatement);
13138 closeConnection(connection);
13153 CaseDbConnection connection =
null;
13154 PreparedStatement statement =
null;
13155 Statement parentStatement =
null;
13156 ResultSet resultSet =
null;
13157 ResultSet parentResultSet =
null;
13161 connection = connections.getConnection();
13165 parentStatement = connection.createStatement();
13166 statement.clearParameters();
13167 statement.setLong(1,
id);
13168 resultSet = connection.executeQuery(statement);
13170 if (resultSet.next()) {
13173 String parentQuery = String.format(
"SELECT * FROM tsk_objects WHERE obj_id = %s;",
id);
13174 parentResultSet = parentStatement.executeQuery(parentQuery);
13175 if (parentResultSet.next()) {
13176 long parentId = parentResultSet.getLong(
"par_obj_id");
13180 report =
new Report(
this, resultSet.getLong(
"obj_id"),
13181 Paths.get(
getDbDirPath(), resultSet.getString(
"path")).normalize().toString(),
13182 resultSet.getLong(
"crtime"),
13183 resultSet.getString(
"src_module_name"),
13184 resultSet.getString(
"report_name"),
13189 }
catch (SQLException ex) {
13190 throw new TskCoreException(
"Error querying reports table for id: " +
id, ex);
13192 closeResultSet(resultSet);
13193 closeResultSet(parentResultSet);
13194 closeStatement(statement);
13195 closeStatement(parentStatement);
13196 closeConnection(connection);
13212 try (CaseDbConnection connection = connections.getConnection();) {
13215 statement.setLong(1, report.getId());
13216 connection.executeUpdate(statement);
13219 statement.setLong(1, report.getId());
13221 connection.executeUpdate(statement);
13222 }
catch (SQLException ex) {
13229 static void closeResultSet(ResultSet resultSet) {
13230 if (resultSet !=
null) {
13233 }
catch (SQLException ex) {
13234 logger.log(Level.SEVERE,
"Error closing ResultSet", ex);
13239 static void closeStatement(Statement statement) {
13240 if (statement !=
null) {
13243 }
catch (SQLException ex) {
13244 logger.log(Level.SEVERE,
"Error closing Statement", ex);
13250 static void closeConnection(CaseDbConnection connection) {
13251 if (connection !=
null) {
13252 connection.close();
13256 private static void rollbackTransaction(CaseDbConnection connection) {
13257 if (connection !=
null) {
13258 connection.rollbackTransaction();
13270 void setIngestJobEndDateTime(
long ingestJobId,
long endDateTime)
throws TskCoreException {
13272 try (CaseDbConnection connection = connections.getConnection();) {
13273 Statement statement = connection.createStatement();
13274 statement.executeUpdate(
"UPDATE ingest_jobs SET end_date_time=" + endDateTime +
" WHERE ingest_job_id=" + ingestJobId +
";");
13275 }
catch (SQLException ex) {
13276 throw new TskCoreException(
"Error updating the end date (ingest_job_id = " + ingestJobId +
".", ex);
13282 void setIngestJobStatus(
long ingestJobId, IngestJobStatusType status)
throws TskCoreException {
13284 try (CaseDbConnection connection = connections.getConnection();
13285 Statement statement = connection.createStatement();) {
13286 statement.executeUpdate(
"UPDATE ingest_jobs SET status_id=" + status.ordinal() +
" WHERE ingest_job_id=" + ingestJobId +
";");
13287 }
catch (SQLException ex) {
13288 throw new TskCoreException(
"Error ingest job status (ingest_job_id = " + ingestJobId +
".", ex);
13311 CaseDbConnection connection =
null;
13313 ResultSet resultSet =
null;
13314 Statement statement;
13316 connection = connections.getConnection();
13317 connection.beginTransaction();
13318 statement = connection.createStatement();
13320 insertStatement.setLong(1, dataSource.getId());
13321 insertStatement.setString(2, hostName);
13322 insertStatement.setLong(3, jobStart.getTime());
13323 insertStatement.setLong(4, jobEnd.getTime());
13324 insertStatement.setInt(5, status.ordinal());
13325 insertStatement.setString(6, settingsDir);
13326 connection.executeUpdate(insertStatement);
13327 resultSet = insertStatement.getGeneratedKeys();
13329 long id = resultSet.getLong(1);
13330 for (
int i = 0; i < ingestModules.size(); i++) {
13332 statement.executeUpdate(
"INSERT INTO ingest_job_modules (ingest_job_id, ingest_module_id, pipeline_position) "
13333 +
"VALUES (" +
id +
", " + ingestModule.
getIngestModuleId() +
", " + i +
");");
13337 connection.commitTransaction();
13338 return new IngestJobInfo(
id, dataSource.getId(), hostName, jobStart,
"", ingestModules,
this);
13339 }
catch (SQLException ex) {
13340 rollbackTransaction(connection);
13343 closeResultSet(resultSet);
13344 closeConnection(connection);
13363 CaseDbConnection connection =
null;
13364 ResultSet resultSet =
null;
13365 Statement statement =
null;
13366 String uniqueName = factoryClassName +
"-" + displayName +
"-" + version;
13369 connection = connections.getConnection();
13370 statement = connection.createStatement();
13371 resultSet = statement.executeQuery(
"SELECT * FROM ingest_modules WHERE unique_name = '" + uniqueName +
"'");
13372 if (!resultSet.next()) {
13376 insertStatement.setString(1, displayName);
13377 insertStatement.setString(2, uniqueName);
13378 insertStatement.setInt(3, type.ordinal());
13379 insertStatement.setString(4, version);
13380 connection.executeUpdate(insertStatement);
13381 resultSet = insertStatement.getGeneratedKeys();
13383 long id = resultSet.getLong(1);
13388 return new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
13389 resultSet.getString(
"unique_name"),
IngestModuleType.
fromID(resultSet.getInt(
"type_id")), resultSet.getString(
"version"));
13391 }
catch (SQLException ex) {
13393 closeStatement(statement);
13394 if (connection !=
null) {
13395 statement = connection.createStatement();
13396 resultSet = statement.executeQuery(
"SELECT * FROM ingest_modules WHERE unique_name = '" + uniqueName +
"'");
13397 if (resultSet.next()) {
13398 return new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
13403 }
catch (SQLException ex1) {
13407 closeResultSet(resultSet);
13408 closeStatement(statement);
13409 closeConnection(connection);
13422 CaseDbConnection connection =
null;
13423 ResultSet resultSet =
null;
13424 Statement statement =
null;
13425 List<IngestJobInfo> ingestJobs =
new ArrayList<>();
13428 connection = connections.getConnection();
13429 statement = connection.createStatement();
13430 resultSet = statement.executeQuery(
"SELECT * FROM ingest_jobs");
13431 while (resultSet.next()) {
13432 ingestJobs.add(
new IngestJobInfo(resultSet.getInt(
"ingest_job_id"), resultSet.getLong(
"obj_id"),
13433 resultSet.getString(
"host_name"),
new Date(resultSet.getLong(
"start_date_time")),
13435 resultSet.getString(
"settings_dir"),
this.getIngestModules(resultSet.getInt(
"ingest_job_id"), connection),
this));
13438 }
catch (SQLException ex) {
13441 closeResultSet(resultSet);
13442 closeStatement(statement);
13443 closeConnection(connection);
13458 private List<IngestModuleInfo> getIngestModules(
int ingestJobId, CaseDbConnection connection)
throws SQLException {
13459 ResultSet resultSet =
null;
13460 Statement statement =
null;
13461 List<IngestModuleInfo> ingestModules =
new ArrayList<>();
13464 statement = connection.createStatement();
13465 resultSet = statement.executeQuery(
"SELECT ingest_job_modules.ingest_module_id AS ingest_module_id, "
13466 +
"ingest_job_modules.pipeline_position AS pipeline_position, "
13467 +
"ingest_modules.display_name AS display_name, ingest_modules.unique_name AS unique_name, "
13468 +
"ingest_modules.type_id AS type_id, ingest_modules.version AS version "
13469 +
"FROM ingest_job_modules, ingest_modules "
13470 +
"WHERE ingest_job_modules.ingest_job_id = " + ingestJobId +
" "
13471 +
"AND ingest_modules.ingest_module_id = ingest_job_modules.ingest_module_id "
13472 +
"ORDER BY (ingest_job_modules.pipeline_position);");
13473 while (resultSet.next()) {
13474 ingestModules.add(
new IngestModuleInfo(resultSet.getInt(
"ingest_module_id"), resultSet.getString(
"display_name"),
13475 resultSet.getString(
"unique_name"),
IngestModuleType.
fromID(resultSet.getInt(
"type_id")), resultSet.getString(
"version")));
13477 return ingestModules;
13479 closeResultSet(resultSet);
13480 closeStatement(statement);
13495 String getInsertOrIgnoreSQL(String sql) {
13498 return " INSERT " + sql +
" ON CONFLICT DO NOTHING ";
13500 return " INSERT OR IGNORE " + sql;
13502 throw new UnsupportedOperationException(
"Unsupported DB type: " +
getDatabaseType().name());
13526 private List<? extends BlackboardArtifact> getArtifactsForValues(BlackboardArtifact.Category category, String dbColumn, List<? extends Number> values, CaseDbConnection connection)
throws TskCoreException {
13530 for (Number value : values) {
13531 if (!where.isEmpty()) {
13534 where += dbColumn +
" = " + value;
13539 if (category == BlackboardArtifact.Category.DATA_ARTIFACT) {
13540 return blackboard.getDataArtifactsWhere(where, connection);
13542 return blackboard.getAnalysisResultsWhere(where, connection);
13549 static class ObjectInfo {
13552 private TskData.ObjectType type;
13554 ObjectInfo(
long id, ObjectType type) {
13563 TskData.ObjectType getType() {
13573 private enum PREPARED_STATEMENT {
13576 +
"WHERE artifact_type_id = ?"),
13582 +
"FROM tsk_objects INNER JOIN tsk_files "
13583 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13584 +
"WHERE (tsk_objects.par_obj_id = ? ) "
13585 +
"ORDER BY tsk_files.meta_type DESC, LOWER(tsk_files.name)"),
13587 +
"FROM tsk_objects INNER JOIN tsk_files "
13588 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13589 +
"WHERE (tsk_objects.par_obj_id = ? AND tsk_files.type = ? ) "
13590 +
"ORDER BY tsk_files.dir_type, LOWER(tsk_files.name)"),
13592 +
"FROM tsk_objects INNER JOIN tsk_files "
13593 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13594 +
"WHERE (tsk_objects.par_obj_id = ? AND "
13595 +
"LOWER(tsk_files.name) LIKE LOWER(?) AND LOWER(tsk_files.name) NOT LIKE LOWER('%journal%')) "
13596 +
"ORDER BY tsk_files.dir_type, LOWER(tsk_files.name)"),
13598 +
"FROM tsk_objects INNER JOIN tsk_files "
13599 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13600 +
"WHERE tsk_files.extension = ? AND "
13601 +
"(tsk_objects.par_obj_id = ? AND "
13602 +
"LOWER(tsk_files.name) LIKE LOWER(?) AND LOWER(tsk_files.name) NOT LIKE LOWER('%journal%')) "
13603 +
"ORDER BY tsk_files.dir_type, LOWER(tsk_files.name)"),
13605 +
"FROM tsk_objects INNER JOIN tsk_files "
13606 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13607 +
"WHERE (tsk_objects.par_obj_id = ?)"),
13609 +
"FROM tsk_objects INNER JOIN tsk_files "
13610 +
"ON tsk_objects.obj_id=tsk_files.obj_id "
13611 +
"WHERE (tsk_objects.par_obj_id = ? "
13612 +
"AND tsk_files.type = ? )"),
13617 INSERT_ARTIFACT(
"INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_obj_id, data_source_obj_id, artifact_type_id, review_status_id) "
13619 POSTGRESQL_INSERT_ARTIFACT(
"INSERT INTO blackboard_artifacts (artifact_id, obj_id, artifact_obj_id, data_source_obj_id, artifact_type_id, review_status_id) "
13621 INSERT_ANALYSIS_RESULT(
"INSERT INTO tsk_analysis_results (artifact_obj_id, conclusion, significance, priority, configuration, justification) "
13622 +
"VALUES (?, ?, ?, ?, ?, ?)"),
13623 INSERT_STRING_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_text) "
13624 +
"VALUES (?,?,?,?,?,?,?)"),
13625 INSERT_BYTE_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_byte) "
13626 +
"VALUES (?,?,?,?,?,?,?)"),
13627 INSERT_INT_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_int32) "
13628 +
"VALUES (?,?,?,?,?,?,?)"),
13629 INSERT_LONG_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_int64) "
13630 +
"VALUES (?,?,?,?,?,?,?)"),
13631 INSERT_DOUBLE_ATTRIBUTE(
"INSERT INTO blackboard_attributes (artifact_id, artifact_type_id, source, context, attribute_type_id, value_type, value_double) "
13632 +
"VALUES (?,?,?,?,?,?,?)"),
13633 INSERT_FILE_ATTRIBUTE(
"INSERT INTO tsk_file_attributes (obj_id, attribute_type_id, value_type, value_byte, value_text, value_int32, value_int64, value_double) "
13634 +
"VALUES (?,?,?,?,?,?,?,?)"),
13659 INSERT_FILE(
"INSERT INTO tsk_files (obj_id, fs_obj_id, name, type, has_path, dir_type, meta_type, dir_flags, meta_flags, size, ctime, crtime, atime, mtime, md5, sha256, sha1, known, mime_type, parent_path, data_source_obj_id, extension, owner_uid, os_account_obj_id, collected) "
13660 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
13661 INSERT_FILE_SYSTEM_FILE(
"INSERT INTO tsk_files(obj_id, fs_obj_id, data_source_obj_id, attr_type, attr_id, name, meta_addr, meta_seq, type, has_path, dir_type, meta_type, dir_flags, meta_flags, size, ctime, crtime, atime, mtime, md5, sha256, sha1, mime_type, parent_path, extension, owner_uid, os_account_obj_id, collected)"
13662 +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
13663 UPDATE_DERIVED_FILE(
"UPDATE tsk_files SET type = ?, dir_type = ?, meta_type = ?, dir_flags = ?, meta_flags = ?, size= ?, ctime= ?, crtime= ?, atime= ?, mtime= ?, mime_type = ? "
13664 +
"WHERE obj_id = ?"),
13666 +
"VALUES (?, ?, ?, ?)"),
13673 +
"WHERE tag_name_id IN "
13674 +
"(SELECT tag_name_id from content_tags UNION SELECT tag_name_id FROM blackboard_artifact_tags)"),
13676 +
"WHERE tag_name_id IN "
13677 +
"( SELECT content_tags.tag_name_id as tag_name_id "
13678 +
"FROM content_tags as content_tags, tsk_files as tsk_files"
13679 +
" WHERE content_tags.obj_id = tsk_files.obj_id"
13680 +
" AND tsk_files.data_source_obj_id = ?"
13682 +
"SELECT artifact_tags.tag_name_id as tag_name_id "
13683 +
" FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts "
13684 +
" WHERE artifact_tags.artifact_id = arts.artifact_id"
13685 +
" AND arts.data_source_obj_id = ?"
13687 INSERT_TAG_NAME(
"INSERT INTO tag_names (display_name, description, color, knownStatus) VALUES (?, ?, ?, ?)"),
13688 INSERT_CONTENT_TAG(
"INSERT INTO content_tags (obj_id, tag_name_id, comment, begin_byte_offset, end_byte_offset, examiner_id) VALUES (?, ?, ?, ?, ?, ?)"),
13692 "SELECT COUNT(*) AS count FROM content_tags as content_tags, tsk_files as tsk_files WHERE content_tags.obj_id = tsk_files.obj_id"
13693 +
" AND content_tags.tag_name_id = ? "
13694 +
" AND tsk_files.data_source_obj_id = ? "
13696 SELECT_CONTENT_TAGS(
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tsk_examiners.login_name, tag_names.tag_set_id, tag_names.rank "
13697 +
"FROM content_tags "
13698 +
"INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id "
13699 +
"LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id"),
13700 SELECT_CONTENT_TAGS_BY_TAG_NAME(
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tsk_examiners.login_name "
13701 +
"FROM content_tags "
13702 +
"LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id "
13703 +
"WHERE tag_name_id = ?"),
13704 SELECT_CONTENT_TAGS_BY_TAG_NAME_BY_DATASOURCE(
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tag_names.tag_set_id, tsk_examiners.login_name "
13705 +
"FROM content_tags "
13706 +
"JOIN tsk_os_accounts acc ON content_tags.obj_id = acc.os_account_obj_id "
13707 +
"JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id "
13708 +
"JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id "
13709 +
"WHERE content_tags.tag_name_id = ? "
13710 +
"AND acc.os_account_obj_id IN (SELECT os_account_obj_id FROM tsk_os_account_instances WHERE data_source_obj_id = ?) "
13713 +
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tag_names.tag_set_id, tsk_examiners.login_name "
13714 +
"FROM content_tags as content_tags, tsk_files as tsk_files, tag_names as tag_names, tsk_examiners as tsk_examiners "
13715 +
"WHERE content_tags.examiner_id = tsk_examiners.examiner_id "
13716 +
"AND content_tags.obj_id = tsk_files.obj_id "
13717 +
"AND content_tags.tag_name_id = tag_names.tag_name_id "
13718 +
"AND content_tags.tag_name_id = ? "
13719 +
"AND tsk_files.data_source_obj_id = ? "),
13720 SELECT_CONTENT_TAG_BY_ID(
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tsk_examiners.login_name, tag_names.tag_set_id, tag_names.rank "
13721 +
"FROM content_tags "
13722 +
"INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id "
13723 +
"LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id "
13724 +
"WHERE tag_id = ?"),
13725 SELECT_CONTENT_TAGS_BY_CONTENT(
"SELECT content_tags.tag_id, content_tags.obj_id, content_tags.tag_name_id, content_tags.comment, content_tags.begin_byte_offset, content_tags.end_byte_offset, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tsk_examiners.login_name, tag_names.tag_set_id, tag_names.rank "
13726 +
"FROM content_tags "
13727 +
"INNER JOIN tag_names ON content_tags.tag_name_id = tag_names.tag_name_id "
13728 +
"LEFT OUTER JOIN tsk_examiners ON content_tags.examiner_id = tsk_examiners.examiner_id "
13729 +
"WHERE content_tags.obj_id = ?"),
13731 +
"VALUES (?, ?, ?, ?)"),
13733 SELECT_ARTIFACT_TAGS(
"SELECT blackboard_artifact_tags.tag_id, blackboard_artifact_tags.artifact_id, blackboard_artifact_tags.tag_name_id, blackboard_artifact_tags.comment, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tag_names.tag_set_id, tsk_examiners.login_name, tag_names.rank "
13734 +
"FROM blackboard_artifact_tags "
13735 +
"INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id "
13736 +
"LEFT OUTER JOIN tsk_examiners ON blackboard_artifact_tags.examiner_id = tsk_examiners.examiner_id"),
13739 +
" AND artifact_tags.tag_name_id = ?"
13740 +
" AND arts.data_source_obj_id = ? "),
13741 SELECT_ARTIFACT_TAGS_BY_TAG_NAME(
"SELECT blackboard_artifact_tags.tag_id, blackboard_artifact_tags.artifact_id, blackboard_artifact_tags.tag_name_id, blackboard_artifact_tags.comment, tsk_examiners.login_name "
13742 +
"FROM blackboard_artifact_tags "
13743 +
"LEFT OUTER JOIN tsk_examiners ON blackboard_artifact_tags.examiner_id = tsk_examiners.examiner_id "
13744 +
"WHERE tag_name_id = ?"),
13745 SELECT_ARTIFACT_TAGS_BY_TAG_NAME_BY_DATASOURCE(
"SELECT artifact_tags.tag_id, artifact_tags.artifact_id, artifact_tags.tag_name_id, artifact_tags.comment, arts.obj_id, arts.artifact_obj_id, arts.data_source_obj_id, arts.artifact_type_id, arts.review_status_id, tsk_examiners.login_name "
13746 +
"FROM blackboard_artifact_tags as artifact_tags, blackboard_artifacts AS arts, tsk_examiners AS tsk_examiners "
13747 +
"WHERE artifact_tags.examiner_id = tsk_examiners.examiner_id"
13748 +
" AND artifact_tags.artifact_id = arts.artifact_id"
13749 +
" AND artifact_tags.tag_name_id = ? "
13750 +
" AND arts.data_source_obj_id = ? "),
13751 SELECT_ARTIFACT_TAG_BY_ID(
"SELECT blackboard_artifact_tags.tag_id, blackboard_artifact_tags.artifact_id, blackboard_artifact_tags.tag_name_id, blackboard_artifact_tags.comment, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tsk_examiners.login_name, tag_names.tag_set_id, tag_names.rank "
13752 +
"FROM blackboard_artifact_tags "
13753 +
"INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id "
13754 +
"LEFT OUTER JOIN tsk_examiners ON blackboard_artifact_tags.examiner_id = tsk_examiners.examiner_id "
13755 +
"WHERE blackboard_artifact_tags.tag_id = ?"),
13756 SELECT_ARTIFACT_TAGS_BY_ARTIFACT(
"SELECT blackboard_artifact_tags.tag_id, blackboard_artifact_tags.artifact_id, blackboard_artifact_tags.tag_name_id, blackboard_artifact_tags.comment, tag_names.display_name, tag_names.description, tag_names.color, tag_names.knownStatus, tsk_examiners.login_name, tag_names.tag_set_id, tag_names.rank "
13757 +
"FROM blackboard_artifact_tags "
13758 +
"INNER JOIN tag_names ON blackboard_artifact_tags.tag_name_id = tag_names.tag_name_id "
13759 +
"LEFT OUTER JOIN tsk_examiners ON blackboard_artifact_tags.examiner_id = tsk_examiners.examiner_id "
13760 +
"WHERE blackboard_artifact_tags.artifact_id = ?"),
13763 INSERT_REPORT(
"INSERT INTO reports (obj_id, path, crtime, src_module_name, report_name) VALUES (?, ?, ?, ?, ?)"),
13766 INSERT_INGEST_JOB(
"INSERT INTO ingest_jobs (obj_id, host_name, start_date_time, end_date_time, status_id, settings_dir) VALUES (?, ?, ?, ?, ?, ?)"),
13768 SELECT_ATTR_BY_VALUE_BYTE(
"SELECT source FROM blackboard_attributes WHERE artifact_id = ? AND attribute_type_id = ? AND value_type = 4 AND value_byte = ?"),
13769 UPDATE_ATTR_BY_VALUE_BYTE(
"UPDATE blackboard_attributes SET source = ? WHERE artifact_id = ? AND attribute_type_id = ? AND value_type = 4 AND value_byte = ?"),
13772 +
"FROM tsk_objects INNER JOIN blackboard_artifacts "
13773 +
"ON tsk_objects.obj_id=blackboard_artifacts.obj_id "
13774 +
"WHERE (tsk_objects.par_obj_id = ?)"),
13784 INSERT_IMAGE_INFO(
"INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
13785 +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"),
13786 INSERT_DATA_SOURCE_INFO(
"INSERT INTO data_source_info (obj_id, device_id, time_zone, added_date_time, host_id, acquisition_tool_settings) VALUES (?, ?, ?, ?, ?, ?)"),
13787 INSERT_VS_INFO(
"INSERT INTO tsk_vs_info (obj_id, vs_type, img_offset, block_size) VALUES (?, ?, ?, ?)"),
13788 INSERT_VS_PART_SQLITE(
"INSERT INTO tsk_vs_parts (obj_id, addr, start, length, desc, flags) VALUES (?, ?, ?, ?, ?, ?)"),
13789 INSERT_VS_PART_POSTGRESQL(
"INSERT INTO tsk_vs_parts (obj_id, addr, start, length, descr, flags) VALUES (?, ?, ?, ?, ?, ?)"),
13791 INSERT_FS_INFO(
"INSERT INTO tsk_fs_info (obj_id, data_source_obj_id, img_offset, fs_type, block_size, block_count, root_inum, first_inum, last_inum, display_name)"
13792 +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"),
13795 private final String sql;
13797 private PREPARED_STATEMENT(String sql) {
13811 abstract private class ConnectionPool {
13813 private PooledDataSource pooledDataSource;
13815 public ConnectionPool() {
13816 pooledDataSource =
null;
13819 CaseDbConnection getConnection() throws TskCoreException {
13820 if (pooledDataSource ==
null) {
13821 throw new TskCoreException(
"Error getting case database connection - case is closed");
13824 return getPooledConnection();
13825 }
catch (SQLException exp) {
13826 throw new TskCoreException(exp.getMessage());
13830 void close() throws TskCoreException {
13831 if (pooledDataSource !=
null) {
13833 pooledDataSource.close();
13834 }
catch (SQLException exp) {
13835 throw new TskCoreException(exp.getMessage());
13837 pooledDataSource =
null;
13842 abstract CaseDbConnection getPooledConnection() throws SQLException;
13844 public PooledDataSource getPooledDataSource() {
13845 return pooledDataSource;
13848 public void setPooledDataSource(PooledDataSource pooledDataSource) {
13849 this.pooledDataSource = pooledDataSource;
13857 private final class SQLiteConnections
extends ConnectionPool {
13859 private final Map<String, String> configurationOverrides =
new HashMap<String, String>();
13861 SQLiteConnections(String dbPath,
boolean useWAL)
throws SQLException {
13862 configurationOverrides.put(
"acquireIncrement",
"2");
13863 configurationOverrides.put(
"initialPoolSize",
"5");
13864 configurationOverrides.put(
"minPoolSize",
"5");
13869 configurationOverrides.put(
"maxPoolSize",
"20");
13870 configurationOverrides.put(
"maxStatements",
"200");
13871 configurationOverrides.put(
"maxStatementsPerConnection",
"20");
13873 SQLiteConfig config =
new SQLiteConfig();
13874 config.setSynchronous(SQLiteConfig.SynchronousMode.OFF);
13875 config.setReadUncommitted(
true);
13876 config.enforceForeignKeys(
true);
13878 config.setJournalMode(SQLiteConfig.JournalMode.WAL);
13880 SQLiteDataSource unpooled =
new SQLiteDataSource(config);
13881 unpooled.setUrl(
"jdbc:sqlite:" + dbPath);
13882 setPooledDataSource((PooledDataSource) DataSources.pooledDataSource(unpooled, configurationOverrides));
13886 public CaseDbConnection getPooledConnection() throws SQLException {
13888 if (CaseDbTransaction.hasOpenTransaction(Thread.currentThread().getId())) {
13890 if (!Thread.currentThread().getName().contains(
"ImageGallery")) {
13891 logger.log(Level.WARNING, String.format(
"Thread %s (ID = %d) already has an open transaction. New connection may encounter SQLITE_BUSY error. ", Thread.currentThread().getName(), Thread.currentThread().getId()),
new Throwable());
13894 java.sql.Connection conn = getPooledDataSource().getConnection();
13895 CaseDbConnection caseDbConn =
new SQLiteConnection(conn);
13904 private final class PostgreSQLConnections
extends ConnectionPool {
13906 PostgreSQLConnections(CaseDbConnectionInfo info, String dbName)
throws PropertyVetoException, UnsupportedEncodingException {
13908 ComboPooledDataSource comboPooledDataSource =
new ComboPooledDataSource();
13909 comboPooledDataSource.setDriverClass(
"org.postgresql.Driver");
13911 String connectionURL =
"jdbc:postgresql://" + info.getHost() +
":" + Integer.valueOf(info.getPort()) +
"/"
13912 + URLEncoder.encode(dbName, StandardCharsets.UTF_8.toString());
13913 if (info.isSslEnabled()) {
13914 if (info.isSslVerify()) {
13915 if (info.getCustomSslValidationClassName().isBlank()) {
13916 connectionURL += CaseDatabaseFactory.SSL_VERIFY_DEFAULT_URL;
13919 connectionURL += CaseDatabaseFactory.getCustomPostrgesSslVerificationUrl(info.getCustomSslValidationClassName());
13922 connectionURL += CaseDatabaseFactory.SSL_NONVERIFY_URL;
13925 comboPooledDataSource.setJdbcUrl(connectionURL);
13926 comboPooledDataSource.setUser(info.getUserName());
13927 comboPooledDataSource.setPassword(info.getPassword());
13928 comboPooledDataSource.setAcquireIncrement(2);
13929 comboPooledDataSource.setInitialPoolSize(5);
13930 comboPooledDataSource.setMinPoolSize(5);
13935 comboPooledDataSource.setMaxPoolSize(20);
13936 comboPooledDataSource.setMaxStatements(200);
13937 comboPooledDataSource.setMaxStatementsPerConnection(20);
13938 setPooledDataSource(comboPooledDataSource);
13942 public CaseDbConnection getPooledConnection() throws SQLException {
13943 return new PostgreSQLConnection(getPooledDataSource().getConnection());
13950 abstract class CaseDbConnection
implements AutoCloseable {
13952 static final int SLEEP_LENGTH_IN_MILLISECONDS = 5000;
13953 static final int MAX_RETRIES = 20;
13955 private class CreateStatement
implements DbCommand {
13957 private final Connection connection;
13958 private Statement statement =
null;
13960 CreateStatement(Connection connection) {
13961 this.connection = connection;
13964 Statement getStatement() {
13969 public void execute() throws SQLException {
13970 statement = connection.createStatement();
13974 private class SetAutoCommit
implements DbCommand {
13976 private final Connection connection;
13977 private final boolean mode;
13979 SetAutoCommit(Connection connection,
boolean mode) {
13980 this.connection = connection;
13985 public void execute() throws SQLException {
13986 connection.setAutoCommit(mode);
13990 private class Commit
implements DbCommand {
13992 private final Connection connection;
13994 Commit(Connection connection) {
13995 this.connection = connection;
13999 public void execute() throws SQLException {
14000 connection.commit();
14012 private class AggregateScoreTablePostgreSQLWriteLock
implements DbCommand {
14014 private final Connection connection;
14016 AggregateScoreTablePostgreSQLWriteLock(Connection connection) {
14017 this.connection = connection;
14021 public void execute() throws SQLException {
14022 try (PreparedStatement preparedStatement =
14023 connection.prepareStatement(
"LOCK TABLE ONLY tsk_aggregate_score in SHARE ROW EXCLUSIVE MODE")) {
14024 preparedStatement.execute();
14029 private class ExecuteQuery
implements DbCommand {
14031 private final Statement statement;
14032 private final String query;
14033 private ResultSet resultSet;
14035 ExecuteQuery(Statement statement, String query) {
14036 this.statement = statement;
14037 this.query = query;
14040 ResultSet getResultSet() {
14045 public void execute() throws SQLException {
14046 resultSet = statement.executeQuery(query);
14050 private class ExecutePreparedStatementQuery
implements DbCommand {
14052 private final PreparedStatement preparedStatement;
14053 private ResultSet resultSet;
14055 ExecutePreparedStatementQuery(PreparedStatement preparedStatement) {
14056 this.preparedStatement = preparedStatement;
14059 ResultSet getResultSet() {
14064 public void execute() throws SQLException {
14065 resultSet = preparedStatement.executeQuery();
14069 private class ExecutePreparedStatementUpdate
implements DbCommand {
14071 private final PreparedStatement preparedStatement;
14073 ExecutePreparedStatementUpdate(PreparedStatement preparedStatement) {
14074 this.preparedStatement = preparedStatement;
14078 public void execute() throws SQLException {
14079 preparedStatement.executeUpdate();
14083 private class ExecuteStatementUpdate
implements DbCommand {
14085 private final Statement statement;
14086 private final String updateCommand;
14088 ExecuteStatementUpdate(Statement statement, String updateCommand) {
14089 this.statement = statement;
14090 this.updateCommand = updateCommand;
14094 public void execute() throws SQLException {
14095 statement.executeUpdate(updateCommand);
14099 private class ExecuteStatementUpdateGenerateKeys
implements DbCommand {
14101 private final Statement statement;
14102 private final int generateKeys;
14103 private final String updateCommand;
14105 ExecuteStatementUpdateGenerateKeys(Statement statement, String updateCommand,
int generateKeys) {
14106 this.statement = statement;
14107 this.generateKeys = generateKeys;
14108 this.updateCommand = updateCommand;
14112 public void execute() throws SQLException {
14113 statement.executeUpdate(updateCommand, generateKeys);
14117 private class PrepareStatement
implements DbCommand {
14119 private final Connection connection;
14120 private final String input;
14121 private PreparedStatement preparedStatement =
null;
14123 PrepareStatement(Connection connection, String input) {
14124 this.connection = connection;
14125 this.input = input;
14128 PreparedStatement getPreparedStatement() {
14129 return preparedStatement;
14133 public void execute() throws SQLException {
14134 preparedStatement = connection.prepareStatement(input);
14138 private class PrepareStatementGenerateKeys
implements DbCommand {
14140 private final Connection connection;
14141 private final String input;
14142 private final int generateKeys;
14143 private PreparedStatement preparedStatement =
null;
14145 PrepareStatementGenerateKeys(Connection connection, String input,
int generateKeysInput) {
14146 this.connection = connection;
14147 this.input = input;
14148 this.generateKeys = generateKeysInput;
14151 PreparedStatement getPreparedStatement() {
14152 return preparedStatement;
14156 public void execute() throws SQLException {
14157 preparedStatement = connection.prepareStatement(input, generateKeys);
14161 abstract void executeCommand(DbCommand command)
throws SQLException;
14163 private final Connection connection;
14164 private final Map<PREPARED_STATEMENT, PreparedStatement> preparedStatements;
14165 private final Map<String, PreparedStatement> adHocPreparedStatements;
14167 CaseDbConnection(Connection connection) {
14168 this.connection = connection;
14169 preparedStatements =
new EnumMap<PREPARED_STATEMENT, PreparedStatement>(PREPARED_STATEMENT.class);
14170 adHocPreparedStatements =
new HashMap<>();
14174 return this.connection !=
null;
14177 PreparedStatement getPreparedStatement(PREPARED_STATEMENT statementKey)
throws SQLException {
14178 return getPreparedStatement(statementKey, Statement.NO_GENERATED_KEYS);
14181 PreparedStatement getPreparedStatement(PREPARED_STATEMENT statementKey,
int generateKeys)
throws SQLException {
14183 PreparedStatement statement;
14184 if (this.preparedStatements.containsKey(statementKey)) {
14185 statement = this.preparedStatements.get(statementKey);
14187 statement = prepareStatement(statementKey.getSQL(), generateKeys);
14188 this.preparedStatements.put(statementKey, statement);
14204 PreparedStatement getPreparedStatement(String sqlStatement,
int generateKeys)
throws SQLException {
14205 PreparedStatement statement;
14206 String statementKey =
"SQL:" + sqlStatement +
" Key:" + generateKeys;
14207 if (adHocPreparedStatements.containsKey(statementKey) && !adHocPreparedStatements.get(statementKey).isClosed()) {
14208 statement = this.adHocPreparedStatements.get(statementKey);
14210 statement = prepareStatement(sqlStatement, generateKeys);
14211 this.adHocPreparedStatements.put(statementKey, statement);
14216 PreparedStatement prepareStatement(String sqlStatement,
int generateKeys)
throws SQLException {
14217 PrepareStatement prepareStatement =
new PrepareStatement(this.getConnection(), sqlStatement);
14218 executeCommand(prepareStatement);
14219 return prepareStatement.getPreparedStatement();
14222 Statement createStatement() throws SQLException {
14223 CreateStatement createStatement =
new CreateStatement(this.connection);
14224 executeCommand(createStatement);
14225 return createStatement.getStatement();
14228 void beginTransaction() throws SQLException {
14229 SetAutoCommit setAutoCommit =
new SetAutoCommit(connection,
false);
14230 executeCommand(setAutoCommit);
14233 void commitTransaction() throws SQLException {
14234 Commit commit =
new Commit(connection);
14235 executeCommand(commit);
14237 SetAutoCommit setAutoCommit =
new SetAutoCommit(connection,
true);
14238 executeCommand(setAutoCommit);
14246 void rollbackTransaction() {
14248 connection.rollback();
14249 }
catch (SQLException e) {
14250 logger.log(Level.SEVERE,
"Error rolling back transaction", e);
14253 connection.setAutoCommit(
true);
14254 }
catch (SQLException e) {
14255 logger.log(Level.SEVERE,
"Error restoring auto-commit", e);
14266 void rollbackTransactionWithThrow() throws SQLException {
14268 connection.rollback();
14270 connection.setAutoCommit(
true);
14282 void getAggregateScoreTableWriteLock() throws SQLException, TskCoreException {
14283 switch (getDatabaseType()) {
14285 AggregateScoreTablePostgreSQLWriteLock tableWriteLock =
new AggregateScoreTablePostgreSQLWriteLock(connection);
14286 executeCommand(tableWriteLock);
14293 throw new TskCoreException(
"Unknown DB Type: " + getDatabaseType().name());
14297 ResultSet executeQuery(Statement statement, String query)
throws SQLException {
14298 ExecuteQuery queryCommand =
new ExecuteQuery(statement, query);
14299 executeCommand(queryCommand);
14300 return queryCommand.getResultSet();
14312 ResultSet executeQuery(PreparedStatement statement)
throws SQLException {
14313 ExecutePreparedStatementQuery executePreparedStatementQuery =
new ExecutePreparedStatementQuery(statement);
14314 executeCommand(executePreparedStatementQuery);
14315 return executePreparedStatementQuery.getResultSet();
14318 void executeUpdate(Statement statement, String update)
throws SQLException {
14319 executeUpdate(statement, update, Statement.NO_GENERATED_KEYS);
14322 void executeUpdate(Statement statement, String update,
int generateKeys)
throws SQLException {
14323 ExecuteStatementUpdate executeStatementUpdate =
new ExecuteStatementUpdate(statement, update);
14324 executeCommand(executeStatementUpdate);
14327 void executeUpdate(PreparedStatement statement)
throws SQLException {
14328 ExecutePreparedStatementUpdate executePreparedStatementUpdate =
new ExecutePreparedStatementUpdate(statement);
14329 executeCommand(executePreparedStatementUpdate);
14336 public void close() {
14338 for (PreparedStatement stmt : preparedStatements.values()) {
14339 closeStatement(stmt);
14341 for (PreparedStatement stmt : adHocPreparedStatements.values()) {
14342 closeStatement(stmt);
14344 connection.close();
14345 }
catch (SQLException ex) {
14346 logger.log(Level.SEVERE,
"Unable to close connection to case database", ex);
14350 Connection getConnection() {
14351 return this.connection;
14358 private final class SQLiteConnection
extends CaseDbConnection {
14360 private static final int DATABASE_LOCKED_ERROR = 0;
14361 private static final int SQLITE_BUSY_ERROR = 5;
14363 SQLiteConnection(Connection conn) {
14368 void executeCommand(DbCommand command)
throws SQLException {
14369 int retryCounter = 0;
14374 }
catch (SQLException ex) {
14375 if ((ex.getErrorCode() == SQLITE_BUSY_ERROR || ex.getErrorCode() == DATABASE_LOCKED_ERROR) && retryCounter < MAX_RETRIES) {
14382 Thread.sleep(SLEEP_LENGTH_IN_MILLISECONDS);
14383 }
catch (InterruptedException exp) {
14384 Logger.getLogger(SleuthkitCase.class.getName()).log(Level.WARNING,
"Unexpectedly unable to wait for database.", exp);
14397 private final class PostgreSQLConnection
extends CaseDbConnection {
14399 private final String COMMUNICATION_ERROR = PSQLState.COMMUNICATION_ERROR.getState();
14400 private final String SYSTEM_ERROR = PSQLState.SYSTEM_ERROR.getState();
14401 private final String UNKNOWN_STATE = PSQLState.UNKNOWN_STATE.getState();
14402 private static final int MAX_RETRIES = 3;
14404 PostgreSQLConnection(Connection conn) {
14409 void executeUpdate(Statement statement, String update,
int generateKeys)
throws SQLException {
14410 CaseDbConnection.ExecuteStatementUpdateGenerateKeys executeStatementUpdateGenerateKeys =
new CaseDbConnection.ExecuteStatementUpdateGenerateKeys(statement, update, generateKeys);
14411 executeCommand(executeStatementUpdateGenerateKeys);
14415 PreparedStatement prepareStatement(String sqlStatement,
int generateKeys)
throws SQLException {
14416 CaseDbConnection.PrepareStatementGenerateKeys prepareStatementGenerateKeys =
new CaseDbConnection.PrepareStatementGenerateKeys(this.getConnection(), sqlStatement, generateKeys);
14417 executeCommand(prepareStatementGenerateKeys);
14418 return prepareStatementGenerateKeys.getPreparedStatement();
14422 void executeCommand(DbCommand command)
throws SQLException {
14423 SQLException lastException =
null;
14424 for (
int retries = 0; retries < MAX_RETRIES; retries++) {
14427 lastException =
null;
14429 }
catch (SQLException ex) {
14430 lastException = ex;
14431 String sqlState = ex.getSQLState();
14432 if (sqlState ==
null || sqlState.equals(COMMUNICATION_ERROR) || sqlState.equals(SYSTEM_ERROR) || sqlState.equals(UNKNOWN_STATE)) {
14434 Thread.sleep(SLEEP_LENGTH_IN_MILLISECONDS);
14435 }
catch (InterruptedException exp) {
14436 Logger.getLogger(SleuthkitCase.class.getName()).log(Level.WARNING,
"Unexpectedly unable to wait for database.", exp);
14445 if (lastException !=
null) {
14446 throw lastException;
14482 public static final class CaseDbTransaction {
14484 private final CaseDbConnection connection;
14485 private final boolean readOnlyTransaction;
14486 private SleuthkitCase sleuthkitCase;
14493 private Map<Long, ScoreChange> scoreChangeMap =
new HashMap<>();
14494 private List<Host> hostsAdded =
new ArrayList<>();
14495 private List<TimelineEventAddedEvent> timelineEvents =
new ArrayList<>();
14496 private List<OsAccount> accountsChanged =
new ArrayList<>();
14497 private List<OsAccount> accountsAdded =
new ArrayList<>();
14500 private List<Long> deletedOsAccountObjectIds =
new ArrayList<>();
14501 private List<Long> deletedResultObjectIds =
new ArrayList<>();
14505 private static Set<Long> threadsWithOpenTransaction =
new HashSet<>();
14506 private static final Object threadsWithOpenTransactionLock =
new Object();
14518 private CaseDbTransaction(SleuthkitCase sleuthkitCase,
boolean readOnlyTransaction)
throws TskCoreException {
14519 this.sleuthkitCase = sleuthkitCase;
14520 this.readOnlyTransaction = readOnlyTransaction;
14522 if (readOnlyTransaction) {
14523 sleuthkitCase.acquireSingleUserCaseReadLock();
14525 sleuthkitCase.acquireSingleUserCaseWriteLock();
14528 this.connection = sleuthkitCase.getConnection();
14530 synchronized (threadsWithOpenTransactionLock) {
14531 this.connection.beginTransaction();
14532 threadsWithOpenTransaction.add(Thread.currentThread().getId());
14534 }
catch (SQLException ex) {
14535 if (readOnlyTransaction) {
14536 sleuthkitCase.releaseSingleUserCaseReadLock();
14538 sleuthkitCase.releaseSingleUserCaseWriteLock();
14540 throw new TskCoreException(
"Failed to create transaction on case database", ex);
14552 CaseDbConnection getConnection() {
14553 return this.connection;
14561 void registerScoreChange(
ScoreChange scoreChange) {
14562 scoreChangeMap.put(scoreChange.
getObjectId(), scoreChange);
14570 if (timelineEvent !=
null) {
14571 timelineEvents.add(timelineEvent);
14580 void registerAddedHost(
Host host) {
14581 if (host !=
null) {
14582 this.hostsAdded.add(host);
14591 void registerChangedOsAccount(
OsAccount account) {
14592 if (account !=
null) {
14593 accountsChanged.add(account);
14602 void registerDeletedOsAccount(
long osAccountObjId) {
14603 deletedOsAccountObjectIds.add(osAccountObjId);
14611 void registerAddedOsAccount(
OsAccount account) {
14612 if (account !=
null) {
14613 accountsAdded.add(account);
14623 void registerMergedOsAccount(
long sourceOsAccountObjId,
long destinationOsAccountObjId) {
14633 void registerDeletedAnalysisResult(
long analysisResultObjId) {
14634 this.deletedResultObjectIds.add(analysisResultObjId);
14645 private static boolean hasOpenTransaction(
long threadId) {
14646 synchronized (threadsWithOpenTransactionLock) {
14647 return threadsWithOpenTransaction.contains(threadId);
14659 this.connection.commitTransaction();
14660 }
catch (SQLException ex) {
14661 throw new TskCoreException(
"Failed to commit transaction on case database", ex);
14665 if (!scoreChangeMap.isEmpty()) {
14666 Map<Long, List<ScoreChange>> changesByDataSource = scoreChangeMap.values().stream()
14668 for (Map.Entry<Long, List<ScoreChange>> entry : changesByDataSource.entrySet()) {
14672 if (!timelineEvents.isEmpty()) {
14674 sleuthkitCase.fireTSKEvent(evt);
14677 if (!hostsAdded.isEmpty()) {
14680 if (!accountsAdded.isEmpty()) {
14683 if (!accountsChanged.isEmpty()) {
14686 if (!accountsMerged.isEmpty()) {
14689 if (!deletedOsAccountObjectIds.isEmpty()) {
14692 if (!deletedResultObjectIds.isEmpty()) {
14706 this.connection.rollbackTransactionWithThrow();
14707 }
catch (SQLException ex) {
14708 throw new TskCoreException(
"Case database transaction rollback failed", ex);
14719 this.connection.close();
14720 if (readOnlyTransaction) {
14725 synchronized (threadsWithOpenTransactionLock) {
14726 threadsWithOpenTransaction.remove(Thread.currentThread().getId());
14740 public final class CaseDbQuery
implements AutoCloseable {
14742 private ResultSet resultSet;
14743 private CaseDbConnection connection;
14746 this(query,
false);
14749 private CaseDbQuery(String query,
boolean allowWriteQuery)
throws TskCoreException {
14750 if (!allowWriteQuery) {
14751 if (!query.regionMatches(
true, 0,
"SELECT", 0,
"SELECT".length())) {
14752 throw new TskCoreException(
"Unsupported query: Only SELECT queries are supported.");
14756 SleuthkitCase.this.acquireSingleUserCaseReadLock();
14758 connection = connections.getConnection();
14759 resultSet = connection.executeQuery(connection.createStatement(), query);
14760 }
catch (SQLException ex) {
14761 SleuthkitCase.this.releaseSingleUserCaseReadLock();
14764 SleuthkitCase.this.releaseSingleUserCaseReadLock();
14781 if (resultSet !=
null) {
14782 final Statement statement = resultSet.getStatement();
14783 if (statement !=
null) {
14788 closeConnection(connection);
14789 }
catch (SQLException ex) {
14792 SleuthkitCase.this.releaseSingleUserCaseReadLock();
14806 sleuthkitCaseErrorObservers.add(observer);
14818 int i = sleuthkitCaseErrorObservers.indexOf(observer);
14820 sleuthkitCaseErrorObservers.remove(i);
14834 for (
ErrorObserver observer : sleuthkitCaseErrorObservers) {
14835 if (observer !=
null) {
14837 observer.receiveError(context, errorMessage);
14838 }
catch (Exception ex) {
14839 logger.log(Level.SEVERE,
"Observer client unable to receive message: {0}, {1}",
new Object[]{context, errorMessage, ex});
14860 public enum Context {
14871 private final String contextString;
14873 private Context(String context) {
14874 this.contextString = context;
14878 return contextString;
14896 long getDataSourceObjectId(
long objectId) {
14898 CaseDbConnection connection = connections.getConnection();
14900 return getDataSourceObjectId(connection, objectId);
14902 closeConnection(connection);
14904 }
catch (TskCoreException ex) {
14905 logger.log(Level.SEVERE,
"Error getting data source object id for a file", ex);
14921 CaseDbConnection connection =
null;
14922 ResultSet rs =
null;
14925 connection = connections.getConnection();
14929 rs = connection.executeQuery(statement);
14932 id = rs.getLong(
"max_obj_id");
14935 }
catch (SQLException e) {
14938 closeResultSet(rs);
14939 closeConnection(connection);
14959 CaseDbConnection connection =
null;
14960 Statement s =
null;
14961 ResultSet rs =
null;
14964 connection = connections.getConnection();
14965 s = connection.createStatement();
14966 rs = connection.executeQuery(s,
"SELECT * FROM tsk_files WHERE " + sqlWhereClause);
14967 List<FsContent> results =
new ArrayList<FsContent>();
14968 List<AbstractFile> temp = resultSetToAbstractFiles(rs, connection);
14976 }
catch (SQLException e) {
14977 throw new TskCoreException(
"SQLException thrown when calling 'SleuthkitCase.findFilesWhere().", e);
14979 closeResultSet(rs);
14981 closeConnection(connection);
15000 try (CaseDbConnection connection = connections.getConnection();
15001 PreparedStatement getTypeNamePrepState = connection.prepareStatement(
15002 "SELECT artifact_type_id FROM blackboard_artifact_types WHERE type_name = ?",
15003 Statement.RETURN_GENERATED_KEYS)) {
15005 getTypeNamePrepState.setString(1, artifactTypeName);
15007 try (ResultSet rs = getTypeNamePrepState.executeQuery()) {
15010 typeId = rs.getInt(
"artifact_type_id");
15014 }
catch (SQLException ex) {
15091 CaseDbConnection connection =
null;
15092 Statement s =
null;
15093 ResultSet rs =
null;
15096 connection = connections.getConnection();
15097 s = connection.createStatement();
15098 rs = connection.executeQuery(s,
"SELECT attribute_type_id FROM blackboard_attribute_types WHERE type_name = '" + attrTypeName +
"'");
15101 typeId = rs.getInt(
"attribute_type_id");
15104 }
catch (SQLException ex) {
15107 closeResultSet(rs);
15109 closeConnection(connection);
15128 CaseDbConnection connection =
null;
15129 Statement s =
null;
15130 ResultSet rs =
null;
15133 connection = connections.getConnection();
15134 s = connection.createStatement();
15135 rs = connection.executeQuery(s,
"SELECT type_name FROM blackboard_attribute_types WHERE attribute_type_id = " + attrTypeID);
15137 return rs.getString(
"type_name");
15141 }
catch (SQLException ex) {
15142 throw new TskCoreException(
"Error getting or creating a attribute type name", ex);
15144 closeResultSet(rs);
15146 closeConnection(connection);
15165 CaseDbConnection connection =
null;
15166 Statement s =
null;
15167 ResultSet rs =
null;
15170 connection = connections.getConnection();
15171 s = connection.createStatement();
15172 rs = connection.executeQuery(s,
"SELECT display_name FROM blackboard_attribute_types WHERE attribute_type_id = " + attrTypeID);
15174 return rs.getString(
"display_name");
15178 }
catch (SQLException ex) {
15179 throw new TskCoreException(
"Error getting or creating a attribute type name", ex);
15181 closeResultSet(rs);
15183 closeConnection(connection);
15218 public ResultSet
runQuery(String query)
throws SQLException {
15219 CaseDbConnection connection =
null;
15222 connection = connections.getConnection();
15223 return connection.executeQuery(connection.createStatement(), query);
15225 throw new SQLException(
"Error getting connection for ad hoc query", ex);
15229 closeConnection(connection);
15245 final Statement statement = resultSet.getStatement();
15247 if (statement !=
null) {
15272 files.add(carvedFile);
15276 || parent instanceof
Volume
15277 || parent instanceof
Image) {
15280 throw new TskCoreException(String.format(
"Parent (id =%d) is not an file system, volume or image", containerId));
15303 carvedFiles.add(carvedFile);
15308 || parent instanceof
Volume
15309 || parent instanceof
Image) {
15312 throw new TskCoreException(String.format(
"Parent (id =%d) is not an file system, volume or image", parent.
getId()));
15348 long size,
long ctime,
long crtime,
long atime,
long mtime,
15350 String rederiveDetails, String toolName, String toolVersion, String otherDetails)
throws TskCoreException {
15351 return addDerivedFile(fileName, localPath, size, ctime, crtime, atime, mtime,
15352 isFile, parentFile, rederiveDetails, toolName, toolVersion,
15387 long size,
long ctime,
long crtime,
long atime,
long mtime,
15388 String md5,
FileKnown known, String mimeType,
15392 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime,
15393 md5,
null, known, mimeType, isFile, encodingType,
15394 parent, transaction);
15423 long size,
long ctime,
long crtime,
long atime,
long mtime,
15426 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime, isFile,
15451 long size,
long ctime,
long crtime,
long atime,
long mtime,
15454 return addLocalFile(fileName, localPath, size, ctime, crtime, atime, mtime,
15476 return this.caseHandle.initAddImageProcess(timezone, addUnallocSpace, noFatFsOrphans,
"",
null,
this);
15494 logger.log(Level.SEVERE,
"Error loading all file systems for image with ID {0}", image.
getId());
15495 return new ArrayList<>();