auditlog.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  3. * Copyright (C) 2005 Red Hat, Inc.
  4. * All rights reserved.
  5. *
  6. * License: GPL (version 3 or any later version).
  7. * See LICENSE for details.
  8. * END COPYRIGHT BLOCK **/
  9. #ifdef HAVE_CONFIG_H
  10. # include <config.h>
  11. #endif
  12. #include "slap.h"
  13. /*
  14. * JCM - The audit log might be better implemented as a post-op plugin.
  15. */
  16. #define ATTR_CHANGETYPE "changetype"
  17. #define ATTR_NEWRDN "newrdn"
  18. #define ATTR_DELETEOLDRDN "deleteoldrdn"
  19. #define ATTR_NEWSUPERIOR "newsuperior"
  20. #define ATTR_MODIFIERSNAME "modifiersname"
  21. char *attr_changetype = ATTR_CHANGETYPE;
  22. char *attr_newrdn = ATTR_NEWRDN;
  23. char *attr_deleteoldrdn = ATTR_DELETEOLDRDN;
  24. char *attr_newsuperior = ATTR_NEWSUPERIOR;
  25. char *attr_modifiersname = ATTR_MODIFIERSNAME;
  26. static int audit_hide_unhashed_pw = 1;
  27. static int auditfail_hide_unhashed_pw = 1;
  28. /* Forward Declarations */
  29. static void write_audit_file(int logtype, int optype, const char *dn, void *change, int flag, time_t curtime, int rc );
  30. static char *modrdn_changes[4];
  31. void
  32. write_audit_log_entry( Slapi_PBlock *pb )
  33. {
  34. time_t curtime;
  35. Slapi_DN *sdn;
  36. const char *dn;
  37. void *change;
  38. int flag = 0;
  39. Operation *op;
  40. /* if the audit log is not enabled, just skip all of
  41. this stuff */
  42. if (!config_get_auditlog_logging_enabled()) {
  43. return;
  44. }
  45. slapi_pblock_get( pb, SLAPI_OPERATION, &op );
  46. slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
  47. switch ( operation_get_type(op) )
  48. {
  49. case SLAPI_OPERATION_MODIFY:
  50. slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
  51. break;
  52. case SLAPI_OPERATION_ADD:
  53. slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
  54. break;
  55. case SLAPI_OPERATION_DELETE:
  56. {
  57. char * deleterDN = NULL;
  58. slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &deleterDN);
  59. change = deleterDN;
  60. }
  61. break;
  62. case SLAPI_OPERATION_MODDN:
  63. {
  64. char *rdn = NULL;
  65. Slapi_DN *snewsuperior = NULL;
  66. char *requestor = NULL;
  67. /* newrdn: change is just for logging -- case does not matter. */
  68. slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &rdn );
  69. slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &flag );
  70. slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &snewsuperior );
  71. slapi_pblock_get( pb, SLAPI_REQUESTOR_DN, &requestor );
  72. modrdn_changes[0] = rdn;
  73. modrdn_changes[1] = requestor;
  74. if (snewsuperior && slapi_sdn_get_dn(snewsuperior)) {
  75. modrdn_changes[2] = slapi_sdn_get_dn(snewsuperior);
  76. modrdn_changes[3] = NULL;
  77. } else {
  78. modrdn_changes[2] = NULL;
  79. }
  80. change = (void *)modrdn_changes;
  81. break;
  82. }
  83. default:
  84. return; /* Unsupported operation type. */
  85. }
  86. curtime = current_time();
  87. /* log the raw, unnormalized DN */
  88. dn = slapi_sdn_get_udn(sdn);
  89. write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, LDAP_SUCCESS);
  90. }
  91. void
  92. write_auditfail_log_entry( Slapi_PBlock *pb )
  93. {
  94. time_t curtime;
  95. Slapi_DN *sdn;
  96. const char *dn;
  97. void *change;
  98. int flag = 0;
  99. Operation *op;
  100. int pbrc = 0;
  101. char *auditfail_config = NULL;
  102. /* if the audit log is not enabled, just skip all of
  103. this stuff */
  104. if (!config_get_auditfaillog_logging_enabled()) {
  105. return;
  106. }
  107. slapi_pblock_get( pb, SLAPI_OPERATION, &op );
  108. slapi_pblock_get( pb, SLAPI_TARGET_SDN, &sdn );
  109. slapi_pblock_get( pb, SLAPI_RESULT_CODE, &pbrc );
  110. switch ( operation_get_type(op) )
  111. {
  112. case SLAPI_OPERATION_MODIFY:
  113. slapi_pblock_get( pb, SLAPI_MODIFY_MODS, &change );
  114. break;
  115. case SLAPI_OPERATION_ADD:
  116. slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &change );
  117. break;
  118. case SLAPI_OPERATION_DELETE:
  119. {
  120. char * deleterDN = NULL;
  121. slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &deleterDN);
  122. change = deleterDN;
  123. }
  124. break;
  125. case SLAPI_OPERATION_MODDN:
  126. {
  127. char *rdn = NULL;
  128. Slapi_DN *snewsuperior = NULL;
  129. char *requestor = NULL;
  130. /* newrdn: change is just for logging -- case does not matter. */
  131. slapi_pblock_get( pb, SLAPI_MODRDN_NEWRDN, &rdn );
  132. slapi_pblock_get( pb, SLAPI_MODRDN_DELOLDRDN, &flag );
  133. slapi_pblock_get( pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &snewsuperior );
  134. slapi_pblock_get( pb, SLAPI_REQUESTOR_DN, &requestor );
  135. modrdn_changes[0] = rdn;
  136. modrdn_changes[1] = requestor;
  137. if (snewsuperior && slapi_sdn_get_dn(snewsuperior)) {
  138. modrdn_changes[2] = slapi_sdn_get_dn(snewsuperior);
  139. modrdn_changes[3] = NULL;
  140. } else {
  141. modrdn_changes[2] = NULL;
  142. }
  143. change = (void *)modrdn_changes;
  144. break;
  145. }
  146. default:
  147. return; /* Unsupported operation type. */
  148. }
  149. curtime = current_time();
  150. /* log the raw, unnormalized DN */
  151. dn = slapi_sdn_get_udn(sdn);
  152. auditfail_config = config_get_auditfaillog();
  153. if (auditfail_config == NULL || strlen(auditfail_config) == 0) {
  154. /* If no auditfail log write to audit log */
  155. write_audit_file(SLAPD_AUDIT_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc);
  156. } else {
  157. /* If we have our own auditfail log path */
  158. write_audit_file(SLAPD_AUDITFAIL_LOG, operation_get_type(op), dn, change, flag, curtime, pbrc);
  159. }
  160. slapi_ch_free_string(&auditfail_config);
  161. }
  162. /*
  163. * Function: write_audit_file
  164. * Arguments:
  165. * optype - type of LDAP operation being logged
  166. * dn - distinguished name of entry being changed
  167. * change - pointer to the actual change operation
  168. * For a delete operation, may contain the modifier's DN.
  169. * flag - only used by modrdn operations - value of deleteoldrdn flag
  170. * curtime - the current time
  171. * rc - The ldap result code. Used in conjunction with auditfail
  172. * Returns: nothing
  173. */
  174. static void
  175. write_audit_file(
  176. int logtype,
  177. int optype,
  178. const char *dn,
  179. void *change,
  180. int flag,
  181. time_t curtime,
  182. int rc
  183. )
  184. {
  185. LDAPMod **mods;
  186. Slapi_Entry *e;
  187. char *newrdn, *tmp, *tmpsave;
  188. int len, i, j;
  189. char *timestr;
  190. char *rcstr;
  191. lenstr *l;
  192. l = lenstr_new();
  193. addlenstr( l, "time: " );
  194. timestr = format_localTime( curtime );
  195. addlenstr( l, timestr );
  196. slapi_ch_free_string(&timestr);
  197. addlenstr( l, "\n" );
  198. addlenstr( l, "dn: " );
  199. addlenstr( l, dn );
  200. addlenstr( l, "\n" );
  201. addlenstr( l, "result: " );
  202. rcstr = slapi_ch_smprintf("%d", rc);
  203. addlenstr( l, rcstr );
  204. slapi_ch_free_string(&rcstr);
  205. addlenstr( l, "\n" );
  206. switch ( optype )
  207. {
  208. case SLAPI_OPERATION_MODIFY:
  209. addlenstr( l, attr_changetype );
  210. addlenstr( l, ": modify\n" );
  211. mods = change;
  212. for ( j = 0; (mods != NULL) && (mods[j] != NULL); j++ )
  213. {
  214. int operationtype= mods[j]->mod_op & ~LDAP_MOD_BVALUES;
  215. if(strcmp(mods[j]->mod_type, PSEUDO_ATTR_UNHASHEDUSERPASSWORD) == 0){
  216. switch (logtype)
  217. {
  218. case SLAPD_AUDIT_LOG:
  219. if (audit_hide_unhashed_pw != 0) {
  220. continue;
  221. }
  222. break;
  223. case SLAPD_AUDITFAIL_LOG:
  224. if (auditfail_hide_unhashed_pw != 0) {
  225. continue;
  226. }
  227. break;
  228. }
  229. }
  230. switch ( operationtype )
  231. {
  232. case LDAP_MOD_ADD:
  233. addlenstr( l, "add: " );
  234. addlenstr( l, mods[j]->mod_type );
  235. addlenstr( l, "\n" );
  236. break;
  237. case LDAP_MOD_DELETE:
  238. addlenstr( l, "delete: " );
  239. addlenstr( l, mods[j]->mod_type );
  240. addlenstr( l, "\n" );
  241. break;
  242. case LDAP_MOD_REPLACE:
  243. addlenstr( l, "replace: " );
  244. addlenstr( l, mods[j]->mod_type );
  245. addlenstr( l, "\n" );
  246. break;
  247. default:
  248. operationtype= LDAP_MOD_IGNORE;
  249. break;
  250. }
  251. if(operationtype!=LDAP_MOD_IGNORE)
  252. {
  253. for ( i = 0; mods[j]->mod_bvalues != NULL && mods[j]->mod_bvalues[i] != NULL; i++ )
  254. {
  255. char *buf, *bufp;
  256. len = strlen( mods[j]->mod_type );
  257. len = LDIF_SIZE_NEEDED( len, mods[j]->mod_bvalues[i]->bv_len ) + 1;
  258. buf = slapi_ch_malloc( len );
  259. bufp = buf;
  260. slapi_ldif_put_type_and_value_with_options( &bufp, mods[j]->mod_type,
  261. mods[j]->mod_bvalues[i]->bv_val,
  262. mods[j]->mod_bvalues[i]->bv_len, 0 );
  263. *bufp = '\0';
  264. addlenstr( l, buf );
  265. slapi_ch_free( (void**)&buf );
  266. }
  267. }
  268. addlenstr( l, "-\n" );
  269. }
  270. break;
  271. case SLAPI_OPERATION_ADD:
  272. e = change;
  273. addlenstr( l, attr_changetype );
  274. addlenstr( l, ": add\n" );
  275. tmp = slapi_entry2str( e, &len );
  276. tmpsave = tmp;
  277. while (( tmp = strchr( tmp, '\n' )) != NULL )
  278. {
  279. tmp++;
  280. if ( !ldap_utf8isspace( tmp ))
  281. {
  282. break;
  283. }
  284. }
  285. addlenstr( l, tmp );
  286. slapi_ch_free((void**)&tmpsave );
  287. break;
  288. case SLAPI_OPERATION_DELETE:
  289. tmp = change;
  290. addlenstr( l, attr_changetype );
  291. addlenstr( l, ": delete\n" );
  292. if (tmp && tmp[0]) {
  293. addlenstr( l, attr_modifiersname );
  294. addlenstr( l, ": ");
  295. addlenstr( l, tmp);
  296. addlenstr( l, "\n");
  297. }
  298. break;
  299. case SLAPI_OPERATION_MODDN:
  300. newrdn = ((char **)change)[0];
  301. addlenstr( l, attr_changetype );
  302. addlenstr( l, ": modrdn\n" );
  303. addlenstr( l, attr_newrdn );
  304. addlenstr( l, ": " );
  305. addlenstr( l, newrdn );
  306. addlenstr( l, "\n" );
  307. addlenstr( l, attr_deleteoldrdn );
  308. addlenstr( l, ": " );
  309. addlenstr( l, flag ? "1" : "0" );
  310. addlenstr( l, "\n" );
  311. if (((char **)change)[2]) {
  312. char *newsuperior = ((char **)change)[2];
  313. addlenstr( l, attr_newsuperior );
  314. addlenstr( l, ": " );
  315. addlenstr( l, newsuperior );
  316. addlenstr( l, "\n" );
  317. }
  318. if (((char **)change)[1]) {
  319. char *modifier = ((char **)change)[1];
  320. addlenstr( l, attr_modifiersname );
  321. addlenstr( l, ": " );
  322. addlenstr( l, modifier );
  323. addlenstr( l, "\n" );
  324. }
  325. }
  326. addlenstr( l, "\n" );
  327. switch (logtype)
  328. {
  329. case SLAPD_AUDIT_LOG:
  330. slapd_log_audit (l->ls_buf, l->ls_len);
  331. break;
  332. case SLAPD_AUDITFAIL_LOG:
  333. slapd_log_auditfail (l->ls_buf, l->ls_len);
  334. break;
  335. default:
  336. /* Unsupported log type, we should make some noise */
  337. LDAPDebug1Arg(LDAP_DEBUG_ANY, "write_audit_log: Invalid log type specified. logtype %d\n", logtype);
  338. break;
  339. }
  340. lenstr_free( &l );
  341. }
  342. void
  343. auditlog_hide_unhashed_pw()
  344. {
  345. audit_hide_unhashed_pw = 1;
  346. }
  347. void
  348. auditlog_expose_unhashed_pw()
  349. {
  350. audit_hide_unhashed_pw = 0;
  351. }
  352. void
  353. auditfaillog_hide_unhashed_pw()
  354. {
  355. auditfail_hide_unhashed_pw = 1;
  356. }
  357. void
  358. auditfaillog_expose_unhashed_pw()
  359. {
  360. auditfail_hide_unhashed_pw = 0;
  361. }