how to "ban" clients?

Chris Hecker checker at d6.com
Thu Jul 28 05:12:57 EDT 2011


The patch below has a bug I just found with more testing:

+ request->client) == KRB5_NT_ENTERPRISE_PRINCIPAL) {

should be

+ header_enc_tkt->client) == KRB5_NT_ENTERPRISE_PRINCIPAL) {

The former line will deference a null pointer and crash (request->client 
is 0 on tgs_req).

Chris



On 2011/07/27 04:02, Chris Hecker wrote:
>
> Oh, and I should point out there's the obvious code in
> validate_tgs_request that uses the client:
>
> + /* Client must not be locked out */
> + if (client && isflagset(client->attributes, KRB5_KDB_DISALLOW_ALL_TIX)) {
> + *status = "CLIENT LOCKED OUT";
> + return(KDC_ERR_CLIENT_REVOKED);
> + }
>
> Chris
>
>
>
> On 2011/07/27 03:35, Chris Hecker wrote:
>>
>> Okay, I implemented this today. Most of the patch is loading the bool
>> from kdc.conf and updating all the places those config variables are
>> declared and copied, but I've put the business end of things below.
>> I'll put the full patch up somewhere, but I wanted more clued people to
>> take a look at this and see if it looks right. It works perfectly, and
>> it correctly rejects new tickets if somebody's been -allow_tix'd even if
>> they have a valid TGT.
>>
>> I haven't done any perf testing yet.
>>
>> As you can see from the comment, I've got a couple questions that maybe
>> Greg or somebody can answer...
>>
>> Also, do I need to set the canonicalize flags? Basically, I only need
>> to be able to check is_local_principal, and get the attributes to check
>> the allow_tix flag...
>>
>> Thanks,
>> Chris
>>
>> === modified file 'src/kdc/do_tgs_req.c'
>> --- old/src/kdc/do_tgs_req.c 2011-07-26 10:46:03 +0000
>> +++ new/src/kdc/do_tgs_req.c 2011-07-27 07:37:15 +0000
>> @@ -201,6 +201,63 @@
>> * decrypted with the session key.
>> */
>>
>> + if (validate_tgs_req_local_client &&
>> + is_local_principal(header_enc_tkt->client)) {
>> +
>> + /*
>> + * If validate_tgs_req_local_client is set in kdc.conf, we
>> + * will check KRB5_KDB_DISALLOW_ALL_TIX on any local clients.
>> + *
>> + * This client db_entry get code is basically copied from
>> + * process_as_req. We free the client below after passing it
>> + * to validate_tgs_request, before the s4u2self request sets
>> + * it, and we use a local flags for getting the entry.
>> + *
>> + * Note: I have to admit to not understanding all the
>> + * subtleties of this code, so somebody with more of a clue
>> + * should review it! Some things I don't understand yet:
>> + *
>> + * - We really only need to be able to check if the client is
>> + * local, and if the tix flag is set, but the
>> + * KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY flag is only valid
>> + * for AS_REQ, so is the db doing more work than it needs
>> + * to? Is there a fast path here I could use?
>> + *
>> + * - The s4u code below also is confusing, and reusing the
>> + * client local variable is a bit cheesy. Do they refer to
>> + * the same client? From looking at the code below, I don't
>> + * think so, but I'm not sure. If they are, would we save
>> + * any work by reusing it below if we get it here?
>> + *
>> + */
>> +
>> + unsigned int local_c_flags = 0;
>> +
>> + /*
>> + * Note that according to the referrals draft we should
>> + * always canonicalize enterprise principal names.
>> + */
>> + if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE) ||
>> + krb5_princ_type(kdc_context,
>> + request->client) ==
>> KRB5_NT_ENTERPRISE_PRINCIPAL) {
>> + setflag(local_c_flags, KRB5_KDB_FLAG_CANONICALIZE);
>> + setflag(local_c_flags, KRB5_KDB_FLAG_ALIAS_OK);
>> + }
>> + errcode = krb5_db_get_principal(kdc_context,
>> header_enc_tkt->client,
>> + local_c_flags, &client);
>> + if (errcode == KRB5_KDB_NOENTRY) {
>> + status = "CLIENT_NOT_FOUND";
>> + if (vague_errors)
>> + errcode = KRB5KRB_ERR_GENERIC;
>> + else
>> + errcode = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
>> + goto cleanup;
>> + } else if (errcode) {
>> + status = "LOOKING_UP_CLIENT";
>> + goto cleanup;
>> + }
>> + }
>> +
>> /* XXX make sure server here has the proper realm...taken from AP_REQ
>> header? */
>>
>> @@ -276,7 +333,7 @@
>> goto cleanup;
>> }
>>
>> - if ((retval = validate_tgs_request(request, 0, server, header_ticket,
>> + if ((retval = validate_tgs_request(request, client, server,
>> header_ticket,
>> kdc_time, &status, &e_data))) {
>> if (!status)
>> status = "UNKNOWN_REASON";
>> @@ -284,6 +341,14 @@
>> goto cleanup;
>> }
>>
>> + /* free the client if we created one above, so the below s4u code
>> + works exactly the same as before the validate flag was added. */
>> + if (client) {
>> + krb5_db_free_principal(kdc_context, client);
>> + client = 0;
>> + }
>> +
>> +
>> if (!is_local_principal(header_enc_tkt->client))
>> setflag(c_flags, KRB5_KDB_FLAG_CROSS_REALM);
>>
>>



More information about the Kerberos mailing list