--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/krb5/patches/019-log-rotation.patch Wed Feb 24 10:43:57 2016 -0600
@@ -0,0 +1,274 @@
+#
+# This patch is to provide internal log rotation functionality for both
+# kadmind & krb5kdc daemons. The functionality is defined in krb5.conf
+# man page via 'admin_server_rotate' & 'kdc_rotate' parameters.
+#
+# Following two relations can be specified:
+#
+# period = delta_time
+# versions = number
+#
+# NOTE:
+#
+# MIT Kerberos Consortium did not accept new features for MIT kerberos 1.13
+# release. For that matter, we would like to try to push this log rotation
+# functionality in later MIT kerberos release, 1.14 or later.
+# Patch source: in-house
+#
+--- ORIGINAL/src/lib/kadm5/logger.c 2014-08-11 02:19:59.000000000 -0700
++++ krb5-1.13.mockup/src/lib/kadm5/logger.c 2014-09-11 17:13:22.608854008 -0700
+@@ -115,6 +115,13 @@
+ struct log_file {
+ FILE *lf_filep;
+ char *lf_fname;
++ /* Solaris Kerberos */
++ char *lf_fopen_mode; /* "a+" or "w" */
++#define K_LOG_DEF_FILE_ROTATE_PERIOD -1 /* never */
++#define K_LOG_DEF_FILE_ROTATE_VERSIONS 0 /* no versions */
++ time_t lf_rotate_period;
++ time_t lf_last_rotated;
++ int lf_rotate_versions;
+ } log_file;
+ struct log_syslog {
+ int ls_facility;
+@@ -128,6 +135,11 @@
+ };
+ #define lfu_filep log_union.log_file.lf_filep
+ #define lfu_fname log_union.log_file.lf_fname
++/* Solaris Kerberos */
++#define lfu_fopen_mode log_union.log_file.lf_fopen_mode
++#define lfu_rotate_period log_union.log_file.lf_rotate_period
++#define lfu_last_rotated log_union.log_file.lf_last_rotated
++#define lfu_rotate_versions log_union.log_file.lf_rotate_versions
+ #define lsu_facility log_union.log_syslog.ls_facility
+ #define lsu_severity log_union.log_syslog.ls_severity
+ #define ldu_filep log_union.log_device.ld_filep
+@@ -161,6 +173,133 @@
+ -1)
+ #define DEVICE_CLOSE(d) fclose(d)
+
++/*
++ * Solaris Kerberos
++ * klog_rotate() - roate a log file if we have specified rotation
++ * parameters in krb5.conf.
++ */
++static void
++klog_rotate(struct log_entry *le)
++{
++ time_t t;
++ int i;
++ char *name_buf1;
++ char *name_buf2;
++ char *old_name;
++ char *new_name;
++ char *tmp;
++ FILE *fp;
++ int num_vers;
++ mode_t old_umask;
++
++
++ /*
++ * By default we don't rotate.
++ */
++ if (le->lfu_rotate_period == K_LOG_DEF_FILE_ROTATE_PERIOD)
++ return;
++
++ t = time(0);
++
++ if (t >= le->lfu_last_rotated + le->lfu_rotate_period) {
++ /*
++ * The N log file versions will be renamed X.N-1 X.N-2, ... X.0.
++ * So the allocate file name buffers that can the version
++ * number extensions.
++ * 32 extra bytes is plenty.
++ */
++ name_buf1 = malloc(strlen(le->lfu_fname) + 32);
++
++ if (name_buf1 == NULL)
++ return;
++
++ name_buf2 = malloc(strlen(le->lfu_fname) + 32);
++
++ if (name_buf2 == NULL) {
++ free(name_buf1);
++ return;
++ }
++
++ old_name = name_buf1;
++ new_name = name_buf2;
++
++ /*
++ * If there N versions, then the first one has file extension
++ * of N-1.
++ */
++ (void) sprintf(new_name, "%s.%d", le->lfu_fname,
++ le->lfu_rotate_versions - 1);
++
++ /*
++ * Rename file.N-2 to file.N-1, file.N-3 to file.N-2, ...
++ * file.0 to file.1
++ */
++ for (i = le->lfu_rotate_versions - 1; i > 0; i--) {
++ (void) sprintf(old_name, "%s.%d", le->lfu_fname, i - 1);
++ (void) rename(old_name, new_name);
++
++ /*
++ * swap old name and new name. This way,
++ * on the next iteration, new_name.X
++ * becomes new_name.X-1.
++ */
++ tmp = old_name;
++ old_name = new_name;
++ new_name = tmp;
++ }
++ old_name = le->lfu_fname;
++
++ (void) rename(old_name, new_name);
++
++ /*
++ * Even though we don't know yet if the fopen()
++ * of the log file will succeed, we mark the log
++ * as rotated. This is so we don't repeatably
++ * rotate file.N-2 to file.N-1 ... etc without
++ * waiting for the rotate period to elapse.
++ */
++ le->lfu_last_rotated = t;
++
++ /*
++ * Default log file creation mode should be read-only
++ * by owner(root), but the admin can override with
++ * chmod(1) if desired.
++ */
++
++ old_umask = umask(077);
++ fp = fopen(old_name, le->lfu_fopen_mode);
++
++ umask(old_umask);
++
++ if (fp != NULL) {
++
++ (void) fclose(le->lfu_filep);
++ le->lfu_filep = fp;
++
++ /*
++ * If the version parameter in krb5.conf was
++ * 0, then we take this to mean that rotating the
++ * log file will cause us to dispose of the
++ * old one, and created a new one. We have just
++ * renamed the old one to file.-1, so remove it.
++ */
++ if (le->lfu_rotate_versions <= 0)
++ (void) unlink(new_name);
++
++ } else {
++ fprintf(stderr,
++ _("During rotate, couldn't open log file %s: %s\n"),
++ old_name, error_message(errno));
++ /*
++ * Put it back.
++ */
++ (void) rename(new_name, old_name);
++ }
++ free(name_buf1);
++ free(name_buf2);
++ }
++}
++
+
+ /*
+ * klog_com_err_proc() - Handle com_err(3) messages as specified by the
+@@ -276,6 +415,8 @@
+ for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
+ switch (log_control.log_entries[lindex].log_type) {
+ case K_LOG_FILE:
++ /* Solaris Kerberos */
++ klog_rotate(&log_control.log_entries[lindex]);
+ case K_LOG_STDERR:
+ /*
+ * Files/standard error.
+@@ -360,6 +501,7 @@
+ int error;
+ int do_openlog, log_facility;
+ FILE *f;
++ mode_t old_umask;
+
+ /* Initialize */
+ do_openlog = 0;
+@@ -423,12 +565,66 @@
+ * Check for append/overwrite, then open the file.
+ */
+ if (cp[4] == ':' || cp[4] == '=') {
+- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
++ /* Solaris Kerberos */
++ log_control.log_entries[i].lfu_fopen_mode =
++ (cp[4] == ':') ? "a" : "w";
++ old_umask = umask(077);
++ f = fopen(&cp[5],
++ log_control.log_entries[i].lfu_fopen_mode);
++ umask(old_umask);
+ if (f) {
+- set_cloexec_file(f);
++ char rotate_kw[128];
+ log_control.log_entries[i].lfu_filep = f;
+ log_control.log_entries[i].log_type = K_LOG_FILE;
+ log_control.log_entries[i].lfu_fname = &cp[5];
++ log_control.log_entries[i].lfu_rotate_period =
++ K_LOG_DEF_FILE_ROTATE_PERIOD;
++ log_control.log_entries[i].lfu_rotate_versions =
++ K_LOG_DEF_FILE_ROTATE_VERSIONS;
++ log_control.log_entries[i].lfu_last_rotated =
++ time(0);
++
++ /*
++ * Now parse for ename_"rotate" = {
++ * period = XXX
++ * versions = 10
++ * }
++ */
++ if (strlen(ename) + strlen("_rotate") <
++ sizeof (rotate_kw)) {
++
++ char *time;
++ krb5_deltat dt;
++ int vers;
++
++ strcpy(rotate_kw, ename);
++ strcat(rotate_kw, "_rotate");
++
++ if (!profile_get_string(kcontext->profile,
++ "logging", rotate_kw,
++ "period", NULL,
++ &time)) {
++
++ if (time != NULL) {
++ if (!krb5_string_to_deltat(time,
++ &dt)) {
++ log_control.log_entries[i].lfu_rotate_period =
++ (time_t) dt;
++ }
++ free(time);
++ }
++ }
++
++ if (!profile_get_integer(
++ kcontext->profile,
++ "logging", rotate_kw,
++ "versions",
++ K_LOG_DEF_FILE_ROTATE_VERSIONS,
++ &vers)) {
++ log_control.log_entries[i].lfu_rotate_versions = vers;
++ }
++
++ }
+ } else {
+ fprintf(stderr,"Couldn't open log file %s: %s\n",
+ &cp[5], error_message(errno));
+@@ -880,6 +1076,8 @@
+ for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
+ switch (log_control.log_entries[lindex].log_type) {
+ case K_LOG_FILE:
++ /* Solaris Kerberos */
++ klog_rotate(&log_control.log_entries[lindex]);
+ case K_LOG_STDERR:
+ /*
+ * Files/standard error.