#!/bin/bash
#set -x
# ======================================================================
# This script initializes and possibly starts a cron daemon.
# It includes numerous tests to insure that the environmnet is sound.
# On Windows 2003 it is capable of creating a privileged user.
# ======================================================================

# ======================================================================
# Routine: getvalue
# Get a verified non-empty string in variable "value"
# The second argument can be -s
# ======================================================================
getvalue() {
  while true
    do
    if read $2 -p "$1 " value; then
      echo
      if [ -n "${value}" ]; then
	  read $2 -p "Reenter: " verify
          echo
	  [ "${verify}" = "${value}" ] && return 0;
      fi
    else
      echo -e "Quitting.\n"
      exit 1
    fi
  done
} # === End of getvalue() === #

# ======================================================================
# Routine: request
# Get a yes/no anwer
# ======================================================================
request() {
  return 1;
  while true
  do
    echo -en "$1 (yes/no) "
    if read answer
      then
      if [ "${answer}" = "yes" ]
        then
	return 0
      elif [ "${answer}" = "no" ]
        then
        return 1
      fi
    else
      echo -e "Quitting.\n"
      exit 1
    fi
  done
} # === End of request() === #

#############################
# get CYGWIN
#############################
getcygenv()
{
  cygenv="ntsec"
  return 0
  default=$*
  while true
    do
    echo -n "Enter the value of CYGWIN for the daemon: [${default}] "
    if read cygenv; then
      if [ -z "${cygenv}" ]; then
        cygenv="${default}"
      fi
      failed=0
      for word in ${cygenv}
        do
        [ "$failed" = 0 ] &&
        failed=1 &&
        echo "$word" | grep -q '\(no\)\?\(ntsec\)\|\(smbntsec\)\|\(traverse\)' &&
        failed=0
      done
      [ "$failed" = 0 ] && return
      echo "ERROR: Only \"[no]ntsec\" \"[no]smbntsec\" \"[no]traverse\" allowed."
    else
      echo -e "Quitting.\n"
      exit 1
    fi
  done
}

# ======================================================================
# Routine: check_program
# Check to see that a specified program ($1) is installed and accessible
# by this script.  If it is not, then alert the user about which package
# ($2) should be installed to provide that program.
# ======================================================================
check_program() {
    unset "$1"
    prog="$1"
    if [ ! -e "/usr/bin/${prog}" ]; then
	echo "The '$1' program is not in /usr/bin."
	echo "This program is included in the \'$2\' package."
	echo "Please install this program."
	echo
        return 1
    elif [ ! -x "/usr/bin/${prog}" ]; then
	echo "The '$1' program (/usr/bin/${prog}') is not executable."
	echo
	return 1
    fi
} # === End of check_program() === #


# ======================================================================
# Routine: sanity_check
# Check for the set of programs that are used by this script.
# ======================================================================
sanity_check() {
    ret=0
    # Check for programs that this script uses.
    check_program awk gawk || ret=1
    check_program ls coreutils || ret=1
    check_program grep grep || ret=1
    check_program sed sed || ret=1
    check_program id coreutils || ret=1
    check_program cut coreutils || ret=1
    check_program uname coreutils || ret=1
    check_program cygcheck cygwin || ret=1
    check_program getfacl cygwin || ret=1
    check_program regtool cygwin || ret=1
    check_program mkpasswd cygwin || ret=1
    check_program mkgroup cygwin || ret=1
    return "${ret}"
} # === End of sanity_check() === #

# ======================================================================
# Routine: get_NT
# ======================================================================
get_NT() {
    nt2003=""
    nt=$(uname -s | sed -ne 's/^CYGWIN_NT-\([^ ]*\)/\1/p')
    [ -z "$nt" ] && echo "Unknown system name" && return 1
    [ "$nt" \> 5.1 ] && nt2003=yes
    return 0
} # === End of get_NT() === #

# ======================================================================
# Routine: warning_for_etc_file
# Display a warning message for the user about overwriting the specified
# file in /etc.
# ======================================================================
warning_for_etc_file() {
	echo
	echo "WARNING: The command above overwrites any existing /etc/$1."
	echo "You may want to preserve /etc/$1 before generating a new,"
	echo "one, and then compare your saved /etc/$1 file with the"
	echo "newly-generated one in case you need to restore other"
	echo "entries."
	echo
} # === warning_for_etc_file() === #


