- Improve permissions checks in run-cron. Just check if the permission

matches completely. Otherwise e.g. setgid directories causes failures

OBS-URL: https://build.opensuse.org/package/show/Base:System/cronie?expand=0&rev=224
This commit is contained in:
Marcus Meissner 2024-07-20 18:19:58 +00:00 committed by Git OBS Bridge
commit c6d73cb753
16 changed files with 2426 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.osc

14
cron.service Normal file
View File

@ -0,0 +1,14 @@
[Unit]
Description=Command Scheduler
After=nss-user-lookup.target network.target time-sync.target
After=postfix.service sendmail.service exim.service
[Service]
ExecStart=/usr/sbin/cron -n
ExecReload=/usr/bin/kill -s SIGHUP $MAINPID
Restart=on-abort
KillMode=process
TasksMax=infinity
[Install]
WantedBy=multi-user.target

5
cron_to_cronie.README Normal file
View File

@ -0,0 +1,5 @@
package cron 4.2 is only auxiliary package needed for proper renaming package cron to cronie
usefull links :
http://en.opensuse.org/Cron_replace
http://en.opensuse.org/Cron_rename

3
cronie-1.7.2.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:241ecc1dcd8d4b2a6744fe93509932254d20b7bb9d979d27429809493806357f
size 156043

13
cronie-crond_pid.diff Normal file
View File

@ -0,0 +1,13 @@
Index: cronie-cronie-1.7.0/src/pathnames.h
===================================================================
--- cronie-cronie-1.7.0.orig/src/pathnames.h
+++ cronie-cronie-1.7.0/src/pathnames.h
@@ -45,7 +45,7 @@
# define PIDDIR SYSCONFDIR "/"
# endif
#endif
-#define PIDFILE "crond.pid"
+#define PIDFILE "cron.pid"
#define _PATH_CRON_PID PIDDIR PIDFILE
#define REBOOT_LOCK PIDDIR "cron.reboot"

101
cronie-nheader_lines.diff Normal file
View File

