Sleuth Kit Java Bindings (JNI)  4.11.0
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  OsAccountManager accountMgr = caseDb.getOsAccountManager();
388  OsAccount newAccount = accountMgr.newWindowsOsAccount(ownerUid, null, null, imageHost, OsAccountRealm.RealmScope.UNKNOWN);
389  Content ds = caseDb.getContentById(fileInfo.dataSourceObjId); // Data sources are cached so this will only access the database once
390  if (ds instanceof DataSource) {
391  accountMgr.newOsAccountInstance(newAccount, (DataSource)ds, OsAccountInstance.OsAccountInstanceType.ACCESSED);
392  }
393  ownerIdToAccountMap.put(ownerUid, newAccount);
394  }
395  } catch (NotUserSIDException ex) {
396  // if the owner SID is not a user SID, set the owner account to null
397  ownerIdToAccountMap.put(ownerUid, null);
398  }
399  }
400  }
401 
402 
403 
404  beginTransaction();
405  FileInfo fileInfo;
406  while ((fileInfo = batchedFiles.poll()) != null) {
407  long computedParentObjId = fileInfo.parentObjId;
408  try {
409  // If we weren't given the parent object ID, look it up
410  if (fileInfo.parentObjId == 0) {
411  computedParentObjId = getParentObjId(fileInfo);
412  }
413 
414  Long ownerAccountObjId = OsAccount.NO_ACCOUNT;
415  if (Strings.isNullOrEmpty(fileInfo.ownerUid) == false) {
416  if (ownerIdToAccountMap.containsKey(fileInfo.ownerUid)) {
417  // for any non user SIDs, the map will have a null for account
418  if (Objects.nonNull(ownerIdToAccountMap.get(fileInfo.ownerUid))) {
419  ownerAccountObjId = ownerIdToAccountMap.get(fileInfo.ownerUid).getId();
420  }
421  } else {
422  // Error - the map should have an account or a null at this point for the owner SID.
423  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));
424  }
425  }
426 
427  // We've seen a case where the root folder comes in with an undefined meta type.
428  // We've also seen a case where it comes in as a regular file. The root folder should always be
429  // a directory so it will be cached properly and will not cause errors later for
430  // being an unexpected type.
431  if ((fileInfo.parentObjId == fileInfo.fsObjId)
432  && (fileInfo.metaType != TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue())) {
433  fileInfo.metaType = TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue();
434  }
435 
436  long objId = addFileToDb(computedParentObjId,
437  fileInfo.fsObjId, fileInfo.dataSourceObjId,
438  fileInfo.fsType,
439  fileInfo.attrType, fileInfo.attrId, fileInfo.name,
440  fileInfo.metaAddr, fileInfo.metaSeq,
441  fileInfo.dirType, fileInfo.metaType, fileInfo.dirFlags, fileInfo.metaFlags,
442  fileInfo.size,
443  fileInfo.crtime, fileInfo.ctime, fileInfo.atime, fileInfo.mtime,
444  fileInfo.meta_mode, fileInfo.gid, fileInfo.uid,
445  null, TskData.FileKnown.UNKNOWN,
446  fileInfo.escaped_path, fileInfo.extension, fileInfo.ownerUid, ownerAccountObjId,
447  false, trans);
448  if (fileInfo.fsObjId != fileInfo.parentObjId) {
449  // Add new file ID to the list to send to ingest unless it is the root folder
450  newObjIds.add(objId);
451  }
452 
453  // If we're adding the root directory for the file system, cache it
454  if (fileInfo.parentObjId == fileInfo.fsObjId) {
455  fsIdToRootDir.put(fileInfo.fsObjId, objId);
456  }
457 
458  // If the file is a directory, cache the object ID.
459  if ((fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
460  || (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()))
461  && (fileInfo.name != null)
462  && ! fileInfo.name.equals(".")
463  && ! fileInfo.name.equals("..")) {
464  String dirName = fileInfo.escaped_path + fileInfo.name;
465  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.metaAddr, fileInfo.seq, dirName);
466  parentDirCache.put(key, objId);
467  }
468  } catch (TskCoreException ex) {
469  if (computedParentObjId > 0) {
470  // Most likely a database error occurred
471  logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
472  + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
473  } else {
474  // The parent lookup failed
475  logger.log(Level.SEVERE, "Error adding file to the database", ex);
476  }
477  }
478  }
479  commitTransaction();
480  try {
481  addDataSourceCallbacks.onFilesAdded(newObjIds);
482  } catch (Exception ex) {
483  // Exception firewall to prevent unexpected return to the native code
484  logger.log(Level.SEVERE, "Unexpected error from files added callback", ex);
485  }
486  } catch (TskCoreException ex) {
487  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
488  revertTransaction();
489  return -1;
490  }
491  return 0;
492  }
493 
503  private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
504  // Remove the final slash from the path unless we're in the root folder
505  String parentPath = fileInfo.escaped_path;
506  if(parentPath.endsWith("/") && ! parentPath.equals("/")) {
507  parentPath = parentPath.substring(0, parentPath.lastIndexOf('/'));
508  }
509 
510  // Look up the parent
511  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.parMetaAddr, fileInfo.parSeq, parentPath);
512  if (parentDirCache.containsKey(key)) {
513  return parentDirCache.get(key);
514  } else {
515  // There's no reason to do a database query since every folder added is being
516  // stored in the cache.
517  throw new TskCoreException("Could not find parent (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
518  + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
519  }
520  }
521 
535  long addLayoutFile(long parentObjId,
536  long fsObjId, long dataSourceObjId,
537  int fileType,
538  String name, long size) {
539  try {
540 
541  // The file system may be null for layout files
542  Long fsObjIdForDb = fsObjId;
543  if (fsObjId == 0) {
544  fsObjIdForDb = null;
545  }
546 
547  beginTransaction();
548  long objId = addFileToDb(parentObjId,
549  fsObjIdForDb, dataSourceObjId,
550  fileType,
551  null, null, name,
552  null, null,
553  TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue(),
554  TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(),
555  TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
556  TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue(),
557  size,
558  null, null, null, null,
559  null, null, null,
560  null, TskData.FileKnown.UNKNOWN,
561  null, null, null, OsAccount.NO_ACCOUNT,
562  true, trans);
563  commitTransaction();
564 
565  // Store the layout file ID for later processing
566  layoutFileIds.add(objId);
567 
568  return objId;
569  } catch (TskCoreException ex) {
570  logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
571  + ", file system object ID: " + fsObjId + ", name: " + name, ex);
572  revertTransaction();
573  return -1;
574  }
575  }
576 
588  long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
589  batchedLayoutRanges.add(new LayoutRangeInfo(objId, byteStart, byteLen, seq));
590 
591  if (batchedLayoutRanges.size() > BATCH_FILE_THRESHOLD) {
592  return addBatchedLayoutRangesToDb();
593  }
594  return 0;
595  }
596 
602  private long addBatchedLayoutRangesToDb() {
603  try {
604  beginTransaction();
605  LayoutRangeInfo range;
606  while ((range = batchedLayoutRanges.poll()) != null) {
607  try {
608  addLayoutFileRangeToDb(range.objId, range.byteStart, range.byteLen, range.seq, trans);
609  } catch (TskCoreException ex) {
610  logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId
611  + ", byte start: " + range.byteStart + ", length: " + range.byteLen + ", seq: " + range.seq, ex);
612  }
613  }
614  commitTransaction();
615  return 0;
616  } catch (TskCoreException ex) {
617  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
618  revertTransaction();
619  return -1;
620  }
621  }
622 
628  void processLayoutFiles() {
629  addDataSourceCallbacks.onFilesAdded(layoutFileIds);
630  layoutFileIds.clear();
631  }
632 
642  long addUnallocFsBlockFilesParent(long fsObjId, String name) {
643  try {
644  if (! fsIdToRootDir.containsKey(fsObjId)) {
645  logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId);
646  return -1;
647  }
648  beginTransaction();
649  VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
650  commitTransaction();
651  addDataSourceCallbacks.onFilesAdded(Arrays.asList(dir.getId()));
652  return dir.getId();
653  } catch (TskCoreException ex) {
654  logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
655  revertTransaction();
656  return -1;
657  }
658  }
659 
663  private class ParentCacheKey {
664  long fsObjId;
665  long metaAddr;
666  long seqNum;
667  String path;
668 
678  ParentCacheKey(long fsObjId, long metaAddr, long seqNum, String path) {
679  this.fsObjId = fsObjId;
680  this.metaAddr = metaAddr;
681  if (ownerIdToAccountMap.containsKey(fsObjId)
682  && (ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS)
683  || ownerIdToAccountMap.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS_DETECT))) {
684  this.seqNum = seqNum;
685  } else {
686  this.seqNum = 0;
687  }
688  this.path = path;
689  }
690 
691  @Override
692  public boolean equals(Object obj) {
693  if (! (obj instanceof ParentCacheKey)) {
694  return false;
695  }
696 
697  ParentCacheKey otherKey = (ParentCacheKey) obj;
698  if (this.fsObjId != otherKey.fsObjId
699  || this.metaAddr != otherKey.metaAddr
700  || this.seqNum != otherKey.seqNum) {
701  return false;
702  }
703 
704  return StringUtils.equals(this.path, otherKey.path);
705  }
706 
707  @Override
708  public int hashCode() {
709  int hash = 3;
710  hash = 31 * hash + (int) (this.fsObjId ^ (this.fsObjId >>> 32));
711  hash = 31 * hash + (int) (this.metaAddr ^ (this.metaAddr >>> 32));
712  hash = 31 * hash + (int) (this.seqNum ^ (this.seqNum >>> 32));
713  hash = 31 * hash + Objects.hashCode(this.path);
714  return hash;
715  }
716  }
717 
722  private class LayoutRangeInfo {
723  long objId;
724  long byteStart;
725  long byteLen;
726  long seq;
727 
728  LayoutRangeInfo(long objId, long byteStart, long byteLen, long seq) {
729  this.objId = objId;
730  this.byteStart = byteStart;
731  this.byteLen = byteLen;
732  this.seq = seq;
733  }
734  }
735 
740  private class FileInfo {
741  long parentObjId;
742  long fsObjId;
743  long dataSourceObjId;
744  int fsType;
745  int attrType;
746  int attrId;
747  String name;
748  long metaAddr;
749  long metaSeq;
750  int dirType;
751  int metaType;
752  int dirFlags;
753  int metaFlags;
754  long size;
755  long crtime;
756  long ctime;
757  long atime;
758  long mtime;
759  int meta_mode;
760  int gid;
761  int uid;
762  String escaped_path;
763  String extension;
764  long seq;
765  long parMetaAddr;
766  long parSeq;
767  String ownerUid;
768 
769  FileInfo(long parentObjId,
770  long fsObjId, long dataSourceObjId,
771  int fsType,
772  int attrType, int attrId, String name,
773  long metaAddr, long metaSeq,
774  int dirType, int metaType, int dirFlags, int metaFlags,
775  long size,
776  long crtime, long ctime, long atime, long mtime,
777  int meta_mode, int gid, int uid,
778  String escaped_path, String extension,
779  long seq, long parMetaAddr, long parSeq, String ownerUid) {
780 
781  this.parentObjId = parentObjId;
782  this.fsObjId = fsObjId;
783  this.dataSourceObjId = dataSourceObjId;
784  this.fsType = fsType;
785  this.attrType = attrType;
786  this.attrId = attrId;
787  this.name = name;
788  this.metaAddr = metaAddr;
789  this.metaSeq = metaSeq;
790  this.dirType = dirType;
791  this.metaType = metaType;
792  this.dirFlags = dirFlags;
793  this.metaFlags = metaFlags;
794  this.size = size;
795  this.crtime = crtime;
796  this.ctime = ctime;
797  this.atime = atime;
798  this.mtime = mtime;
799  this.meta_mode = meta_mode;
800  this.gid = gid;
801  this.uid = uid;
802  this.escaped_path = escaped_path;
803  this.extension = extension;
804  this.seq = seq;
805  this.parMetaAddr = parMetaAddr;
806  this.parSeq = parSeq;
807  this.ownerUid = ownerUid;
808  }
809  }
810 
854  private long addFileToDb(long parentObjId,
855  Long fsObjId, long dataSourceObjId,
856  int fsType,
857  Integer attrType, Integer attrId, String name,
858  Long metaAddr, Long metaSeq,
859  int dirType, int metaType, int dirFlags, int metaFlags,
860  long size,
861  Long crtime, Long ctime, Long atime, Long mtime,
862  Integer meta_mode, Integer gid, Integer uid,
863  String md5, TskData.FileKnown known,
864  String escaped_path, String extension, String ownerUid, Long ownerAcctObjId,
865  boolean hasLayout, CaseDbTransaction transaction) throws TskCoreException {
866 
867  try {
868  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
869 
870  // Insert a row for the local/logical file into the tsk_objects table.
871  // INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)
872  long objectId = caseDb.addObject(parentObjId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
873 
874  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)"
875  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
876  PreparedStatement preparedStatement = connection.getPreparedStatement(fileInsert, Statement.NO_GENERATED_KEYS);
877  preparedStatement.clearParameters();
878 
879  if (fsObjId != null) {
880  preparedStatement.setLong(1, fsObjId); // fs_obj_id
881  } else {
882  preparedStatement.setNull(1, java.sql.Types.BIGINT);
883  }
884  preparedStatement.setLong(2, objectId); // obj_id
885  preparedStatement.setLong(3, dataSourceObjId); // data_source_obj_id
886  preparedStatement.setShort(4, (short) fsType); // type
887  if (attrType != null) {
888  preparedStatement.setShort(5, attrType.shortValue()); // attr_type
889  } else {
890  preparedStatement.setNull(5, java.sql.Types.SMALLINT);
891  }
892  if (attrId != null) {
893  preparedStatement.setInt(6, attrId); // attr_id
894  } else {
895  preparedStatement.setNull(6, java.sql.Types.INTEGER);
896  }
897  preparedStatement.setString(7, name); // name
898  if (metaAddr != null) {
899  preparedStatement.setLong(8, metaAddr); // meta_addr
900  } else {
901  preparedStatement.setNull(8, java.sql.Types.BIGINT);
902  }
903  if (metaSeq != null) {
904  preparedStatement.setInt(9, metaSeq.intValue()); // meta_seq
905  } else {
906  preparedStatement.setNull(9, java.sql.Types.INTEGER);
907  }
908  preparedStatement.setShort(10, (short) dirType); // dir_type
909  preparedStatement.setShort(11, (short) metaType); // meta_type
910  preparedStatement.setShort(12, (short) dirFlags); // dir_flags
911  preparedStatement.setShort(13, (short) metaFlags); // meta_flags
912  preparedStatement.setLong(14, size < 0 ? 0 : size); // size
913  if (crtime != null) {
914  preparedStatement.setLong(15, crtime); // crtime
915  } else {
916  preparedStatement.setNull(15, java.sql.Types.BIGINT);
917  }
918  if (ctime != null) {
919  preparedStatement.setLong(16, ctime); // ctime
920  } else {
921  preparedStatement.setNull(16, java.sql.Types.BIGINT);
922  }
923  if (atime != null) {
924  preparedStatement.setLong(17, atime); // atime
925  } else {
926  preparedStatement.setNull(17, java.sql.Types.BIGINT);
927  }
928  if (mtime != null) {
929  preparedStatement.setLong(18, mtime); // mtime
930  } else {
931  preparedStatement.setNull(18, java.sql.Types.BIGINT);
932  }
933  if (meta_mode != null) {
934  preparedStatement.setLong(19, meta_mode); // mode
935  } else {
936  preparedStatement.setNull(19, java.sql.Types.BIGINT);
937  }
938  if (gid != null) {
939  preparedStatement.setLong(20, gid); // gid
940  } else {
941  preparedStatement.setNull(20, java.sql.Types.BIGINT);
942  }
943  if (uid != null) {
944  preparedStatement.setLong(21, uid); // uid
945  } else {
946  preparedStatement.setNull(21, java.sql.Types.BIGINT);
947  }
948  preparedStatement.setString(22, md5); // md5
949  preparedStatement.setInt(23, known.getFileKnownValue());// known
950  preparedStatement.setString(24, escaped_path); // parent_path
951  preparedStatement.setString(25, extension); // extension
952  if (hasLayout) {
953  preparedStatement.setInt(26, 1); // has_layout
954  } else {
955  preparedStatement.setNull(26, java.sql.Types.INTEGER);
956  }
957 
958  preparedStatement.setString(27, ownerUid); // ownerUid
959 
960  if (ownerAcctObjId != OsAccount.NO_ACCOUNT) {
961  preparedStatement.setLong(28, ownerAcctObjId); //
962  } else {
963  preparedStatement.setNull(28, java.sql.Types.BIGINT);
964  }
965 
966  connection.executeUpdate(preparedStatement);
967 
968  // If this is not a slack file create the timeline events
969  if (!hasLayout
970  && TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() != fsType
971  && (!name.equals(".")) && (!name.equals(".."))) {
972  TimelineManager timelineManager = caseDb.getTimelineManager();
973  DerivedFile derivedFile = new DerivedFile(caseDb, objectId, dataSourceObjId, name,
974  TskData.TSK_FS_NAME_TYPE_ENUM.valueOf((short) dirType),
975  TskData.TSK_FS_META_TYPE_ENUM.valueOf((short) metaType),
976  TskData.TSK_FS_NAME_FLAG_ENUM.valueOf(dirFlags),
977  (short) metaFlags,
978  size, ctime, crtime, atime, mtime, null, null, null, escaped_path, null, parentObjId, null, null, extension, ownerUid, ownerAcctObjId);
979 
980  timelineManager.addEventsForNewFileQuiet(derivedFile, connection);
981  }
982 
983  return objectId;
984  } catch (SQLException ex) {
985  throw new TskCoreException("Failed to add file system file", ex);
986  }
987  }
988 
1008  private long addImageToDb(TskData.TSK_IMG_TYPE_ENUM type, long sectorSize, long size,
1009  String timezone, String md5, String sha1, String sha256,
1010  String deviceId, String collectionDetails,
1011  CaseDbTransaction transaction) throws TskCoreException {
1012  try {
1013  // Insert a row for the Image into the tsk_objects table.
1014  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1015  long newObjId = caseDb.addObject(0, TskData.ObjectType.IMG.getObjectType(), connection);
1016 
1017  // Add a row to tsk_image_info
1018  // INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)
1019  String imageInfoSql = "INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
1020  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
1021  PreparedStatement preparedStatement = connection.getPreparedStatement(imageInfoSql, Statement.NO_GENERATED_KEYS);
1022  preparedStatement.clearParameters();
1023  preparedStatement.setLong(1, newObjId);
1024  preparedStatement.setShort(2, (short) type.getValue());
1025  preparedStatement.setLong(3, sectorSize);
1026  preparedStatement.setString(4, timezone);
1027  //prevent negative size
1028  long savedSize = size < 0 ? 0 : size;
1029  preparedStatement.setLong(5, savedSize);
1030  preparedStatement.setString(6, md5);
1031  preparedStatement.setString(7, sha1);
1032  preparedStatement.setString(8, sha256);
1033  preparedStatement.setString(9, null);
1034  connection.executeUpdate(preparedStatement);
1035 
1036  // Add a row to data_source_info
1037  String dataSourceInfoSql = "INSERT INTO data_source_info (obj_id, device_id, time_zone, acquisition_details, host_id) VALUES (?, ?, ?, ?, ?)"; // NON-NLS
1038  preparedStatement = connection.getPreparedStatement(dataSourceInfoSql, Statement.NO_GENERATED_KEYS);
1039  preparedStatement.clearParameters();
1040  preparedStatement.setLong(1, newObjId);
1041  preparedStatement.setString(2, deviceId);
1042  preparedStatement.setString(3, timezone);
1043  preparedStatement.setString(4, collectionDetails);
1044  preparedStatement.setLong(5, imageHost.getHostId());
1045  connection.executeUpdate(preparedStatement);
1046 
1047  return newObjId;
1048  } catch (SQLException ex) {
1049  throw new TskCoreException(String.format("Error adding image to database"), ex);
1050  }
1051  }
1052 
1063  private void addImageNameToDb(long objId, String name, long sequence,
1064  CaseDbTransaction transaction) throws TskCoreException {
1065  try {
1066  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1067 
1068  String imageNameSql = "INSERT INTO tsk_image_names (obj_id, name, sequence) VALUES (?, ?, ?)"; // NON-NLS
1069  PreparedStatement preparedStatement = connection.getPreparedStatement(imageNameSql, Statement.NO_GENERATED_KEYS);
1070  preparedStatement.clearParameters();
1071  preparedStatement.setLong(1, objId);
1072  preparedStatement.setString(2, name);
1073  preparedStatement.setLong(3, sequence);
1074  connection.executeUpdate(preparedStatement);
1075  } catch (SQLException ex) {
1076  throw new TskCoreException(String.format("Error adding image name %s to image with object ID %d", name, objId), ex);
1077  }
1078  }
1079 
1091  void addLayoutFileRangeToDb(long objId, long byteStart, long byteLen,
1092  long seq, CaseDbTransaction transaction) throws TskCoreException {
1093  try {
1094  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1095 
1096  String insertRangeSql = "INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) " //NON-NLS
1097  + "VALUES (?, ?, ?, ?)";
1098  PreparedStatement preparedStatement = connection.getPreparedStatement(insertRangeSql, Statement.NO_GENERATED_KEYS);
1099  preparedStatement.clearParameters();
1100  preparedStatement.setLong(1, objId);
1101  preparedStatement.setLong(2, byteStart);
1102  preparedStatement.setLong(3, byteLen);
1103  preparedStatement.setLong(4, seq);
1104  connection.executeUpdate(preparedStatement);
1105  } catch (SQLException ex) {
1106  throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex);
1107  }
1108  }
1109 }

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.