File 0006-Rotate-child-log-files.patch of Package sssd.22444

From 57406881fe6efd0369d07429ce48afe254a94bf7 Mon Sep 17 00:00:00 2001
From: Josef Cejka <jcejka@suse.com>
Date: Mon, 24 Dec 2018 10:32:14 +0100
Subject: [PATCH] Rotate child log files

Registers child debug file descriptors of all loaded modules and rotate
them on SIGHUP.
---
 src/providers/ad/ad_gpo.c               | 11 ++++----
 src/providers/ipa/ipa_selinux.c         |  9 ++++---
 src/providers/krb5/krb5_child_handler.c |  2 +-
 src/providers/krb5/krb5_common.h        |  3 ++-
 src/providers/krb5/krb5_init_shared.c   |  6 ++---
 src/providers/ldap/ldap_common.c        |  5 +++-
 src/providers/ldap/ldap_common.h        |  2 +-
 src/providers/ldap/sdap_child_helpers.c |  4 +--
 src/responder/pam/pamsrv.c              |  1 -
 src/responder/pam/pamsrv.h              |  3 ++-
 src/responder/pam/pamsrv_cmd.c          |  2 +-
 src/responder/pam/pamsrv_p11.c          |  4 ++-
 src/util/child_common.c                 | 22 +++++++++++-----
 src/util/child_common.h                 | 12 ++++++++-
 src/util/debug.c                        | 17 ++++++++----
 src/util/server.c                       | 35 +++++++++++++++++++++++++
 src/util/util.h                         |  1 +
 17 files changed, 105 insertions(+), 34 deletions(-)

diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index d9ea31141..877ea994b 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -104,7 +104,10 @@
 #endif
 
 /* fd used by the gpo_child process for logging */
-int gpo_child_debug_fd = -1;
+struct child_debug gpo_child_debug = {
+    .fd = -1,
+    .filename =  "gpo_child"
+};
 
 /* == common data structures and declarations ============================= */
 
@@ -1419,11 +1422,9 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
     return ret;
 }
 
-#define GPO_CHILD_LOG_FILE "gpo_child"
-
 static errno_t gpo_child_init(void)
 {
-    return child_debug_init(GPO_CHILD_LOG_FILE, &gpo_child_debug_fd);
+    return child_debug_init(&gpo_child_debug);
 }
 
 /*
@@ -4287,7 +4288,7 @@ gpo_fork_child(struct tevent_req *req)
     if (pid == 0) { /* child */
         exec_child_ex(state,
                       pipefd_to_child, pipefd_from_child,
-                      GPO_CHILD, gpo_child_debug_fd, NULL, false,
+                      GPO_CHILD, gpo_child_debug.fd, NULL, false,
                       STDIN_FILENO, AD_GPO_CHILD_OUT_FILENO);
 
         /* We should never get here */
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 630f68ad5..4f3f54f1a 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -52,7 +52,10 @@
 #include <selinux/selinux.h>
 
 /* fd used by the selinux_child process for logging */
