#8735 ccache-sweeper removes valid ccaches
Closed: fixed 3 years ago by frenaud. Opened 3 years ago by slev.

Current implementation of ccache-sweeper was borrowed from mod_auth_gssapi https://github.com/gssapi/mod_auth_gssapi/blob/master/contrib/sweeper.py, but that example is outdated. There are several issues:

  • credentials lifetime
    today's gssproxy doesn't set correct lifetime for credentials:
(gdb) bt
#0  gpm_acquire_cred (minor_status=minor_status@entry=0x7ffc958cc4e8, in_cred_handle=in_cred_handle@entry=0x766a10, desired_name=<optimized out>, time_req=time_req@entry=4294967295, desired_mechs=desired_mechs@entry=0x7ffc958cc600, cred_usage=cred_usage@entry=1, impersonate=false, output_cred_handle=0x763340, actual_mechs=0x0, time_rec=0x7ffc958cc5d0) at src/client/gpm_acquire_cred.c:128
#1  0x00007f20343f5e3d in gssi_acquire_cred_from (minor_status=0x7ffc958cc6e4, desired_name=0x0, time_req=4294967295, desired_mechs=0x7ffc958cc600, cred_usage=1, cred_store=0x73f2a0, output_cred_handle=0x7ffc958cc5e8, actual_mechs=0x0, time_rec=0x7ffc958cc5d0) at src/mechglue/gpp_acquire_cred.c:165
#2  0x00007f20348496c4 in gss_add_cred_from (minor_status=minor_status@entry=0x7ffc958cc6e4, input_cred_handle=<optimized out>, desired_name=desired_name@entry=0x0, desired_mech=<optimized out>, cred_usage=cred_usage@entry=1, initiator_time_req=initiator_time_req@entry=4294967295, acceptor_time_req=<optimized out>, cred_store=0x73f2a0, output_cred_handle=0x0, actual_mechs=0x0, initiator_time_rec=0x7ffc958cc6e8, acceptor_time_rec=0x7ffc958cc6ec) at g_acquire_cred.c:544
#3  0x00007f2034849c87 in gss_acquire_cred_from (minor_status=0x7ffc958cc7c0, desired_name=0x0, time_req=4294967295, desired_mechs=0x0, cred_usage=1, cred_store=0x73f2a0, output_cred_handle=0x7ffc958cc7d0, actual_mechs=0x7ffc958cc7d8, time_rec=0x7ffc958cc7bc) at g_acquire_cred.c:190
#4  0x00007f203457e952 in ?? () from /usr/lib64/python3/site-packages/gssapi/raw/ext_cred_store.cpython-38.so
(gdb) p res->output_cred_handle.elements.elements_val.initiator_time_rec 
$11 = 59
(gdb) p res->output_cred_handle.elements.elements_val.acceptor_time_rec 
$12 = 0
(gdb) p res->output_cred_handle.elements.elements_val.cred_usage 
$13 = GSSX_C_INITIATE
(gdb) l 137
132             if (res->output_cred_handle->elements.elements_len) {
133                 e = &res->output_cred_handle->elements.elements_val[0];
134                 if (e->initiator_time_rec < e->acceptor_time_rec) {
135                     t = e->initiator_time_rec;
136                 } else {
137                     t = e->acceptor_time_rec;
138                 }
139             }
140
141             *time_rec = t;

This means that condition return creds.lifetime == 0 in ipa-ccache-sweeper always succeeds and all (either valid or expired) ccaches older than 30min are removed.
Though this can be overcomed with explicit creds inquiring the usage of service/ipa-api gssproxy service is not suitable for this task because of

For example, if credentials for 'admin@' user principal are expired.

input creds:

(gdb) p *creds.elements.elements_val 
$26 = {
  MN = {
    display_name = {
      octet_string_len = 14,
      octet_string_val = 0x2157780 "admin@IPA.TEST"
    },
    name_type = {
      octet_string_len = 10,
      octet_string_val = 0x21577c0 "*\206H\206\367\022\001\002\002\001"
    },
    exported_name = {
      octet_string_len = 33,
      octet_string_val = 0x2097fb0 "\004\001"
    },
    exported_composite_name = {
      octet_string_len = 37,
      octet_string_val = 0x21513f0 "\004\002"
    },
    name_attributes = {
      name_attributes_len = 0,
      name_attributes_val = 0x0
    },
    extensions = {
      extensions_len = 0,
      extensions_val = 0x0
    }
  },
  mech = {
    octet_string_len = 9,
    octet_string_val = 0x2156c90 "*\206H\206\367\022\001\002\002\372\033\325\344\177"
  },
  cred_usage = GSSX_C_INITIATE,
  initiator_time_rec = 59,
  acceptor_time_rec = 0,
  options = {
    options_len = 0,
    options_val = 0x0
  }
}

