Sleuth Kit Java Bindings (JNI)  4.12.1
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  private final Map<Long, VirtualDirectory> unallocFileDirs = new HashMap<>();
70 
71  TskCaseDbBridge(SleuthkitCase caseDb, AddDataSourceCallbacks addDataSourceCallbacks, Host host) {
72  this.caseDb = caseDb;
73  this.addDataSourceCallbacks = addDataSourceCallbacks;
74  imageHost = host;
75  trans = null;
76  }
77 
83  private void beginTransaction() throws TskCoreException {
84  trans = caseDb.beginTransaction();
85  }
86 
92  private void commitTransaction() throws TskCoreException {
93  trans.commit();
94  trans = null;
95  }
96 
100  private void revertTransaction() {
101  try {
102  if (trans != null) {
103  trans.rollback();
104  trans = null;
105  }
106  } catch (TskCoreException ex) {
107  logger.log(Level.SEVERE, "Error rolling back transaction", ex);
108  }
109  }
110 
114  void finish() {
115  addBatchedFilesToDb();
116  addBatchedLayoutRangesToDb();
117  processLayoutFiles();
118  }
119 
139  long addImageInfo(int type, long ssize, String timezone,
140  long size, String md5, String sha1, String sha256, String deviceId,
141  String collectionDetails, String[] paths) {
142  try {
143  beginTransaction();
144  long objId = addImageToDb(TskData.TSK_IMG_TYPE_ENUM.valueOf(type), ssize, size,
145  timezone, md5, sha1, sha256, deviceId, collectionDetails, trans);
146  for (int i = 0;i < paths.length;i++) {
147  addImageNameToDb(objId, paths[i], i, trans);
148  }
149  commitTransaction();
150  return objId;
151  } catch (TskCoreException ex) {
152  logger.log(Level.SEVERE, "Error adding image to the database", ex);
153  revertTransaction();
154  return -1;
155  }
156  }
157 
164  void addAcquisitionDetails(long imgId, String details) {
165  try {
166  beginTransaction();
167  caseDb.setAcquisitionDetails(imgId, details, trans);
168  commitTransaction();
169  } catch (TskCoreException ex) {
170  logger.log(Level.SEVERE, "Error adding image details \"" + details + "\" to image with ID " + imgId, ex);
171  revertTransaction();
172  }
173  }
174 
186  long addVsInfo(long parentObjId, int vsType, long imgOffset, long blockSize) {
187  try {
188  beginTransaction();
189  VolumeSystem vs = caseDb.addVolumeSystem(parentObjId, TskData.TSK_VS_TYPE_ENUM.valueOf(vsType), imgOffset, blockSize, trans);
190  commitTransaction();
191  return vs.getId();
192  } catch (TskCoreException ex) {
193  logger.log(Level.SEVERE, "Error adding volume system to the database - parent obj ID: " + parentObjId
194  + ", image offset: " + imgOffset, ex);
195  revertTransaction();
196  return -1;
197  }
198  }
199 
213  long addVolume(long parentObjId, long addr, long start, long length, String desc,
214  long flags) {
215  try {
216  beginTransaction();
217  Volume vol = caseDb.addVolume(parentObjId, addr, start, length, desc, flags, trans);
218  commitTransaction();
219  return vol.getId();
220  } catch (TskCoreException ex) {
221  logger.log(Level.SEVERE, "Error adding volume to the database - parent object ID: " + parentObjId
222  + ", addr: " + addr, ex);
223  revertTransaction();
224  return -1;
225  }
226  }
227 
237  long addPool(long parentObjId, int poolType) {
238  try {
239  beginTransaction();
240  Pool pool = caseDb.addPool(parentObjId, TskData.TSK_POOL_TYPE_ENUM.valueOf(poolType), trans);
241  commitTransaction();
242  return pool.getId();
243  } catch (TskCoreException ex) {
244  logger.log(Level.SEVERE, "Error adding pool to the database - parent object ID: " + parentObjId, ex);
245  revertTransaction();
246  return -1;
247  }
248  }
249 
265  long addFileSystem(long parentObjId, long imgOffset, int fsType, long blockSize, long blockCount,
266  long rootInum, long firstInum, long lastInum) {
267  try {
268  beginTransaction();
269  FileSystem fs = caseDb.addFileSystem(parentObjId, imgOffset, TskData.TSK_FS_TYPE_ENUM.valueOf(fsType), blockSize, blockCount,
270  rootInum, firstInum, lastInum, null, trans);
271  commitTransaction();
272  fsIdToFsType.put(fs.getId(), TskData.TSK_FS_TYPE_ENUM.valueOf(fsType));
273  return fs.getId();
274  } catch (TskCoreException ex) {
275  logger.log(Level.SEVERE, "Error adding file system to the database - parent object ID: " + parentObjId
276  + ", offset: " + imgOffset, ex);
277  revertTransaction();
278  return -1;
279  }
280  }
281 
323  long addFile(long parentObjId,
324  long fsObjId, long dataSourceObjId,
325  int fsType,
326  int attrType, int attrId, String name,
327  long metaAddr, long metaSeq,
328  int dirType, int metaType, int dirFlags, int metaFlags,
329  long size,
330  long crtime, long ctime, long atime, long mtime,
331  int meta_mode, int gid, int uid,
332  String escaped_path, String extension,
333  long seq, long parMetaAddr, long parSeq, String ownerUid) {
334 
335  // Add the new file to the list
336  batchedFiles.add(new FileInfo(parentObjId,
337  fsObjId, dataSourceObjId,
338  fsType,
339  attrType, attrId, name,
340  metaAddr, metaSeq,
341  dirType, metaType, dirFlags, metaFlags,
342  size,
343  crtime, ctime, atime, mtime,
344  meta_mode, gid, uid,
345  escaped_path, extension,
346  seq, parMetaAddr, parSeq, ownerUid));
347 
348  // Add the current files to the database if we've exceeded the threshold or if we
349  // have the root folder.
350  if ((fsObjId == parentObjId)
351  || (batchedFiles.size() > BATCH_FILE_THRESHOLD)) {
352  return addBatchedFilesToDb();
353  }
354  return 0;
355  }
356 
362  private long addBatchedFilesToDb() {
363  List<Long> newObjIds = new ArrayList<>();
364  try {
365 
366  // loop through the batch, and make sure owner accounts exist for all the files in the batch.
367  // If not, create accounts.
368  Iterator<FileInfo> it = batchedFiles.iterator();
369 
370  while (it.hasNext()) {
371  FileInfo fileInfo = it.next();
372  String ownerUid = fileInfo.ownerUid;
373  if (Strings.isNullOrEmpty(fileInfo.ownerUid) == false) {
374  // first check the owner id is in the map, if found, then continue
375  if (this.ownerIdToAccountMap.containsKey(ownerUid)) {
376  continue;
377  }
378 
379  // query the DB to get the owner account
380  try {
381  Optional<OsAccount> ownerAccount = caseDb.getOsAccountManager().getWindowsOsAccount(ownerUid, null, null, imageHost);
382  if (ownerAccount.isPresent()) {
383  // found account - add to map
384  ownerIdToAccountMap.put(ownerUid, ownerAccount.get());
385  } else {
386  // account not found in the database, create the account and add to map
387  // Currently we expect only NTFS systems to provide a windows style SID as owner id.
388  OsAccountManager accountMgr = caseDb.getOsAccountManager();
389  OsAccount newAccount = accountMgr.newWindowsOsAccount(ownerUid, null, null, imageHost, OsAccountRealm.RealmScope.UNKNOWN);
390  Content ds = caseDb.getContentById(fileInfo.dataSourceObjId); // Data sources are cached so this will only access the database once
391  if (ds instanceof DataSource) {
392  accountMgr.newOsAccountInstance(newAccount, (DataSource)ds, OsAccountInstance.OsAccountInstanceType.ACCESSED);
393  }
394  ownerIdToAccountMap.put(ownerUid, newAccount);
395  }
396  } catch (NotUserSIDException ex) {
397  // if the owner SID is not a user SID, set the owner account to null
398  ownerIdToAccountMap.put(ownerUid, null);
399  } catch (Exception ex) {
400  // catch other exceptions to avoid skiping add batched files loop below
401  logger.log(Level.WARNING, "Error mapping ownerId " + ownerUid + " to account", ex);
402  ownerIdToAccountMap.put(ownerUid, null);
403  }
404  }
405  }
406 
407 
408 
409  beginTransaction();
410  FileInfo fileInfo;
411  while ((fileInfo = batchedFiles.poll()) != null) {
412  long computedParentObjId = fileInfo.parentObjId;
413  try {
414  // If we weren't given the parent object ID, look it up
415  if (fileInfo.parentObjId == 0) {
416  computedParentObjId = getParentObjId(fileInfo);
417  }
418 
419  Long ownerAccountObjId = OsAccount.NO_ACCOUNT;
420  if (Strings.isNullOrEmpty(fileInfo.ownerUid) == false) {
421  if (ownerIdToAccountMap.containsKey(fileInfo.ownerUid)) {
422  // for any non user SIDs, the map will have a null for account
423  if (Objects.nonNull(ownerIdToAccountMap.get(fileInfo.ownerUid))) {
424  ownerAccountObjId = ownerIdToAccountMap.get(fileInfo.ownerUid).getId();
425  }
426  } else {
427  // Error - the map should have an account or a null at this point for the owner SID.
428  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));
429  }
430  }
431 
432  // We've seen a case where the root folder comes in with an undefined meta type.
433  // We've also seen a case where it comes in as a regular file. The root folder should always be
434  // a directory so it will be cached properly and will not cause errors later for
435  // being an unexpected type.
436  if ((fileInfo.parentObjId == fileInfo.fsObjId)
437  && (fileInfo.metaType != TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue())) {
438  fileInfo.metaType = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue();
439  }
440 
441  long objId = addFileToDb(computedParentObjId,
442  fileInfo.fsObjId, fileInfo.dataSourceObjId,
443  fileInfo.fsType,
444  fileInfo.attrType, fileInfo.attrId, fileInfo.name,
445  fileInfo.metaAddr, fileInfo.metaSeq,
446  fileInfo.dirType, fileInfo.metaType, fileInfo.dirFlags, fileInfo.metaFlags,
447  fileInfo.size,
448  fileInfo.crtime, fileInfo.ctime, fileInfo.atime, fileInfo.mtime,
449  fileInfo.meta_mode, fileInfo.gid, fileInfo.uid,
450  null, TskData.FileKnown.UNKNOWN,
451  fileInfo.escaped_path, fileInfo.extension, fileInfo.ownerUid, ownerAccountObjId,
452  false, trans);
453  if (fileInfo.fsObjId != fileInfo.parentObjId) {
454  // Add new file ID to the list to send to ingest unless it is the root folder
455  newObjIds.add(objId);
456  }
457 
458  // If we're adding the root directory for the file system, cache it
459  if (fileInfo.parentObjId == fileInfo.fsObjId) {
460  fsIdToRootDir.put(fileInfo.fsObjId, objId);
461  }
462 
463  // If the file is a directory, cache the object ID.
464  if ((fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
465  || (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()))
466  && (fileInfo.name != null)
467  && ! fileInfo.name.equals(".")
468  && ! fileInfo.name.equals("..")) {
469  String dirName = fileInfo.escaped_path + fileInfo.name;
470  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.metaAddr, fileInfo.seq, dirName);
471  parentDirCache.put(key, objId);
472  }
473  } catch (TskCoreException ex) {
474  if (computedParentObjId > 0) {
475  // Most likely a database error occurred
476  logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
477  + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
478  } else {
479  // The parent lookup failed
480  logger.log(Level.SEVERE, "Error adding file to the database", ex);
481  }
482  }
483  }
484  commitTransaction();
485  try {
486  addDataSourceCallbacks.onFilesAdded(newObjIds);
487  } catch (Exception ex) {
488  // Exception firewall to prevent unexpected return to the native code
489  logger.log(Level.SEVERE, "Unexpected error from files added callback", ex);
490  }
491  } catch (Throwable ex) {
492  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
493  revertTransaction();
494  return -1;
495  }
496  return 0;
497  }
498 
508  private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
509  // Remove the final slash from the path unless we're in the root folder
510  String parentPath = fileInfo.escaped_path;
511  if(parentPath.endsWith("/") && ! parentPath.equals("/")) {
512  parentPath = parentPath.substring(0, parentPath.lastIndexOf('/'));
513  }
514 
515  // Look up the parent
516  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.parMetaAddr, fileInfo.parSeq, parentPath);
517  if (parentDirCache.containsKey(key)) {
518  return parentDirCache.get(key);
519  } else {
520  // There's no reason to do a database query since every folder added is being
521  // stored in the cache.
522  throw new TskCoreException("Could not find parent (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
523  + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
524  }
525  }
526 
540  long addLayoutFile(long parentObjId,
541  long fsObjId, long dataSourceObjId,
542  int fileType,
543  String name, long size) {
544  try {
545 
546  // The file system may be null for layout files
547  Long fsObjIdForDb = fsObjId;
548  if (fsObjId == 0) {
549  fsObjIdForDb = null;
550  }
551 
552  // If the layout file is in an $Unalloc folder, add the name. Otherwise use "/".
553  String parentPath = "/";
554  if (unallocFileDirs.containsKey(parentObjId)) {
555  parentPath = "/" + unallocFileDirs.get(parentObjId).getName() + "/";
556  }
557 
558  beginTransaction();
559  long objId = addFileToDb(parentObjId,
560  fsObjIdForDb, dataSourceObjId,
561  fileType,
562  null, null, name,
563  null, null,
564  TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue(),
565  TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(),
566  TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
567  TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue(),
568  size,
569  null, null, null, null,
570  null, null, null,
571  null, TskData.FileKnown.UNKNOWN,
572  parentPath, null, null, OsAccount.NO_ACCOUNT,
573  true, trans);
574  commitTransaction();
575 
576  // Store the layout file ID for later processing
577  layoutFileIds.add(objId);
578 
579  return objId;
580  } catch (TskCoreException ex) {
581  logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
582  + ", file system object ID: " + fsObjId + ", name: " + name, ex);
583  revertTransaction();
584  return -1;
585  }
586  }
587 
599  long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
600  batchedLayoutRanges.add(new LayoutRangeInfo(objId, byteStart, byteLen, seq));
601 
602  if (batchedLayoutRanges.size() > BATCH_FILE_THRESHOLD) {
603  return addBatchedLayoutRangesToDb();
604  }
605  return 0;
606  }
607 
613  private long addBatchedLayoutRangesToDb() {
614  try {
615  beginTransaction();
616  LayoutRangeInfo range;
617  while ((range = batchedLayoutRanges.poll()) != null) {
618  try {
619  addLayoutFileRangeToDb(range.objId, range.byteStart, range.byteLen, range.seq, trans);
620  } catch (TskCoreException ex) {
621  logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId
622  + ", byte start: " + range.byteStart + ", length: " + range.byteLen + ", seq: " + range.seq, ex);
623  }
624  }
625  commitTransaction();
626  return 0;
627  } catch (TskCoreException ex) {
628  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
629  revertTransaction();
630  return -1;
631  }
632  }
633 
639  void processLayoutFiles() {
640  addDataSourceCallbacks.onFilesAdded(layoutFileIds);
641  layoutFileIds.clear();
642  }
643 
653  long addUnallocFsBlockFilesParent(long fsObjId, String name) {
654  try {
655  if (! fsIdToRootDir.containsKey(fsObjId)) {
656  logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId);
657  return -1;
658  }
659  beginTransaction();
660  VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
661  commitTransaction();
662  unallocFileDirs.put(dir.getId(), dir);
663  addDataSourceCallbacks.onFilesAdded(Arrays.asList(dir.getId()));
664  return dir.getId();
665  } catch (TskCoreException ex) {
666  logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
667  revertTransaction();
668  return -1;
669  }
670  }
671 
675  private class ParentCacheKey {
676  long fsObjId;
677  long metaAddr;
678  long seqNum;
679  String path;
680 
690  ParentCacheKey(long fsObjId, long metaAddr, long seqNum, String path) {
691  this.fsObjId = fsObjId;
692  this.metaAddr = metaAddr;
693  if (ownerIdToAccountMap.containsKey(fsObjId)
694  && (ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS)
695  || ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS_DETECT))) {
696  this.seqNum = seqNum;
697  } else {
698  this.seqNum = 0;
699  }
700  this.path = path;
701  }
702 
703  @Override
704  public boolean equals(Object obj) {
705  if (! (obj instanceof ParentCacheKey)) {
706  return false;
707  }
708 
709  ParentCacheKey otherKey = (ParentCacheKey) obj;
710  if (this.fsObjId != otherKey.fsObjId
711  || this.metaAddr != otherKey.metaAddr
712  || this.seqNum != otherKey.seqNum) {
713  return false;
714  }
715 
716  return StringUtils.equals(this.path, otherKey.path);
717  }
718 
719  @Override
720  public int hashCode() {
721  int hash = 3;
722  hash = 31 * hash + (int) (this.fsObjId ^ (this.fsObjId >>> 32));
723  hash = 31 * hash + (int) (this.metaAddr ^ (this.metaAddr >>> 32));
724  hash = 31 * hash + (int) (this.seqNum ^ (this.seqNum >>> 32));
725  hash = 31 * hash + Objects.hashCode(this.path);
726  return hash;
727  }
728  }
729 
734  private class LayoutRangeInfo {
735  long objId;
736  long byteStart;
737  long byteLen;
738  long seq;
739 
740  LayoutRangeInfo(long objId, long byteStart, long byteLen, long seq) {
741  this.objId = objId;
742  this.byteStart = byteStart;
743  this.byteLen = byteLen;
744  this.seq = seq;
745  }
746  }
747 
752  private class FileInfo {
753  long parentObjId;
754  long fsObjId;
755  long dataSourceObjId;
756  int fsType;
757  int attrType;
758  int attrId;
759  String name;
760  long metaAddr;
761  long metaSeq;
762  int dirType;
763  int metaType;
764  int dirFlags;
765  int metaFlags;
766  long size;
767  long crtime;
768  long ctime;
769  long atime;
770  long mtime;
771  int meta_mode;
772  int gid;
773  int uid;
774  String escaped_path;
775  String extension;
776  long seq;
777  long parMetaAddr;
778  long parSeq;
779  String ownerUid;
780 
781  FileInfo(long parentObjId,
782  long fsObjId, long dataSourceObjId,
783  int fsType,
784  int attrType, int attrId, String name,
785  long metaAddr, long metaSeq,
786  int dirType, int metaType, int dirFlags, int metaFlags,
787  long size,
788  long crtime, long ctime, long atime, long mtime,
789  int meta_mode, int gid, int uid,
790  String escaped_path, String extension,
791  long seq, long parMetaAddr, long parSeq, String ownerUid) {
792 
793  this.parentObjId = parentObjId;
794  this.fsObjId = fsObjId;
795  this.dataSourceObjId = dataSourceObjId;
796  this.fsType = fsType;
797  this.attrType = attrType;
798  this.attrId = attrId;
799  this.name = name;
800  this.metaAddr = metaAddr;
801  this.metaSeq = metaSeq;
802  this.dirType = dirType;
803  this.metaType = metaType;
804  this.dirFlags = dirFlags;
805  this.metaFlags = metaFlags;
806  this.size = size;
807  this.crtime = crtime;
808  this.ctime = ctime;
809  this.atime = atime;
810  this.mtime = mtime;
811  this.meta_mode = meta_mode;
812  this.gid = gid;
813  this.uid = uid;
814  this.escaped_path = escaped_path;
815  this.extension = extension;
816  this.seq = seq;
817  this.parMetaAddr = parMetaAddr;
818  this.parSeq = parSeq;
819  this.ownerUid = ownerUid;
820  }
821  }
822 
866  private long addFileToDb(long parentObjId,
867  Long fsObjId, long dataSourceObjId,
868  int fsType,
869  Integer attrType, Integer attrId, String name,
870  Long metaAddr, Long metaSeq,
871  int dirType, int metaType, int dirFlags, int metaFlags,
872  long size,
873  Long crtime, Long ctime, Long atime, Long mtime,
874  Integer meta_mode, Integer gid, Integer uid,
875  String md5, TskData.FileKnown known,
876  String escaped_path, String extension, String ownerUid, Long ownerAcctObjId,
877  boolean hasLayout, CaseDbTransaction transaction) throws TskCoreException {
878 
879  try {
880  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
881 
882  // Insert a row for the local/logical file into the tsk_objects table.
883  // INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)
884  long objectId = caseDb.addObject(parentObjId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
885 
886  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, collected)"
887  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
888  PreparedStatement preparedStatement = connection.getPreparedStatement(fileInsert, Statement.NO_GENERATED_KEYS);
889  preparedStatement.clearParameters();
890 
891  if (fsObjId != null) {
892  preparedStatement.setLong(1, fsObjId); // fs_obj_id
893  } else {
894  preparedStatement.setNull(1, java.sql.Types.BIGINT);
895  }
896  preparedStatement.setLong(2, objectId); // obj_id
897  preparedStatement.setLong(3, dataSourceObjId); // data_source_obj_id
898  preparedStatement.setShort(4, (short) fsType); // type
899  if (attrType != null) {
900  preparedStatement.setShort(5, attrType.shortValue()); // attr_type
901  } else {
902  preparedStatement.setNull(5, java.sql.Types.SMALLINT);
903  }
904  if (attrId != null) {
905  preparedStatement.setInt(6, attrId); // attr_id
906  } else {
907  preparedStatement.setNull(6, java.sql.Types.INTEGER);
908  }
909  preparedStatement.setString(7, name); // name
910  if (metaAddr != null) {
911  preparedStatement.setLong(8, metaAddr); // meta_addr
912  } else {
913  preparedStatement.setNull(8, java.sql.Types.BIGINT);
914  }
915  if (metaSeq != null) {
916  preparedStatement.setInt(9, metaSeq.intValue()); // meta_seq
917  } else {
918  preparedStatement.setNull(9, java.sql.Types.INTEGER);
919  }
920  preparedStatement.setShort(10, (short) dirType); // dir_type
921  preparedStatement.setShort(11, (short) metaType); // meta_type
922  preparedStatement.setShort(12, (short) dirFlags); // dir_flags
923  preparedStatement.setShort(13, (short) metaFlags); // meta_flags
924  preparedStatement.setLong(14, size < 0 ? 0 : size); // size
925  if (crtime != null) {
926  preparedStatement.setLong(15, crtime); // crtime
927  } else {
928  preparedStatement.setNull(15, java.sql.Types.BIGINT);
929  }
930  if (ctime != null) {
931  preparedStatement.setLong(16, ctime); // ctime
932  } else {
933  preparedStatement.setNull(16, java.sql.Types.BIGINT);
934  }
935  if (atime != null) {
936  preparedStatement.setLong(17, atime); // atime
937  } else {
938  preparedStatement.setNull(17, java.sql.Types.BIGINT);
939  }
940  if (mtime != null) {
941  preparedStatement.setLong(18, mtime); // mtime
942  } else {
943  preparedStatement.setNull(18, java.sql.Types.BIGINT);
944  }
945  if (meta_mode != null) {
946  preparedStatement.setLong(19, meta_mode); // mode
947  } else {
948  preparedStatement.setNull(19, java.sql.Types.BIGINT);
949  }
950  if (gid != null) {
951  preparedStatement.setLong(20, gid); // gid
952  } else {
953  preparedStatement.setNull(20, java.sql.Types.BIGINT);
954  }
955  if (uid != null) {
956  preparedStatement.setLong(21, uid); // uid
957  } else {
958  preparedStatement.setNull(21, java.sql.Types.BIGINT);
959  }
960  preparedStatement.setString(22, md5); // md5
961  preparedStatement.setInt(23, known.getFileKnownValue());// known
962  preparedStatement.setString(24, escaped_path); // parent_path
963  preparedStatement.setString(25, extension); // extension
964  if (hasLayout) {
965  preparedStatement.setInt(26, 1); // has_layout
966  } else {
967  preparedStatement.setNull(26, java.sql.Types.INTEGER);
968  }
969 
970  preparedStatement.setString(27, ownerUid); // ownerUid
971 
972  if (ownerAcctObjId != OsAccount.NO_ACCOUNT) {
973  preparedStatement.setLong(28, ownerAcctObjId); //
974  } else {
975  preparedStatement.setNull(28, java.sql.Types.BIGINT);
976  }
977 
978  preparedStatement.setLong(29, TskData.CollectedStatus.UNKNOWN.getType());
979 
980  connection.executeUpdate(preparedStatement);
981 
982  // If this is not a slack file create the timeline events
983  if (!hasLayout
984  && TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() != fsType
985  && (!name.equals(".")) && (!name.equals(".."))) {
986  TimelineManager timelineManager = caseDb.getTimelineManager();
987  DerivedFile derivedFile = new DerivedFile(caseDb, objectId, dataSourceObjId, fsObjId, name,
988  TskData.TSK_FS_NAME_TYPE_ENUM.valueOf((short) dirType),
989  TskData.TSK_FS_META_TYPE_ENUM.valueOf((short) metaType),
990  TskData.TSK_FS_NAME_FLAG_ENUM.valueOf(dirFlags),
991  (short) metaFlags,
992  size, ctime, crtime, atime, mtime, null, null, null, null, escaped_path, null, parentObjId, null, null, extension, ownerUid, ownerAcctObjId);
993 
994  timelineManager.addEventsForNewFileQuiet(derivedFile, connection);
995  }
996 
997  return objectId;
998  } catch (SQLException ex) {
999  throw new TskCoreException("Failed to add file system file", ex);
1000  }
1001  }
1002 
1022  private long addImageToDb(TskData.TSK_IMG_TYPE_ENUM type, long sectorSize, long size,
1023  String timezone, String md5, String sha1, String sha256,
1024  String deviceId, String collectionDetails,
1025  CaseDbTransaction transaction) throws TskCoreException {
1026  try {
1027  // Insert a row for the Image into the tsk_objects table.
1028  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1029  long newObjId = caseDb.addObject(0, TskData.ObjectType.IMG.getObjectType(), connection);
1030 
1031  // Add a row to tsk_image_info
1032  // INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)
1033  String imageInfoSql = "INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
1034  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
1035  PreparedStatement preparedStatement = connection.getPreparedStatement(imageInfoSql, Statement.NO_GENERATED_KEYS);
1036  preparedStatement.clearParameters();
1037  preparedStatement.setLong(1, newObjId);
1038  preparedStatement.setShort(2, (short) type.getValue());
1039  preparedStatement.setLong(3, sectorSize);
1040  preparedStatement.setString(4, timezone);
1041  //prevent negative size
1042  long savedSize = size < 0 ? 0 : size;
1043  preparedStatement.setLong(5, savedSize);
1044  preparedStatement.setString(6, md5);
1045  preparedStatement.setString(7, sha1);
1046  preparedStatement.setString(8, sha256);
1047  preparedStatement.setString(9, null);
1048  connection.executeUpdate(preparedStatement);
1049 
1050  // Add a row to data_source_info
1051  String dataSourceInfoSql = "INSERT INTO data_source_info (obj_id, device_id, time_zone, acquisition_details, host_id) VALUES (?, ?, ?, ?, ?)"; // NON-NLS
1052  preparedStatement = connection.getPreparedStatement(dataSourceInfoSql, Statement.NO_GENERATED_KEYS);
1053  preparedStatement.clearParameters();
1054  preparedStatement.setLong(1, newObjId);
1055  preparedStatement.setString(2, deviceId);
1056  preparedStatement.setString(3, timezone);
1057  preparedStatement.setString(4, collectionDetails);
1058  preparedStatement.setLong(5, imageHost.getHostId());
1059  connection.executeUpdate(preparedStatement);
1060 
1061  return newObjId;
1062  } catch (SQLException ex) {
1063  throw new TskCoreException(String.format("Error adding image to database"), ex);
1064  }
1065  }
1066 
1077  private void addImageNameToDb(long objId, String name, long sequence,
1078  CaseDbTransaction transaction) throws TskCoreException {
1079  try {
1080  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1081 
1082  String imageNameSql = "INSERT INTO tsk_image_names (obj_id, name, sequence) VALUES (?, ?, ?)"; // NON-NLS
1083  PreparedStatement preparedStatement = connection.getPreparedStatement(imageNameSql, Statement.NO_GENERATED_KEYS);
1084  preparedStatement.clearParameters();
1085  preparedStatement.setLong(1, objId);
1086  preparedStatement.setString(2, name);
1087  preparedStatement.setLong(3, sequence);
1088  connection.executeUpdate(preparedStatement);
1089  } catch (SQLException ex) {
1090  throw new TskCoreException(String.format("Error adding image name %s to image with object ID %d", name, objId), ex);
1091  }
1092  }
1093 
1105  void addLayoutFileRangeToDb(long objId, long byteStart, long byteLen,
1106  long seq, CaseDbTransaction transaction) throws TskCoreException {
1107  try {
1108  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1109 
1110  String insertRangeSql = "INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) " //NON-NLS
1111  + "VALUES (?, ?, ?, ?)";
1112  PreparedStatement preparedStatement = connection.getPreparedStatement(insertRangeSql, Statement.NO_GENERATED_KEYS);
1113  preparedStatement.clearParameters();
1114  preparedStatement.setLong(1, objId);
1115  preparedStatement.setLong(2, byteStart);
1116  preparedStatement.setLong(3, byteLen);
1117  preparedStatement.setLong(4, seq);
1118  connection.executeUpdate(preparedStatement);
1119  } catch (SQLException ex) {
1120  throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex);
1121  }
1122  }
1123 }

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.