From 80a3846c5c7b04625b112b2ee555292f8347dd52 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Tue, 13 Jul 2010 00:53:46 +0000 Subject: Add check_policy_as and check_policy_tgs to the DAL table with corresponding libkdb5 APIs, replacing the CHECK_POLICY_AS and CHECK_POLICY_TGS methods of db_invoke. ticket: 6749 status: open git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24184 dc483132-0cff-0310-8789-dd5450dbe970 --- src/include/kdb.h | 92 ++++++++++++---------- src/kdc/kdc_util.c | 20 +++-- src/kdc/policy.c | 75 +----------------- src/lib/kdb/kdb5.c | 39 +++++++++ src/lib/kdb/libkdb5.exports | 2 + src/plugins/kdb/db2/db2_exp.c | 8 ++ src/plugins/kdb/db2/kdb_db2.c | 14 ++++ src/plugins/kdb/db2/kdb_db2.h | 6 ++ src/plugins/kdb/db2/kdb_ext.c | 26 ------ src/plugins/kdb/ldap/ldap_exp.c | 2 + src/plugins/kdb/ldap/libkdb_ldap/kdb_ext.c | 26 ------ src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c | 14 ++++ src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h | 5 ++ .../kdb/ldap/libkdb_ldap/libkdb_ldap.exports | 1 + 14 files changed, 156 insertions(+), 174 deletions(-) (limited to 'src') diff --git a/src/include/kdb.h b/src/include/kdb.h index cb9a328..53a4e24 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -323,40 +323,11 @@ extern char *krb5_mkey_pwd_prompt2; #define KRB5_DB_LOCKMODE_PERMANENT 0x0008 /* db_invoke methods */ -#define KRB5_KDB_METHOD_CHECK_POLICY_AS 0x00000030 -#define KRB5_KDB_METHOD_CHECK_POLICY_TGS 0x00000040 #define KRB5_KDB_METHOD_AUDIT_AS 0x00000050 #define KRB5_KDB_METHOD_AUDIT_TGS 0x00000060 #define KRB5_KDB_METHOD_REFRESH_POLICY 0x00000070 #define KRB5_KDB_METHOD_CHECK_ALLOWED_TO_DELEGATE 0x00000080 -typedef struct _kdb_check_policy_as_req { - krb5_magic magic; - krb5_kdc_req *request; - krb5_db_entry *client; - krb5_db_entry *server; - krb5_timestamp kdc_time; -} kdb_check_policy_as_req; - -typedef struct _kdb_check_policy_as_rep { - krb5_magic magic; - const char *status; - krb5_data e_data; -} kdb_check_policy_as_rep; - -typedef struct _kdb_check_policy_tgs_req { - krb5_magic magic; - krb5_kdc_req *request; - krb5_db_entry *server; - krb5_ticket *ticket; -} kdb_check_policy_tgs_req; - -typedef struct _kdb_check_policy_tgs_rep { - krb5_magic magic; - const char *status; - krb5_data e_data; -} kdb_check_policy_tgs_rep; - typedef struct _kdb_audit_as_req { krb5_magic magic; krb5_kdc_req *request; @@ -649,6 +620,21 @@ krb5_error_code krb5_db_check_transited_realms(krb5_context kcontext, const krb5_data *client_realm, const krb5_data *server_realm); +krb5_error_code krb5_db_check_policy_as(krb5_context kcontext, + krb5_kdc_req *request, + krb5_db_entry *client, + krb5_db_entry *server, + krb5_timestamp kdc_time, + const char **status, + krb5_data *e_data); + +krb5_error_code krb5_db_check_policy_tgs(krb5_context kcontext, + krb5_kdc_req *request, + krb5_db_entry *server, + krb5_ticket *ticket, + const char **status, + krb5_data *e_data); + krb5_error_code krb5_db_invoke ( krb5_context kcontext, unsigned int method, const krb5_data *req, @@ -1263,24 +1249,44 @@ typedef struct _kdb_vftabl { const krb5_data *server_realm); /* + * Optional: Perform a policy check on an AS request, in addition to the + * standard policy checks. Return 0 if the AS request is allowed. If the + * AS request is not allowed: + * - Place a short string literal into *status. + * - If desired, place data into e_data. Any data placed here will be + * freed by the caller using the standard free function. + * - Return an appropriate error (such as KDC_ERR_POLICY). + */ + krb5_error_code (*check_policy_as)(krb5_context kcontext, + krb5_kdc_req *request, + krb5_db_entry *client, + krb5_db_entry *server, + krb5_timestamp kdc_time, + const char **status, + krb5_data *e_data); + + /* + * Optional: Perform a policy check on a TGS request, in addition to the + * standard policy checks. Return 0 if the TGS request is allowed. If the + * TGS request is not allowed: + * - Place a short string literal into *status. + * - If desired, place data into e_data. Any data placed here will be + * freed by the caller using the standard free function. + * - Return an appropriate error (such as KDC_ERR_POLICY). + * The input parameter ticket contains the TGT used in the TGS request. + */ + krb5_error_code (*check_policy_tgs)(krb5_context kcontext, + krb5_kdc_req *request, + krb5_db_entry *server, + krb5_ticket *ticket, + const char **status, + krb5_data *e_data); + + /* * Optional: Perform an operation on input data req with output stored in * rep. Return KRB5_PLUGIN_OP_NOTSUPP if the module does not implement the * method. Defined methods are: * - * KRB5_KDB_METHOD_CHECK_POLICY_AS: req contains a kdb_check_policy_as_req - * structure. Perform a policy check on an AS request, in addition to - * the standard policy checks. Return 0 if the AS request is allowed - * or an appropriate error (such as KDC_ERR_POLICY) if it is - * disallowed. Place in rep a kdb_check_policy_as_rep structure - * containing a status string and e_data value to return to the client - * if the policy check fails. The status string may be NULL, but must - * not contain allocated data as it will not be freed. The e_data - * structure may be empty; if not, it will be freed by the caller using - * the standard free function. - * - * KRB5_KDB_METHOD_CHECK_POLICY_TGS: Same as above, except the structures - * are kdb_check_policy_tgs_req and kdb_check_policy_tgs_rep. - * * KRB5_KDB_METHOD_AUDIT_AS: req contains a kdb_audit_as_req structure. * Informs the module of a successful or unsuccessful AS request. Do * not place any data in rep. diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index db5434d..b892a27 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -1051,9 +1051,13 @@ validate_as_request(register krb5_kdc_req *request, krb5_db_entry client, return(KDC_ERR_MUST_USE_USER2USER); } - /* - * Check against local policy - */ + /* Perform KDB module policy checks. */ + errcode = krb5_db_check_policy_as(kdc_context, request, &client, &server, + kdc_time, status, e_data); + if (errcode && errcode != KRB5_PLUGIN_OP_NOTSUPP) + return errcode; + + /* Check against local policy. */ errcode = against_local_policy_as(request, client, server, kdc_time, status, e_data); if (errcode) @@ -1468,9 +1472,13 @@ validate_tgs_request(register krb5_kdc_req *request, krb5_db_entry server, return KRB_ERR_GENERIC; } - /* - * Check local policy - */ + /* Perform KDB module policy checks. */ + errcode = krb5_db_check_policy_tgs(kdc_context, request, &server, + ticket, status, e_data); + if (errcode && errcode != KRB5_PLUGIN_OP_NOTSUPP) + return errcode; + + /* Check local policy. */ errcode = against_local_policy_tgs(request, server, ticket, status, e_data); if (errcode) diff --git a/src/kdc/policy.c b/src/kdc/policy.c index fa403e5..939ddb0 100644 --- a/src/kdc/policy.c +++ b/src/kdc/policy.c @@ -63,12 +63,6 @@ against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client, krb5_db_entry server, krb5_timestamp kdc_time, const char **status, krb5_data *e_data) { - krb5_error_code code; - kdb_check_policy_as_req req; - kdb_check_policy_as_rep rep; - krb5_data req_data; - krb5_data rep_data; - #if 0 /* An AS request must include the addresses field */ if (request->addresses == 0) { @@ -77,37 +71,7 @@ against_local_policy_as(register krb5_kdc_req *request, krb5_db_entry client, } #endif - memset(&req, 0, sizeof(req)); - memset(&rep, 0, sizeof(rep)); - - req.request = request; - req.client = &client; - req.server = &server; - req.kdc_time = kdc_time; - - req_data.data = (void *)&req; - req_data.length = sizeof(req); - - rep_data.data = (void *)&rep; - rep_data.length = sizeof(rep); - - code = krb5_db_invoke(kdc_context, - KRB5_KDB_METHOD_CHECK_POLICY_AS, - &req_data, - &rep_data); - if (code == KRB5_PLUGIN_OP_NOTSUPP) - return 0; - - *status = rep.status; - *e_data = rep.e_data; - - if (code != 0) { - code -= ERROR_TABLE_BASE_krb5; - if (code < 0 || code > 128) - code = KRB_ERR_GENERIC; - } - - return code; + return 0; /* not against policy */ } /* @@ -118,12 +82,6 @@ against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server, krb5_ticket *ticket, const char **status, krb5_data *e_data) { - krb5_error_code code; - kdb_check_policy_tgs_req req; - kdb_check_policy_tgs_rep rep; - krb5_data req_data; - krb5_data rep_data; - #if 0 /* * For example, if your site wants to disallow ticket forwarding, @@ -136,34 +94,5 @@ against_local_policy_tgs(register krb5_kdc_req *request, krb5_db_entry server, } #endif - memset(&req, 0, sizeof(req)); - memset(&rep, 0, sizeof(rep)); - - req.request = request; - req.server = &server; - req.ticket = ticket; - - req_data.data = (void *)&req; - req_data.length = sizeof(req); - - rep_data.data = (void *)&rep; - rep_data.length = sizeof(rep); - - code = krb5_db_invoke(kdc_context, - KRB5_KDB_METHOD_CHECK_POLICY_TGS, - &req_data, - &rep_data); - if (code == KRB5_PLUGIN_OP_NOTSUPP) - return 0; - - *status = rep.status; - *e_data = rep.e_data; - - if (code != 0) { - code -= ERROR_TABLE_BASE_krb5; - if (code < 0 || code > 128) - code = KRB_ERR_GENERIC; - } - - return code; + return 0; /* not against policy */ } diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index 0e12eb1..521bbb4 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -2265,6 +2265,45 @@ krb5_db_check_transited_realms(krb5_context kcontext, } krb5_error_code +krb5_db_check_policy_as(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_timestamp kdc_time, const char **status, + krb5_data *e_data) +{ + krb5_error_code ret; + kdb_vftabl *v; + + *status = NULL; + *e_data = empty_data(); + ret = get_vftabl(kcontext, &v); + if (ret) + return ret; + if (v->check_policy_as == NULL) + return KRB5_PLUGIN_OP_NOTSUPP; + return v->check_policy_as(kcontext, request, client, server, kdc_time, + status, e_data); +} + +krb5_error_code +krb5_db_check_policy_tgs(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *server, krb5_ticket *ticket, + const char **status, krb5_data *e_data) +{ + krb5_error_code ret; + kdb_vftabl *v; + + *status = NULL; + *e_data = empty_data(); + ret = get_vftabl(kcontext, &v); + if (ret) + return ret; + if (v->check_policy_tgs == NULL) + return KRB5_PLUGIN_OP_NOTSUPP; + return v->check_policy_tgs(kcontext, request, server, ticket, status, + e_data); +} + +krb5_error_code krb5_db_invoke(krb5_context kcontext, unsigned int method, const krb5_data *req, diff --git a/src/lib/kdb/libkdb5.exports b/src/lib/kdb/libkdb5.exports index dcba09e..f83532d 100644 --- a/src/lib/kdb/libkdb5.exports +++ b/src/lib/kdb/libkdb5.exports @@ -3,6 +3,8 @@ krb5_db_open krb5_db_inited krb5_db_alloc krb5_db_free +krb5_db_check_policy_as +krb5_db_check_policy_tgs krb5_db_check_transited_realms krb5_db_create krb5_db_delete_principal diff --git a/src/plugins/kdb/db2/db2_exp.c b/src/plugins/kdb/db2/db2_exp.c index c274886..a95d47d 100644 --- a/src/plugins/kdb/db2/db2_exp.c +++ b/src/plugins/kdb/db2/db2_exp.c @@ -180,6 +180,12 @@ WRAP_K (krb5_db2_promote_db, ( krb5_context kcontext, char *conf_section, char **db_args ), (kcontext, conf_section, db_args)); +WRAP_K (krb5_db2_check_policy_as, + (krb5_context kcontext, krb5_kdc_req *request, krb5_db_entry *client, + krb5_db_entry *server, krb5_timestamp kdc_time, const char **status, + krb5_data *e_data), + (kcontext, request, client, server, kdc_time, status, e_data)); + WRAP_K (krb5_db2_invoke, (krb5_context kcontext, unsigned int method, @@ -243,5 +249,7 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_db2, kdb_function_table) = { /* blah blah blah */ 0,0,0,0,0, /* promote_db */ wrap_krb5_db2_promote_db, 0, 0, 0, 0, + /* check_policy_as */ wrap_krb5_db2_check_policy_as, + 0, /* invoke */ wrap_krb5_db2_invoke }; diff --git a/src/plugins/kdb/db2/kdb_db2.c b/src/plugins/kdb/db2/kdb_db2.c index 707bf84..a53e262 100644 --- a/src/plugins/kdb/db2/kdb_db2.c +++ b/src/plugins/kdb/db2/kdb_db2.c @@ -1635,3 +1635,17 @@ errout: return retval; } + +krb5_error_code +krb5_db2_check_policy_as(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_timestamp kdc_time, const char **status, + krb5_data *e_data) +{ + krb5_error_code retval; + + retval = krb5_db2_lockout_check_policy(kcontext, client, kdc_time); + if (retval == KRB5KDC_ERR_CLIENT_REVOKED) + *status = "LOCKED_OUT"; + return retval; +} diff --git a/src/plugins/kdb/db2/kdb_db2.h b/src/plugins/kdb/db2/kdb_db2.h index 6096dc4..0bddcf4 100644 --- a/src/plugins/kdb/db2/kdb_db2.h +++ b/src/plugins/kdb/db2/kdb_db2.h @@ -146,6 +146,12 @@ krb5_db2_lockout_audit(krb5_context context, krb5_timestamp stamp, krb5_error_code status); +krb5_error_code +krb5_db2_check_policy_as(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_timestamp kdc_time, const char **status, + krb5_data *e_data); + /* methods */ krb5_error_code krb5_db2_invoke(krb5_context context, diff --git a/src/plugins/kdb/db2/kdb_ext.c b/src/plugins/kdb/db2/kdb_ext.c index 1895b70..8f7ad94 100644 --- a/src/plugins/kdb/db2/kdb_ext.c +++ b/src/plugins/kdb/db2/kdb_ext.c @@ -35,29 +35,6 @@ #include "kdb_db2.h" static krb5_error_code -krb5_db2_check_policy_as(krb5_context context, - unsigned int method, - const krb5_data *request, - krb5_data *response) -{ - const kdb_check_policy_as_req *req; - kdb_check_policy_as_rep *rep; - krb5_error_code code; - - req = (const kdb_check_policy_as_req *)request->data; - rep = (kdb_check_policy_as_rep *)response->data; - - rep->status = NULL; - - code = krb5_db2_lockout_check_policy(context, req->client, - req->kdc_time); - if (code == KRB5KDC_ERR_CLIENT_REVOKED) - rep->status = "LOCKED_OUT"; - - return code; -} - -static krb5_error_code krb5_db2_audit_as(krb5_context context, unsigned int method, const krb5_data *request, @@ -83,9 +60,6 @@ krb5_db2_invoke(krb5_context context, krb5_error_code code = KRB5_PLUGIN_OP_NOTSUPP; switch (method) { - case KRB5_KDB_METHOD_CHECK_POLICY_AS: - code = krb5_db2_check_policy_as(context, method, req, rep); - break; case KRB5_KDB_METHOD_AUDIT_AS: code = krb5_db2_audit_as(context, method, req, rep); break; diff --git a/src/plugins/kdb/ldap/ldap_exp.c b/src/plugins/kdb/ldap/ldap_exp.c index 3228aa0..8236406 100644 --- a/src/plugins/kdb/ldap/ldap_exp.c +++ b/src/plugins/kdb/ldap/ldap_exp.c @@ -84,6 +84,8 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_ldap, kdb_function_table) = { /* encrypt_key_data */ NULL, /* sign_authdata */ NULL, /* check_transited_realms */ NULL, + /* check_policy_as */ krb5_ldap_check_policy_as, + /* check_policy_tgs */ NULL, /* invoke */ krb5_ldap_invoke, }; diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ext.c b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ext.c index fdbb1a1..0330e15 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ext.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ext.c @@ -35,29 +35,6 @@ #include "kdb_ldap.h" static krb5_error_code -krb5_ldap_check_policy_as(krb5_context context, - unsigned int method, - const krb5_data *request, - krb5_data *response) -{ - const kdb_check_policy_as_req *req; - kdb_check_policy_as_rep *rep; - krb5_error_code code; - - req = (const kdb_check_policy_as_req *)request->data; - rep = (kdb_check_policy_as_rep *)response->data; - - rep->status = NULL; - - code = krb5_ldap_lockout_check_policy(context, req->client, - req->kdc_time); - if (code == KRB5KDC_ERR_CLIENT_REVOKED) - rep->status = "LOCKED_OUT"; - - return code; -} - -static krb5_error_code krb5_ldap_audit_as(krb5_context context, unsigned int method, const krb5_data *request, @@ -117,9 +94,6 @@ krb5_ldap_invoke(krb5_context context, krb5_error_code code = KRB5_PLUGIN_OP_NOTSUPP; switch (method) { - case KRB5_KDB_METHOD_CHECK_POLICY_AS: - code = krb5_ldap_check_policy_as(context, method, req, rep); - break; case KRB5_KDB_METHOD_AUDIT_AS: code = krb5_ldap_audit_as(context, method, req, rep); break; diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c index 633de85..7127ce4 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.c @@ -527,3 +527,17 @@ kldap_ensure_initialized(void) { return CALL_INIT_FUNCTION (kldap_init_fn); } + +krb5_error_code +krb5_ldap_check_policy_as(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_timestamp kdc_time, const char **status, + krb5_data *e_data) +{ + krb5_error_code retval; + + retval = krb5_ldap_lockout_check_policy(kcontext, client, kdc_time); + if (retval == KRB5KDC_ERR_CLIENT_REVOKED) + *status = "LOCKED_OUT"; + return retval; +} diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h index 35dd12e..8e935e1 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h +++ b/src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h @@ -296,6 +296,11 @@ has_modify_increment(krb5_context, char *); krb5_error_code krb5_ldap_free_server_context_params(krb5_ldap_context *ldap_context); +krb5_error_code +krb5_ldap_check_policy_as(krb5_context kcontext, krb5_kdc_req *request, + krb5_db_entry *client, krb5_db_entry *server, + krb5_timestamp kdc_time, const char **status, + krb5_data *e_data); /* DAL functions */ diff --git a/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports b/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports index 7f285ce..affdb38 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports +++ b/src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports @@ -44,4 +44,5 @@ krb5_ldap_unlock krb5_ldap_create krb5_ldap_set_mkey_list krb5_ldap_get_mkey_list +krb5_ldap_check_policy_as krb5_ldap_invoke -- cgit v1.1