[SSSD] [sssd PR#5776][synchronized] kcm: replace existing credentials to avoid unnecessary ccache growth

2021-09-13 Thread pbrezina
   URL: https://github.com/SSSD/sssd/pull/5776
Author: pbrezina
 Title: #5776: kcm: replace existing credentials to avoid unnecessary ccache 
growth
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5776/head:pr5776
git checkout pr5776
From 966ee10d89246925d647a712c64872bcfac4ee8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= 
Date: Tue, 7 Sep 2021 11:16:22 +0200
Subject: [PATCH 1/2] krb5: remove unused mem_ctx from
 get_krb5_data_from_cred()

Also don't return value since it is useless.
---
 src/responder/kcm/kcmsrv_ccache.c | 7 +--
 src/util/sss_krb5.c   | 6 +-
 src/util/sss_krb5.h   | 4 +---
 3 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index 8c447eacef..cc449877b3 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -333,12 +333,7 @@ krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
 cred_list = talloc_zero_array(tmp_ctx, krb5_creds *, count + 1);
 
 for (cred = kcm_cc_get_cred(cc); cred != NULL; cred = kcm_cc_next_cred(cred), i++) {
-ret = get_krb5_data_from_cred(tmp_ctx, cred->cred_blob, _data);
-if (ret != EOK) {
-DEBUG(SSSDBG_CRIT_FAILURE, "Failed to convert cred to krb5_data"
-   "[%d]: %s\n", ret, sss_strerror(ret));
-goto done;
-}
+get_krb5_data_from_cred(cred->cred_blob, _data);
 
 kerr = krb5_unmarshal_credentials(krb_context, _data,
   _list[i]);
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index cf96f3ffc4..3a2c9d6496 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -1211,14 +1211,10 @@ static errno_t iobuf_get_len_bytes(TALLOC_CTX *mem_ctx,
 return EOK;
 }
 
-errno_t get_krb5_data_from_cred(TALLOC_CTX *mem_ctx,
-struct sss_iobuf *iobuf,
-krb5_data *k5data)
+void get_krb5_data_from_cred(struct sss_iobuf *iobuf, krb5_data *k5data)
 {
 k5data->data = (char *) sss_iobuf_get_data(iobuf);
 k5data->length = sss_iobuf_get_size(iobuf);
-
-return EOK;
 }
 
 static errno_t get_krb5_data(TALLOC_CTX *mem_ctx,
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index aa1a258eb2..37158d803f 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -199,8 +199,6 @@ krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
 
 krb5_error_code sss_krb5_init_context(krb5_context *context);
 
-errno_t get_krb5_data_from_cred(TALLOC_CTX *mem_ctx,
-struct sss_iobuf *iobuf,
-krb5_data *k5data);
+void get_krb5_data_from_cred(struct sss_iobuf *iobuf, krb5_data *k5data);
 
 #endif /* __SSS_KRB5_H__ */

From 56af538e35acc643f81ad17ab70042587c199a4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= 
Date: Tue, 7 Sep 2021 11:01:45 +0200
Subject: [PATCH 2/2] kcm: replace existing credentials to avoid unnecessary
 ccache growth

Currently, we just append input credential to the ccache. This however
make the ccache grow over time as credentials expires and more control
credentials are stored.

Now we remove or credentials that are the same and overwrite them with
the input credential.

Resolves: https://github.com/SSSD/sssd/issues/5775

:fixes: KCM now replace the old credential with new one when storing
  an update credential that is however already present in the ccache
  to avoid unnecessary growth of the ccache.
---
 src/responder/kcm/kcmsrv_ccache.c | 93 ---
 src/util/sss_krb5.c   | 13 +
 src/util/sss_krb5.h   |  2 +
 3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index cc449877b3..522ccc138d 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -253,10 +253,91 @@ static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
 return dup;
 }
 
+#ifdef HAVE_KRB5_UNMARSHAL_CREDENTIALS
+static krb5_creds *kcm_cred_to_krb5(krb5_context kctx, struct kcm_cred *kcm_crd)
+{
+krb5_error_code kerr;
+krb5_creds *kcrd;
+krb5_data data;
+
+get_krb5_data_from_cred(kcm_crd->cred_blob, );
+
+kerr = krb5_unmarshal_credentials(kctx, , );
+if (kerr != 0) {
+DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unmarshal credentials\n");
+return NULL;
+}
+
+return kcrd;
+}
+#endif
+
+static errno_t
+kcm_cc_remove_duplicates(struct kcm_ccache *cc,
+ struct kcm_cred *kcm_crd)
+{
+#ifdef HAVE_KRB5_UNMARSHAL_CREDENTIALS
+struct kcm_cred *p, *q;
+krb5_error_code kerr;
+krb5_context kctx;
+krb5_creds *kcrd_cc;
+krb5_creds *kcrd;
+errno_t ret;
+bool bret;
+
+kerr = krb5_init_context();
+if (kerr != 

[SSSD] [sssd PR#5776][synchronized] kcm: replace existing credentials to avoid unnecessary ccache growth

2021-09-07 Thread pbrezina
   URL: https://github.com/SSSD/sssd/pull/5776
Author: pbrezina
 Title: #5776: kcm: replace existing credentials to avoid unnecessary ccache 
growth
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5776/head:pr5776
git checkout pr5776
From 128f09725cce510cef65aa1e11ae6b487f13fdee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= 
Date: Tue, 7 Sep 2021 11:16:22 +0200
Subject: [PATCH 1/2] krb5: remove unused mem_ctx from
 get_krb5_data_from_cred()

Also don't return value since it is useless.
---
 src/responder/kcm/kcmsrv_ccache.c | 7 +--
 src/util/sss_krb5.c   | 6 +-
 src/util/sss_krb5.h   | 4 +---
 3 files changed, 3 insertions(+), 14 deletions(-)

diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index 8c447eacef..cc449877b3 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -333,12 +333,7 @@ krb5_creds **kcm_cc_unmarshal(TALLOC_CTX *mem_ctx,
 cred_list = talloc_zero_array(tmp_ctx, krb5_creds *, count + 1);
 
 for (cred = kcm_cc_get_cred(cc); cred != NULL; cred = kcm_cc_next_cred(cred), i++) {
-ret = get_krb5_data_from_cred(tmp_ctx, cred->cred_blob, _data);
-if (ret != EOK) {
-DEBUG(SSSDBG_CRIT_FAILURE, "Failed to convert cred to krb5_data"
-   "[%d]: %s\n", ret, sss_strerror(ret));
-goto done;
-}
+get_krb5_data_from_cred(cred->cred_blob, _data);
 
 kerr = krb5_unmarshal_credentials(krb_context, _data,
   _list[i]);
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index cf96f3ffc4..3a2c9d6496 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -1211,14 +1211,10 @@ static errno_t iobuf_get_len_bytes(TALLOC_CTX *mem_ctx,
 return EOK;
 }
 
-errno_t get_krb5_data_from_cred(TALLOC_CTX *mem_ctx,
-struct sss_iobuf *iobuf,
-krb5_data *k5data)
+void get_krb5_data_from_cred(struct sss_iobuf *iobuf, krb5_data *k5data)
 {
 k5data->data = (char *) sss_iobuf_get_data(iobuf);
 k5data->length = sss_iobuf_get_size(iobuf);
-
-return EOK;
 }
 
 static errno_t get_krb5_data(TALLOC_CTX *mem_ctx,
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index aa1a258eb2..37158d803f 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -199,8 +199,6 @@ krb5_error_code sss_krb5_unmarshal_princ(TALLOC_CTX *mem_ctx,
 
 krb5_error_code sss_krb5_init_context(krb5_context *context);
 
-errno_t get_krb5_data_from_cred(TALLOC_CTX *mem_ctx,
-struct sss_iobuf *iobuf,
-krb5_data *k5data);
+void get_krb5_data_from_cred(struct sss_iobuf *iobuf, krb5_data *k5data);
 
 #endif /* __SSS_KRB5_H__ */

From d171992d6915cc2cc60d309eafdcbf197ff9556e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= 
Date: Tue, 7 Sep 2021 11:01:45 +0200
Subject: [PATCH 2/2] kcm: replace existing credentials to avoid unnecessary
 ccache growth

Currently, we just append input credential to the ccache. This however
make the ccache grow over time as credentials expires and more control
credentials are stored.

Now we remove or credentials that are the same and overwrite them with
the input credential.

Resolves: https://github.com/SSSD/sssd/issues/5775

:fixes: KCM now replace the old credential with new one when storing
  an update credential that is however already present in the ccache
  to avoid unnecessary growth of the ccache.
---
 src/responder/kcm/kcmsrv_ccache.c | 93 ---
 src/util/sss_krb5.c   | 13 +
 src/util/sss_krb5.h   |  2 +
 3 files changed, 99 insertions(+), 9 deletions(-)

diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c
index cc449877b3..522ccc138d 100644
--- a/src/responder/kcm/kcmsrv_ccache.c
+++ b/src/responder/kcm/kcmsrv_ccache.c
@@ -253,10 +253,91 @@ static struct kcm_cred *kcm_cred_dup(TALLOC_CTX *mem_ctx,
 return dup;
 }
 
+#ifdef HAVE_KRB5_UNMARSHAL_CREDENTIALS
+static krb5_creds *kcm_cred_to_krb5(krb5_context kctx, struct kcm_cred *kcm_crd)
+{
+krb5_error_code kerr;
+krb5_creds *kcrd;
+krb5_data data;
+
+get_krb5_data_from_cred(kcm_crd->cred_blob, );
+
+kerr = krb5_unmarshal_credentials(kctx, , );
+if (kerr != 0) {
+DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unmarshal credentials\n");
+return NULL;
+}
+
+return kcrd;
+}
+#endif
+
+static errno_t
+kcm_cc_remove_duplicates(struct kcm_ccache *cc,
+ struct kcm_cred *kcm_crd)
+{
+#ifdef HAVE_KRB5_UNMARSHAL_CREDENTIALS
+struct kcm_cred *p, *q;
+krb5_error_code kerr;
+krb5_context kctx;
+krb5_creds *kcrd_cc;
+krb5_creds *kcrd;
+errno_t ret;
+bool bret;
+
+kerr = krb5_init_context();
+if (kerr !=