Re: cron -n/-s/-q whitespace and /etc/crontab

2023-07-19 Thread Todd C . Miller
On Wed, 19 Jul 2023 16:44:23 +0100, Stuart Henderson wrote:

> When /etc/crontab is used, cron only skips over a single whitespace
> character between the username and -n/-s/-q flags; more than one and
> the flag is taken as part of the command:
>
> printf '*\t*\t*\t*\t*\tnobody\t-n true 1\n' | doas tee -a /etc/crontab
> printf '*\t*\t*\t*\t*\tnobody\t\t-n true 2\n' | doas tee -a /etc/crontab
>
> 2023-07-19T15:39:01.316Z symphytum cron[96294]: (nobody) CMD (  -n true 2)
> 2023-07-19T15:39:01.317Z symphytum cron[81012]: (nobody) CMD (true 1)
>
> Is this a "so don't do that then", or is it expected to work?
> (There's no problem with "per-user crontab" files).

It is a bug.  There is a missing call to Skip_Blanks() for the
/etc/crontab case.  Instead of adding yet another unget_char() after
Skip_Blanks(), we can get rid of a superfluous unget_char() +
get_char() pair.
 
 - todd

Index: usr.sbin/cron/entry.c
===
RCS file: /cvs/src/usr.sbin/cron/entry.c,v
retrieving revision 1.58
diff -u -p -u -r1.58 entry.c
--- usr.sbin/cron/entry.c   13 Jun 2023 15:36:21 -  1.58
+++ usr.sbin/cron/entry.c   19 Jul 2023 16:01:08 -
@@ -275,18 +275,17 @@ load_entry(FILE *file, void (*error_func
goto eof;
}
 
-   /* ch is the first character of a command, or a username */
-   unget_char(ch, file);
-
if (!pw) {
char*username = cmd;/* temp buffer */
 
+   unget_char(ch, file);
ch = get_string(username, MAX_COMMAND, file, " \t\n");
 
if (ch == EOF || ch == '\n' || ch == '*') {
ecode = e_cmd;
goto eof;
}
+   Skip_Blanks(ch, file)
 
pw = getpwnam(username);
if (pw == NULL) {
@@ -356,7 +355,6 @@ load_entry(FILE *file, void (*error_func
/* An optional series of '-'-prefixed flags in getopt style can
 * occur before the command.
 */
-   ch = get_char(file);
while (ch == '-') {
int flags = 0, loop = 1;
 



cron -n/-s/-q whitespace and /etc/crontab

2023-07-19 Thread Stuart Henderson
When /etc/crontab is used, cron only skips over a single whitespace
character between the username and -n/-s/-q flags; more than one and
the flag is taken as part of the command:

printf '*\t*\t*\t*\t*\tnobody\t-n true 1\n' | doas tee -a /etc/crontab
printf '*\t*\t*\t*\t*\tnobody\t\t-n true 2\n' | doas tee -a /etc/crontab

2023-07-19T15:39:01.316Z symphytum cron[96294]: (nobody) CMD (  -n true 2)
2023-07-19T15:39:01.317Z symphytum cron[81012]: (nobody) CMD (true 1)

Is this a "so don't do that then", or is it expected to work?
(There's no problem with "per-user crontab" files).