Sleuth Kit Java Bindings (JNI) 4.14.0
Java bindings for using The Sleuth Kit
Loading...
Searching...
No Matches
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 */
19package org.sleuthkit.datamodel;
20
21import com.google.common.base.Strings;
22import java.sql.PreparedStatement;
23import java.sql.SQLException;
24import java.sql.Statement;
25import org.apache.commons.lang3.StringUtils;
26import java.util.List;
27import java.util.Arrays;
28import java.util.ArrayList;
29import java.util.HashMap;
30import java.util.Iterator;
31import java.util.LinkedList;
32import java.util.Map;
33import java.util.Objects;
34import java.util.Optional;
35import java.util.Queue;
36import java.util.logging.Level;
37import java.util.logging.Logger;
38import org.sleuthkit.datamodel.OsAccountManager.NotUserSIDException;
39import org.sleuthkit.datamodel.SleuthkitCase.CaseDbTransaction;
40
50class 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-2024 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.