Sleuth Kit Java Bindings (JNI)  4.10.2
Java bindings for using The Sleuth Kit
TskCaseDbBridge.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import com.google.common.base.Strings;
22 import java.sql.PreparedStatement;
23 import java.sql.SQLException;
24 import java.sql.Statement;
25 import org.apache.commons.lang3.StringUtils;
26 import java.util.List;
27 import java.util.Arrays;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.LinkedList;
32 import java.util.Map;
33 import java.util.Objects;
34 import java.util.Optional;
35 import java.util.Queue;
36 import java.util.logging.Level;
37 import java.util.logging.Logger;
40 
50 class TskCaseDbBridge {
51 
52  private static final Logger logger = Logger.getLogger(TskCaseDbBridge.class.getName());
53 
54  private final SleuthkitCase caseDb;
55  private CaseDbTransaction trans = null;
56  private final AddDataSourceCallbacks addDataSourceCallbacks;
57  private final Host imageHost;
58 
59  private final Map<Long, Long> fsIdToRootDir = new HashMap<>();
60  private final Map<Long, TskData.TSK_FS_TYPE_ENUM> fsIdToFsType = new HashMap<>();
61  private final Map<ParentCacheKey, Long> parentDirCache = new HashMap<>();
62 
63  private final Map<String, OsAccount> ownerIdToAccountMap = new HashMap<>();
64 
65  private static final long BATCH_FILE_THRESHOLD = 500;
66  private final Queue<FileInfo> batchedFiles = new LinkedList<>();
67  private final Queue<LayoutRangeInfo> batchedLayoutRanges = new LinkedList<>();
68  private final List<Long> layoutFileIds = new ArrayList<>();
69 
70  TskCaseDbBridge(SleuthkitCase caseDb, AddDataSourceCallbacks addDataSourceCallbacks, Host host) {
71  this.caseDb = caseDb;
72  this.addDataSourceCallbacks = addDataSourceCallbacks;
73  imageHost = host;
74  trans = null;
75  }
76 
82  private void beginTransaction() throws TskCoreException {
83  trans = caseDb.beginTransaction();
84  }
85 
91  private void commitTransaction() throws TskCoreException {
92  trans.commit();
93  trans = null;
94  }
95 
99  private void revertTransaction() {
100  try {
101  if (trans != null) {
102  trans.rollback();
103  trans = null;
104  }
105  } catch (TskCoreException ex) {
106  logger.log(Level.SEVERE, "Error rolling back transaction", ex);
107  }
108  }
109 
113  void finish() {
114  addBatchedFilesToDb();
115  addBatchedLayoutRangesToDb();
116  processLayoutFiles();
117  }
118 
138  long addImageInfo(int type, long ssize, String timezone,
139  long size, String md5, String sha1, String sha256, String deviceId,
140  String collectionDetails, String[] paths) {
141  try {
142  beginTransaction();
143  long objId = addImageToDb(TskData.TSK_IMG_TYPE_ENUM.valueOf(type), ssize, size,
144  timezone, md5, sha1, sha256, deviceId, collectionDetails, trans);
145  for (int i = 0;i < paths.length;i++) {
146  addImageNameToDb(objId, paths[i], i, trans);
147  }
148  commitTransaction();
149  return objId;
150  } catch (TskCoreException ex) {
151  logger.log(Level.SEVERE, "Error adding image to the database", ex);
152  revertTransaction();
153  return -1;
154  }
155  }
156 
163  void addAcquisitionDetails(long imgId, String details) {
164  try {
165  beginTransaction();
166  caseDb.setAcquisitionDetails(imgId, details, trans);
167  commitTransaction();
168  } catch (TskCoreException ex) {
169  logger.log(Level.SEVERE, "Error adding image details \"" + details + "\" to image with ID " + imgId, ex);
170  revertTransaction();
171  }
172  }
173 
185  long addVsInfo(long parentObjId, int vsType, long imgOffset, long blockSize) {
186  try {
187  beginTransaction();
188  VolumeSystem vs = caseDb.addVolumeSystem(parentObjId, TskData.TSK_VS_TYPE_ENUM.valueOf(vsType), imgOffset, blockSize, trans);
189  commitTransaction();
190  return vs.getId();
191  } catch (TskCoreException ex) {
192  logger.log(Level.SEVERE, "Error adding volume system to the database - parent obj ID: " + parentObjId
193  + ", image offset: " + imgOffset, ex);
194  revertTransaction();
195  return -1;
196  }
197  }
198 
212  long addVolume(long parentObjId, long addr, long start, long length, String desc,
213  long flags) {
214  try {
215  beginTransaction();
216  Volume vol = caseDb.addVolume(parentObjId, addr, start, length, desc, flags, trans);
217  commitTransaction();
218  return vol.getId();
219  } catch (TskCoreException ex) {
220  logger.log(Level.SEVERE, "Error adding volume to the database - parent object ID: " + parentObjId
221  + ", addr: " + addr, ex);
222  revertTransaction();
223  return -1;
224  }
225  }
226 
236  long addPool(long parentObjId, int poolType) {
237  try {
238  beginTransaction();
239  Pool pool = caseDb.addPool(parentObjId, TskData.TSK_POOL_TYPE_ENUM.valueOf(poolType), trans);
240  commitTransaction();
241  return pool.getId();
242  } catch (TskCoreException ex) {
243  logger.log(Level.SEVERE, "Error adding pool to the database - parent object ID: " + parentObjId, ex);
244  revertTransaction();
245  return -1;
246  }
247  }
248 
264  long addFileSystem(long parentObjId, long imgOffset, int fsType, long blockSize, long blockCount,
265  long rootInum, long firstInum, long lastInum) {
266  try {
267  beginTransaction();
268  FileSystem fs = caseDb.addFileSystem(parentObjId, imgOffset, TskData.TSK_FS_TYPE_ENUM.valueOf(fsType), blockSize, blockCount,
269  rootInum, firstInum, lastInum, null, trans);
270  commitTransaction();
271  fsIdToFsType.put(fs.getId(), TskData.TSK_FS_TYPE_ENUM.valueOf(fsType));
272  return fs.getId();
273  } catch (TskCoreException ex) {
274  logger.log(Level.SEVERE, "Error adding file system to the database - parent object ID: " + parentObjId
275  + ", offset: " + imgOffset, ex);
276  revertTransaction();
277  return -1;
278  }
279  }
280 
322  long addFile(long parentObjId,
323  long fsObjId, long dataSourceObjId,
324  int fsType,
325  int attrType, int attrId, String name,
326  long metaAddr, long metaSeq,
327  int dirType, int metaType, int dirFlags, int metaFlags,
328  long size,
329  long crtime, long ctime, long atime, long mtime,
330  int meta_mode, int gid, int uid,
331  String escaped_path, String extension,
332  long seq, long parMetaAddr, long parSeq, String ownerUid) {
333 
334  // Add the new file to the list
335  batchedFiles.add(new FileInfo(parentObjId,
336  fsObjId, dataSourceObjId,
337  fsType,
338  attrType, attrId, name,
339  metaAddr, metaSeq,
340  dirType, metaType, dirFlags, metaFlags,
341  size,
342  crtime, ctime, atime, mtime,
343  meta_mode, gid, uid,
344  escaped_path, extension,
345  seq, parMetaAddr, parSeq, ownerUid));
346 
347  // Add the current files to the database if we've exceeded the threshold or if we
348  // have the root folder.
349  if ((fsObjId == parentObjId)
350  || (batchedFiles.size() > BATCH_FILE_THRESHOLD)) {
351  return addBatchedFilesToDb();
352  }
353  return 0;
354  }
355 
361  private long addBatchedFilesToDb() {
362  List<Long> newObjIds = new ArrayList<>();
363  try {
364 
365  // loop through the batch, and make sure owner accounts exist for all the files in the batch.
366  // If not, create accounts.
367  Iterator<FileInfo> it = batchedFiles.iterator();
368 
369  while (it.hasNext()) {
370  FileInfo fileInfo = it.next();
371  String ownerUid = fileInfo.ownerUid;
372  if (Strings.isNullOrEmpty(fileInfo.ownerUid) == false) {
373  // first check the owner id is in the map, if found, then continue
374  if (this.ownerIdToAccountMap.containsKey(ownerUid)) {
375  continue;
376  }
377 
378  // query the DB to get the owner account
379  try {
380  Optional<OsAccount> ownerAccount = caseDb.getOsAccountManager().getWindowsOsAccount(ownerUid, null, null, imageHost);
381  if (ownerAccount.isPresent()) {
382  // found account - add to map
383  ownerIdToAccountMap.put(ownerUid, ownerAccount.get());
384  } else {
385  // account not found in the database, create the account and add to map
386  // Currently we expect only NTFS systems to provide a windows style SID as owner id.
387  OsAccount newAccount = caseDb.getOsAccountManager().newWindowsOsAccount(ownerUid, null, null, imageHost, OsAccountRealm.RealmScope.UNKNOWN);
388  ownerIdToAccountMap.put(ownerUid, newAccount);
389  }
390  } catch (NotUserSIDException ex) {
391  // if the owner SID is not a user SID, set the owner account to null
392  ownerIdToAccountMap.put(ownerUid, null);
393  }
394  }
395  }
396 
397 
398 
399  beginTransaction();
400  FileInfo fileInfo;
401  while ((fileInfo = batchedFiles.poll()) != null) {
402  long computedParentObjId = fileInfo.parentObjId;
403  try {
404  // If we weren't given the parent object ID, look it up
405  if (fileInfo.parentObjId == 0) {
406  computedParentObjId = getParentObjId(fileInfo);
407  }
408 
409  Long ownerAccountObjId = OsAccount.NO_ACCOUNT;
410  if (Strings.isNullOrEmpty(fileInfo.ownerUid) == false) {
411  if (ownerIdToAccountMap.containsKey(fileInfo.ownerUid)) {
412  // for any non user SIDs, the map will have a null for account
413  if (Objects.nonNull(ownerIdToAccountMap.get(fileInfo.ownerUid))) {
414  ownerAccountObjId = ownerIdToAccountMap.get(fileInfo.ownerUid).getId();
415  }
416  } else {
417  // Error - the map should have an account or a null at this point for the owner SID.
418  throw new TskCoreException(String.format("Failed to add file. Owner account not found for file with parent object ID: %d, name: %s, owner id: %s", fileInfo.parentObjId, fileInfo.name, fileInfo.ownerUid));
419  }
420  }
421 
422  // We've seen a case where the root folder comes in with an undefined meta type.
423  // In that case, we alter the type to TSK_FS_META_TYPE_DIR so it will be cached
424  // properly and will not cause errors later for being an unexpected type.
425  if ((fileInfo.parentObjId == fileInfo.fsObjId)
426  && (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_UNDEF.getValue())) {
427  fileInfo.metaType = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue();
428  }
429 
430  long objId = addFileToDb(computedParentObjId,
431  fileInfo.fsObjId, fileInfo.dataSourceObjId,
432  fileInfo.fsType,
433  fileInfo.attrType, fileInfo.attrId, fileInfo.name,
434  fileInfo.metaAddr, fileInfo.metaSeq,
435  fileInfo.dirType, fileInfo.metaType, fileInfo.dirFlags, fileInfo.metaFlags,
436  fileInfo.size,
437  fileInfo.crtime, fileInfo.ctime, fileInfo.atime, fileInfo.mtime,
438  fileInfo.meta_mode, fileInfo.gid, fileInfo.uid,
439  null, TskData.FileKnown.UNKNOWN,
440  fileInfo.escaped_path, fileInfo.extension, fileInfo.ownerUid, ownerAccountObjId,
441  false, trans);
442  if (fileInfo.fsObjId != fileInfo.parentObjId) {
443  // Add new file ID to the list to send to ingest unless it is the root folder
444  newObjIds.add(objId);
445  }
446 
447  // If we're adding the root directory for the file system, cache it
448  if (fileInfo.parentObjId == fileInfo.fsObjId) {
449  fsIdToRootDir.put(fileInfo.fsObjId, objId);
450  }
451 
452  // If the file is a directory, cache the object ID.
453  if ((fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
454  || (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()))
455  && (fileInfo.name != null)
456  && ! fileInfo.name.equals(".")
457  && ! fileInfo.name.equals("..")) {
458  String dirName = fileInfo.escaped_path + fileInfo.name;
459  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.metaAddr, fileInfo.seq, dirName);
460  parentDirCache.put(key, objId);
461  }
462  } catch (TskCoreException ex) {
463  if (computedParentObjId > 0) {
464  // Most likely a database error occurred
465  logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
466  + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
467  } else {
468  // The parent lookup failed
469  logger.log(Level.SEVERE, "Error adding file to the database", ex);
470  }
471  }
472  }
473  commitTransaction();
474  try {
475  addDataSourceCallbacks.onFilesAdded(newObjIds);
476  } catch (Exception ex) {
477  // Exception firewall to prevent unexpected return to the native code
478  logger.log(Level.SEVERE, "Unexpected error from files added callback", ex);
479  }
480  } catch (TskCoreException ex) {
481  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
482  revertTransaction();
483  return -1;
484  }
485  return 0;
486  }
487 
497  private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
498  // Remove the final slash from the path unless we're in the root folder
499  String parentPath = fileInfo.escaped_path;
500  if(parentPath.endsWith("/") && ! parentPath.equals("/")) {
501  parentPath = parentPath.substring(0, parentPath.lastIndexOf('/'));
502  }
503 
504  // Look up the parent
505  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.parMetaAddr, fileInfo.parSeq, parentPath);
506  if (parentDirCache.containsKey(key)) {
507  return parentDirCache.get(key);
508  } else {
509  // There's no reason to do a database query since every folder added is being
510  // stored in the cache.
511  throw new TskCoreException("Could not find parent (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
512  + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
513  }
514  }
515 
529  long addLayoutFile(long parentObjId,
530  long fsObjId, long dataSourceObjId,
531  int fileType,
532  String name, long size) {
533  try {
534 
535  // The file system may be null for layout files
536  Long fsObjIdForDb = fsObjId;
537  if (fsObjId == 0) {
538  fsObjIdForDb = null;
539  }
540 
541  beginTransaction();
542  long objId = addFileToDb(parentObjId,
543  fsObjIdForDb, dataSourceObjId,
544  fileType,
545  null, null, name,
546  null, null,
547  TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue(),
548  TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(),
549  TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
550  TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue(),
551  size,
552  null, null, null, null,
553  null, null, null,
554  null, TskData.FileKnown.UNKNOWN,
555  null, null, null, OsAccount.NO_ACCOUNT,
556  true, trans);
557  commitTransaction();
558 
559  // Store the layout file ID for later processing
560  layoutFileIds.add(objId);
561 
562  return objId;
563  } catch (TskCoreException ex) {
564  logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
565  + ", file system object ID: " + fsObjId + ", name: " + name, ex);
566  revertTransaction();
567  return -1;
568  }
569  }
570 
582  long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
583  batchedLayoutRanges.add(new LayoutRangeInfo(objId, byteStart, byteLen, seq));
584 
585  if (batchedLayoutRanges.size() > BATCH_FILE_THRESHOLD) {
586  return addBatchedLayoutRangesToDb();
587  }
588  return 0;
589  }
590 
596  private long addBatchedLayoutRangesToDb() {
597  try {
598  beginTransaction();
599  LayoutRangeInfo range;
600  while ((range = batchedLayoutRanges.poll()) != null) {
601  try {
602  addLayoutFileRangeToDb(range.objId, range.byteStart, range.byteLen, range.seq, trans);
603  } catch (TskCoreException ex) {
604  logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId
605  + ", byte start: " + range.byteStart + ", length: " + range.byteLen + ", seq: " + range.seq, ex);
606  }
607  }
608  commitTransaction();
609  return 0;
610  } catch (TskCoreException ex) {
611  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
612  revertTransaction();
613  return -1;
614  }
615  }
616 
622  void processLayoutFiles() {
623  addDataSourceCallbacks.onFilesAdded(layoutFileIds);
624  layoutFileIds.clear();
625  }
626 
636  long addUnallocFsBlockFilesParent(long fsObjId, String name) {
637  try {
638  if (! fsIdToRootDir.containsKey(fsObjId)) {
639  logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId);
640  return -1;
641  }
642  beginTransaction();
643  VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
644  commitTransaction();
645  addDataSourceCallbacks.onFilesAdded(Arrays.asList(dir.getId()));
646  return dir.getId();
647  } catch (TskCoreException ex) {
648  logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
649  revertTransaction();
650  return -1;
651  }
652  }
653 
657  private class ParentCacheKey {
658  long fsObjId;
659  long metaAddr;
660  long seqNum;
661  String path;
662 
672  ParentCacheKey(long fsObjId, long metaAddr, long seqNum, String path) {
673  this.fsObjId = fsObjId;
674  this.metaAddr = metaAddr;
675  if (ownerIdToAccountMap.containsKey(fsObjId)
676  && (ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS)
677  || ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS_DETECT))) {
678  this.seqNum = seqNum;
679  } else {
680  this.seqNum = 0;
681  }
682  this.path = path;
683  }
684 
685  @Override
686  public boolean equals(Object obj) {
687  if (! (obj instanceof ParentCacheKey)) {
688  return false;
689  }
690 
691  ParentCacheKey otherKey = (ParentCacheKey) obj;
692  if (this.fsObjId != otherKey.fsObjId
693  || this.metaAddr != otherKey.metaAddr
694  || this.seqNum != otherKey.seqNum) {
695  return false;
696  }
697 
698  return StringUtils.equals(this.path, otherKey.path);
699  }
700 
701  @Override
702  public int hashCode() {
703  int hash = 3;
704  hash = 31 * hash + (int) (this.fsObjId ^ (this.fsObjId >>> 32));
705  hash = 31 * hash + (int) (this.metaAddr ^ (this.metaAddr >>> 32));
706  hash = 31 * hash + (int) (this.seqNum ^ (this.seqNum >>> 32));
707  hash = 31 * hash + Objects.hashCode(this.path);
708  return hash;
709  }
710  }
711 
716  private class LayoutRangeInfo {
717  long objId;
718  long byteStart;
719  long byteLen;
720  long seq;
721 
722  LayoutRangeInfo(long objId, long byteStart, long byteLen, long seq) {
723  this.objId = objId;
724  this.byteStart = byteStart;
725  this.byteLen = byteLen;
726  this.seq = seq;
727  }
728  }
729 
734  private class FileInfo {
735  long parentObjId;
736  long fsObjId;
737  long dataSourceObjId;
738  int fsType;
739  int attrType;
740  int attrId;
741  String name;
742  long metaAddr;
743  long metaSeq;
744  int dirType;
745  int metaType;
746  int dirFlags;
747  int metaFlags;
748  long size;
749  long crtime;
750  long ctime;
751  long atime;
752  long mtime;
753  int meta_mode;
754  int gid;
755  int uid;
756  String escaped_path;
757  String extension;
758  long seq;
759  long parMetaAddr;
760  long parSeq;
761  String ownerUid;
762 
763  FileInfo(long parentObjId,
764  long fsObjId, long dataSourceObjId,
765  int fsType,
766  int attrType, int attrId, String name,
767  long metaAddr, long metaSeq,
768  int dirType, int metaType, int dirFlags, int metaFlags,
769  long size,
770  long crtime, long ctime, long atime, long mtime,
771  int meta_mode, int gid, int uid,
772  String escaped_path, String extension,
773  long seq, long parMetaAddr, long parSeq, String ownerUid) {
774 
775  this.parentObjId = parentObjId;
776  this.fsObjId = fsObjId;
777  this.dataSourceObjId = dataSourceObjId;
778  this.fsType = fsType;
779  this.attrType = attrType;
780  this.attrId = attrId;
781  this.name = name;
782  this.metaAddr = metaAddr;
783  this.metaSeq = metaSeq;
784  this.dirType = dirType;
785  this.metaType = metaType;
786  this.dirFlags = dirFlags;
787  this.metaFlags = metaFlags;
788  this.size = size;
789  this.crtime = crtime;
790  this.ctime = ctime;
791  this.atime = atime;
792  this.mtime = mtime;
793  this.meta_mode = meta_mode;
794  this.gid = gid;
795  this.uid = uid;
796  this.escaped_path = escaped_path;
797  this.extension = extension;
798  this.seq = seq;
799  this.parMetaAddr = parMetaAddr;
800  this.parSeq = parSeq;
801  this.ownerUid = ownerUid;
802  }
803  }
804 
848  private long addFileToDb(long parentObjId,
849  Long fsObjId, long dataSourceObjId,
850  int fsType,
851  Integer attrType, Integer attrId, String name,
852  Long metaAddr, Long metaSeq,
853  int dirType, int metaType, int dirFlags, int metaFlags,
854  long size,
855  Long crtime, Long ctime, Long atime, Long mtime,
856  Integer meta_mode, Integer gid, Integer uid,
857  String md5, TskData.FileKnown known,
858  String escaped_path, String extension, String ownerUid, Long ownerAcctObjId,
859  boolean hasLayout, CaseDbTransaction transaction) throws TskCoreException {
860 
861  try {
862  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
863 
864  // Insert a row for the local/logical file into the tsk_objects table.
865  // INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)
866  long objectId = caseDb.addObject(parentObjId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
867 
868  String fileInsert = "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path, extension, has_layout, owner_uid, os_account_obj_id)"
869  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
870  PreparedStatement preparedStatement = connection.getPreparedStatement(fileInsert, Statement.NO_GENERATED_KEYS);
871  preparedStatement.clearParameters();
872 
873  if (fsObjId != null) {
874  preparedStatement.setLong(1, fsObjId); // fs_obj_id
875  } else {
876  preparedStatement.setNull(1, java.sql.Types.BIGINT);
877  }
878  preparedStatement.setLong(2, objectId); // obj_id
879  preparedStatement.setLong(3, dataSourceObjId); // data_source_obj_id
880  preparedStatement.setShort(4, (short) fsType); // type
881  if (attrType != null) {
882  preparedStatement.setShort(5, attrType.shortValue()); // attr_type
883  } else {
884  preparedStatement.setNull(5, java.sql.Types.SMALLINT);
885  }
886  if (attrId != null) {
887  preparedStatement.setInt(6, attrId); // attr_id
888  } else {
889  preparedStatement.setNull(6, java.sql.Types.INTEGER);
890  }
891  preparedStatement.setString(7, name); // name
892  if (metaAddr != null) {
893  preparedStatement.setLong(8, metaAddr); // meta_addr
894  } else {
895  preparedStatement.setNull(8, java.sql.Types.BIGINT);
896  }
897  if (metaSeq != null) {
898  preparedStatement.setInt(9, metaSeq.intValue()); // meta_seq
899  } else {
900  preparedStatement.setNull(9, java.sql.Types.INTEGER);
901  }
902  preparedStatement.setShort(10, (short) dirType); // dir_type
903  preparedStatement.setShort(11, (short) metaType); // meta_type
904  preparedStatement.setShort(12, (short) dirFlags); // dir_flags
905  preparedStatement.setShort(13, (short) metaFlags); // meta_flags
906  preparedStatement.setLong(14, size < 0 ? 0 : size); // size
907  if (crtime != null) {
908  preparedStatement.setLong(15, crtime); // crtime
909  } else {
910  preparedStatement.setNull(15, java.sql.Types.BIGINT);
911  }
912  if (ctime != null) {
913  preparedStatement.setLong(16, ctime); // ctime
914  } else {
915  preparedStatement.setNull(16, java.sql.Types.BIGINT);
916  }
917  if (atime != null) {
918  preparedStatement.setLong(17, atime); // atime
919  } else {
920  preparedStatement.setNull(17, java.sql.Types.BIGINT);
921  }
922  if (mtime != null) {
923  preparedStatement.setLong(18, mtime); // mtime
924  } else {
925  preparedStatement.setNull(18, java.sql.Types.BIGINT);
926  }
927  if (meta_mode != null) {
928  preparedStatement.setLong(19, meta_mode); // mode
929  } else {
930  preparedStatement.setNull(19, java.sql.Types.BIGINT);
931  }
932  if (gid != null) {
933  preparedStatement.setLong(20, gid); // gid
934  } else {
935  preparedStatement.setNull(20, java.sql.Types.BIGINT);
936  }
937  if (uid != null) {
938  preparedStatement.setLong(21, uid); // uid
939  } else {
940  preparedStatement.setNull(21, java.sql.Types.BIGINT);
941  }
942  preparedStatement.setString(22, md5); // md5
943  preparedStatement.setInt(23, known.getFileKnownValue());// known
944  preparedStatement.setString(24, escaped_path); // parent_path
945  preparedStatement.setString(25, extension); // extension
946  if (hasLayout) {
947  preparedStatement.setInt(26, 1); // has_layout
948  } else {
949  preparedStatement.setNull(26, java.sql.Types.INTEGER);
950  }
951 
952  preparedStatement.setString(27, ownerUid); // ownerUid
953 
954  if (ownerAcctObjId != OsAccount.NO_ACCOUNT) {
955  preparedStatement.setLong(28, ownerAcctObjId); //
956  } else {
957  preparedStatement.setNull(28, java.sql.Types.BIGINT);
958  }
959 
960  connection.executeUpdate(preparedStatement);
961 
962  // If this is not a slack file create the timeline events
963  if (!hasLayout
964  && TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() != fsType
965  && (!name.equals(".")) && (!name.equals(".."))) {
966  TimelineManager timelineManager = caseDb.getTimelineManager();
967  DerivedFile derivedFile = new DerivedFile(caseDb, objectId, dataSourceObjId, name,
968  TskData.TSK_FS_NAME_TYPE_ENUM.valueOf((short) dirType),
969  TskData.TSK_FS_META_TYPE_ENUM.valueOf((short) metaType),
970  TskData.TSK_FS_NAME_FLAG_ENUM.valueOf(dirFlags),
971  (short) metaFlags,
972  size, ctime, crtime, atime, mtime, null, null, null, escaped_path, null, parentObjId, null, null, extension, ownerUid, ownerAcctObjId);
973 
974  timelineManager.addEventsForNewFileQuiet(derivedFile, connection);
975  }
976 
977  return objectId;
978  } catch (SQLException ex) {
979  throw new TskCoreException("Failed to add file system file", ex);
980  }
981  }
982 
1002  private long addImageToDb(TskData.TSK_IMG_TYPE_ENUM type, long sectorSize, long size,
1003  String timezone, String md5, String sha1, String sha256,
1004  String deviceId, String collectionDetails,
1005  CaseDbTransaction transaction) throws TskCoreException {
1006  try {
1007  // Insert a row for the Image into the tsk_objects table.
1008  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1009  long newObjId = caseDb.addObject(0, TskData.ObjectType.IMG.getObjectType(), connection);
1010 
1011  // Add a row to tsk_image_info
1012  // INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)
1013  String imageInfoSql = "INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
1014  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
1015  PreparedStatement preparedStatement = connection.getPreparedStatement(imageInfoSql, Statement.NO_GENERATED_KEYS);
1016  preparedStatement.clearParameters();
1017  preparedStatement.setLong(1, newObjId);
1018  preparedStatement.setShort(2, (short) type.getValue());
1019  preparedStatement.setLong(3, sectorSize);
1020  preparedStatement.setString(4, timezone);
1021  //prevent negative size
1022  long savedSize = size < 0 ? 0 : size;
1023  preparedStatement.setLong(5, savedSize);
1024  preparedStatement.setString(6, md5);
1025  preparedStatement.setString(7, sha1);
1026  preparedStatement.setString(8, sha256);
1027  preparedStatement.setString(9, null);
1028  connection.executeUpdate(preparedStatement);
1029 
1030  // Add a row to data_source_info
1031  String dataSourceInfoSql = "INSERT INTO data_source_info (obj_id, device_id, time_zone, acquisition_details, host_id) VALUES (?, ?, ?, ?, ?)"; // NON-NLS
1032  preparedStatement = connection.getPreparedStatement(dataSourceInfoSql, Statement.NO_GENERATED_KEYS);
1033  preparedStatement.clearParameters();
1034  preparedStatement.setLong(1, newObjId);
1035  preparedStatement.setString(2, deviceId);
1036  preparedStatement.setString(3, timezone);
1037  preparedStatement.setString(4, collectionDetails);
1038  preparedStatement.setLong(5, imageHost.getHostId());
1039  connection.executeUpdate(preparedStatement);
1040 
1041  return newObjId;
1042  } catch (SQLException ex) {
1043  throw new TskCoreException(String.format("Error adding image to database"), ex);
1044  }
1045  }
1046 
1057  private void addImageNameToDb(long objId, String name, long sequence,
1058  CaseDbTransaction transaction) throws TskCoreException {
1059  try {
1060  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1061 
1062  String imageNameSql = "INSERT INTO tsk_image_names (obj_id, name, sequence) VALUES (?, ?, ?)"; // NON-NLS
1063  PreparedStatement preparedStatement = connection.getPreparedStatement(imageNameSql, Statement.NO_GENERATED_KEYS);
1064  preparedStatement.clearParameters();
1065  preparedStatement.setLong(1, objId);
1066  preparedStatement.setString(2, name);
1067  preparedStatement.setLong(3, sequence);
1068  connection.executeUpdate(preparedStatement);
1069  } catch (SQLException ex) {
1070  throw new TskCoreException(String.format("Error adding image name %s to image with object ID %d", name, objId), ex);
1071  }
1072  }
1073 
1085  void addLayoutFileRangeToDb(long objId, long byteStart, long byteLen,
1086  long seq, CaseDbTransaction transaction) throws TskCoreException {
1087  try {
1088  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1089 
1090  String insertRangeSql = "INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) " //NON-NLS
1091  + "VALUES (?, ?, ?, ?)";
1092  PreparedStatement preparedStatement = connection.getPreparedStatement(insertRangeSql, Statement.NO_GENERATED_KEYS);
1093  preparedStatement.clearParameters();
1094  preparedStatement.setLong(1, objId);
1095  preparedStatement.setLong(2, byteStart);
1096  preparedStatement.setLong(3, byteLen);
1097  preparedStatement.setLong(4, seq);
1098  connection.executeUpdate(preparedStatement);
1099  } catch (SQLException ex) {
1100  throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex);
1101  }
1102  }
1103 }

Copyright © 2011-2021 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.