ccache_sweeper: Add gssproxy service

The usage of the existing gssproxy service(`service/ipa-api`) leads
to undesirable for this case side effects such as auto renew of
expired credentials.

Fixes: https://pagure.io/freeipa/issue/8735
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
Stanislav Levin
2021-03-04 14:17:01 +02:00
committed by Alexander Bokovoy
parent 216720af83
commit 271fd162a7
6 changed files with 109 additions and 34 deletions
+7
View File
@@ -16,3 +16,10 @@
allow_client_ccache_sync = true
cred_usage = initiate
euid = $IPAAPI_USER
[service/ipa-sweeper]
mechs = krb5
cred_store = keytab:$HTTP_KEYTAB
socket = $SWEEPER_SOCKET
euid = $IPAAPI_USER
cred_usage = initiate
+35 -22
View File
@@ -17,31 +17,39 @@ import stat
import sys
import time
from gssapi.raw import acquire_cred_from
from ipalib.krb_utils import get_credentials_if_valid
from ipaplatform.paths import paths
# process file as a ccache and indicate whether it is expired
def should_delete(fname, t, minlife):
"""Process file as a ccache and indicate whether it is expired"""
# skip directories and other non-files
st = os.stat(fname)
if not stat.S_ISREG(st.st_mode):
return False
# ignore files that are newer than minlife minutes
if t - st.st_mtime < minlife * 60:
return False
# gssproxy inquires input credentials. If they are expired
# then gssproxy acquires creds from cred_store according to
# the configuration of gssproxy's service, which in this case
# hasn't cred_store(besides `keytab:`, used for decryption of
# ccache). If there is no ccache within cred_store then gssproxy
# adds its own one("MEMORY:internal_%d"), which hasn't
# any credentials, thus, scan_ccache fails with KRB5_FCC_NOFILE.
# Since the caller requires INITIATE-ONLY and the client keytab
# is not provided in cred_store the result of gss_acquire_cred_from
# is KRB5_FCC_NOFILE, which is mapped by gssproxy to
# 0x04200000 + KRB5_FCC_NOFILE.
try:
# skip directories and other non-files
st = os.stat(fname)
if not stat.S_ISREG(st.st_mode):
return False
creds = get_credentials_if_valid(ccache_name=fname)
return creds is None
except ValueError:
return True
# ignore files that are newer than minlife minutes
if t - st.st_mtime < minlife * 60:
return False
creds = acquire_cred_from({b"ccache": fname.encode("UTF-8")})
except FileNotFoundError:
# someone else did the work for us
return False
except Exception as e:
print("Not deleting %s due to error %s" % (fname, e))
return False
return creds.lifetime == 0
return False
if __name__ == "__main__":
@@ -52,7 +60,8 @@ if __name__ == "__main__":
args = parser.parse_args()
os.environ["GSS_USE_PROXY"] = "yes"
os.environ["GSSPROXY_BEHAVIOR"] = "REMOTE_FIRST"
os.environ["GSSPROXY_BEHAVIOR"] = "REMOTE_ONLY"
os.environ["GSSPROXY_SOCKET"] = paths.IPA_CCACHE_SWEEPER_GSSPROXY_SOCK
print("Running sweeper...")
@@ -60,8 +69,12 @@ if __name__ == "__main__":
os.chdir(paths.IPA_CCACHES)
for fname in os.listdir(paths.IPA_CCACHES):
if should_delete(fname, t, args.minlife):
os.unlink(fname)
try:
if should_delete(fname, t, args.minlife):
os.unlink(fname)
except FileNotFoundError:
# someone else did the work for us
pass
print("Sweeper finished successfully!")
sys.exit(0)