account_sentinel.install 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. /**
  3. * @file
  4. * Installation and requirements for Account Sentinel module.
  5. */
  6. /**
  7. * Implements hook_schema().
  8. */
  9. function account_sentinel_schema() {
  10. $schema['account_sentinel_logs'] = array(
  11. 'description' => "Stores Account Sentinel's events.",
  12. 'fields' => array(
  13. 'eid' => array(
  14. 'description' => 'The primary identifier for an event.',
  15. 'type' => 'serial',
  16. 'unsigned' => TRUE,
  17. 'not null' => TRUE,
  18. ),
  19. 'uid' => array(
  20. 'description' => "Subject account's {users}.uid.",
  21. 'type' => 'int',
  22. 'unsigned' => TRUE,
  23. 'not null' => TRUE,
  24. 'default' => 0,
  25. ),
  26. 'origin' => array(
  27. 'description' => 'From where the event was detected.',
  28. 'type' => 'varchar',
  29. 'length' => 32,
  30. 'not null' => TRUE,
  31. ),
  32. 'type' => array(
  33. 'description' => 'Type of the event.',
  34. 'type' => 'varchar',
  35. 'length' => 32,
  36. 'not null' => TRUE,
  37. ),
  38. 'data' => array(
  39. 'description' => 'Additional event data.',
  40. 'type' => 'blob',
  41. 'not null' => FALSE,
  42. 'size' => 'big',
  43. 'serialize' => TRUE,
  44. ),
  45. 'by_uid' => array(
  46. 'description' => 'The {users}.uid of the user who triggered the event.',
  47. 'type' => 'int',
  48. 'unsigned' => TRUE,
  49. 'not null' => TRUE,
  50. 'default' => 0,
  51. ),
  52. 'ip' => array(
  53. 'description' => 'The IP of the user who triggered the event.',
  54. 'type' => 'varchar',
  55. 'length' => 45,
  56. 'default' => NULL,
  57. ),
  58. 'timestamp' => array(
  59. 'description' => 'Unix timestamp of when the event occurred.',
  60. 'type' => 'int',
  61. 'unsigned' => TRUE,
  62. 'not null' => TRUE,
  63. 'default' => 0,
  64. ),
  65. ),
  66. 'indexes' => array(
  67. 'uid' => array('uid'),
  68. 'origin' => array('origin'),
  69. 'type' => array('type'),
  70. 'by_uid' => array('by_uid'),
  71. 'ip' => array('ip'),
  72. 'timestamp' => array('timestamp'),
  73. ),
  74. 'primary key' => array('eid'),
  75. );
  76. $schema['account_sentinel_users'] = array(
  77. 'description' => "Stores a copy of monitored users' data from the users table.",
  78. 'fields' => array(
  79. 'uid' => array(
  80. 'description' => 'Primary Key: Unique user ID.',
  81. 'type' => 'int',
  82. 'unsigned' => TRUE,
  83. 'not null' => TRUE,
  84. 'default' => 0,
  85. ),
  86. 'name' => array(
  87. 'description' => 'Unique user name.',
  88. 'type' => 'varchar',
  89. 'length' => 60,
  90. 'not null' => TRUE,
  91. 'default' => '',
  92. ),
  93. 'pass' => array(
  94. 'description' => "User's password (hashed).",
  95. 'type' => 'varchar',
  96. 'length' => 128,
  97. 'not null' => TRUE,
  98. 'default' => '',
  99. ),
  100. 'mail' => array(
  101. 'description' => "User's e-mail address.",
  102. 'type' => 'varchar',
  103. 'length' => 254,
  104. 'not null' => FALSE,
  105. 'default' => '',
  106. ),
  107. 'status' => array(
  108. 'description' => 'Whether the user is active(1) or blocked(0).',
  109. 'type' => 'int',
  110. 'size' => 'tiny',
  111. 'not null' => TRUE,
  112. 'default' => 0,
  113. ),
  114. 'checksum' => array(
  115. 'description' => "Checksum calculated with site-specific hash-key.",
  116. 'type' => 'varchar',
  117. 'length' => 96,
  118. 'not null' => TRUE,
  119. ),
  120. ),
  121. 'primary key' => array('uid'),
  122. );
  123. $schema['account_sentinel_users_roles'] = array(
  124. 'description' => 'Maps monitored users to monitored roles.',
  125. 'fields' => array(
  126. 'uid' => array(
  127. 'description' => 'Primary Key: {users}.uid for user.',
  128. 'type' => 'int',
  129. 'unsigned' => TRUE,
  130. 'not null' => TRUE,
  131. 'default' => 0,
  132. ),
  133. 'rid' => array(
  134. 'description' => 'Primary Key: {role}.rid for role.',
  135. 'type' => 'int',
  136. 'unsigned' => TRUE,
  137. 'not null' => TRUE,
  138. 'default' => 0,
  139. ),
  140. 'checksum' => array(
  141. 'description' => "Checksum calculated with site-specific hash-key.",
  142. 'type' => 'varchar',
  143. 'length' => 96,
  144. 'not null' => TRUE,
  145. ),
  146. ),
  147. 'primary key' => array('uid', 'rid'),
  148. );
  149. return $schema;
  150. }
  151. /**
  152. * Implements hook_requirements().
  153. */
  154. function account_sentinel_requirements($phase) {
  155. $t = get_t();
  156. $requirements = array();
  157. if ($phase == 'runtime') {
  158. // Warn if it's been a while since the last database audit.
  159. $warn_after = variable_get('account_sentinel_audit_warn_after', 3 * 24 * 60 * 60);
  160. $last = variable_get('account_sentinel_audit_last', 0);
  161. $enabled_on = variable_get('account_sentinel_enabled_on', 0);
  162. if (REQUEST_TIME - max($last, $enabled_on) > $warn_after) {
  163. $requirements[] = array(
  164. 'title' => $t('Account Sentinel database audit'),
  165. 'value' => $t(
  166. 'Last run @ago ago',
  167. array('@ago' => format_interval(REQUEST_TIME - $last))
  168. ),
  169. 'description' => $t("It's been a while since the last database audit run of Account Sentinel. It is highly recommended that you run it frequently either via cron or Drush. For more information check README.txt in the module's directory."),
  170. 'severity' => REQUIREMENT_WARNING,
  171. );
  172. }
  173. }
  174. return $requirements;
  175. }
  176. /**
  177. * Implements hook_install().
  178. */
  179. function account_sentinel_install() {
  180. $t = get_t();
  181. account_sentinel_reset_cron_key();
  182. drupal_set_message($t(
  183. 'Account Sentinel successfully installed! Please head over <a href="!configure">here</a> to configure it.',
  184. array('!configure' => url('admin/config/system/account-sentinel'))
  185. ));
  186. }
  187. /**
  188. * Implements hook_enable().
  189. */
  190. function account_sentinel_enable() {
  191. variable_set('account_sentinel_enabled_on', REQUEST_TIME);
  192. // Reset snapshot tables to prevent false detections after enabling the
  193. // module.
  194. db_truncate('account_sentinel_users')->execute();
  195. db_truncate('account_sentinel_users_roles')->execute();
  196. $roles = account_sentinel_get_monitored_roles();
  197. account_sentinel_rebuild_snapshots(array(), $roles);
  198. }
  199. /**
  200. * Implements hook_uninstall().
  201. */
  202. function account_sentinel_uninstall() {
  203. variable_del('account_sentinel_audit_last');
  204. variable_del('account_sentinel_audit_warn_after');
  205. variable_del('account_sentinel_cron_key');
  206. variable_del('account_sentinel_cron_method');
  207. variable_del('account_sentinel_email_to');
  208. variable_del('account_sentinel_enabled_on');
  209. variable_del('account_sentinel_monitored_roles');
  210. }
  211. /**
  212. * Change checksums to use SHA384.
  213. */
  214. function account_sentinel_update_1() {
  215. $checksum_field = array(
  216. 'description' => "Checksum calculated with site-specific hash-key.",
  217. 'type' => 'varchar',
  218. 'length' => 96,
  219. 'not null' => TRUE,
  220. );
  221. // Update checksum columns.
  222. db_change_field('account_sentinel_users', 'checksum', 'checksum', $checksum_field);
  223. db_change_field('account_sentinel_users_roles', 'checksum', 'checksum', $checksum_field);
  224. // Regenerate valid checksums.
  225. $hash_key = drupal_get_hash_salt();
  226. $args = array(':hash_key' => $hash_key);
  227. db_update('account_sentinel_users')
  228. ->where('checksum = md5(concat(uid, name, pass, mail, status, :hash_key))', $args)
  229. ->expression('checksum', 'sha2(concat(uid, name, pass, mail, status, :hash_key), 384)', $args)
  230. ->execute();
  231. db_update('account_sentinel_users_roles')
  232. ->where('checksum = md5(concat(uid, rid, :hash_key))', $args)
  233. ->expression('checksum', 'sha2(concat(uid, rid, :hash_key), 384)', $args)
  234. ->execute();
  235. }