@ -0,0 +1,101 @@
Index: src/crontab.c
===================================================================
--- src/crontab.c.orig
+++ src/crontab.c
@@ -64,7 +64,7 @@
#include "pathnames.h"
#include "structs.h"
-#define NHEADER_LINES 0
+#define NHEADER_LINES 3
#define COMMENT_COLOR "\x1B[34;1m"
#define ERROR_COLOR "\x1B[31;1m"
@@ -418,7 +418,7 @@ static void parse_args(int argc, char *a
static void list_cmd(void) {
char n[MAX_FNAME];
FILE *f;
- int ch;
+ int ch, x;
const int colorize = isatty(STDOUT) && getenv("NO_COLOR") == NULL;
int new_line = 1;
int in_comment = 0;
@@ -439,6 +439,22 @@ static void list_cmd(void) {
/* file is open. copy to stdout, close.
*/
Set_LineNum(1);
+ /* ignore the top few comments since we probably put them there.
+ */
+ x = 0;
+ while (EOF != (ch = get_char(f))) {
+ if ('#' != ch) {
+ putchar(ch);
+ break;
+ }
+ while (EOF != (ch = get_char(f)))
+ if (ch == '\n')
+ break;
+ if (++x >= NHEADER_LINES)
+ break;
+ }
+ /* copy the rest of the crontab (if any) to the stdout.
+ */
while (EOF != (ch = get_char(f))) {
if (colorize) {
if (!in_comment && new_line && ch == '#') {
@@ -646,7 +662,7 @@ static void edit_cmd(void) {
char n[MAX_FNAME], q[MAX_TEMPSTR];
const char *editor;
FILE *f;
- int ch = '\0', t;
+ int ch = '\0', t, x;
struct stat statbuf;
struct utimbuf utimebuf;
WAIT_T waiter;
@@ -698,10 +714,20 @@ static void edit_cmd(void) {
}
Set_LineNum(1);
- /*
- * NHEADER_LINES processing removed for clarity
- * (NHEADER_LINES == 0 in all Red Hat crontabs)
+ /* ignore the top few comments since we probably put them there.
*/
+ x = 0;
+ while (EOF != (ch = get_char(f))) {
+ if ('#' != ch) {
+ putc(ch, NewCrontab);
+ break;
+ }
+ while (EOF != (ch = get_char(f)))
+ if (ch == '\n')
+ break;
+ if (++x >= NHEADER_LINES)
+ break;
+ }
/* copy the rest of the crontab (if any) to the temp file.
*/
if (EOF != ch)
@@ -925,6 +951,7 @@ static int replace_cmd(void) {
int ch, fd;
int error = 0;
uid_t file_owner;
+ time_t now = time(NULL);
char *safename;
safename = host_specific_filename("#tmp", "XXXXXXXXXX");
@@ -952,10 +979,10 @@ static int replace_cmd(void) {
*
* VERY IMPORTANT: make sure NHEADER_LINES agrees with this code.
*/
- /*fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
- *fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
- *fprintf(tmp, "# (Cron version %s)\n", CRON_VERSION);
- */
+ fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n");
+ fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now));
+ fprintf(tmp, "# (Cronie version %s)\n", CRON_VERSION);
+
#ifdef WITH_SELINUX
if (selinux_context)
fprintf(tmp, "SELINUX_ROLE_TYPE=%s\n", selinux_context);

View File

@ -0,0 +1,14 @@
---
pam/crond | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: cronie-cronie-1.7.0/pam/crond
===================================================================
--- cronie-cronie-1.7.0.orig/pam/crond
+++ cronie-cronie-1.7.0/pam/crond
@@ -10,4 +10,4 @@ auth include common-auth
account include common-account
password include common-password
session optional pam_keyinit.so force revoke
-session include common-session
+session include common-session-nonlogin

20
cronie-pam_config.diff Normal file
View File

@ -0,0 +1,20 @@
Index: cronie-cronie-1.7.0/pam/crond
===================================================================
--- cronie-cronie-1.7.0.orig/pam/crond
+++ cronie-cronie-1.7.0/pam/crond
@@ -4,8 +4,10 @@
#
# Although no PAM authentication is called, auth modules
# are used for credential setting
-auth include system-auth
-account required pam_access.so
-account include system-auth
-session required pam_loginuid.so
-session include system-auth
+auth sufficient pam_rootok.so
+account sufficient pam_listfile.so item=user sense=allow file=/etc/cron.allow onerr=succeed quiet
+auth include common-auth
+account include common-account
+password include common-password
+session optional pam_keyinit.so force revoke
+session include common-session

1542
cronie.changes Normal file

File diff suppressed because it is too large Load Diff

257
cronie.spec Normal file
View File

@ -0,0 +1,257 @@
#
# spec file for package cronie
#
# Copyright (c) 2024 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
%define cron_configs %{_sysconfdir}/pam.d/crond %{_sysconfdir}/crontab %{_sysconfdir}/cron.deny
#Compat macro for new _fillupdir macro introduced in Nov 2017
%if ! %{defined _fillupdir}
%define _fillupdir %{_localstatedir}/adm/fillup-templates
%endif
Name: cronie
Version: 1.7.2
Release: 0
Summary: Cron Daemon
License: BSD-3-Clause AND GPL-2.0-only AND MIT
Group: System/Daemons
URL: https://github.com/cronie-crond/%{name}
Source0: https://github.com/cronie-crond/%{name}/archive/%{name}-%{version}.tar.gz
Source2: run-crons
Source3: sample.root
Source4: deny.sample
Source7: cron_to_cronie.README
Source8: cron.service
Source9: sysconfig.cron
# PATCH-FEATURE-OPENSUSE cronie-pam_config.diff added pam config file from old cron
Patch3: cronie-pam_config.diff
# openSUSE set NHEADER_LINES to 3 - old openSUSE cron put three lines of comments
# in top of crontab file, so we want to hide this junk comments if user edit
# crontab file with crontab -e command, patch grabbed from old openSUSE cron
Patch4: cronie-nheader_lines.diff
# we use cron.pid instead of crond.pid
Patch5: cronie-crond_pid.diff
# PATCH-FIX-SUSE the first occurance of "/etc/anacrontab" was replaced by "/etc/crontab"
# in manpage file because the /etc/crontab is still used in SUSE.
Patch13: fix-manpage-replace-anacrontab-with-crontab.patch
# PATCH-FEATURE-OPENSUSE user common-session-nonlogin
Patch14: cronie-pam_config-nonlogin.diff
BuildRequires: audit-devel
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: libselinux-devel
BuildRequires: pam-devel
BuildRequires: pkgconfig
BuildRequires: pkgconfig(systemd)
Requires: mail
Requires(post): %fillup_prereq
Requires(post): debianutils
Requires(post): permissions
Requires(pre): cron
Suggests: mailx
Conflicts: cron <= 4.1
%{?systemd_requires}
# This is needed as cron subpkg has its own version
%{expand: %%define cronie_version %{version}}
%if 0%{?suse_version} >= 1330
Requires(pre): group(trusted)
%endif
%description
cron automatically starts programs at specific times. Add new entries
with "crontab -e". (See "man 5 crontab" and "man 1 crontab" for
documentation.)
Under /etc, find the directories cron.hourly, cron.daily, cron.weekly,
and cron.monthly. Scripts and programs that are located there are
started automatically.
%package -n cron
Version: 4.2
Release: 0
Summary: Auxiliary package
Group: System/Daemons
Requires: %{name} = %{cronie_version}-%{release}
Requires(post): permissions
%description -n cron
Auxiliary package, needed for proper update from vixie-cron 4.1 to cronie 1.4.4
%package anacron
Summary: Utility for running regular jobs
Group: System/Base
Requires: %{name} = %{cronie_version}
%description anacron
Anacron becames part of cronie. Anacron is used only for running regular jobs.
The default settings execute regular jobs by anacron, however this could be
overloaded in settings.
%prep
%setup -q -n %{name}-%{name}-%{cronie_version}
%patch -P 3 -p1
%patch -P 4
%patch -P 5 -p1
cp %{SOURCE7} ./cron_to_cronie.README
%patch -P 13 -p1
%if 0%{?suse_version} > 1500
%patch -P 14 -p1
%endif
%build
# fill macro CRON_VERSION it is used in top three lines of crontab file,should be reworked
export CFLAGS="%{optflags} -DCRON_VERSION=\\\"%{version}\\\""
export LDFLAGS="-Wl,-z,relro,-z,now,-z,defs"
autoreconf -f -i
%configure \
--with-audit \
--enable-anacron \
--with-pam \
--with-selinux \
--with-inotify \
--enable-pie \
SPOOL_DIR="%{_localstatedir}/spool/cron/tabs"
%make_build
%install
%make_install
mkdir -p -v %{buildroot}%{_localstatedir}/spool/cron/{tabs,lastrun}
mkdir -p -v %{buildroot}%{_sysconfdir}/cron.{d,hourly,daily,weekly,monthly}
install -v -m 600 %{SOURCE3} %{buildroot}%{_sysconfdir}/crontab
install -v -m 600 %{SOURCE4} %{buildroot}%{_sysconfdir}/cron.deny
install -v -d %{buildroot}%{_libexecdir}/cron
install -v %{SOURCE2} %{buildroot}%{_libexecdir}/cron
ln -s -f %{_sbindir}/service %{buildroot}%{_sbindir}/rccron
install -v -d %{buildroot}/%{_unitdir}
install -v -m 644 %{SOURCE8} %{buildroot}/%{_unitdir}
install -m 644 contrib/anacrontab %{buildroot}%{_sysconfdir}/anacrontab
install -c -m755 contrib/0anacron %{buildroot}%{_sysconfdir}/cron.hourly/0anacron
mkdir -p %{buildroot}%{_localstatedir}/spool/anacron
mv %{buildroot}%{_sbindir}/crond %{buildroot}%{_sbindir}/cron
mkdir -p %{buildroot}%{_fillupdir}
cp %{SOURCE9} %{buildroot}%{_fillupdir}/
mkdir -p %{buildroot}%{_sysconfdir}/cron.d
mkdir -p %{buildroot}%{_sysconfdir}/cron.hourly
mkdir -p %{buildroot}%{_sysconfdir}/cron.daily
mkdir -p %{buildroot}%{_sysconfdir}/cron.weekly
mkdir -p %{buildroot}%{_sysconfdir}/cron.monthly
touch %{buildroot}%{_localstatedir}/spool/anacron/cron.daily
touch %{buildroot}%{_localstatedir}/spool/anacron/cron.weekly
touch %{buildroot}%{_localstatedir}/spool/anacron/cron.monthly
%if 0%{?suse_version} > 1500
mkdir -p %{buildroot}%{_pam_vendordir}
mv %{buildroot}%{_sysconfdir}/pam.d/crond %{buildroot}%{_pam_vendordir}/
%endif
%pre
%if 0%{?suse_version} > 1500
# Prepare for migration to /usr/etc; save any old .rpmsave
for i in pam.d/crond ; do
test -f %{_sysconfdir}/${i}.rpmsave && mv -v %{_sysconfdir}/${i}.rpmsave %{_sysconfdir}/${i}.rpmsave.old ||:
done
%endif
%service_add_pre cron.service
%post
%set_permissions %{_sysconfdir}/crontab %{_bindir}/crontab
%{fillup_only -n cron}
%service_add_post cron.service
exit 0
%if 0%{?suse_version} > 1500
%posttrans
# Migration to /usr/etc, restore just created .rpmsave
for i in pam.d/crond ; do
test -f %{_sysconfdir}/${i}.rpmsave && mv -v %{_sysconfdir}/${i}.rpmsave %{_sysconfdir}/${i} ||:
done
%endif
%verifyscript
%verify_permissions -e %{_sysconfdir}/crontab -e %{_bindir}/crontab
%preun
%service_del_preun cron.service
%postun
%service_del_postun cron.service
%post anacron
[ -e %{_localstatedir}/spool/anacron/cron.daily ] || touch %{_localstatedir}/spool/anacron/cron.daily
[ -e %{_localstatedir}/spool/anacron/cron.weekly ] || touch %{_localstatedir}/spool/anacron/cron.weekly
[ -e %{_localstatedir}/spool/anacron/cron.monthly ] || touch %{_localstatedir}/spool/anacron/cron.monthly
%verifyscript -n cron
%verify_permissions -e %{_sysconfdir}/cron.d/
%verify_permissions -e %{_sysconfdir}/cron.daily/
%verify_permissions -e %{_sysconfdir}/cron.hourly/
%verify_permissions -e %{_sysconfdir}/cron.monthly/
%verify_permissions -e %{_sysconfdir}/cron.weekly/
%post -n cron
%set_permissions %{_sysconfdir}/cron.d/
%set_permissions %{_sysconfdir}/cron.daily/
%set_permissions %{_sysconfdir}/cron.hourly/
%set_permissions %{_sysconfdir}/cron.monthly/
%set_permissions %{_sysconfdir}/cron.weekly/
%files
%license COPYING
%doc AUTHORS README ChangeLog
%dir %attr(700,root,root) %{_localstatedir}/spool/cron
%dir %attr(700,root,root) %{_localstatedir}/spool/cron/tabs
%dir %{_localstatedir}/spool/cron/lastrun
%if 0%{?suse_version} > 1500
%{_pam_vendordir}/crond
%else
%config %{_sysconfdir}/pam.d/crond
%endif
%verify(not mode) %config(noreplace) %{_sysconfdir}/crontab
%config(noreplace) %{_sysconfdir}/cron.deny
%{_mandir}/man1/crontab.1%{?ext_man}
%{_mandir}/man5/crontab.5%{?ext_man}
%{_mandir}/man8/cron.8%{?ext_man}
%{_mandir}/man8/crond.8%{?ext_man}
%{_mandir}/man1/cronnext.1%{?ext_man}
%verify(not mode) %attr (4750,root,trusted) %{_bindir}/crontab
%attr (755,root,root) %{_sbindir}/cron
%attr (755,root,root) %{_bindir}/cronnext
%{_sbindir}/rccron
%{_libexecdir}/cron
%{_unitdir}/cron.service
%{_fillupdir}/sysconfig.cron
%files anacron
%{_sbindir}/anacron
%attr(0755,root,root) %{_sysconfdir}/cron.hourly/0anacron
%config(noreplace) %{_sysconfdir}/anacrontab
%dir %{_localstatedir}/spool/anacron
%ghost %verify(not md5 size mtime) %{_localstatedir}/spool/anacron/cron.daily
%ghost %verify(not md5 size mtime) %{_localstatedir}/spool/anacron/cron.weekly
%ghost %verify(not md5 size mtime) %{_localstatedir}/spool/anacron/cron.monthly
%{_mandir}/man5/anacrontab.5%{?ext_man}
%{_mandir}/man8/anacron.8%{?ext_man}
%files -n cron
%doc cron_to_cronie.README
%dir %attr(755,root,root) %{_sysconfdir}/cron.d
%dir %attr(755,root,root) %{_sysconfdir}/cron.hourly
%dir %attr(755,root,root) %{_sysconfdir}/cron.daily
%dir %attr(755,root,root) %{_sysconfdir}/cron.weekly
%dir %attr(755,root,root) %{_sysconfdir}/cron.monthly
%changelog

1
deny.sample Normal file
View File

@ -0,0 +1 @@
guest

View File

@ -0,0 +1,24 @@
From 8769bba06b1632c6bd275f88c0fd10f591efdb9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Krist=C3=BDna=20Streitov=C3=A1?= <kstreitova@suse.cz>
Date: Mon, 22 Sep 2014 10:41:14 +0200
Subject: [PATCH] fix manpage replace anacrontab with crontab
/etc/anacrontab replaced by /etc/crontab in the first occurance of it.
Fixes bnc#833240
---
man/cron.8 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: cronie-cronie-1.7.0/man/cron.8
===================================================================
--- cronie-cronie-1.7.0.orig/man/cron.8
+++ cronie-cronie-1.7.0/man/cron.8
@@ -56,7 +56,7 @@ for crontab files which are named after
The found crontabs are loaded into the memory.
.I Cron
also searches for
-.I /etc/anacrontab
+.I /etc/crontab
and any files in the
.I /etc/cron.d
directory, which have a different format (see

297
run-crons Normal file
View File

@ -0,0 +1,297 @@
#!/bin/bash
#
# /usr/libexec/cron/run-crons
#
# Copyright (c) 1998-2001 SuSE GmbH Nuernberg, Germany. All rights reserved.
#
# this script looks into /etc/cron.{hourly,daily,weekly,monthly} for
# scripts to be executed. The info about last run is stored in
# /var/spool/cron/lastrun
#
# concept similar to debian and redhat
#
# Changes:
# 1998 - Burchard Steinbild <bs@suse.de>, 1998
# initial version
# before 2001 - va@org.chemie.uni-frankfurt.de
# send an email with name of date-script instead of cron entry
# "Subject: cronjob@www - daily - FAILURE"
# (better one script for each date-sub-script)
# requires changes to /etc/crontab
# append > /dev/null 2>&1 to the line calling run-cons
# 2001-09-11
# updated to Suse 7.2 merged
# 2001-09-12
# changed FAILURE detection, until now all scripts with output
# had "failed", now only scripts with error status != 0
# have failed.
# 2001-09-13 - ro@suse.de
# merged with 7.3: call logger with exit value for scripts
# respect MAILTO as cron does
# use mktemp -d for all tmpfiles
# add variable to disable mail if all jobs returned 0
# 2015-06-25 - jmatejek@suse.com
# bnc#812367 support MAILFROM as cron does
# 2016-08-08 - tchvatal@suse.com
# bnc#983925 run crons even on battery
# 2017-10-24 - jsegitz@suse.de
# bsc#1062722 - harden run-cron to ensure correct directory permissions
if [ -f /etc/sysconfig/cron ]; then
. /etc/sysconfig/cron
fi
BASENAME=`/usr/bin/basename $0`
LOGGER="/bin/logger -t $BASENAME[$$]"
export LC_TIME=POSIX
TMPDIR=`mktemp -d /tmp/run-crons.XXXXXX`
trap "rm -rf $TMPDIR" 0 1 2 3 13 15
# We will force to run cron.daily after 14 days, even
# if you set MAX_NOT_RUN in /etc/sysconfig/cron
# value is in minutes
MAX_NOT_RUN_FORCE="20160"
# Priority change for sub scripts.
# range: highest -20 ... 19 lowest prioriy
# default processes start in level 10
CRON_SCRIPT_NICE_VALUE=15
SPOOL=/var/spool/cron/lastrun
# CRON Result EMail is sent to
if [ -z "$MAILTO" ]; then
SEND_TO="root"
else
SEND_TO="$MAILTO"
fi
if [ -z "$MAILFROM" ]; then
SEND_FROM="root"
else
SEND_FROM="$MAILFROM"
fi
# XXX support external specification of $MAILER?
for POSSIBLE_MAILER in /usr/bin/mail /usr/lib/sendmail /usr/bin/mailx /usr/sbin/sendmail; do
test -x $POSSIBLE_MAILER && MAILER=$POSSIBLE_MAILER
done
if [ -z "$MAILER" ]; then
echo "Could not find suitable mailer."
exit 1
fi
export MAIL_CONFIG
export MAILER
function send_email() {
SUBJECT="$1"; shift
TMP=`mktemp`
echo "Subject: $SUBJECT" > "$TMP"
echo "From: $SEND_FROM" >> "$TMP"
echo "To: $SEND_TO" >> "$TMP"
echo >> "$TMP"
cat "$@" >> "$TMP"
"$MAILER" -r "$SEND_FROM" "$SEND_TO" < "$TMP"
rm -f "$TMP"
}
mkdir -p $SPOOL
#set verbose
## stage 1, search directories/scripts to run
RUN=""
SECURE_PERMISSIONS="${SECURE_DIR_PERMISSIONS:-755}"
for CRONDIR in /etc/cron.{hourly,daily,weekly,monthly} ; do
test -d $CRONDIR || continue
# these checks are racy but better than nothing
if [ ! "$ENFORCE_ROOT_OWNER_GROUP_DIR" = "no" ] && [ ! -O $CRONDIR -o ! -G $CRONDIR ]; then
echo "wrong owner/group for $CRONDIR, skipping" | logger
continue
fi
ACTUAL_PERMISSIONS=$(stat -c %a $CRONDIR)
if [ ! "${ACTUAL_PERMISSIONS}" = "${SECURE_PERMISSIONS}" ]; then
echo "wrong permissions $ACTUAL_PERMISSIONS for $CRONDIR, expecting $SECURE_PERMISSIONS (see SECURE_DIR_PERMISSIONS in /etc/sysconfig/cron). Skipping" | logger
continue
fi
BASE=${CRONDIR##*/}
TIME_EXT=${BASE##cron.}
test -e $SPOOL/$BASE && {
case $BASE in
cron.hourly) TIME="-cmin +60 -or -cmin 60" ;;
cron.daily)
# if DAILY_TIME set, run only at a fixed time of day
if [ "$DAILY_TIME" != "" ] ; then
DAILY_TIME_NEW="`echo $DAILY_TIME | sed s,:,, | sed s,^0\*,, `"
test -z "$DAILY_TIME_NEW" && DAILY_TIME_NEW=0
if [ "$DAILY_TIME_NEW" -gt "2359" ] ; then
echo "wrong time format in /etc/sysconfig/cron DAILY_TIME, value is $DAILY_TIME" | logger
fi
NOW_H=`date +%H%M| sed s,^0\*,,`
test -z "$NOW_H" && NOW_H=0
if [ $DAILY_TIME_NEW -gt $(($NOW_H-15)) ] && [ $DAILY_TIME_NEW -le $NOW_H ]; then
TIME=""
else
# take care of MAX_NOT_RUN, default is 7 days
if [ "$MAX_NOT_RUN" != "0" ] ; then
TIME="-cmin +$((1440*$MAX_NOT_RUN)) -or -cmin $((1440*$MAX_NOT_RUN))"
else
TIME="-cmin +$MAX_NOT_RUN_FORCE -or -cmin $MAX_NOT_RUN_FORCE"
fi
fi
# run as usual
else
TIME="-cmin +1440 -or -cmin 1440"
fi ;;
cron.weekly) TIME="-cmin +10080 -or -cmin 10080" ;;
cron.monthly)
DAYOFMONTH=`date '+%d'`
DAYSLASTMONTH=`date -d "-$DAYOFMONTH days" '+%d'`
if [ $DAYOFMONTH -gt $DAYSLASTMONTH ] ; then
LASTMONTHSTR="-$DAYOFMONTH days"
else
LASTMONTHSTR="last month"
fi
NOW=`date +%s`
LASTMONTH=`date -d "$LASTMONTHSTR" +%s`
DIFF=`expr '(' $NOW - $LASTMONTH ')' / 86400`
TIME="-ctime +$DIFF"
;;
esac
# remove all lock files for scripts that are due to run
eval find $SPOOL/$BASE $TIME | \
xargs --no-run-if-empty rm
}
if test ! -e $SPOOL/$BASE ; then
# accept this dir, if it isn't empty
LIST=`find $CRONDIR ! -type d`
if [ ! -z "$LIST" ] ; then
RUN="${RUN} ${TIME_EXT}"
fi
fi
done
## STATUS communication variable between
# function run_scripts ()
# and loop-over-all-scripts
# set in run_scripts to FAILURE if this script failed!
# else it is empty
# because it is never reset to empty after the initialization
# it implements an OR like logic over all scripts
##
STATUS=""
# helper, run all scripts in one cron directory
function run_scripts (){
local CRONDIR=$1
local TIME_EXT=$2
local TEMP_MSG=$TMPDIR/run-crons.${TIME_EXT}.$$
rm -r $TMPDIR/run-crons.${TIME_EXT}.* >/dev/null 2>&1
# keep going when something fails
set +e
for SCRIPT in $CRONDIR/* ; do
test -d $SCRIPT && continue
case "$SCRIPT" in
.svn) continue ;;
*.rpm*) continue ;;
*.swap) continue ;;
*.bak) continue ;;
*.orig) continue ;;
\#*) continue ;;
*~) continue ;;
esac
if test -x $SCRIPT ; then
BASESCRIPT=`/usr/bin/basename $SCRIPT`
nice -n ${CRON_SCRIPT_NICE_VALUE} $SCRIPT >$TEMP_MSG 2>&1
local ERRNO=$?
if [ 0 -eq $ERRNO ] ; then
if [ "$SYSLOG_ON_NO_ERROR" = "yes" ]; then
echo "$BASESCRIPT: OK" | $LOGGER -p info
fi
else
echo "$BASESCRIPT returned $ERRNO" | $LOGGER -p warn
echo "SCRIPT: $BASESCRIPT exited with RETURNCODE = $ERRNO."
STATUS="FAILURE"
fi
# write some wrapper text around the original output
if [ -s "$TEMP_MSG" ] ; then
echo "SCRIPT: output (stdout && stderr) follows"
echo ""
cat $TEMP_MSG
echo -e "SCRIPT: $BASESCRIPT\n------- END OF OUTPUT"
echo ""
echo ""
fi
rm -f $TEMP_MSG > /dev/null 2>&1
else
echo "WARNING: $SCRIPT is not executable, script is ignored !"
fi
done
}
# stage 2:
# run all scripts and collect output into one mail
# for each TIME_EXT with a meaningfull subject.
#
if [ ! -z "${RUN}" ] ; then
for EXT in ${RUN} ; do
CRONDIR="/etc/cron."${EXT}
test -d $CRONDIR || continue
BASE=`/usr/bin/basename $CRONDIR`
TIME_EXT=${BASE##cron.}
STATUS=""
if test ! -e $SPOOL/$BASE ; then
CONTROL_MAIL=$TMPDIR/run-crons_mail.$$
JOB_OUTPUT=$TMPDIR/run-crons_output.$$
echo "running ${TIME_EXT} cronjob scripts" >> ${CONTROL_MAIL}
echo "" >> ${CONTROL_MAIL}
touch $SPOOL/$BASE
run_scripts ${CRONDIR} ${TIME_EXT} >> ${JOB_OUTPUT} 2>&1
TITLE="cronjob@$HOSTNAME - ${TIME_EXT}"
if [ -n "${STATUS}" ] ; then
TITLE="${TITLE} - ${STATUS}"
else
TITLE="${TITLE} - OK"
fi
if [ -n "${STATUS}" -o "$SEND_MAIL_ON_NO_ERROR" = "yes" ] ; then
send_email "$TITLE" "$CONTROL_MAIL" "$JOB_OUTPUT"
elif [ -s ${JOB_OUTPUT} -a "$SEND_OUTPUT_ON_NO_ERROR" = "yes" ] ; then
send_email "$TITLE" "$CONTROL_MAIL" "$JOB_OUTPUT"
fi
rm -f ${CONTROL_MAIL} ${JOB_OUTPUT}
fi
done
fi
#
# now make sure, we have no lastrun files dated to future
#
touch $SPOOL
NOW=`date -u +%s`
for i in `find $SPOOL -type f`
do
FILEDATE=`date -u -r $i +%s`
# allow for up to one hour in the future because of summer/wintertime
if [ $((FILEDATE - NOW)) -gt 3600 ]
then
rm $i
fi
done

19
sample.root Normal file
View File

@ -0,0 +1,19 @@
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
#
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
@hourly root run-parts /etc/cron.hourly
@daily root run-parts /etc/cron.daily
@weekly root run-parts /etc/cron.weekly
@monthly root run-parts /etc/cron.monthly

92
sysconfig.cron Normal file
View File

@ -0,0 +1,92 @@
## The Parameters MAX_DAYS_IN_TMP, MAX_DAYS_IN_LONG_TMP, TMP_DIRS_TO_CLEAR,
## LONG_TMP_DIRS_TO_CLEAR, CLEAR_TMP_DIRS_AT_BOOTUP and OWNER_TO_KEEP_IN_TMP have
## been converted to systemd-tmpfiles settings in /etc/tmpfiles.d/tmp.conf.
## Please check and modify to your needs.
## See 'man tmpfiles.d' for details.
## Type: string
## Default: ""
#
# At which time cron.daily should start. Default is 15 minutes after booting
# the system. Example setting would be "14:00".
# Due to the fact that cron script runs only every 15 minutes,
# it will only run on xx:00, xx:15, xx:30, xx:45, not at the accurate time
# you set.
DAILY_TIME=""
## Type: integer
## Default: 5
#
# Maximum days not running when using a fixed time set in DAILY_TIME.
# 0 to skip this. This is for users who will power off their system.
#
# There is a fixed max. of 14 days set, if you want to override this
# change MAX_NOT_RUN_FORCE in /usr/libexec/cron/run-crons
MAX_NOT_RUN="5"
## Type: yesno
## Default: no
#
# send status email even if all scripts in
# cron.{hourly,daily,weekly,monthly}
# returned without error? (yes/no)
#
SEND_MAIL_ON_NO_ERROR="no"
## Type: yesno
## Default: no
#
# send email containing output from all successful jobs in
# cron.{hourly,daily,weekly,monthly}. Output from failed
# jobs is always sent. If SEND_MAIL_ON_NO_ERROR is yes, this
# setting is ignored. (yes/no)
#
SEND_OUTPUT_ON_NO_ERROR="no"
## Type: yesno
## Default: no
#
# generate syslog message for all scripts in
# cron.{hourly,daily,weekly,monthly}
# even if they haven't returned an error? (yes/no)
#
SYSLOG_ON_NO_ERROR="no"
## Path: System/Cron/Man
## Description: cron configuration for man utility
## Type: yesno
## Default: yes
#
# Should mandb and whatis be recreated by cron.daily ("yes" or "no")
#
REINIT_MANDB=yes
## Type: yesno
## Default: yes
#
# Should old preformatted man pages (in /var/cache/man) be deleted? (yes/no)
#
DELETE_OLD_CATMAN=yes
## Type: integer
## Default: 7
#
# How long should old preformatted man pages be kept before deletion? (days)
#
CATMAN_ATIME=7
## Type: yesno
## Default: yes
#
# Force cron.{hourly,daily,weekly,monthly} to be
# owned by user and group root
#
ENFORCE_ROOT_OWNER_GROUP_DIR="yes"
## Type: integer
## Default: 755
#
# Force cron.{hourly,daily,weekly,monthly} to have
# at most the listed permissions
#
SECURE_DIR_PERMISSIONS="755"