# ======================================================================
# Routine: get_system_and_admins_gids
# Get the ADMINs ids from /etc/group and /etc/passwd
# ======================================================================
get_system_and_admins_ids() {
    ret=0
    for fname in /etc/passwd /etc/group; do
	if ls -ld "${fname}" | grep -Eq  '^-r..r..r..'; then
	    true
	else
	    echo "The file $fname is not readable by all."
	    echo "Please run 'chmod +r $fname'."
	    echo
	    ret=1
	fi
    done

    [ ! -r /etc/passwd -o ! -r  /etc/group ] && return 1;

    ADMINSGID=$(sed -ne '/^[^:]*:S-1-5-32-544:.*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' /etc/group)
    SYSTEMGID=$(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 correct entries for the"
		echo "ADMINISTRATORS and/or SYSTEM sids in /etc/group."
		echo
		echo "Use the 'mkgroup' utility to generate them"
		echo "   mkgroup -l > /etc/group"
		warning_for_etc_file group
		ret=1;
    fi

    ADMINSUID=$(sed -ne '/^[^:]*:[^:]*:[0-9]*:[0-9]*:[^:]*,S-1-5-32-544:.*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' /etc/passwd)
    SYSTEMUID=$(sed -ne '/^[^:]*:[^:]*:[0-9]*:[0-9]*:[^:]*,S-1-5-18:.*:/{s/[^:]*:[^:]*:\([0-9]*\):.*$/\1/p;q}' /etc/passwd)
    if [ -z "$ADMINSUID" -o -z "$SYSTEMUID" ]; then
		echo "It appears that you do not have correct entries for the"
		echo "ADMINISTRATORS and/or SYSTEM sids in /etc/passwd."
		echo
		echo "Use the 'mkpasswd' utility to generate it"
		echo "   mkpasswd -l > /etc/passwd."
		warning_for_etc_file passwd
		ret=1;
    fi
    return "${ret}"
}  # === get_system_and_admins_ids() === #

# ======================================================================
# Routine: check_passwd_and_group
# Check to see whether the user's password ID and group exist in the
# system /etc/passwd and /etc/group files, respectively.
# ======================================================================
check_passwd_and_group() {
    ret=0
    if [ "$(id -gn)" = "mkpasswd" ]; then
	echo "It appears that you do not have an entry for your user ID"
	echo "in /etc/passwd."
	echo
	echo "If so, use the 'mkpasswd' utility to generate an"
	echo "entry for your User ID in the password file:"
	echo "   mkpasswd -l -u User_ID >> /etc/passwd"
	echo "or"
	echo "   mkpasswd -d -u User_ID >> /etc/passwd."
	echo
	ret=1
    fi

    if [ "$(id -gn)" = mkgroup ]; then
	echo "It appears that you do not have an entry for your group ID"
	echo "in /etc/group.  If this check is incorrect, then re-run"
	echo "this script with the '-f' command-line option."
	echo
	echo "Otherwise, use the 'mkgroup' utility to generate an"
	echo "entry for your group ID in the password file:"
	echo "   mkgroup -l -g Group_id  >> /etc/group"
	echo "or"
	echo "   mkgroup -d -g Group_id >> /etc/group."
	echo
	ret=1
    fi
    return "${ret}"
} # === End of check_passwd_and_group() === #

# ======================================================================
# Routine: check_user
# Check to see that the specified user exists once in /etc/passwd
# ======================================================================
check_user() {
 count=$(grep -ic "^$1:" /etc/passwd)
 if [ $count = 0 ]; then
     echo "ERROR: User $1 does not appear in /etc/passwd."
     echo
     return 1;
 fi
 if [ $count -gt 1 ]; then
     echo "WARNING: User $1 appears $count times in /etc/passwd."
     echo "This may confuse the system."
     echo "Edit /etc/passwd and assign unique user ids."
     echo
     return 1;
 fi
 return 0
} # === End of check_user() === #

# ======================================================================
# Routine: check_dir_perms
# Check to see that the specified directory ($1) exists and has the
# permissions ($2).
# ======================================================================
check_dir_perms() {
    if [ ! -e "$1" ]; then
	echo "Your computer is missing $1".
	echo
	return 1
    fi

    if ls -ld "$1" | grep -q ^"$2"; then
	true
    else
	echo "The permissions on the directory $1 are not correct."
	echo "They must match the regexp $2"
	echo
	return 1
    fi
} # === End of check_dir_perms() === #


# ======================================================================
# 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
# ======================================================================
check_access() {
    file="$1"
    perm="$2"
    msg="$3"
    notify=0;
    ls="$(ls -dLln "$file" 2> /dev/null)"

    # If the owner of the file does not have access,
    # then notify the user.
    if [ -z "$(echo "$ls" | sed -n /^."$perm"/p)" ]; then
	notify=1;
    # 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 $SYSTEMUID \) ]; then
	true;
    elif [ "$(echo "$ls" | awk '{ print $4 }')" -eq $ADMINSGID \
	-o \( -z "$nt2003" -a "$(echo "$ls" | awk '{ print $4 }')" -eq $SYSTEMGID \) ]; then
	[ -z "$(echo "$ls" | sed -n /^...."$perm"/p)" ] &&  notify=1
    # Check if there is a group entry for 'Administrators'
    elif [ -z "$(getfacl -n "$file" | sed -n /^group:"$ADMINSGID":"$perm"/p )" ]; then
	[ -z "$(echo "$ls" | sed -n /^......."$perm"/p)" ] && notify=1
    fi

    if [ "$notify" -eq 1 ]; then
	echo "The owner and the Administrators need";
	echo "to have $perm permission to $file.";
	echo "Here are the current permissions:";
	ls -dlL "${file}";
	echo;
	echo "Please change the user and/or group ownership and";
	echo "permissions of $file.";
	[ -z "${msg}" ] || echo "${msg}"
	echo
	return 1;
    fi
} # === End of check_access() === #

# ======================================================================
# Routine: check_mounts
# Issue a warning if a user mount matches an argument
# ======================================================================
check_mounts() {
  USERMOUNTS=$(mount | sed -ne 's%^.*\ on\ \(/.*\)\ type\ [^ ]*\ .*(\([^ ]*,\)\?user\(,[^ ]*\)\?).*$%\1%p')
  ret=0
  OLD_IFS=$IFS
  IFS=$'\n'
  for file in "$@"
    do
    for mount in ${USERMOUNTS}
      do
      if [ "$file" = "$mount" -o "${file#$mount\/}" != "${file}" ]
        then
        ret=1
        echo WARNING: The path to $file can be modified by user mount $mount;
      fi
    done
  done
  IFS=$OLD_IFS
  return $ret
} # === End of check_mounts() === #


# ======================================================================
# Routine: check_cron_table
# Check for the existence of a crontab for the user, and check its
# permissions and ownership.
# ======================================================================
check_cron_table() {
    cron_table="/var/cron/tabs/${USER}"
    couldbeFAT=0

    if [ ! -f "$cron_table" ]; then
	echo "WARNING: Your computer does not appear to have a cron table for ${USER}."
	echo "Please generate a cron table for ${USER} using 'crontab -e'"
	echo
	return 0
    fi

    fail=0
    ls="$(ls -ln "$cron_table")"
    if echo "${ls}" | grep -Eq '^-rw-r--.--'; then
	true
    else
	echo "cron table files need to writable only by the owner,"
	echo "readable by the owner and he group, and executable by no one."
	echo "The permissions of your cron table file are set to:"
	ls -l "$cron_table"
	echo
	echo
	echo "You can set the file permissions with:"
	echo "	chmod 640 $cron_table"
	echo
	fail=1
    fi

    couldbeFAT=0
    echo "${ls}" | grep -Eq '^-rw-r--r--' && couldbeFAT=1

    if [ "$(echo "$ls"  | awk '{ print $4 }')" -ne "$ADMINSGID" \
	-a \( -n "$nt2003" -o "$(echo "$ls" | awk '{ print $4 }')" -ne "$SYSTEMGID" \) \
	-a "$username" != "$USER" ]; then
	echo "The group membership of your cron table file should be ADMINISTRATORS."
	echo "Here is your cron table file listing:"
	ls -l "$cron_table"
	echo
	[ "$couldbeFAT" = 1 ] &&
	echo "This rule does not apply on FAT/FAT32 file systems."
	echo "This rule does not apply if the daemon runs with nontsec."
	echo
	echo "You can change the group membership setting with:"
	echo "	 chgrp $ADMINSGID $cron_table"
	echo "Please change your cron table's group membership."
	echo
	fail=1
    fi
    return "${fail}"
} # === End of check_cron_table() === #

# ======================================================================
# Routine: check_myself
# Check for the existence and accessibility of key files
# ======================================================================
check_myself() {
    ret=0
    if [ ! -x /usr/sbin/cron ]; then
	echo "ERROR: You need x access to /usr/sbin/cron.";
	echo
	ret=1
    fi
    if [ ! -x /var ]; then
	echo "ERROR: You need x access to /var/run.";
	echo
	ret=1
    fi
    if [ ! -w /var/run ]; then
	echo "ERROR: You need w access to /var/run.";
	echo
	ret=1
    fi
    if [ ! -w /var/log ]; then
	echo "ERROR: You need w access to /var/log.";
	echo
	ret=1
    fi
    if [ ! -x /usr/sbin/sendmail ]; then
	echo "WARNING: /usr/sbin/sendmail does not point to an executable mailer";
	echo "     such as ssmtp, exim or cronlog."
	echo "     If the cron job produces any output on stdout or stderr,"
	echo "     you MUST set MAILTO=\"\" in the crontab file."
	echo
    fi
    if [ ! -x /var/cron ]; then
	echo "ERROR: You need x access to /var/cron.";
	echo
	ret=1
    fi
    if [ ! -e "/var/cron/tabs/${USER}" ]; then
	echo "WARNING: You do not currently have a crontab file."
	echo
    elif [ ! -r "/var/cron/tabs/${USER}" ]; then
	echo "ERROR: Your crontab file is not readable."
	echo
	ret=1
    elif [ -n "$nt" ]; then
	check_cron_table
	ret=$?
    fi
    return "${ret}"
} # === End of check_myself() === #

# ======================================================================
# Routine: get_temp_dir
# Returns a temporary directory
# ======================================================================

get_temp_dir() {
    for dir in "$TEMP" "$TMP" "/tmp" "$HOME"; do
	if [ -d "$dir" ] && [ -w "$dir" ]; then
	    TEMP_DIR="$dir"
            return
	fi
    done
    echo "ERROR: Cannot find a temporary directory."
    TEMP_DIR=/tmp
} # === End of get_temp_dir() === #

# ======================================================================
# Routine: cron_diagnose
# Checks the environment.
# "nt" and "username" must be set.
# ======================================================================
cron_diagnose() {
    echo "Running cron_diagnose ..."
    # Check the integrity of the files in the 'cron' package:
    if cygcheck -c cron | grep -F -q 'Incomplete'; then
	echo "'cygcheck -c cron' reports that your cron installation"
	echo "is incomplete.  Please consider running 'setup.exe' and"
	echo "selecting 'Reinstall' from the install options."
	echo
    return 1
    fi

    get_system_and_admins_ids || return 1
    check_passwd_and_group || return 1

    if [ "$username" = "$USER" ]
	then
	check_myself
	ret=$?
	if [ ! "$ret" = 1 ]; then
	  echo "... no problem found."
	  echo
        fi
	return $ret
    fi

    ret=0
    check_mounts /usr/sbin /usr/bin /var/cron/tabs /var/run /var/log /etc/crontab || ret=1

    check_dir_perms /var d..x..x..x || ret=1

    # There is no reason to have t on /var/cron,
    # but it used to be set that way.
    check_dir_perms /var/cron d..x..x..[xt] || ret=1

    check_dir_perms /var/cron/tabs drwxrwxrwt || ret=1

    # Check write access to /var/run, to create cron_pid
    check_access /var/run .w. || ret=1

    # Check write access to /var/log, to create cron.log
    check_access /var/log .w. || ret=1

    # Check x access to /usr/sbin/cron
    check_access /usr/sbin/cron ..x || ret=1

    if [ ! -f "/usr/sbin/sendmail" ]; then
	echo "WARNING: /usr/sbin/sendmail does not point to an executable mailer";
	echo "     such as ssmtp or exim, or /usr/bin/cronlog."
	echo "     If the cron job produces any output on stdout or stderr,"
	echo "     you MUST set MAILTO=\"\" in the crontab file."
	echo
    else
    	check_access /usr/sbin/sendmail ..x
    fi

    check_cron_table || ret=1

    if [ ! "$ret" = 1 ]; then
	echo "... no problem found."
	echo
    fi
    return "${ret}"
} # === End of cron_diagnose() === #

# ======================================================================
# Routine: create_user
# Create a privileged user on Windows 2003
# Returns the name in variable "username"
# ======================================================================
create_user() {
    SYSCONFDIR="/etc"
    TEMP_FILE=$TEMP_DIR/nu.$$
    first_account=""
    accounts=""
    ret=0

    echo
    echo "Attempting to find or create a privileged user."

    for username in ${slapos_administrator} cyg_server cron_server sshd_server
    do
      if net user "${username}" 1> /dev/null 2>&1; then
	  [ -z "${first_account}" ] && first_account="${username}"
	  accounts="${accounts}'${username}' "
      fi
    done
    if [ -n "${accounts}" ]; then
	echo "The following accounts were found: ${accounts}."
	username="${first_account}"
    else
	echo "No privileged account could be found."
	username="${slapos_administrator}"
    fi
    echo "This script plans to use the name ${username} for the new user,"
    echo "which will only be able to run as a service."
    if request "Do you want to use another name (not an interactive account)?"; then
        getvalue "Enter the new user name:"
        username="${value}"
    fi
    echo


    if net user "${username}" >/dev/null 2>&1 ; then
	if editrights -u "$username" -t SeInteractiveLogonRight ; then
	    echo "ERROR: You have chosen an interactive account. This is not allowed."
	    return 1;
	fi
    else
        username_in_sam=
	echo "User ${username} needs a password. It must match"
	echo "the rules in force on your system."
	getvalue "Please enter the password for ${username}:" -s
	_password="${value}"
	echo
	net user "${username}" "${_password}" /add /fullname:"Privileged server" /yes > "$TEMP_FILE" 2>&1 && username_in_sam=yes
	if [ "${username_in_sam}" != "yes" ]; then
	    echo "ERROR: Creating the user '${username}' failed!  Reason:"
	    cat "$TEMP_FILE"
	    rm -f "$TEMP_FILE"
	    echo
	    return 1
	else
	    echo "User '${username}' has been created."
	    echo "If you change the password, please keep in mind to change the"
	    echo "password for the cron service, too."
	fi
	echo

	passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
	if [ "${passwd_has_expiry_flags}" != "yes" ]
	    then
	    echo "WARNING: User ${username} has password expiry set to system default."
	    echo "Please check that password never expires or set it to your needs."
	    echo
	elif ! passwd -e "${username}"
	    then
	    echo "WARNING: Setting password expiry for user ${username} failed!"
	    echo "Please check that password never expires or set it to your needs."
	    echo
	fi
    fi

    _admingroup="$( mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' )"
    if [ -z "${_admingroup}" ]; then
	echo "ERROR: Cannot obtain the Administrators group name from 'mkgroup -l'."
	echo
	ret=1
    elif net localgroup "${_admingroup}" | grep -Eiq "^${username}.?$"; then
	true
    else
	net localgroup "${_admingroup}" "${username}" /add > /dev/null 2>&1 && username_in_admingroup=yes
	if [ "${username_in_admingroup}" != "yes" ]
	    then
	    echo "ERROR: Adding user ${username} to group ${_admingroup} failed!"
	    echo "Please add ${username} to group ${_admingroup} before"
	    echo "starting the sshd service!"
	    echo
	    ret=1
	fi
    fi

    if [ ! -x /usr/bin/editrights ]; then
	echo "WARNING: The 'editrights' program cannot be found or is not executable."
	echo"          Unable to insure that ${username} has the appropriate privileges."
	echo
    else
	editrights -a SeAssignPrimaryTokenPrivilege -u "${username}" &&
	editrights -a SeCreateTokenPrivilege -u "${username}" &&
	editrights -a SeDenyInteractiveLogonRight -u "${username}" &&
	editrights -a SeDenyNetworkLogonRight -u "${username}" &&
	editrights -a SeDenyRemoteInteractiveLogonRight -u "${username}" &&
	editrights -a SeIncreaseQuotaPrivilege -u "${username}" &&
	editrights -a SeServiceLogonRight -u "${username}" &&
	username_got_all_rights="yes"
	if [ "${username_got_all_rights}" != "yes" ]
	    then
	    echo "ERROR: Assigning the appropriate privileges to user '${username}' failed!"
	    echo
	    ret=1
	fi
    fi
    pwd_entry="$(mkpasswd -l -u "${username}" | sed -e 's?\(^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:\).*?\1/var/empty:/bin/false?')"
    grep -Eiq "^${username}:" "${SYSCONFDIR}/passwd" && username_in_passwd=yes &&
      grep -Fiq "${pwd_entry}" "${SYSCONFDIR}"/passwd && entry_in_passwd=yes
    if [ "${entry_in_passwd}" != "yes" ]; then
      if [ "${username_in_passwd}" = "yes" ]; then
	temp="${TEMP_DIR}/passwd.$$.tmp"
	grep -Ev "^${username}:" "${SYSCONFDIR}/passwd" > "${temp}" &&
          mv -f "${temp}" "${SYSCONFDIR}/passwd" || return 1
      fi
      echo "${pwd_entry}" >> "${SYSCONFDIR}/passwd" || ret=1
    fi
    return "${ret}"
}

# ======================================================================
# Routine: install_service
# Install cron as a service.
# Start the service or start cron as a job.
# ======================================================================
install_service() {
    service="job"
    servtest=""
    # The default is valid for jobs
    username="$USER"

    if [ ! -e /usr/bin/cygrunsrv.exe ]; then
	echo "WARNING: Download the cygrunsrv package to start the cron daemon as a service."
	servtest=no
    else
	cygrunsrv -Q ${cron_service_name} > /dev/null 2>&1
	servtest=$?
    fi

    if [ "${servtest}" = "0" ]; then
	cronusername="$(cygrunsrv -VQ ${cron_service_name} | sed -n -e 's/^Account[ :]*//p')"
	echo "Cron is already installed as a service under account ${cronusername}."
	if request "Do you want to remove or reinstall it?"; then
	    if cygrunsrv -R ${cron_service_name}; then
		echo "OK. The cron service was removed."
		echo
	    fi
	else
	    # cron_diagnose needs to know if it's the current user
	    username="$(echo "${cronusername}" | sed "s/.*\\${USER}$/${USER}/")"
	    service="service"
	    servtest=no
	fi
    fi

    if [ "${servtest}" = "no" ]; then
	true
    else

	    getcygenv " "

	    echo
            echo "You must decide under what account the cron daemon will run."
            echo "If you are the only user on this machine, the daemon can run as yourself."
            echo "   This gives access to all network drives but only allows you as user."
            if [ -z "$nt2003" ]; then
                echo "Otherwise cron should run under the local system account".
                echo "  It will be capable of changing to other users without requiring a"
                echo "  password, using one of the three methods detailed in"
                echo "  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1"
            else
                echo "To run multiple users, cron must change user context without knowing"
                echo "  the passwords. There are three methods to do that, as explained in"
                echo "  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1"
		echo "If all the cron users have executed \"passwd -R\" (see man passwd),"
                echo "  which provides access to network drives, or if you are using the"
		echo "  cyglsa package, then cron should run under the local system account."
		echo "Otherwise you need to have or to create a privileged account."
		echo "  This script will help you do so."
	    fi
	    if request "Do you want the cron daemon to run as yourself?"; then
		if [ -x /usr/bin/editrights ] && editrights -a SeServiceLogonRight -u "${username}"; then
		    true
		else
		    echo "WARNING: Make sure you have the privilege to logon as a service."
		fi
	    else
		echo
		username="$1"
                _password="$2"
		if [ -n "$nt2003" ]; then
                    if request "Were the passwords of all cron users saved with \"passwd -R\", or \nare you using the cyglsa package ?"; then
                        echo "The cron daemon will run as SYSTEM".
		    elif ! create_user; then
		        echo "There was a serious problem creating a privileged user."
		        request "Do you want to proceed anyway?" || exit 1
                    fi
		fi
	    fi
	    echo

	    if [ -n "${username}" ]; then
		check_user "${username}"

		if [ -z "${_password}" ]
		    then
		    getvalue "Please enter the password for user '$username':" -s
		    _password="${value}"
		fi

		if cygrunsrv -I ${cron_service_name} -p /usr/sbin/cron -e CYGWIN="${cygenv}" \
		    -a "-n" -d "CYGWIN ${cron_service_name}" -u "$username" -w "$_password"
		    then
		    service="service"
		else
		    service="off"
		fi
	    else
		if cygrunsrv -I ${cron_service_name} -p /usr/sbin/cron -e CYGWIN="${cygenv}" \
		    -a "-n" -d "CYGWIN ${cron_service_name}"
		    then
		    service="service"
		else
		    service="off"
		fi
	    fi
    fi
#    echo

    #############################
    # Run diagnostic
    #############################
    if ! cron_diagnose; then
	echo "There may be serious issues with your environment."
	echo "You should look into them and run this script again."
	request "Do you want to continue anyway?" || exit 1
    fi

    #############################
    # Start the daemon?
    #############################
    if ps -es | grep -Fqi '/usr/sbin/cron'; then
	echo "INFO: A cron daemon is already running."
    elif [ "${service}" != "off" ]; then
	for file in /var/run/cron.pid /var/log/cron.log ; do
	    chown "${USER}" "${file}" 2>/dev/null
	    rm -f "${file}"
	    if [ -f "${file}" ]; then
		echo "WARNING: ${file} could not be deleted."
		echo "         Make sure the daemon can write to it."
		echo
	    fi
	done

	if request "Do you want to start the cron daemon as a ${service} now?"; then
	    if [ "${service}" = "job" ]; then
                echo "WARNING: The cron daemon may stop when you log off."
                echo "         To avoid that, launch cron as a service (using cygrunsrv)."
		/usr/sbin/cron
	    else
		cygrunsrv -S ${cron_service_name}
	    fi
	    [ $? -eq 0 ] && echo "OK. The cron daemon is now running."
	elif [ "${service}" = "job" ]; then
	    echo "OK. Type '/usr/sbin/cron' to start the cron daemon job."
	else
	    echo "OK. Type 'cygrunsrv -S ${cron_service_name}' to start the cron daemon service."
	    echo "    It will restart automatically at each reboot."
	fi
    fi
    echo
    echo "In case of problem, examine the log file for cron,"
    echo -n "/var/log/cron.log, and the "
    if [ -S "/dev/log" ]; then
        echo "appropriate syslog file"
    else
	echo "Windows event log (using /usr/bin/cronevents)"
    fi
    echo "for information about the problem cron is having."
    echo

    ls -l /usr/sbin/sendmail | fgrep -q cronlog &&
        echo -e "Examine also any cron.log file in the HOME directory\n(or the file specified in MAILTO) and cron related files in /tmp.\n"

    echo "If you cannot fix the problem, then report it to cygwin@cygwin.com."
    echo "Please run the script /usr/bin/cronbug and ATTACH its output"
    echo "(the file cronbug.txt) to your e-mail."
    echo
    echo "WARNING: PATH may be set differently under cron than in interactive shells."
    echo "         Names such as \"find\" and \"date\" may refer to Windows programs."
    echo

} # === End of install_service() === #

#=========================
# Entry point:
#=========================

# Set PATH to use the Cygwin programs
PATH=/usr/bin:$PATH
USER="$(id -un)"
get_temp_dir

# Take care of obsolete cron_diagnose.sh
if expr "$0" : '.*cron_diagnose.sh' > /dev/null; then
    echo -e "\nINFO: cron_diagnose.sh is now included in cron-config.\n"
fi

sanity_check || exit 1

get_NT || exit 1

cron_service_name=${1:-cron}
slapos_administrator=${2:-slaproot}
_password=$3
install_service ${slapos_administrator} ${_password}

exit $?