/** Return the user's secure_hash_key. If one wasn't found create one on the fly. */ private SecureHashKeyResult getSecureHashKey(UserAccount user, Connection c) throws SQLException { PreparedStatement select = null; // Create lazily. PreparedStatement update = null; int userId = user.getUserID(); boolean justCreated = false; byte[] key = null; try { // TODO: consider having UserManager returning secure_hash_key. // TODO: We have similar logic in several places for creating secure_hash_key just-in-time. // D.R.Y. this out. Sorry I couldn't resist using this cliche :) select = c.prepareStatement("SELECT secure_hash_key FROM dat_user_account WHERE object_id=?"); select.setInt(1, userId); ResultSet rs = select.executeQuery(); if (!rs.next()) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("dat_user_account row not found"); lmg.param(LoggingConsts.USER_ID, userId); // possible that the user simply disappeared by the time we got here. m_logCategory.warn(lmg.toString()); } else { key = rs.getBytes(1); if (key == null || key.length == 0) { // hash key not found; create one on the fly. update = c.prepareStatement("UPDATE dat_user_account SET secure_hash_key=? WHERE object_id=?"); key = createNewRandomKey(); update.setBytes(1, key); update.setInt(2, userId); int ct = update.executeUpdate(); if (ct != 1) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Unable to update dat_user_account.secure_hash_key"); lmg.param(LoggingConsts.USER_ID, userId); m_logCategory.error(lmg.toString()); } else { justCreated = true; } } // needed to set key. } // user found } finally { DbUtils.safeClose(select); DbUtils.safeClose(update); } return new SecureHashKeyResult(key, justCreated); }
@Override public Operation getOperation(int operationId) throws OperationManagementDAOException { PreparedStatement stmt = null; ResultSet rs = null; PolicyOperation policyOperation = null; ByteArrayInputStream bais; ObjectInputStream ois; try { Connection conn = OperationManagementDAOFactory.getConnection(); String sql = "SELECT OPERATION_ID, ENABLED, OPERATION_DETAILS FROM DM_POLICY_OPERATION WHERE OPERATION_ID=?"; stmt = conn.prepareStatement(sql); stmt.setInt(1, operationId); rs = stmt.executeQuery(); if (rs.next()) { byte[] operationDetails = rs.getBytes("OPERATION_DETAILS"); bais = new ByteArrayInputStream(operationDetails); ois = new ObjectInputStream(bais); policyOperation = (PolicyOperation) ois.readObject(); } } catch (IOException e) { throw new OperationManagementDAOException( "IO Error occurred while de serialize the policy operation " + "object", e); } catch (ClassNotFoundException e) { throw new OperationManagementDAOException( "Class not found error occurred while de serialize the " + "policy operation object", e); } catch (SQLException e) { throw new OperationManagementDAOException( "SQL Error occurred while retrieving the policy operation " + "object available for the id '" + operationId + "'", e); } finally { OperationManagementDAOUtil.cleanupResources(stmt, rs); } return policyOperation; }
public void setKeyCreatingIfNeeded( List<? extends IClientInfo> clients, List<IClientInfo> clientsNeedingSignalUpdate, Connection c) throws SQLException { PreparedStatement select = null; // Create lazily. PreparedStatement update = null; try { select = c.prepareStatement("SELECT secure_hash_key FROM dat_user_account WHERE object_id=?"); for (IClientInfo client : clients) { int userId = client.getUserId(); // ensure dat_user_account.secure_hash_key is filled. select.setInt(1, userId); ResultSet rs = select.executeQuery(); if (!rs.next()) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("dat_user_account row not found"); lmg.param(LoggingConsts.USER_ID, userId); // possible that the user simply disappeared by the time we got here. m_logCategory.warn(lmg.toString()); continue; } boolean firstTimeCreate = false; byte[] key = rs.getBytes(1); if (key == null || key.length == 0) { if (update == null) { update = c.prepareStatement( "UPDATE dat_user_account SET secure_hash_key=? WHERE object_id=?"); } key = createNewRandomKey(); update.setBytes(1, key); update.setInt(2, userId); int ct = update.executeUpdate(); if (ct != 1) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Unable to update dat_user_account.secure_hash_key"); lmg.param(LoggingConsts.USER_ID, userId); m_logCategory.error(lmg.toString()); continue; } else { firstTimeCreate = true; } } // no existing key. client.getHashSupport().setHashKey(key); if (firstTimeCreate) { if (clientsNeedingSignalUpdate != null) { // EMSDEV-7854. Don't actually do // updateSignalFiles(client) right here; we want to avoid nfs usage in the middle of a // db // transaction. clientsNeedingSignalUpdate.add(client); } } } // each client. } finally { DbUtils.safeClose(select); DbUtils.safeClose(update); } }
/** Writes user state information to the shared filesystem */ private void updateStateCache( Customer customer, int transitionId, CustomerState newState, Connection c) throws SQLException { PreparedStatement pst = null; ResultSet rs = null; try { pst = c.prepareStatement( "SELECT u.secure_hash_key, u.object_id, u.user_state, u.is_deleted, u.last_activation_id " + "FROM dat_user_account u, dat_transition_users tr " + "WHERE u.object_id = tr.user_id AND u.customer_id=? " + "AND tr.transition_id=?;"); // The state files are used by Outlook, BB, and maybe future clients. pst.setInt(1, customer.getCustID()); pst.setInt(2, transitionId); rs = pst.executeQuery(); while (rs.next()) { int i = 0; byte[] key = rs.getBytes(++i); int userId = rs.getInt(++i); CustomerState state = CustomerState.fromInt(rs.getInt(++i)); int isDeletedInt = rs.getInt(++i); int lastActivationId = rs.getInt(++i); // If the user is marked deleted but has a key, we'll try cleaning // up state files. boolean isDeleted = isDeletedInt != IUserManager.USER_NOT_DELETED; if (key == null || key.length == 0) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("dat_user_account.secure_hash_key not set"); lmg.param(LoggingConsts.USER_ID, userId); m_logCategory.info(lmg.toString()); // Without a key, we can't determine the signal filenames // so no cleanup is possible. continue; } ClientHashSupport hash = null; hash = new ClientHashSupport(); hash.setCustomerId(customer.getCustID()); hash.setUserId(userId); hash.setHashKey(key); hash.setLastActivationId(lastActivationId); if (m_logCategory.isInfoEnabled()) { LogMessageGen lmg = new LogMessageGen(); lmg.setSubject("Updating signal files"); lmg.param(LoggingConsts.USER_ID, userId); m_logCategory.info(lmg.toString()); } // wrt EMSDEV-7854 nfs calls and database transactions. // Above is only doing a select; no locks are taken and this // method is private. updateSignalFiles(hash, state, isDeleted); } // each row. } finally { DbUtils.safeClose(rs); DbUtils.safeClose(pst); } }
@Override public List<? extends Operation> getOperationsByDeviceAndStatus( int enrolmentId, Operation.Status status) throws OperationManagementDAOException { PreparedStatement stmt = null; ResultSet rs = null; PolicyOperation policyOperation; List<Operation> operations = new ArrayList<>(); ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { Connection conn = OperationManagementDAOFactory.getConnection(); String sql = "SELECT po.OPERATION_ID, ENABLED, OPERATION_DETAILS FROM DM_POLICY_OPERATION po " + "INNER JOIN (SELECT * FROM DM_ENROLMENT_OPERATION_MAPPING WHERE ENROLMENT_ID = ? " + "AND STATUS = ?) dm ON dm.OPERATION_ID = po.OPERATION_ID"; stmt = conn.prepareStatement(sql); stmt.setInt(1, enrolmentId); stmt.setString(2, status.toString()); rs = stmt.executeQuery(); while (rs.next()) { byte[] operationDetails = rs.getBytes("OPERATION_DETAILS"); bais = new ByteArrayInputStream(operationDetails); ois = new ObjectInputStream(bais); policyOperation = (PolicyOperation) ois.readObject(); policyOperation.setStatus(status); operations.add(policyOperation); } } catch (IOException e) { throw new OperationManagementDAOException( "IO Error occurred while de serialize the profile " + "operation object", e); } catch (ClassNotFoundException e) { throw new OperationManagementDAOException( "Class not found error occurred while de serialize the " + "profile operation object", e); } catch (SQLException e) { throw new OperationManagementDAOException( "SQL error occurred while retrieving the operation " + "available for the device'" + enrolmentId + "' with status '" + status.toString(), e); } finally { if (bais != null) { try { bais.close(); } catch (IOException e) { log.warn("Error occurred while closing ByteArrayOutputStream", e); } } if (ois != null) { try { ois.close(); } catch (IOException e) { log.warn("Error occurred while closing ObjectOutputStream", e); } } OperationManagementDAOUtil.cleanupResources(stmt, rs); } return operations; }