remote:

(gdb) p *out_cred_handle->remote.elements.elements_val
$31 = {
  MN = {
    display_name = {
      octet_string_len = 30,
      octet_string_val = 0x16c9d80 "HTTP/master1.ipa.test@IPA.TEST"
    },
    name_type = {
      octet_string_len = 10,
      octet_string_val = 0x16c8940 "*\206H\206\367\022\001\002\002\001"
    },
    exported_name = {
      octet_string_len = 49,
      octet_string_val = 0x16c9db0 "\004\001"
    },
    exported_composite_name = {
      octet_string_len = 53,
      octet_string_val = 0x16c9cb0 "\004\002"
    },
    name_attributes = {
      name_attributes_len = 0,
      name_attributes_val = 0x0
    },
    extensions = {
      extensions_len = 0,
      extensions_val = 0x0
    }
  },
  mech = {
    octet_string_len = 9,
    octet_string_val = 0x16c8830 "*\206H\206\367\022\001\002\002"
  },
  cred_usage = GSSX_C_INITIATE,
  initiator_time_rec = 60,
  acceptor_time_rec = 0,
  options = {
    options_len = 0,
    options_val = 0x0
  }
}

This results in the new initial credentials for HTTP/: service principal are obtained and stored into gssproxy client ccache. Additionally, such credentials are not expirable.

[root@master1 /]# KRB5_KTNAME=/var/lib/ipa/gssproxy/http.keytab /usr/sbin/gssproxy -d --extract-ccache /run/ipa/ccaches/admin\@IPA.TEST-dfqZbs --into-ccache /tmp/ipa_krbccache_ && klist -A /tmp/ipa_krbccache_

Ticket cache: FILE:/tmp/ipa_krbccache_
Default principal: HTTP/master1.ipa.test@IPA.TEST

Valid starting       Expires              Service principal
03/02/2021 14:21:42  03/02/2021 14:22:42  krbtgt/IPA.TEST@IPA.TEST
        renew until 03/03/2021 14:21:42

For comparison the original ccache looks as:

[root@master1 /]# klist -A /tmp/ipa_krbccache
Ticket cache: FILE:/tmp/ipa_krbccache
Default principal: admin@IPA.TEST

Valid starting       Expires              Service principal
03/02/2021 14:20:35  03/02/2021 14:21:34  HTTP/master1.ipa.test@IPA.TEST
        renew until 03/03/2021 14:20:32
03/02/2021 14:20:35  03/02/2021 14:21:35  krbtgt/IPA.TEST@IPA.TEST
        for client HTTP/master1.ipa.test@IPA.TEST, renew until 03/03/2021 14:20:35
03/02/2021 14:20:35  03/02/2021 14:21:35  ldap/master1.ipa.test@
        renew until 03/03/2021 14:20:35
        Ticket server: ldap/master1.ipa.test@IPA.TEST
  • ipa-ccache-sweeper during test_ccache_sweep is run under root, while the expected user is ipaapi. So, the wrong gssproxy service is in use(service/nfs-client instead of service/ipa-api).

The problem is that a user's session in a browser will end up with:

Your session has expired. Please log in again.

Possible fixes:
- use the existing service/ipa-api gssproxy service and explicitly set the desired_name for gss_acquire_cred_from
- using the gssproxy 0.8.4+ to decrypt the encrypted ccache
- additional gssproxy service which will have only cred_store = keytab:xxx for decryption ccache. Obtaining will not happen if the requester set 'usage=initial'.

I have the working example for the latter.

master:

  • 271fd16 ccache_sweeper: Add gssproxy service
  • 7972d28 cleanup: Drop never used path for httpd's ccache

ipa-4-9:

  • cf80bb3 ccache_sweeper: Add gssproxy service
  • 99a65e3 cleanup: Drop never used path for httpd's ccache

Metadata Update from @frenaud:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

3 years ago

Login to comment on this ticket.

Metadata