Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-Id: <3.0.5.32.20041221090708.0082fbf0@verizon.net> X-Sender: phumblet AT verizon DOT net (Unverified) Date: Tue, 21 Dec 2004 09:07:08 -0500 To: cygwin AT cygwin DOT com From: "Pierre A. Humblet" Subject: [Patch] crontab Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_1103656028==_" --=====================_1103656028==_ Content-Type: text/plain; charset="us-ascii" The attached patch makes cron more friendly to Windows2003 users who run it under a privileged user different from SYSTEM. The main difference is that crontab now places the /var/cron/tabs files in the Administrators (instead of System) group. This is not expected to have an impact on existing installations. cron_diagnose.sh checks access to various files by Administrators (or by System on older system), and includes more tests. Pierre --=====================_1103656028==_ Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="cron.diff" --- compat.h.orig 2003-04-15 11:13:42.000000000 -0400 +++ compat.h 2004-12-20 19:49:18.000000000 -0500 @@ -150,6 +150,15 @@ #if defined(__CYGWIN__) #include +#include +/* Macro to define variable length SID structures */ +#define SID(n, name, sid...) \ +struct { \ + BYTE Revision; \ + BYTE SubAuthorityCount; \ + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; \ + DWORD SubAuthority[n]; \ +} name =3D { SID_REVISION, n, {SECURITY_NT_AUTHORITY}, {sid}} #define CRONDIR "/var/cron" #define _PATH_VARRUN "/var/run/" #endif --- crontab.c.orig 2003-04-15 11:13:42.000000000 -0400 +++ crontab.c 2004-12-20 19:55:22.000000000 -0500 @@ -627,7 +627,7 @@ replace_cmd() { /* Cygwin can't support changing the owner since that requires crontab to be a s-uid application which is not supported. - As workaround we try to set group membership to be SYSTEM (=3D=3D ROOT_= UID) + As workaround we try to set group membership to be ADMINISTRATORS and setting permissions to 640 which should allow cron to work. */ #ifndef __CYGWIN__ #ifdef HAS_FCHOWN @@ -636,7 +636,9 @@ replace_cmd() { if (chown(tn, ROOT_UID, -1) < OK) #endif #else /* __CYGWIN__ */ - if (chown(tn, -1, ROOT_UID) < OK) + const SID(2, AdminsSid, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADM= INS); + const int ADMINS_GID =3D cygwin_internal(CW_GET_GID_FROM_SID, &AdminsSid); + if (chown(tn, -1, ADMINS_GID) < OK) #endif { perror("chown"); --- cron.README.orig 2004-12-13 12:07:32.000000000 -0500 +++ cron.README 2004-12-20 23:01:16.000000000 -0500 @@ -17,6 +17,18 @@ Send patches and error reports to : +Crontab now changes group membership of the crontab files to be +ADMINISTRATORS, to allow access from any privileged process. +Modify cron_diagnose to: +- check the new crontab file group setting. +- verify access of /var/run, /usr/sbin/cron.exe and /usr/sbin/sendmail + by Administrators (instead of SYSTEM) and the local user. +- get the system mounts directly from the registry. + 3.0.1-14: --------- --- cron_diagnose.sh.orig 2004-12-13 12:09:14.000000000 -0500 +++ cron_diagnose.sh 2004-12-21 08:31:38.000000000 -0500 @@ -47,6 +47,18 @@ function sanity_check() { check_program cygcheck cygwin || return } # =3D=3D=3D End of sanity_check() =3D=3D=3D # +# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +# Routine: get_NT +# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +function get_NT() { + NT2003=3D"" + NT=3D$(uname -s | sed -ne 's/^CYGWIN_NT-\([^ ]*\)/\1/p') + if [ "$NT" \> 5.1 ]; then NT2003=3Dyes; fi + if [ -z "$NT" ]; then + echo "This script is only meant to run on NT." + exit 0 + fi +} # =3D=3D=3D End of get_NT() =3D=3D=3D # # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D # Routine: warning_for_etc_file @@ -84,14 +96,14 @@ function check_system_in_group() { # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D # Routine: get_system_and_admins_gids -# Get the SYSTEM and ADMINs ids from /etc/group and /etc/passwd +# Get the ADMINs ids from /etc/group and /etc/passwd # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D function get_system_and_admins_ids() { ADMINSGID=3D$(sed -ne '/^[^:]*:S-1-5-32-544:.*:/{s/[^:]*:[^:]*:\([0-9]= *\):.*$/\1/p;q}' /etc/group) SYSTEMGID=3D$(sed -ne '/^[^:]*:S-1-5-18:.*:/{s/[^:]*:[^:]*:\([0-9]*\):= .*$/\1/p;q}' /etc/group) if [ -z "$ADMINSGID" -o -z "$SYSTEMGID" ]; then echo "It appears that you do not have entries for the" - echo "SYSTEM and/or ADMINISTRATORS sids in /etc/group." + echo "ADMINISTRATORS and/or SYSTEM sids in /etc/group." echo echo "Use the 'mkgroup' utility to generate them" echo " mkgroup -l > /etc/group" @@ -100,10 +112,11 @@ function get_system_and_admins_ids() { return 1; fi + ADMINSUID=3D$(sed -ne '/^[^:]*:[^:]*:[0-9]*:[0-9]*:[^:]*,S-1-5-32-544:= .*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' /etc/passwd) SYSTEMUID=3D$(sed -ne '/^[^:]*:[^:]*:[0-9]*:[0-9]*:[^:]*,S-1-5-18:.*:/= {s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' /etc/passwd) - if [ -z "$SYSTEMUID" ]; then + if [ -z "$ADMINSUID" -o -z "$SYSTEMUID" ]; then echo "It appears that you do not have an entry for the" - echo "SYSTEM sid in /etc/passwd." + echo "ADMINISTRATORS and/or SYSTEM sids in /etc/passwd." echo echo "Use the 'mkpasswd' utility to generate it" echo " mkpasswd -l > /etc/passwd" @@ -208,38 +221,43 @@ function check_dir_perms() { # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -# Routine: check_var_run -# Check to see that SYSTEM or the Administrators group has write -# permission in the directory /var/run. This permission is needed -# so that the cron.pid file can be created by the cron service. -# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -function check_var_run() { +# Routine: check_access +# Check to see that the owner and Administrators have +# proper access to the file or directory. +# On installations older than Windows 2003, allow access by System +# =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +function check_access() { + local file=3D"$1" + local perm=3D"$2" local notify=3D0; + local ls=3D"$(ls -dLln "$file" 2> /dev/null)" - # If SYSTEM is the owner of /var/run and does not have write - # permission, then notify the user. - if [ $(ls -dln /var/run | awk '{ print $3 }') -eq $SYSTEMUID ]; then - if [ $(ls -dl /var/run | cut -b3) !=3D w ]; then notify=3D1; fi - # If 'Administrators' has group access to /var/run, but does not have - # write permission, then notify the user. - elif [ $(ls -dln /var/run | awk '{ print $4 }') -eq $ADMINSGID ]; then - if [ $(ls -dl /var/run | cut -b6) !=3D w ]; then notify=3D1; fi - # If 'everyone' / 'other' has write permission, then the permissions - # MUST be sufficient for SYSTEM and administrators to write to it. - elif [ $(ls -dln /var/run | cut -b9) !=3D w ]; then notify=3D1; fi + # If the owner of the file does not have access, + # then notify the user. + if [ -z "$(echo "$ls" | sed -n /^."$perm"/p)" ]; then + notify=3D1; + # If 'Administrators' has owner or group access to the file, + # but does not have the desired access, then notify the user. + elif [ "$(echo "$ls" | awk '{ print $3 }')" -eq $ADMINSUID \ + -o \( -z "$NT2003" -a "$(echo "$ls" | awk '{ print $3 }')" -eq $SY= STEMUID \) ]; then + true; + elif [ "$(echo "$ls" | awk '{ print $4 }')" -eq $ADMINSGID \ + -o \( -z "$NT2003" -a "$(echo "$ls" | awk '{ print $4 }')" -eq $SY= STEMGID \) ]; then + if [ -z "$(echo "$ls" | sed -n /^...."$perm"/p)" ]; then notify=3D1; fi + elif [ -z "$(echo "$ls" | sed -n /^......."$perm"/p)" ]; then notify=3D1;= fi if [ $notify -eq 1 ]; then - echo "The SYSTEM user or Administrators group needs to have"; - echo "write permission in the directory /var/run."; - echo "Here are the permissions of this directory:"; + echo "The owner and the Administrators need"; + echo "to have $perm permission to $file."; + echo "Here are the current permissions:"; echo; - ls -dl /var/run; + ls -dlL "$file"; echo; echo "Please change the user and/or group ownership and"; - echo "permissions of /var/run, and then run this script again."; + echo "permissions of $file, and then run this script again."; return 1; fi -} # =3D=3D=3D End of check_var_run() =3D=3D=3D # +} # =3D=3D=3D End of check_access() =3D=3D=3D # # =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -251,8 +269,8 @@ function check_sys_mount() { local mnt_point=3D$1 local dos_dir=3D$2 - echo -e "Checking mount point for $mnt_point. . .\c"; - if ! mount | grep -E -qe ".+ on $mnt_point .+system.+"; then + local SYSTEM_MOUNTS=3D'/proc/registry/HKey_Local_Machine/Software/Cygnus = Solutions/Cygwin/mounts v2' + if ! ls "$SYSTEM_MOUNTS" | grep -Eq "^${mnt_point}\$"; then echo; echo "The SYSTEM user cannot access the mount point ${mnt_point}." echo "Please run the following command to add a system mount point:" @@ -264,7 +282,6 @@ function check_sys_mount() { echo "After adding this mount point, please re-run this script." return 1 fi - echo "done"; } # =3D=3D=3D End of check_sys_mount() =3D=3D=3D # @@ -288,7 +305,8 @@ function check_cron_table() { return 1 fi - if ! ls -l $cron_table | grep -F -q 'rw-r-----'; then + local ls=3D"$(ls -ln "$cron_table")" + if ! echo "$ls" | grep -F -q 'rw-r-----'; then echo "The file permissions of your cron table need to" echo "provide read/write access for $user_id." echo "The permissions of your cron table file are set to:" @@ -302,24 +320,43 @@ function check_cron_table() { return 1 fi - if ! ls -ln $cron_table | awk '{ print $4 }' | grep -F -q "$SYSTEMGID"; t= hen - echo "The group membership of your cron table file should be SYSTEM," + if [ "$(echo "$ls" | awk '{ print $4 }')" -ne "$ADMINSGID" \ + -a \( -n "$NT2003" -o "$(echo "$ls" | awk '{ print $4 }')" -ne "$SYST= EMGID" \) ]; then + echo "The group membership of your cron table file should be ADMINISTRAT= ORS," echo "as documented in the file /usr/share/doc/Cygwin/cron.README." echo "Here is your cron table file:" echo ls -l $cron_table echo echo "You can change the group membership setting with:" - echo " chgrp $SYSTEMGID $cron_table" + echo " chgrp $ADMINSGID $cron_table" echo "Please change your cron table's group membership, and" echo "run this script again." return 1 fi } # =3D=3D=3D End of check_cron_table() =3D=3D=3D # +function check_myself() { + echo + if [ ! -x /usr/sbin/cron ]; then + echo "If you are running cron as yourself,"; + echo "you need x access to /usr/sbin/cron."; + fi + if [ ! -w /var/run ]; then + echo "If you are running cron as yourself,"; + echo "you need w access to /var/run."; + fi + if [ ! -x /usr/sbin/sendmail ]; then + echo "If you are running cron as yourself,"; + echo "/usr/sbin/sendmail should point to an executable mailer"; + fi + echo +} # =3D=3D=3D End of check_myself() =3D=3D=3D # function main() { - echo -e "cron_diagnose.sh 1.9\n" + echo -e "cron_diagnose.sh 1.10\n" + + get_NT sanity_check || return @@ -345,7 +382,15 @@ function main() { check_dir_perms /var/cron || return check_dir_perms /var/cron/tabs || return - check_var_run || return + # Check write access to /var/run, to create cron_pid + check_access /var/run .w. || return + + # Check x access to /usr/sbin/cron + check_access /usr/sbin/cron ..x || return + + # Check x access to /usr/sbin/sendmail + check_access /usr/sbin/sendmail ..x || + echo " ssmtp and exim are suitable mailers." check_sys_mount /usr/bin /bin || return check_sys_mount /usr/lib /lib || return @@ -354,7 +399,9 @@ function main() { check_cron_table || return - echo "This script did not find any errors in your crontab setup." + echo "This script did not find any errors in your cron setup." + check_myself + echo "If you are still unable to get cron to work, then try" echo "shutting down the cron service, uninstalling it," echo "reinstalling it, and restarting it." @@ -363,6 +410,7 @@ function main() { echo " $ cygrunsrv --stop cron" echo " $ cygrunsrv --remove cron" echo " $ cygrunsrv --install cron -p /usr/sbin/cron -a -D" + echo " (You can also add a -u switch)" echo " $ cygrunsrv --start cron" echo --=====================_1103656028==_ Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --=====================_1103656028==_--