summaryrefslogtreecommitdiffstats
path: root/daemons/ipa-kdb/ipa_kdb_audit_as.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/ipa-kdb/ipa_kdb_audit_as.c')
-rw-r--r--daemons/ipa-kdb/ipa_kdb_audit_as.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_audit_as.c b/daemons/ipa-kdb/ipa_kdb_audit_as.c
new file mode 100644
index 000000000..c71568c38
--- /dev/null
+++ b/daemons/ipa-kdb/ipa_kdb_audit_as.c
@@ -0,0 +1,120 @@
+/*
+ * MIT Kerberos KDC database backend for FreeIPA
+ *
+ * Authors: Simo Sorce <ssorce@redhat.com>
+ *
+ * Copyright (C) 2012 Simo Sorce, Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ipa_kdb.h"
+#include "ipa_pwd.h"
+
+void ipadb_audit_as_req(krb5_context kcontext,
+ krb5_kdc_req *request,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_timestamp authtime,
+ krb5_error_code error_code)
+{
+ struct ipadb_context *ipactx;
+ struct ipadb_e_data *ied;
+ krb5_error_code kerr;
+
+ if (!client) {
+ return;
+ }
+
+ if (error_code != 0 &&
+ error_code != KRB5KDC_ERR_PREAUTH_FAILED &&
+ error_code != KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ return;
+ }
+
+ ipactx = ipadb_get_context(kcontext);
+ if (!ipactx) {
+ return;
+ }
+
+ ied = (struct ipadb_e_data *)client->e_data;
+ if (!ied) {
+ return;
+ }
+
+ if (!ied->pol) {
+ kerr = ipadb_get_ipapwd_policy(ipactx, ied->pw_policy_dn, &ied->pol);
+ if (kerr != 0) {
+ return;
+ }
+ }
+
+ client->mask = 0;
+
+ switch (error_code) {
+ case 0:
+ /* Check if preauth flag is specified (default), otherwise we have
+ * no data to know if auth was successful or not */
+ if (client->attributes & KRB5_KDB_REQUIRES_PRE_AUTH) {
+ if (client->fail_auth_count != 0) {
+ client->fail_auth_count = 0;
+ client->mask |= KMASK_FAIL_AUTH_COUNT;
+ }
+ client->last_success = authtime;
+ client->mask |= KMASK_LAST_SUCCESS;
+ }
+ break;
+
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+
+ if (client->last_failed <= ied->last_admin_unlock) {
+ /* Reset fail_auth_count, and admin unlocked the account */
+ client->fail_auth_count = 0;
+ client->mask |= KMASK_FAIL_AUTH_COUNT;
+ }
+ if (ied->pol->lockout_duration != 0 &&
+ ied->pol->failcnt_interval != 0 &&
+ client->last_failed + ied->pol->failcnt_interval < authtime) {
+ /* Reset fail_auth_count, the interval's expired already */
+ client->fail_auth_count = 0;
+ client->mask |= KMASK_FAIL_AUTH_COUNT;
+ }
+
+ if (ied->pol->max_fail == 0 ||
+ client->fail_auth_count < ied->pol->max_fail) {
+ /* let's increase the fail counter */
+ client->fail_auth_count++;
+ client->mask |= KMASK_FAIL_AUTH_COUNT;
+ }
+ if (client->last_failed + ied->pol->lockout_duration > authtime) {
+ /* client already locked, nothing more to do */
+ break;
+ }
+ client->last_failed = authtime;
+ client->mask |= KMASK_LAST_FAILED;
+ break;
+ default:
+ return;
+ }
+
+ if (client->mask) {
+ kerr = ipadb_put_principal(kcontext, client, NULL);
+ if (kerr != 0) {
+ return;
+ }
+ }
+ client->mask = 0;
+}