19 package org.sleuthkit.datamodel;
21 import com.google.common.base.Strings;
22 import com.google.common.annotations.Beta;
23 import org.apache.commons.lang3.StringUtils;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.sql.Statement;
28 import java.sql.Types;
29 import java.util.Collections;
30 import java.util.ArrayList;
31 import java.util.List;
32 import java.util.NavigableMap;
33 import java.util.Objects;
34 import java.util.Optional;
35 import java.util.UUID;
36 import java.util.concurrent.ConcurrentSkipListMap;
37 import java.util.stream.Collectors;
57 private final Object osAcctInstancesCacheLock;
58 private final NavigableMap<OsAccountInstanceKey, OsAccountInstance> osAccountInstanceCache;
68 osAcctInstancesCacheLock =
new Object();
69 osAccountInstanceCache =
new ConcurrentSkipListMap<>();
88 if (Strings.isNullOrEmpty(uniqueAccountId)) {
105 }
catch (SQLException ex) {
111 Optional<OsAccount> osAccount = this.getOsAccountByAddr(uniqueAccountId, realm);
112 if (osAccount.isPresent()) {
113 return osAccount.get();
117 throw new TskCoreException(String.format(
"Error creating OsAccount with uniqueAccountId = %s in realm id = %d", uniqueAccountId, realm.getRealmId()), ex);
152 if (realmScope == null) {
153 throw new TskCoreException(
"RealmScope cannot be null. Use UNKNOWN if scope is not known.");
155 if (referringHost == null) {
156 throw new TskCoreException(
"A referring host is required to create an account.");
160 if ((StringUtils.isBlank(sid) || sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID))
161 && StringUtils.isBlank(loginName)) {
162 throw new TskCoreException(
"Cannot create OS account with both uniqueId and loginName as null.");
165 if ((StringUtils.isBlank(sid) || sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID))
166 && StringUtils.isBlank(realmName)) {
167 throw new TskCoreException(
"Realm name or SID is required to create a Windows account.");
170 if (!StringUtils.isBlank(sid) && !sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID) && !WindowsAccountUtils.isWindowsUserSid(sid)) {
175 if (StringUtils.isBlank(sid)
176 && !StringUtils.isBlank(loginName) && !StringUtils.isBlank(realmName)
177 && WindowsAccountUtils.isWindowsWellKnownAccountName(loginName, realmName)) {
178 sid = WindowsAccountUtils.getWindowsWellKnownAccountSid(loginName, realmName);
183 Optional<OsAccountRealm> anotherRealmWithSameName = Optional.empty();
184 Optional<OsAccountRealm> anotherRealmWithSameAddr = Optional.empty();
188 try (CaseDbConnection connection = db.getConnection()) {
189 realmUpdateResult = db.
getOsAccountRealmManager().getAndUpdateWindowsRealm(sid, realmName, referringHost, connection);
191 Optional<OsAccountRealm> realmOptional = realmUpdateResult.
getUpdatedRealm();
192 if (realmOptional.isPresent()) {
193 realm = realmOptional.get();
201 anotherRealmWithSameName = db.
getOsAccountRealmManager().getAnotherRealmByName(realmOptional.get(), realmName, referringHost, connection);
204 anotherRealmWithSameAddr = db.
getOsAccountRealmManager().getAnotherRealmByAddr(realmOptional.get(), realmName, referringHost, connection);
214 if (anotherRealmWithSameName.isPresent() || anotherRealmWithSameAddr.isPresent()) {
218 if (anotherRealmWithSameName.isPresent()) {
221 if (anotherRealmWithSameAddr.isPresent()) {
226 }
catch (TskCoreException ex) {
257 if ((StringUtils.isBlank(sid) || sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID))
258 && StringUtils.isBlank(loginName)) {
259 throw new TskCoreException(
"Cannot create OS account with both uniqueId and loginName as null.");
262 if (!StringUtils.isBlank(sid) && !sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID) && !WindowsAccountUtils.isWindowsUserSid(sid)) {
267 String resolvedLoginName = WindowsAccountUtils.toWellknownEnglishLoginName(loginName);
273 String uniqueId = (!StringUtils.isBlank(sid) && !sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID)) ? sid : null;
274 if (!StringUtils.isBlank(sid) && !sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID) && isWindowsWellKnownSid(sid)) {
276 String wellKnownLoginName = WindowsAccountUtils.getWindowsWellKnownSidLoginName(sid);
277 if (!StringUtils.isEmpty(wellKnownLoginName)) {
278 resolvedLoginName = wellKnownLoginName;
285 if (!StringUtils.isBlank(sid) && !sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID) && isWindowsWellKnownSid(sid)) {
286 String fullName = getWindowsWellKnownSidFullName(sid);
287 if (StringUtils.isNotBlank(fullName)) {
297 }
catch (SQLException ex) {
303 Optional<OsAccount> osAccount;
306 if (!Strings.isNullOrEmpty(sid)) {
307 osAccount = getOsAccountByAddr(sid, realm);
308 if (osAccount.isPresent()) {
309 return osAccount.get();
314 if (!Strings.isNullOrEmpty(resolvedLoginName)) {
315 osAccount = getOsAccountByLoginName(resolvedLoginName, realm);
316 if (osAccount.isPresent()) {
317 return osAccount.get();
322 throw new TskCoreException(String.format(
"Error creating OsAccount with sid = %s, loginName = %s, realm = %s, referring host = %s",
323 (sid != null) ? sid :
"Null",
324 (resolvedLoginName != null) ? resolvedLoginName :
"Null",
354 if (referringHost == null) {
355 throw new TskCoreException(
"A referring host is required to create a local OS account.");
359 if (StringUtils.isBlank(uid) && StringUtils.isBlank(loginName)) {
360 throw new TskCoreException(
"Cannot create OS account with both uniqueId and loginName as null.");
374 }
catch (SQLException ex) {
380 Optional<OsAccount> osAccount;
383 if (!Strings.isNullOrEmpty(uid)) {
384 osAccount = getOsAccountByAddr(uid, localRealm);
385 if (osAccount.isPresent()) {
386 return osAccount.get();
391 if (!Strings.isNullOrEmpty(loginName)) {
392 osAccount = getOsAccountByLoginName(loginName, localRealm);
393 if (osAccount.isPresent()) {
394 return osAccount.get();
399 throw new TskCoreException(String.format(
"Error creating OsAccount with uid = %s, loginName = %s, realm = %s, referring host = %s",
400 (uid != null) ? uid :
"Null",
401 (loginName != null) ? loginName :
"Null",
429 if (Objects.isNull(realm)) {
430 throw new TskCoreException(
"Cannot create an OS Account, realm is NULL.");
433 String signature = getOsAccountSignature(uniqueId, loginName);
436 CaseDbConnection connection = trans.getConnection();
441 long parentObjId = 0;
443 int objTypeId = TskData.ObjectType.OS_ACCOUNT.getObjectType();
444 long osAccountObjId = db.addObject(parentObjId, objTypeId, connection);
446 String accountInsertSQL =
"INSERT INTO tsk_os_accounts(os_account_obj_id, login_name, realm_id, addr, signature, status)"
447 +
" VALUES (?, ?, ?, ?, ?, ?)";
449 PreparedStatement preparedStatement = connection.getPreparedStatement(accountInsertSQL, Statement.NO_GENERATED_KEYS);
450 preparedStatement.clearParameters();
452 preparedStatement.setLong(1, osAccountObjId);
454 preparedStatement.setString(2, loginName);
455 preparedStatement.setLong(3, realm.getRealmId());
457 preparedStatement.setString(4, uniqueId);
458 preparedStatement.setString(5, signature);
459 preparedStatement.setInt(6, accountStatus.getId());
461 connection.executeUpdate(preparedStatement);
463 account =
new OsAccount(db, osAccountObjId, realm.getRealmId(), loginName, uniqueId, signature,
464 null, null, null, accountStatus, OsAccount.OsAccountDbStatus.ACTIVE);
466 trans.registerAddedOsAccount(account);
481 private Optional<OsAccount> getOsAccountByAddr(String addr, Host host)
throws TskCoreException {
483 try (CaseDbConnection connection = db.getConnection()) {
484 return getOsAccountByAddr(addr, host, connection);
500 private Optional<OsAccount> getOsAccountByAddr(String uniqueId, Host host, CaseDbConnection connection)
throws TskCoreException {
502 String whereHostClause = (host == null)
504 :
" ( realms.scope_host_id = " + host.getHostId() +
" OR realms.scope_host_id IS NULL) ";
506 String queryString =
"SELECT accounts.os_account_obj_id as os_account_obj_id, accounts.login_name, accounts.full_name, "
507 +
" accounts.realm_id, accounts.addr, accounts.signature, "
508 +
" accounts.type, accounts.status, accounts.created_date, accounts.db_status, "
509 +
" realms.realm_name as realm_name, realms.realm_addr as realm_addr, realms.realm_signature, realms.scope_host_id, realms.scope_confidence, realms.db_status as realm_db_status "
510 +
" FROM tsk_os_accounts as accounts"
511 +
" LEFT JOIN tsk_os_account_realms as realms"
512 +
" ON accounts.realm_id = realms.id"
513 +
" WHERE " + whereHostClause
515 +
" AND LOWER(accounts.addr) = LOWER('" + uniqueId +
"')";
518 try (Statement s = connection.createStatement();
519 ResultSet rs = connection.executeQuery(s, queryString)) {
522 return Optional.empty();
524 return Optional.of(osAccountFromResultSet(rs));
526 }
catch (SQLException ex) {
527 throw new TskCoreException(String.format(
"Error getting OS account for unique id = %s and host = %s", uniqueId, (host != null ? host.getName() :
"null")), ex);
544 Optional<OsAccount> getOsAccountByAddr(String uniqueId, OsAccountRealm realm)
throws TskCoreException {
546 String queryString =
"SELECT * FROM tsk_os_accounts"
547 +
" WHERE LOWER(addr) = LOWER('" + uniqueId +
"')"
549 +
" AND realm_id = " + realm.getRealmId();
552 try (CaseDbConnection connection = this.db.getConnection();
553 Statement s = connection.createStatement();
554 ResultSet rs = connection.executeQuery(s, queryString)) {
557 return Optional.empty();
559 return Optional.of(osAccountFromResultSet(rs));
561 }
catch (SQLException ex) {
562 throw new TskCoreException(String.format(
"Error getting OS account for realm = %s and uniqueId = %s.", (realm != null) ? realm.getSignature() :
"NULL", uniqueId), ex);
579 Optional<OsAccount> getOsAccountByLoginName(String loginName, OsAccountRealm realm)
throws TskCoreException {
581 String queryString =
"SELECT * FROM tsk_os_accounts"
582 +
" WHERE LOWER(login_name) = LOWER('" + loginName +
"')"
584 +
" AND realm_id = " + realm.getRealmId();
587 try (CaseDbConnection connection = this.db.getConnection();
588 Statement s = connection.createStatement();
589 ResultSet rs = connection.executeQuery(s, queryString)) {
592 return Optional.empty();
594 return Optional.of(osAccountFromResultSet(rs));
596 }
catch (SQLException ex) {
597 throw new TskCoreException(String.format(
"Error getting OS account for realm = %s and loginName = %s.", (realm != null) ? realm.getSignature() :
"NULL", loginName), ex);
614 try (CaseDbConnection connection = this.db.getConnection()) {
631 String queryString =
"SELECT * FROM tsk_os_accounts"
632 +
" WHERE os_account_obj_id = " + osAccountObjId;
635 try (Statement s = connection.createStatement();
636 ResultSet rs = connection.executeQuery(s, queryString)) {
639 throw new TskCoreException(String.format(
"No account found with obj id = %d ", osAccountObjId));
641 return osAccountFromResultSet(rs);
643 }
catch (SQLException ex) {
644 throw new TskCoreException(String.format(
"Error getting account with obj id = %d ", osAccountObjId), ex);
675 if (osAccount == null) {
676 throw new TskCoreException(
"Cannot create account instance with null account.");
678 if (dataSource == null) {
679 throw new TskCoreException(
"Cannot create account instance with null data source.");
683 Optional<OsAccountInstance> existingInstance = cachedAccountInstance(osAccount.
getId(), dataSource.
getId(), instanceType);
684 if (existingInstance.isPresent()) {
685 return existingInstance.get();
688 try (CaseDbConnection connection = this.db.getConnection()) {
710 Optional<OsAccountInstance> existingInstance = cachedAccountInstance(osAccountId, dataSourceObjId, instanceType);
711 if (existingInstance.isPresent()) {
712 return existingInstance.get();
720 String accountInsertSQL = db.getInsertOrIgnoreSQL(
"INTO tsk_os_account_instances(os_account_obj_id, data_source_obj_id, instance_type)"
721 +
" VALUES (?, ?, ?)");
722 PreparedStatement preparedStatement = connection.getPreparedStatement(accountInsertSQL, Statement.RETURN_GENERATED_KEYS);
723 preparedStatement.clearParameters();
724 preparedStatement.setLong(1, osAccountId);
725 preparedStatement.setLong(2, dataSourceObjId);
726 preparedStatement.setInt(3, instanceType.getId());
727 connection.executeUpdate(preparedStatement);
728 try (ResultSet resultSet = preparedStatement.getGeneratedKeys();) {
729 if (resultSet.next()) {
730 OsAccountInstance accountInstance =
new OsAccountInstance(db, resultSet.getLong(1), osAccountId, dataSourceObjId, instanceType);
731 synchronized (osAcctInstancesCacheLock) {
732 OsAccountInstanceKey key =
new OsAccountInstanceKey(osAccountId, dataSourceObjId);
734 for (OsAccountInstance.OsAccountInstanceType type : OsAccountInstance.OsAccountInstanceType.values()) {
735 if (accountInstance.getInstanceType().compareTo(type) < 0) {
736 osAccountInstanceCache.remove(key);
740 osAccountInstanceCache.put(key, accountInstance);
757 db.fireTSKEvent(
new TskEvent.OsAcctInstancesAddedTskEvent(Collections.singletonList(accountInstance)));
759 return accountInstance;
764 Optional<OsAccountInstance> existingInstanceRetry = cachedAccountInstance(osAccountId, dataSourceObjId, instanceType);
765 if (existingInstanceRetry.isPresent()) {
766 return existingInstanceRetry.get();
770 }
catch (SQLException ex) {
771 throw new TskCoreException(String.format(
"Error adding OS account instance for OS account object id = %d, data source object id = %d", osAccountId, dataSourceObjId), ex);
779 String whereClause =
"tsk_os_account_instances.os_account_obj_id = " + osAccountId
780 +
"AND tsk_os_account_instances.data_source_obj_id = " + dataSourceObjId;
782 if (instances.isEmpty()) {
783 throw new TskCoreException(String.format(
"Could not get autogen key after row insert or reload instance for OS account instance. OS account object id = %d, data source object id = %d", osAccountId, dataSourceObjId));
786 OsAccountInstance accountInstance = instances.get(0);
787 synchronized (osAcctInstancesCacheLock) {
788 OsAccountInstanceKey key =
new OsAccountInstanceKey(osAccountId, dataSourceObjId);
790 for (OsAccountInstance.OsAccountInstanceType type : OsAccountInstance.OsAccountInstanceType.values()) {
791 if (accountInstance.getInstanceType().compareTo(type) < 0) {
792 osAccountInstanceCache.remove(key);
796 osAccountInstanceCache.put(key, accountInstance);
798 return accountInstance;
817 private Optional<OsAccountInstance> cachedAccountInstance(
long osAccountId,
long dataSourceObjId, OsAccountInstance.OsAccountInstanceType instanceType) {
826 synchronized (osAcctInstancesCacheLock) {
827 OsAccountInstanceKey key =
new OsAccountInstanceKey(osAccountId, dataSourceObjId);
828 OsAccountInstance instance = osAccountInstanceCache.get(key);
829 if (instance != null) {
831 if (instanceType.compareTo(instance.getInstanceType()) >= 0) {
832 return Optional.of(instance);
835 return Optional.empty();
849 String queryString =
"SELECT * FROM tsk_os_accounts accounts "
850 +
"WHERE accounts.os_account_obj_id IN "
851 +
"(SELECT instances.os_account_obj_id "
852 +
"FROM tsk_os_account_instances instances "
853 +
"INNER JOIN data_source_info datasources ON datasources.obj_id = instances.data_source_obj_id "
854 +
"WHERE datasources.host_id = " + host.getHostId() +
") "
858 try (CaseDbConnection connection = this.db.getConnection();
859 Statement s = connection.createStatement();
860 ResultSet rs = connection.executeQuery(s, queryString)) {
862 List<OsAccount> accounts =
new ArrayList<>();
864 accounts.add(osAccountFromResultSet(rs));
867 }
catch (SQLException ex) {
868 throw new TskCoreException(String.format(
"Error getting OS accounts for host id = %d", host.getHostId()), ex);
884 String queryString =
"SELECT * FROM tsk_os_accounts acc "
885 +
"WHERE acc.os_account_obj_id IN "
886 +
"(SELECT instance.os_account_obj_id "
887 +
"FROM tsk_os_account_instances instance "
888 +
"WHERE instance.data_source_obj_id = " + dataSourceId +
") "
892 try (CaseDbConnection connection = this.db.getConnection();
893 Statement s = connection.createStatement();
894 ResultSet rs = connection.executeQuery(s, queryString)) {
896 List<OsAccount> accounts =
new ArrayList<>();
898 accounts.add(osAccountFromResultSet(rs));
901 }
catch (SQLException ex) {
902 throw new TskCoreException(String.format(
"Error getting OS accounts for data source id = %d", dataSourceId), ex);
921 List<OsAccount> destinationAccounts =
getOsAccounts(destRealm, trans.getConnection());
922 List<OsAccount> sourceAccounts =
getOsAccounts(sourceRealm, trans.getConnection());
924 for (
OsAccount sourceAccount : sourceAccounts) {
931 if (sourceAccount.getAddr().isPresent() && sourceAccount.getLoginName().isPresent()) {
932 List<OsAccount> duplicateDestAccounts = destinationAccounts.stream()
933 .filter(p -> p.getAddr().equals(sourceAccount.getAddr())
934 || (p.getLoginName().equals(sourceAccount.getLoginName()) && (!p.getAddr().isPresent())))
935 .collect(Collectors.toList());
936 if (duplicateDestAccounts.size() > 1) {
937 OsAccount combinedDestAccount = duplicateDestAccounts.get(0);
938 duplicateDestAccounts.remove(combinedDestAccount);
939 for (
OsAccount dupeDestAccount : duplicateDestAccounts) {
940 mergeOsAccounts(dupeDestAccount, combinedDestAccount, trans);
946 Optional<OsAccount> matchingDestAccount = getMatchingAccountForMerge(sourceAccount, destinationAccounts);
949 if (matchingDestAccount.isPresent()) {
950 mergeOsAccounts(sourceAccount, matchingDestAccount.get(), trans);
952 String query =
"UPDATE tsk_os_accounts SET realm_id = " + destRealm.getRealmId() +
" WHERE os_account_obj_id = " + sourceAccount.getId();
953 try (Statement s = trans.getConnection().createStatement()) {
954 s.executeUpdate(query);
955 }
catch (SQLException ex) {
956 throw new TskCoreException(
"Error executing SQL update: " + query, ex);
958 trans.registerChangedOsAccount(sourceAccount);
969 private Optional<OsAccount> getMatchingAccountForMerge(OsAccount sourceAccount, List<OsAccount> destinationAccounts) {
971 OsAccount matchingDestAccount = null;
974 if (sourceAccount.getAddr().isPresent()) {
975 List<OsAccount> matchingDestAccounts = destinationAccounts.stream()
976 .filter(p -> p.getAddr().equals(sourceAccount.getAddr()))
977 .collect(Collectors.toList());
978 if (!matchingDestAccounts.isEmpty()) {
979 matchingDestAccount = matchingDestAccounts.get(0);
988 if (matchingDestAccount == null && sourceAccount.getLoginName().isPresent()) {
989 List<OsAccount> matchingDestAccounts = destinationAccounts.stream()
990 .filter(p -> p.getLoginName().isPresent())
991 .filter(p -> (p.getLoginName().get().equalsIgnoreCase(sourceAccount.getLoginName().get())
992 && ((!sourceAccount.getAddr().isPresent()) || (!p.getAddr().isPresent()))))
993 .collect(Collectors.toList());
994 if (!matchingDestAccounts.isEmpty()) {
995 matchingDestAccount = matchingDestAccounts.get(0);
999 return Optional.ofNullable(matchingDestAccount);
1009 private void mergeOsAccount(OsAccount account, CaseDbTransaction trans)
throws TskCoreException {
1015 List<OsAccount> osAccounts =
getOsAccounts(realm, trans.getConnection());
1016 osAccounts.removeIf(acc -> Objects.equals(acc.getId(), account.getId()));
1019 Optional<OsAccount> matchingAccount = getMatchingAccountForMerge(account, osAccounts);
1022 if (matchingAccount.isPresent()) {
1023 mergeOsAccounts(matchingAccount.get(), account, trans);
1041 private void mergeOsAccounts(OsAccount sourceAccount, OsAccount destAccount, CaseDbTransaction trans)
throws TskCoreException {
1044 try (Statement s = trans.getConnection().createStatement()) {
1047 query = makeOsAccountUpdateQuery(
"tsk_os_account_attributes", sourceAccount, destAccount);
1048 s.executeUpdate(query);
1052 query =
"DELETE FROM tsk_os_account_instances "
1055 +
" sourceAccountInstance.id "
1057 +
" tsk_os_account_instances destAccountInstance "
1058 +
"INNER JOIN tsk_os_account_instances sourceAccountInstance ON destAccountInstance.data_source_obj_id = sourceAccountInstance.data_source_obj_id "
1059 +
"WHERE destAccountInstance.os_account_obj_id = " + destAccount.getId()
1060 +
" AND sourceAccountInstance.os_account_obj_id = " + sourceAccount.getId()
1061 +
" AND sourceAccountInstance.instance_type = destAccountInstance.instance_type" +
")";
1063 s.executeUpdate(query);
1065 query = makeOsAccountUpdateQuery(
"tsk_os_account_instances", sourceAccount, destAccount);
1066 s.executeUpdate(query);
1067 synchronized (osAcctInstancesCacheLock) {
1068 osAccountInstanceCache.clear();
1071 query = makeOsAccountUpdateQuery(
"tsk_files", sourceAccount, destAccount);
1072 s.executeUpdate(query);
1074 query = makeOsAccountUpdateQuery(
"tsk_data_artifacts", sourceAccount, destAccount);
1075 s.executeUpdate(query);
1079 trans.registerMergedOsAccount(sourceAccount.getId(), destAccount.getId());
1082 String mergedSignature = makeMergedOsAccountSignature();
1083 query =
"UPDATE tsk_os_accounts SET merged_into = " + destAccount.getId()
1084 +
", db_status = " + OsAccount.OsAccountDbStatus.MERGED.getId()
1085 +
", signature = '" + mergedSignature +
"' "
1086 +
" WHERE os_account_obj_id = " + sourceAccount.getId();
1088 s.executeUpdate(query);
1089 trans.registerDeletedOsAccount(sourceAccount.getId());
1094 mergeOsAccountObjectsAndUpdateDestAccount(sourceAccount, destAccount, trans);
1095 }
catch (SQLException ex) {
1096 throw new TskCoreException(
"Error executing SQL update: " + query, ex);
1105 private String makeMergedOsAccountSignature() {
1106 return "MERGED " + UUID.randomUUID().toString();
1118 private String makeOsAccountUpdateQuery(String tableName, OsAccount sourceAccount, OsAccount destAccount) {
1119 return "UPDATE " + tableName +
" SET os_account_obj_id = " + destAccount.getId() +
" WHERE os_account_obj_id = " + sourceAccount.getId();
1133 private OsAccount mergeOsAccountObjectsAndUpdateDestAccount(OsAccount sourceAccount, OsAccount destAccount, CaseDbTransaction trans)
throws TskCoreException {
1135 OsAccount mergedDestAccount = destAccount;
1137 String destLoginName = null;
1138 String destAddr = null;
1141 if (!destAccount.getLoginName().isPresent() && sourceAccount.getLoginName().isPresent()) {
1145 if (!destAccount.getAddr().isPresent() && sourceAccount.getAddr().isPresent()) {
1146 destAddr = sourceAccount.getAddr().get();
1150 OsAccountUpdateResult updateStatus = this.updateOsAccountCore(destAccount, destAddr, destLoginName, trans);
1152 if (updateStatus.getUpdateStatusCode() == OsAccountUpdateStatus.UPDATED && updateStatus.getUpdatedAccount().isPresent()) {
1153 mergedDestAccount = updateStatus.getUpdatedAccount().get();
1156 String destFullName = null;
1157 Long destCreationTime = null;
1158 if (!destAccount.getFullName().isPresent() && sourceAccount.getFullName().isPresent()) {
1159 destFullName = sourceAccount.getFullName().get();
1162 if (!destAccount.getCreationTime().isPresent() && sourceAccount.getCreationTime().isPresent()) {
1163 destCreationTime = sourceAccount.getCreationTime().get();
1169 if (updateStatus.getUpdateStatusCode() == OsAccountUpdateStatus.UPDATED && updateStatus.getUpdatedAccount().isPresent()) {
1170 mergedDestAccount = updateStatus.getUpdatedAccount().get();
1173 return mergedDestAccount;
1186 private List<OsAccount>
getOsAccounts(OsAccountRealm realm, CaseDbConnection connection)
throws TskCoreException {
1187 String queryString =
"SELECT * FROM tsk_os_accounts"
1189 +
" AND db_status = " + OsAccount.OsAccountDbStatus.ACTIVE.getId()
1190 +
" ORDER BY os_account_obj_id";
1192 try (Statement s = connection.createStatement();
1193 ResultSet rs = connection.executeQuery(s, queryString)) {
1195 List<OsAccount> accounts =
new ArrayList<>();
1197 accounts.add(osAccountFromResultSet(rs));
1200 }
catch (SQLException ex) {
1201 throw new TskCoreException(String.format(
"Error getting OS accounts for realm id = %d", realm.getRealmId()), ex);
1213 String queryString =
"SELECT * FROM tsk_os_accounts"
1217 try (CaseDbConnection connection = this.db.getConnection();
1218 Statement s = connection.createStatement();
1219 ResultSet rs = connection.executeQuery(s, queryString)) {
1221 List<OsAccount> accounts =
new ArrayList<>();
1223 accounts.add(osAccountFromResultSet(rs));
1226 }
catch (SQLException ex) {
1227 throw new TskCoreException(String.format(
"Error getting OS accounts"), ex);
1250 if (referringHost == null) {
1251 throw new TskCoreException(
"A referring host is required to get an account.");
1255 if ((StringUtils.isBlank(sid) || (sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID)) ) && StringUtils.isBlank(loginName)) {
1256 throw new TskCoreException(
"Cannot get an OS account with both SID and loginName as null.");
1260 if (StringUtils.isBlank(sid)
1261 && !StringUtils.isBlank(loginName) && !StringUtils.isBlank(realmName)
1262 && WindowsAccountUtils.isWindowsWellKnownAccountName(loginName, realmName)) {
1263 sid = WindowsAccountUtils.getWindowsWellKnownAccountSid(loginName, realmName);
1269 if (!realm.isPresent()) {
1270 return Optional.empty();
1274 if (!Strings.isNullOrEmpty(sid) && !(sid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID))) {
1275 if (!WindowsAccountUtils.isWindowsUserSid(sid)) {
1279 Optional<OsAccount> account = this.getOsAccountByAddr(sid, realm.get());
1280 if (account.isPresent()) {
1286 if (!Strings.isNullOrEmpty(loginName)) {
1287 String resolvedLoginName = WindowsAccountUtils.toWellknownEnglishLoginName(loginName);
1288 return this.getOsAccountByLoginName(resolvedLoginName, realm.get());
1290 return Optional.empty();
1309 if (referringHost == null) {
1310 throw new TskCoreException(
"A referring host is required to get an account.");
1314 if (StringUtils.isBlank(uid) && StringUtils.isBlank(loginName)) {
1315 throw new TskCoreException(
"Cannot get an OS account with both UID and loginName as null.");
1320 if (!realm.isPresent()) {
1321 return Optional.empty();
1325 if (!Strings.isNullOrEmpty(uid)) {
1326 Optional<OsAccount> account = this.getOsAccountByAddr(uid, realm.get());
1327 if (account.isPresent()) {
1333 if (!Strings.isNullOrEmpty(loginName)) {
1334 return this.getOsAccountByLoginName(loginName, realm.get());
1336 return Optional.empty();
1351 synchronized (account) {
1354 try (CaseDbConnection connection = db.getConnection()) {
1357 String attributeInsertSQL =
"INSERT INTO tsk_os_account_attributes(os_account_obj_id, host_id, source_obj_id, attribute_type_id, value_type, value_byte, value_text, value_int32, value_int64, value_double)"
1358 +
" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
1360 PreparedStatement preparedStatement = connection.getPreparedStatement(attributeInsertSQL, Statement.RETURN_GENERATED_KEYS);
1361 preparedStatement.clearParameters();
1363 preparedStatement.setLong(1, account.getId());
1364 if (accountAttribute.getHostId().isPresent()) {
1365 preparedStatement.setLong(2, accountAttribute.getHostId().get());
1367 preparedStatement.setNull(2, java.sql.Types.NULL);
1369 if (accountAttribute.getSourceObjectId().isPresent()) {
1370 preparedStatement.setLong(3, accountAttribute.getSourceObjectId().get());
1372 preparedStatement.setNull(3, java.sql.Types.NULL);
1375 preparedStatement.setLong(4, accountAttribute.getAttributeType().getTypeID());
1376 preparedStatement.setLong(5, accountAttribute.getAttributeType().getValueType().getType());
1379 preparedStatement.setBytes(6, accountAttribute.getValueBytes());
1381 preparedStatement.setBytes(6, null);
1386 preparedStatement.setString(7, accountAttribute.getValueString());
1388 preparedStatement.setString(7, null);
1391 preparedStatement.setInt(8, accountAttribute.getValueInt());
1393 preparedStatement.setNull(8, java.sql.Types.NULL);
1398 preparedStatement.setLong(9, accountAttribute.getValueLong());
1400 preparedStatement.setNull(9, java.sql.Types.NULL);
1404 preparedStatement.setDouble(10, accountAttribute.getValueDouble());
1406 preparedStatement.setNull(10, java.sql.Types.NULL);
1409 connection.executeUpdate(preparedStatement);
1411 }
catch (SQLException ex) {
1412 throw new TskCoreException(String.format(
"Error adding OS Account attribute for account id = %d", account.getId()), ex);
1417 List<OsAccountAttribute> currentAttribsList = getOsAccountAttributes(account);
1418 account.setAttributesInternal(currentAttribsList);
1420 fireChangeEvent(account);
1432 List<OsAccountAttribute> getOsAccountAttributes(
OsAccount account)
throws TskCoreException {
1434 String queryString =
"SELECT attributes.os_account_obj_id as os_account_obj_id, attributes.host_id as host_id, attributes.source_obj_id as source_obj_id, "
1435 +
" attributes.attribute_type_id as attribute_type_id, attributes.value_type as value_type, attributes.value_byte as value_byte, "
1436 +
" attributes.value_text as value_text, attributes.value_int32 as value_int32, attributes.value_int64 as value_int64, attributes.value_double as value_double, "
1437 +
" hosts.id, hosts.name as host_name, hosts.db_status as host_status "
1438 +
" FROM tsk_os_account_attributes as attributes"
1439 +
" LEFT JOIN tsk_hosts as hosts "
1440 +
" ON attributes.host_id = hosts.id "
1441 +
" WHERE os_account_obj_id = " + account.getId();
1444 try (CaseDbConnection connection = this.db.getConnection();
1445 Statement s = connection.createStatement();
1446 ResultSet rs = connection.executeQuery(s, queryString)) {
1448 List<OsAccountAttribute> attributes =
new ArrayList<>();
1452 long hostId = rs.getLong(
"host_id");
1453 if (!rs.wasNull()) {
1454 host =
new Host(hostId, rs.getString(
"host_name"),
Host.
HostDbStatus.fromID(rs.getInt(
"host_status")));
1457 Content sourceContent = null;
1458 long sourceObjId = rs.getLong(
"source_obj_id");
1459 if (!rs.wasNull()) {
1463 OsAccountAttribute attribute = account.new OsAccountAttribute(attributeType, rs.getInt(
"value_int32"), rs.getLong(
"value_int64"),
1464 rs.getDouble(
"value_double"), rs.getString(
"value_text"), rs.getBytes(
"value_byte"),
1465 db, account, host, sourceContent);
1467 attributes.add(attribute);
1470 }
catch (SQLException ex) {
1471 throw new TskCoreException(String.format(
"Error getting OS account attributes for account obj id = %d", account.getId()), ex);
1487 String whereClause =
"tsk_os_account_instances.os_account_obj_id = " + account.getId();
1502 String instanceIds = instanceIDs.stream().map(
id ->
id.toString()).collect(Collectors.joining(
","));
1504 List<OsAccountInstance> osAcctInstances =
new ArrayList<>();
1506 String querySQL =
"SELECT * FROM tsk_os_account_instances "
1507 +
" WHERE tsk_os_account_instances.id IN (" + instanceIds +
")";
1510 try (CaseDbConnection connection = db.getConnection();
1511 PreparedStatement preparedStatement = connection.getPreparedStatement(querySQL, Statement.NO_GENERATED_KEYS);
1512 ResultSet results = connection.executeQuery(preparedStatement)) {
1514 osAcctInstances = getOsAccountInstancesFromResultSet(results);
1516 }
catch (SQLException ex) {
1517 throw new TskCoreException(
"Failed to get OsAccountInstances (SQL = " + querySQL +
")", ex);
1521 return osAcctInstances;
1538 List<OsAccountInstance> osAcctInstances =
new ArrayList<>();
1541 =
"SELECT tsk_os_account_instances.* "
1542 +
" FROM tsk_os_account_instances "
1543 +
" INNER JOIN ( SELECT os_account_obj_id, data_source_obj_id, MIN(instance_type) AS min_instance_type "
1544 +
" FROM tsk_os_account_instances"
1545 +
" GROUP BY os_account_obj_id, data_source_obj_id ) grouped_instances "
1546 +
" ON tsk_os_account_instances.os_account_obj_id = grouped_instances.os_account_obj_id "
1547 +
" AND tsk_os_account_instances.instance_type = grouped_instances.min_instance_type "
1548 +
" WHERE " + whereClause;
1551 try (CaseDbConnection connection = db.getConnection();
1552 PreparedStatement preparedStatement = connection.getPreparedStatement(querySQL, Statement.NO_GENERATED_KEYS);
1553 ResultSet results = connection.executeQuery(preparedStatement)) {
1555 osAcctInstances = getOsAccountInstancesFromResultSet(results);
1557 }
catch (SQLException ex) {
1558 throw new TskCoreException(
"Failed to get OsAccountInstances (SQL = " + querySQL +
")", ex);
1562 return osAcctInstances;
1574 private List<OsAccountInstance> getOsAccountInstancesFromResultSet(ResultSet results)
throws SQLException {
1576 List<OsAccountInstance> osAcctInstances =
new ArrayList<>();
1577 while (results.next()) {
1578 long instanceId = results.getLong(
"id");
1579 long osAccountObjID = results.getLong(
"os_account_obj_id");
1580 long dataSourceObjId = results.getLong(
"data_source_obj_id");
1581 int instanceType = results.getInt(
"instance_type");
1582 osAcctInstances.add(
new OsAccountInstance(db, instanceId, osAccountObjID, dataSourceObjId, OsAccountInstance.OsAccountInstanceType.fromID(instanceType)));
1585 return osAcctInstances;
1613 return updateStatus;
1615 if (trans != null) {
1640 OsAccountUpdateStatus updateStatusCode = OsAccountUpdateStatus.NO_CHANGE;
1643 CaseDbConnection connection = trans.getConnection();
1645 if (!StringUtils.isBlank(fullName)) {
1646 updateAccountColumn(osAccount.getId(),
"full_name", fullName, connection);
1647 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1650 if (Objects.nonNull(accountType)) {
1651 updateAccountColumn(osAccount.getId(),
"type", accountType.getId(), connection);
1652 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1655 if (Objects.nonNull(accountStatus)) {
1656 updateAccountColumn(osAccount.getId(),
"status", accountStatus.getId(), connection);
1657 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1660 if (Objects.nonNull(creationTime)) {
1661 updateAccountColumn(osAccount.getId(),
"created_date", creationTime, connection);
1662 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1666 if (updateStatusCode == OsAccountUpdateStatus.NO_CHANGE) {
1667 return new OsAccountUpdateResult(updateStatusCode, null);
1674 trans.registerChangedOsAccount(updatedAccount);
1676 return new OsAccountUpdateResult(updateStatusCode, updatedAccount);
1678 }
catch (SQLException ex) {
1679 throw new TskCoreException(String.format(
"Error updating account with addr = %s, account id = %d", osAccount.getAddr().orElse(
"Unknown"), osAccount.getId()), ex);
1696 private <T>
void updateAccountColumn(
long accountObjId, String colName, T colValue, CaseDbConnection connection)
throws SQLException, TskCoreException {
1698 String updateSQL =
"UPDATE tsk_os_accounts "
1699 +
" SET " + colName +
" = ? "
1700 +
" WHERE os_account_obj_id = ?";
1704 PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
1705 preparedStatement.clearParameters();
1707 if (Objects.isNull(colValue)) {
1708 preparedStatement.setNull(1, Types.NULL);
1710 if (colValue instanceof String) {
1711 preparedStatement.setString(1, (String) colValue);
1712 }
else if (colValue instanceof Long) {
1713 preparedStatement.setLong(1, (Long) colValue);
1714 }
else if (colValue instanceof Integer) {
1715 preparedStatement.setInt(1, (Integer) colValue);
1717 throw new TskCoreException(String.format(
"Unhandled column data type received while updating the account (%d) ", accountObjId));
1721 preparedStatement.setLong(2, accountObjId);
1723 connection.executeUpdate(preparedStatement);
1739 private void updateAccountSignature(
long accountObjId, String signature, CaseDbConnection connection)
throws SQLException {
1741 String updateSQL =
"UPDATE tsk_os_accounts SET "
1743 +
" CASE WHEN db_status = " + OsAccount.OsAccountDbStatus.ACTIVE.getId() +
" THEN ? ELSE signature END "
1744 +
" WHERE os_account_obj_id = ?";
1746 PreparedStatement preparedStatement = connection.getPreparedStatement(updateSQL, Statement.NO_GENERATED_KEYS);
1747 preparedStatement.clearParameters();
1749 preparedStatement.setString(1, signature);
1750 preparedStatement.setLong(2, accountObjId);
1752 connection.executeUpdate(preparedStatement);
1782 return updateStatus;
1784 if (trans != null) {
1813 if ((!StringUtils.isBlank(accountSid) && !accountSid.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID)) || !StringUtils.isBlank(realmName)) {
1815 String resolvedRealmName = WindowsAccountUtils.toWellknownEnglishRealmName(realmName);
1821 Optional<OsAccountRealm> realmOptional = realmUpdateResult.
getUpdatedRealm();
1823 if (realmOptional.isPresent()) {
1830 Optional<OsAccountRealm> anotherRealmWithSameName = db.
getOsAccountRealmManager().getAnotherRealmByName(realmOptional.get(), realmName, referringHost, trans.getConnection());
1833 Optional<OsAccountRealm> anotherRealmWithSameAddr = db.
getOsAccountRealmManager().getAnotherRealmByAddr(realmOptional.get(), realmName, referringHost, trans.getConnection());
1835 if (anotherRealmWithSameName.isPresent()) {
1838 if (anotherRealmWithSameAddr.isPresent()) {
1846 String resolvedLoginName = WindowsAccountUtils.toWellknownEnglishLoginName(loginName);
1847 OsAccountUpdateResult updateStatus = this.updateOsAccountCore(osAccount, accountSid, resolvedLoginName, trans);
1849 Optional<OsAccount> updatedAccount = updateStatus.getUpdatedAccount();
1850 if (updatedAccount.isPresent()) {
1852 mergeOsAccount(updatedAccount.get(), trans);
1855 return updateStatus;
1882 return updateStatus;
1884 if (trans != null) {
1911 OsAccountUpdateResult updateStatus = this.updateOsAccountCore(osAccount, uid, loginName, trans);
1913 Optional<OsAccount> updatedAccount = updateStatus.getUpdatedAccount();
1914 if (updatedAccount.isPresent()) {
1916 mergeOsAccount(updatedAccount.get(), trans);
1919 return updateStatus;
1944 private OsAccountUpdateResult updateOsAccountCore(OsAccount osAccount, String address, String loginName, CaseDbTransaction trans)
throws TskCoreException {
1946 OsAccountUpdateStatus updateStatusCode = OsAccountUpdateStatus.NO_CHANGE;
1947 OsAccount updatedAccount;
1950 CaseDbConnection connection = trans.getConnection();
1953 if (!StringUtils.isBlank(address) && !address.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID) && !StringUtils.isBlank(osAccount.getAddr().orElse(null)) && !address.equalsIgnoreCase(osAccount.getAddr().orElse(
""))) {
1954 throw new TskCoreException(String.format(
"Account (%d) already has an address (%s), address cannot be updated.", osAccount.getId(), osAccount.getAddr().orElse(
"NULL")));
1957 if (StringUtils.isBlank(osAccount.getAddr().orElse(null)) && !StringUtils.isBlank(address) && !address.equalsIgnoreCase(WindowsAccountUtils.WINDOWS_NULL_SID)) {
1958 updateAccountColumn(osAccount.getId(),
"addr", address, connection);
1959 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1962 if (StringUtils.isBlank(osAccount.getLoginName().orElse(null)) && !StringUtils.isBlank(loginName)) {
1963 updateAccountColumn(osAccount.getId(),
"login_name", loginName, connection);
1964 updateStatusCode = OsAccountUpdateStatus.UPDATED;
1968 if (updateStatusCode == OsAccountUpdateStatus.NO_CHANGE) {
1969 return new OsAccountUpdateResult(updateStatusCode, osAccount);
1974 String newAddress = currAccount.
getAddr().orElse(null);
1975 String newLoginName = currAccount.getLoginName().orElse(null);
1977 String newSignature = getOsAccountSignature(newAddress, newLoginName);
1980 updateAccountSignature(osAccount.getId(), newSignature, connection);
1981 }
catch (SQLException ex) {
1990 if (osAccount.getAddr().isEmpty() && !StringUtils.isBlank(address)) {
1992 Optional<OsAccount> matchingAddrAcct = getOsAccountByAddr(address, realm.getScopeHost().get(), connection);
1993 if (matchingAddrAcct.isEmpty()
1994 || matchingAddrAcct.get().getId() == osAccount.getId()
1995 || matchingAddrAcct.get().getLoginName().isPresent()) {
2001 mergeOsAccounts(matchingAddrAcct.get(), osAccount, trans);
2009 trans.registerChangedOsAccount(updatedAccount);
2011 return new OsAccountUpdateResult(updateStatusCode, updatedAccount);
2013 }
catch (SQLException ex) {
2014 throw new TskCoreException(String.format(
"Error updating account with unique id = %s, account id = %d", osAccount.getAddr().orElse(
"Unknown"), osAccount.getId()), ex);
2028 List<Host> hostList =
new ArrayList<>();
2030 String query =
"SELECT tsk_hosts.id AS hostId, name, db_status FROM tsk_hosts "
2031 +
" JOIN data_source_info ON tsk_hosts.id = data_source_info.host_id"
2032 +
" JOIN tsk_os_account_instances ON data_source_info.obj_id = tsk_os_account_instances.data_source_obj_id"
2033 +
" WHERE os_account_obj_id = " + account.getId();
2036 try (CaseDbConnection connection = db.getConnection();
2037 Statement s = connection.createStatement();
2038 ResultSet rs = connection.executeQuery(s, query)) {
2041 hostList.add(
new Host(rs.getLong(
"hostId"), rs.getString(
"name"),
Host.
HostDbStatus.fromID(rs.getInt(
"db_status"))));
2044 }
catch (SQLException ex) {
2045 throw new TskCoreException(String.format(
"Failed to get host list for os account %d", account.getId()), ex);
2063 private OsAccount osAccountFromResultSet(ResultSet rs)
throws SQLException {
2066 int typeId = rs.getInt(
"type");
2067 if (!rs.wasNull()) {
2071 Long creationTime = rs.getLong(
"created_date");
2073 creationTime = null;
2076 return new OsAccount(db, rs.getLong(
"os_account_obj_id"), rs.getLong(
"realm_id"), rs.getString(
"login_name"), rs.getString(
"addr"),
2077 rs.getString(
"signature"), rs.getString(
"full_name"), creationTime, accountType, OsAccount.OsAccountStatus.
fromID(rs.getInt(
"status")),
2078 OsAccount.OsAccountDbStatus.
fromID(rs.getInt(
"db_status")));
2088 private void fireChangeEvent(OsAccount account) {
2089 db.fireTSKEvent(
new OsAccountsUpdatedTskEvent(Collections.singletonList(account)));
2106 static String getOsAccountSignature(String uniqueId, String loginName)
throws TskCoreException {
2109 if (Strings.isNullOrEmpty(uniqueId) ==
false) {
2110 signature = uniqueId;
2111 }
else if (Strings.isNullOrEmpty(loginName) ==
false) {
2112 signature = loginName;
2114 throw new TskCoreException(
"OS Account must have either a uniqueID or a login name.");
2125 private static final long serialVersionUID = 1L;
2131 super(
"No error message available.");
2174 this.updateStatus = updateStatus;
2175 this.updatedAccount = updatedAccount;
2179 return updateStatus;
2183 return Optional.ofNullable(updatedAccount);
2191 private class OsAccountInstanceKey
implements Comparable<OsAccountInstanceKey>{
2193 private final long osAccountId;
2194 private final long dataSourceId;
2196 OsAccountInstanceKey(
long osAccountId,
long dataSourceId) {
2197 this.osAccountId = osAccountId;
2198 this.dataSourceId = dataSourceId;
2202 public boolean equals(Object other) {
2203 if (
this == other) {
2206 if (other == null) {
2209 if (getClass() != other.getClass()) {
2213 final OsAccountInstanceKey otherKey = (OsAccountInstanceKey) other;
2215 if (osAccountId != otherKey.osAccountId) {
2219 return dataSourceId == otherKey.dataSourceId;
2223 public int hashCode() {
2225 hash = 53 * hash + (int) (this.osAccountId ^ (this.osAccountId >>> 32));
2226 hash = 53 * hash + (int) (this.dataSourceId ^ (this.dataSourceId >>> 32));
2231 public int compareTo(OsAccountInstanceKey other) {
2232 if(this.equals(other)) {
2236 if (dataSourceId != other.dataSourceId) {
2237 return Long.compare(dataSourceId, other.dataSourceId);
2240 return Long.compare(osAccountId, other.osAccountId);
NotUserSIDException(String msg, Exception ex)
List< OsAccount > getOsAccounts()
Optional< String > getAddr()
OsAccountRealm newWindowsRealm(String accountSid, String realmName, Host referringHost, OsAccountRealm.RealmScope realmScope)
CaseDbTransaction beginTransaction()
List< Host > getHosts(OsAccount account)
OsAccount getOsAccountByObjectId(long osAccountObjId)
Optional< OsAccountRealm > getUpdatedRealm()
static OsAccountType fromID(int typeId)
OsAccountRealm newLocalLinuxRealm(Host referringHost)
Blackboard getBlackboard()
Optional< OsAccount > getWindowsOsAccount(String sid, String loginName, String realmName, Host referringHost)
OsAccountUpdateStatus getUpdateStatusCode()
OsAccountUpdateResult updateStandardOsAccountAttributes(OsAccount osAccount, String fullName, OsAccountType accountType, OsAccountStatus accountStatus, Long creationTime)
Content getContentById(long id)
OsAccount newWindowsOsAccount(String sid, String loginName, OsAccountRealm realm)
NotUserSIDException(String msg)
List< OsAccount > getOsAccounts(Host host)
Optional< OsAccount > getLocalLinuxOsAccount(String uid, String loginName, Host referringHost)
Optional< OsAccountRealm > getLocalLinuxRealm(Host referringHost)
OsAccountRealmManager getOsAccountRealmManager()
OsAccount newLocalLinuxOsAccount(String uid, String loginName, Host referringHost)
void releaseSingleUserCaseReadLock()
Optional< OsAccountRealm > getWindowsRealm(String accountSid, String realmName, Host referringHost)
List< OsAccount > getOsAccountsByDataSourceObjId(long dataSourceId)
List< OsAccountInstance > getOsAccountInstances(List< Long > instanceIDs)
void acquireSingleUserCaseWriteLock()
OsAccountInstance newOsAccountInstance(OsAccount osAccount, DataSource dataSource, OsAccountInstance.OsAccountInstanceType instanceType)
void releaseSingleUserCaseWriteLock()
List< OsAccountInstance > getOsAccountInstances(OsAccount account)
UPDATED
no change was made to account.
Optional< String > getLoginName()
Optional< Host > getScopeHost()
void acquireSingleUserCaseReadLock()
UPDATED
no change was made to account.
void addExtendedOsAccountAttributes(OsAccount account, List< OsAccountAttribute > accountAttributes)
OsAccountRealm getRealmByRealmId(long id)
BlackboardAttribute.Type getAttributeType(String attrTypeName)
OsRealmUpdateStatus getUpdateStatus()
Optional< OsAccount > getUpdatedAccount()
OsAccountUpdateResult updateCoreLocalLinuxOsAccountAttributes(OsAccount osAccount, String uid, String loginName)
OsAccountUpdateResult updateCoreWindowsOsAccountAttributes(OsAccount osAccount, String accountSid, String loginName, String realmName, Host referringHost)
OsAccount newWindowsOsAccount(String sid, String loginName, String realmName, Host referringHost, OsAccountRealm.RealmScope realmScope)
List< String > getRealmNames()