-int selinux_child_debug_fd = -1;
+struct child_debug selinux_child_debug = {
+    .fd = -1,
+    .filename = SELINUX_CHILD_LOG_FILE
+};
 
 static struct tevent_req *
 ipa_get_selinux_send(TALLOC_CTX *mem_ctx,
@@ -640,7 +643,7 @@ immediately:
 
 static errno_t selinux_child_init(void)
 {
-    return child_debug_init(SELINUX_CHILD_LOG_FILE, &selinux_child_debug_fd);
+    return child_debug_init(&selinux_child_debug);
 }
 
 static errno_t selinux_child_create_buffer(struct selinux_child_state *state)
@@ -712,7 +715,7 @@ static errno_t selinux_fork_child(struct selinux_child_state *state)
 
     if (pid == 0) { /* child */
         exec_child(state, pipefd_to_child, pipefd_from_child,
-                   SELINUX_CHILD, selinux_child_debug_fd);
+                   SELINUX_CHILD, selinux_child_debug.fd);
         DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec selinux_child: [%d][%s].\n",
               ret, sss_strerror(ret));
         return ret;
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index 352ff980d..3f5437656 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -461,7 +461,7 @@ static errno_t fork_child(struct tevent_req *req)
     if (pid == 0) { /* child */
         exec_child_ex(state,
                       pipefd_to_child, pipefd_from_child,
-                      KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd,
+                      KRB5_CHILD, state->kr->krb5_ctx->child_debug.fd,
                       krb5_child_extra_args, false,
                       STDIN_FILENO, STDOUT_FILENO);
 
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 48368a528..3e7b62422 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -31,6 +31,7 @@
 
 #include "providers/backend.h"
 #include "util/util.h"
+#include "util/child_common.h"
 #include "util/sss_krb5.h"
 
 #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s"
@@ -117,7 +118,7 @@ struct krb5_ctx {
     struct dp_option *opts;
     struct krb5_service *service;
     struct krb5_service *kpasswd_service;
-    int child_debug_fd;
+    struct child_debug child_debug;
 
     pcre *illegal_path_re;
 
diff --git a/src/providers/krb5/krb5_init_shared.c b/src/providers/krb5/krb5_init_shared.c
index 3901b7272..92f722deb 100644
--- a/src/providers/krb5/krb5_init_shared.c
+++ b/src/providers/krb5/krb5_init_shared.c
@@ -83,9 +83,9 @@ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx,
         goto done;
     }
 
-    krb5_auth_ctx->child_debug_fd = -1; /* -1 means not initialized */
-    ret = child_debug_init(KRB5_CHILD_LOG_FILE,
-                           &krb5_auth_ctx->child_debug_fd);
+    krb5_auth_ctx->child_debug.fd = -1; /* -1 means not initialized */
+    krb5_auth_ctx->child_debug.filename = KRB5_CHILD_LOG_FILE;
+    ret = child_debug_init(&krb5_auth_ctx->child_debug);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Could not set krb5_child debugging!\n");
         goto done;
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 91e229243..70c5429e8 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -38,7 +38,10 @@
 #include "providers/ldap/sdap_idmap.h"
 
 /* a fd the child process would log into */
-int ldap_child_debug_fd = -1;
+struct child_debug ldap_child_debug = {
+    .fd = -1,
+    .filename = LDAP_CHILD_LOG_FILE
+};
 
 int ldap_id_setup_tasks(struct sdap_id_ctx *ctx)
 {
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 44dbc3fb0..288d72673 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -43,7 +43,7 @@
 #define LDAP_ALLOWED_WILDCARDS "*"
 
 /* a fd the child process would log into */
-extern int ldap_child_debug_fd;
+extern struct child_debug ldap_child_debug;
 
 struct sdap_id_ctx;
 
diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c
index a03d28c9c..69a9c9e0b 100644
--- a/src/providers/ldap/sdap_child_helpers.c
+++ b/src/providers/ldap/sdap_child_helpers.c
@@ -111,7 +111,7 @@ static errno_t sdap_fork_child(struct tevent_context *ev,
     if (pid == 0) { /* child */
         exec_child(child,
                    pipefd_to_child, pipefd_from_child,
-                   LDAP_CHILD, ldap_child_debug_fd);
+                   LDAP_CHILD, ldap_child_debug.fd);
 
         /* We should never get here */
         DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Could not exec LDAP child\n");
@@ -518,5 +518,5 @@ static errno_t set_tgt_child_timeout(struct tevent_req *req,
 /* Setup child logging */
 int sdap_setup_child(void)
 {
-    return child_debug_init(LDAP_CHILD_LOG_FILE, &ldap_child_debug_fd);
+    return child_debug_init(&ldap_child_debug);
 }
diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c
index 5791686b9..86d04e400 100644
--- a/src/responder/pam/pamsrv.c
+++ b/src/responder/pam/pamsrv.c
@@ -321,7 +321,6 @@ static int pam_process_init(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    pctx->p11_child_debug_fd = -1;
     if (pctx->cert_auth) {
         ret = p11_child_init(pctx);
         if (ret != EOK) {
diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h
index dfd982178..f53082f83 100644
--- a/src/responder/pam/pamsrv.h
+++ b/src/responder/pam/pamsrv.h
@@ -24,6 +24,7 @@
 
 #include <security/pam_appl.h>
 #include "util/util.h"
+#include "util/child_common.h"
 #include "sbus/sssd_dbus.h"
 #include "responder/common/responder.h"
 #include "responder/common/cache_req/cache_req.h"
@@ -48,7 +49,7 @@ struct pam_ctx {
     char **app_services;
 
     bool cert_auth;
-    int p11_child_debug_fd;
+    struct child_debug p11_child_debug;
     char *nss_db;
     struct sss_certmap_ctx *sss_certmap_ctx;
 };
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 8610b6b80..e1ff8e8c7 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -1334,7 +1334,7 @@ static errno_t check_cert(TALLOC_CTX *mctx,
         return ret;
     }
 
-    req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd,
+    req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug.fd,
                               pctx->nss_db, p11_child_timeout,
                               cert_verification_opts, pctx->sss_certmap_ctx,
                               pd);
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 0c9822fe9..b6f4ba4ad 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -227,7 +227,9 @@ errno_t p11_child_init(struct pam_ctx *pctx)
         return ret;
     }
 
-    return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd);
+    pctx->p11_child_debug.filename = P11_CHILD_LOG_FILE;
+    pctx->p11_child_debug.fd = -1;
+    return child_debug_init(&pctx->p11_child_debug);
 }
 
 bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd)
diff --git a/src/util/child_common.c b/src/util/child_common.c
index 203c115f9..3420d6ad2 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -47,6 +47,8 @@ struct sss_child_ctx {
     struct sss_sigchild_ctx *sigchld_ctx;
 };
 
+struct child_debug *child_debug_list = NULL;
+
 static void sss_child_handler(struct tevent_context *ev,
                               struct tevent_signal *se,
                               int signum,
@@ -803,30 +805,36 @@ int child_io_destructor(void *ptr)
     return EOK;
 }
 
-errno_t child_debug_init(const char *logfile, int *debug_fd)
+errno_t child_debug_init(struct child_debug *cd)
 {
     int ret;
-    FILE *debug_filep;
 
-    if (debug_fd == NULL) {
+    if (cd == NULL) {
         return EOK;
     }
 
-    if (sss_logger == FILES_LOGGER && *debug_fd == -1) {
-        ret = open_debug_file_ex(logfile, &debug_filep, false);
+    if (sss_logger == FILES_LOGGER && cd->fd == -1) {
+        cd->filep = NULL;
+        cd->prev = NULL;
+        cd->next = NULL;
+        ret = open_debug_file_ex(cd->filename, &cd->filep, false);
         if (ret != EOK) {
             DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n",
                         ret, sss_strerror(ret));
             return ret;
         }
 
-        *debug_fd = fileno(debug_filep);
-        if (*debug_fd == -1) {
+        cd->fd = fileno(cd->filep);
+        if (cd->fd == -1) {
             DEBUG(SSSDBG_FATAL_FAILURE,
                   "fileno failed [%d][%s]\n", errno, strerror(errno));
             ret = errno;
+            fclose(cd->filep);
+            cd->filep = NULL;
             return ret;
         }
+
+        DLIST_ADD(child_debug_list, cd);
     }
 
     return EOK;
diff --git a/src/util/child_common.h b/src/util/child_common.h
index 37116e2a7..cddc7161b 100644
--- a/src/util/child_common.h
+++ b/src/util/child_common.h
@@ -53,6 +53,16 @@ struct child_io_fds {
     int write_to_child_fd;
 };
 
+struct child_debug {
+    const char *filename;
+    int fd;
+    FILE *filep;
+    struct child_debug *prev;
+    struct child_debug *next;
+};
+
+extern struct child_debug *child_debug_list;
+
 /* COMMON SIGCHLD HANDLING */
 typedef void (*sss_child_fn_t)(int pid, int wait_status, void *pvt);
 
@@ -119,6 +129,6 @@ void exec_child(TALLOC_CTX *mem_ctx,
 
 int child_io_destructor(void *ptr);
 
-errno_t child_debug_init(const char *logfile, int *debug_fd);
+errno_t child_debug_init(struct child_debug *child_debug);
 
 #endif /* __CHILD_COMMON_H__ */
diff --git a/src/util/debug.c b/src/util/debug.c
index 30801fce7..001445e5a 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -465,16 +465,18 @@ int open_debug_file(void)
     return open_debug_file_ex(NULL, NULL, true);
 }
 
-int rotate_debug_files(void)
+int rotate_debug_file(const char *filename, FILE **filep)
 {
     int ret;
     errno_t error;
 
     if (sss_logger != FILES_LOGGER) return EOK;
 
+    if (filep == NULL) return EOK;
+
     do {
         error = 0;
-        ret = fclose(debug_file);
+        ret = fclose(*filep);
         if (ret != 0) {
             error = errno;
         }
@@ -494,14 +496,19 @@ int rotate_debug_files(void)
          * leak and then proceed with opening the new file.
          */
         sss_log(SSS_LOG_ALERT, "Could not close debug file [%s]. [%d][%s]\n",
-                               debug_log_file, error, strerror(error));
+                               filename, error, strerror(error));
         sss_log(SSS_LOG_ALERT, "Attempting to open new file anyway. "
                                "Be aware that this is a resource leak\n");
     }
 
-    debug_file = NULL;
+    *filep = NULL;
+
+    return open_debug_file_ex(filename, filep, false);
+}
 
-    return open_debug_file();
+int rotate_debug_files(void)
+{
+    return rotate_debug_file(debug_log_file, &debug_file);
 }
 
 void talloc_log_fn(const char *message)
diff --git a/src/util/server.c b/src/util/server.c
index 62e09314c..8bd07b810 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -31,6 +31,7 @@
 #include <signal.h>
 #include <ldb.h>
 #include "util/util.h"
+#include "util/child_common.h"
 #include "confdb/confdb.h"
 #include "monitor/monitor_interfaces.h"
 
@@ -384,6 +385,33 @@ static void te_server_hup(struct tevent_context *ev,
     }
 }
 
+static int rotate_child_debug_files(void)
+{
+    struct child_debug *cd;
+    int ret;
+    int final_ret = EOK;
+
+    DLIST_FOR_EACH(cd, child_debug_list) {
+        ret = rotate_debug_file(cd->filename, &cd->filep);
+        if (ret == EOK) {
+            cd->fd = fileno(cd->filep);
+            if (cd->fd != -1) continue;
+
+            DEBUG(SSSDBG_FATAL_FAILURE,
+                "fileno failed [%d][%s]\n", errno, strerror(errno));
+            ret = errno;
+            fclose(cd->filep);
+            cd->filep = NULL;
+        }
+        /* save the first error and try to rotate remaining files */
+        if (final_ret == EOK) {
+             final_ret = ret;
+        }
+    }
+
+    return final_ret;
+}
+
 errno_t server_common_rotate_logs(struct confdb_ctx *confdb,
                                   const char *conf_path)
 {
@@ -397,6 +425,13 @@ errno_t server_common_rotate_logs(struct confdb_ctx *confdb,
         return ret;
     }
 
+    ret = rotate_child_debug_files();
+    if (ret) {
+        sss_log(SSS_LOG_ALERT, "Could not rotate child debug files! [%d][%s]\n",
+                               ret, strerror(ret));
+        return ret;
+    }
+
     /* Get new debug level from the confdb */
     ret = confdb_get_int(confdb, conf_path,
                          CONFDB_SERVICE_DEBUG_LEVEL,
diff --git a/src/util/util.h b/src/util/util.h
index ef8ef7f57..78ab02dce 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -151,6 +151,7 @@ int chown_debug_file(const char *filename, uid_t uid, gid_t gid);
 int open_debug_file_ex(const char *filename, FILE **filep, bool want_cloexec);
 int open_debug_file(void);
 int rotate_debug_files(void);
+int rotate_debug_file(const char *filename, FILE **filep);
 void talloc_log_fn(const char *msg);
 
 /* From sss_log.c */
-- 
2.21.0

openSUSE Build Service is sponsored by