Discussion:
sudo -u user command vs su user -c command?
(too old to reply)
Adam Funk
2014-05-20 11:53:38 UTC
Permalink
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.

sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null

su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"

(I've tried googling for it, but all I find are explanations of the
main differences between sudo & su, not dealing with su -c.)

Thanks,
Adam
--
You measure democracy by the freedom it gives its dissidents, not the
freedom it gives its assimilated conformists. --- Abbie Hoffman
Barry Margolin
2014-05-20 15:42:02 UTC
Permalink
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
(I've tried googling for it, but all I find are explanations of the
main differences between sudo & su, not dealing with su -c.)
sudo is used mainly by NON-ROOT users -- it makes use of /etc/sudoers to
restrict what they're allowed to do, and specify whether they need to
enter a password (and they enter their own password, they don't need to
know the root password). If the script is being run by root, there's no
need for sudoers, since root can already do anything, and is never asked
for a password.

So root should just use su, it gains no benefit from using sudo.

The -c option is irrelevant for the decision.
--
Barry Margolin, ***@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Thomas 'PointedEars' Lahn
2014-05-22 00:49:00 UTC
Permalink
It's attribution *line*, _not_ attribution novel.
Post by Barry Margolin
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
(I've tried googling for it, but all I find are explanations of the
main differences between sudo & su, not dealing with su -c.)
sudo is used mainly by NON-ROOT users -- it makes use of /etc/sudoers to
restrict what they're allowed to do, and specify whether they need to
enter a password (and they enter their own password, they don't need to
know the root password).
That is not all.
Post by Barry Margolin
If the script is being run by root, there's no need for sudoers, since
root can already do anything, and is never asked for a password.
So root should just use su, it gains no benefit from using sudo.
Untrue and very beside the point. RTFM.
Post by Barry Margolin
The -c option is irrelevant for the decision.
It is not. Had “-c“ not been used, the remaining arguments had been

,-su(1)
|
| […] supplied to the user's login shell […]

which could have resulted in

| /usr/local/sbin/fetchnews: /usr/local/sbin/fetchnews: cannot execute
| binary file

Per POSIX.1,

su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"

is equivalent to

su -c "/usr/local/sbin/fetchnews -f 2>/dev/null" news

as

,-[ibid.]
|
| SYNOPSIS
| su [options] [username]
--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
Geoff Clare
2014-05-22 12:05:58 UTC
Permalink
Post by Thomas 'PointedEars' Lahn
Per POSIX.1,
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
is equivalent to
su -c "/usr/local/sbin/fetchnews -f 2>/dev/null" news
There is no su utility in POSIX.1. Years ago there was a POSIX
system administration standard (IEEE 1387, since withdrawn) which
might have included it, but I've never seen a copy.
Post by Thomas 'PointedEars' Lahn
as
,-[ibid.]
|
| SYNOPSIS
| su [options] [username]
That's quite a misleading synopsis, wherever you got it from.
In particular it doesn't cover the use of "-" as an operand before
the username to request a login shell, nor the ability to specify
arguments after the username which are to be passed on to the shell.

The synopsis on Solaris is:

su [-] [ username [ arg...]]

and on HP-UX it is:

su [-] [username [arguments]]
su [-] -d [username]
--
Geoff Clare <***@gclare.org.uk>
Janis Papanagnou
2014-05-22 12:48:04 UTC
Permalink
[...]
Post by Geoff Clare
Post by Thomas 'PointedEars' Lahn
|
| SYNOPSIS
| su [options] [username]
That's quite a misleading synopsis, wherever you got it from.
I also find that on my Linux system in the man page. Though here you
get a different (not better) synopsis if you use --help ...

$ LC_ALL=C su --help
Usage: su [options] [LOGIN]

Options:
-c, --command COMMAND pass COMMAND to the invoked shell
-h, --help display this help message and exit
-, -l, --login make the shell a login shell
-m, -p,
--preserve-environment do not reset environment variables, and
keep the same shell
-s, --shell SHELL use SHELL instead of the default in passwd


The info pages - something they sadly seem to prefer on Linux - are
not better, even incoherent WRT the man page of the same system...

su [OPTION]... [USER [ARG]...]

`-c COMMAND'
`--command=COMMAND'
Pass COMMAND, a single command line to run, to the shell with a
`-c' option instead of starting an interactive shell.

`-f'
`--fast'
Pass the `-f' option to the shell. This probably only makes sense
if the shell run is `csh' or `tcsh', for which the `-f' option
prevents reading the startup file (`.cshrc'). With Bourne-like
shells, the `-f' option disables file name pattern expansion
(globbing), which is not likely to be useful.

`-'
`-l'
`--login'
Make the shell a login shell. This means the following. Unset all
environment variables except `TERM', `HOME', and `SHELL' (which
are set as described above), and `USER' and `LOGNAME' (which are
set, even for the super-user, as described above), and set `PATH'
to a compiled-in default value. Change to USER's home directory.
Prepend `-' to the shell's name, intended to make it read its
login startup file(s).

[...]


Janis
Post by Geoff Clare
In particular it doesn't cover the use of "-" as an operand before
the username to request a login shell, nor the ability to specify
arguments after the username which are to be passed on to the shell.
su [-] [ username [ arg...]]
su [-] [username [arguments]]
su [-] -d [username]
Lew Pitcher
2014-05-22 12:59:35 UTC
Permalink
On Thursday 22 May 2014 08:48, in comp.unix.shell, "Janis Papanagnou"
Post by Janis Papanagnou
[...]
Post by Geoff Clare
Post by Thomas 'PointedEars' Lahn
|
| SYNOPSIS
| su [options] [username]
That's quite a misleading synopsis, wherever you got it from.
I also find that on my Linux system in the man page. Though here you
get a different (not better) synopsis if you use --help ...
$ LC_ALL=C su --help
Usage: su [options] [LOGIN]
-c, --command COMMAND pass COMMAND to the invoked shell
-h, --help display this help message and exit
-, -l, --login make the shell a login shell
-m, -p,
--preserve-environment do not reset environment variables, and
keep the same shell
-s, --shell SHELL use SHELL instead of the default in passwd
The info pages - something they sadly seem to prefer on Linux - are
not better, even incoherent WRT the man page of the same system...
su [OPTION]... [USER [ARG]...]
`-c COMMAND'
`--command=COMMAND'
Pass COMMAND, a single command line to run, to the shell with a
`-c' option instead of starting an interactive shell.
`-f'
`--fast'
Pass the `-f' option to the shell. This probably only makes sense
if the shell run is `csh' or `tcsh', for which the `-f' option
prevents reading the startup file (`.cshrc'). With Bourne-like
shells, the `-f' option disables file name pattern expansion
(globbing), which is not likely to be useful.
`-'
`-l'
`--login'
Make the shell a login shell. This means the following. Unset all
environment variables except `TERM', `HOME', and `SHELL' (which
are set as described above), and `USER' and `LOGNAME' (which are
set, even for the super-user, as described above), and set `PATH'
to a compiled-in default value. Change to USER's home directory.
Prepend `-' to the shell's name, intended to make it read its
login startup file(s).
[...]
Janis
Post by Geoff Clare
In particular it doesn't cover the use of "-" as an operand before
the username to request a login shell, nor the ability to specify
arguments after the username which are to be passed on to the shell.
su [-] [ username [ arg...]]
su [-] [username [arguments]]
su [-] -d [username]
And, on my Linux systems, su(1) ("man 1 su") shows

SU(1)

NAME
su - change user ID or become super-user

SYNOPSIS
su [-] [username [args]]

DESCRIPTION
su is used to become another user during a login session
...
--
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request
Thomas 'PointedEars' Lahn
2014-05-22 16:05:53 UTC
Permalink
Post by Janis Papanagnou
[...]
Post by Geoff Clare
Post by Thomas 'PointedEars' Lahn
|
| SYNOPSIS
| su [options] [username]
That's quite a misleading synopsis, wherever you got it from.
I also find that on my Linux system in the man page.
It is Debian GNU/Linux jessie/sid here, and it was not just the man page.
I have obtained the error message I posted by testing, just with another
executable that exists here (and then I substituted the path with that of
the OP to make my point).
Post by Janis Papanagnou
Post by Geoff Clare
In particular it doesn't cover the use of "-" as an operand before
the username to request a login shell
Yes, it does. “-” is and always has been a special option.

| SU(1) User Commands SU(1)
| […]
| DESCRIPTION
| The su command is used to become another user during a login
| session. Invoked without a username, su defaults to becoming the
| superuser.
| The optional argument - may be used to provide an environment
| similar to what the user would expect had the user logged in
| directly.
|
| […]
| OPTIONS
| The options which apply to the su command are:
| […]
| -, -l, --login
| Provide an environment similar to what the user would expect had
| the user logged in directly.
|
| When - is used, it must be specified before any username. For
| portability it is recommended to use it as last option, before
| any username. The other forms (-l and --login) do not have this
| restriction.
| […]
| shadow-utils 4.2 05/04/2014 SU(1)
Post by Janis Papanagnou
Post by Geoff Clare
nor the ability to specify arguments after the username which are to be
passed on to the shell.
I had quoted the very part of the man page. Here it is in full, whereas I
had quoted only the marked part due to sufficient context (but I can see now
it was not fool-proof):

| Additional arguments may be provided after the username, in which
| case they are supplied to the user's login shell. In particular, an
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| argument of -c will cause the next argument to be treated as a
| command by most command interpreters. The command will be executed
| by the shell specified in /etc/passwd for the target user.
--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
Geoff Clare
2014-05-23 12:38:08 UTC
Permalink
Post by Thomas 'PointedEars' Lahn
[...]
Post by Geoff Clare
Post by Thomas 'PointedEars' Lahn
|
| SYNOPSIS
| su [options] [username]
That's quite a misleading synopsis, wherever you got it from.
In particular it doesn't cover the use of "-" as an operand before
the username to request a login shell
Yes, it does. “-” is and always has been a special option.
No, that's just another mistake in the man page (a misuse of the term
"option"). A lone "-" is an operand, not an option.
Post by Thomas 'PointedEars' Lahn
| SU(1) User Commands SU(1)
| […]
| DESCRIPTION
| The su command is used to become another user during a login
| session. Invoked without a username, su defaults to becoming the
| superuser.
| The optional argument - may be used to provide an environment
| similar to what the user would expect had the user logged in
| directly.
Calling it an "optional argument" is fine, but that's not what the
term "option" means.
Post by Thomas 'PointedEars' Lahn
| […]
| OPTIONS
| […]
| -, -l, --login
| Provide an environment similar to what the user would expect had
| the user logged in directly.
Listing "-" in this way implies that you can invoke it using

su -x-

where x is any other option (that doesn't take an option-argument), but
if you try that you get:

$ su -m- foo
su: invalid option -- '-'

which is clear an irrefutable evidence that this su does not treat "-" as
an option.

The normal command line convention of using "--" to indicate the
end of options means that "-" can never itself be an option.
Post by Thomas 'PointedEars' Lahn
Post by Geoff Clare
nor the ability to specify arguments after the username which are to be
passed on to the shell.
I had quoted the very part of the man page. Here it is in full, whereas I
had quoted only the marked part due to sufficient context (but I can see now
| Additional arguments may be provided after the username, in which
| case they are supplied to the user's login shell. In particular, an
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| argument of -c will cause the next argument to be treated as a
| command by most command interpreters. The command will be executed
| by the shell specified in /etc/passwd for the target user.
Yes, it's covered by the description, but what I wrote remains true: the
*synopsis* is misleading because it does not indicate that additional
arguments can be given after the username.
--
Geoff Clare <***@gclare.org.uk>
Adam Funk
2014-05-22 11:53:48 UTC
Permalink
Post by Barry Margolin
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
(I've tried googling for it, but all I find are explanations of the
main differences between sudo & su, not dealing with su -c.)
sudo is used mainly by NON-ROOT users -- it makes use of /etc/sudoers to
restrict what they're allowed to do, and specify whether they need to
enter a password (and they enter their own password, they don't need to
know the root password). If the script is being run by root, there's no
need for sudoers, since root can already do anything, and is never asked
for a password.
So root should just use su, it gains no benefit from using sudo.
That make sense, thanks.
Post by Barry Margolin
The -c option is irrelevant for the decision.
(Well, without it, su would be starting a shell owned by news rather
than running a command.)
--
Unix is a user-friendly operating system. It's just very choosy about
its friends.
Kaz Kylheku
2014-05-21 14:17:15 UTC
Permalink
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
This command requires configuration in order to be allowed, and
will ask you for *your* password.
Post by Adam Funk
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
This command requires you to know the password of the news account.

Otherwise, there is little difference. In both cases, a program with
root privileges drops into the "news" user ID, and executes the same thing.

There is another difference. In the sudo example, the redirection of
stderr to /dev/null is arranged in the invoking context, whereas
in the su example, the redirection to /dev/null is done as news.

Since /dev/null is usually world-readable, this doesn't mean much.
But consider:

sudo -u news /path/to/command < file-only-I-can-access

versus:

su news -c "/path/to/command < file-only-I-can-access"

Since user news cannot access "file-only-I-can-access", this will fail.
Barry Margolin
2014-05-21 15:36:56 UTC
Permalink
Post by Kaz Kylheku
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
This command requires configuration in order to be allowed, and
will ask you for *your* password.
I'm not sure if this is a default or a configuration setting, but sudo
doesn't ask me for a password when I run it as root.
Post by Kaz Kylheku
Post by Adam Funk
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
This command requires you to know the password of the news account.
su doesn't ask for passwords when it's run by root.

Your explanation is good in general, but doesn't address the specific
case he asked about: "launched by root from a cron or at job".
Post by Kaz Kylheku
Otherwise, there is little difference. In both cases, a program with
root privileges drops into the "news" user ID, and executes the same thing.
There is another difference. In the sudo example, the redirection of
stderr to /dev/null is arranged in the invoking context, whereas
in the su example, the redirection to /dev/null is done as news.
Since /dev/null is usually world-readable, this doesn't mean much.
In this case, world-writable is what's relevant. Lots of things break if
someone ever accidentally removes world read and write permissions from
/dev/null, so you can reliably assume that this will always be the case.
Post by Kaz Kylheku
sudo -u news /path/to/command < file-only-I-can-access
su news -c "/path/to/command < file-only-I-can-access"
Since user news cannot access "file-only-I-can-access", this will fail.
And if the file is only accessible to the news account, you get the
opposite success and failures. If the user is allowed to run "bash" in
/etc/sudoers, you can do the first one as:

sudo -u news bash -c "/path/to/command < file-only-news-can-access"
--
Barry Margolin, ***@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
Adam Funk
2014-05-22 11:55:17 UTC
Permalink
Post by Barry Margolin
Post by Kaz Kylheku
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
This command requires configuration in order to be allowed, and
will ask you for *your* password.
I'm not sure if this is a default or a configuration setting, but sudo
doesn't ask me for a password when I run it as root.
That's my experience too. Perhaps I should have specified that I'm
running GNU/Linux --- maybe it works differently on BSDs & other
systems.

...
Post by Barry Margolin
Post by Kaz Kylheku
Otherwise, there is little difference. In both cases, a program with
root privileges drops into the "news" user ID, and executes the same thing.
There is another difference. In the sudo example, the redirection of
stderr to /dev/null is arranged in the invoking context, whereas
in the su example, the redirection to /dev/null is done as news.
Since /dev/null is usually world-readable, this doesn't mean much.
In this case, world-writable is what's relevant. Lots of things break if
someone ever accidentally removes world read and write permissions from
/dev/null, so you can reliably assume that this will always be the case.
Post by Kaz Kylheku
sudo -u news /path/to/command < file-only-I-can-access
su news -c "/path/to/command < file-only-I-can-access"
Since user news cannot access "file-only-I-can-access", this will fail.
And if the file is only accessible to the news account, you get the
opposite success and failures. If the user is allowed to run "bash" in
sudo -u news bash -c "/path/to/command < file-only-news-can-access"
Thanks for the info.
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Thomas 'PointedEars' Lahn
2014-05-22 01:21:06 UTC
Permalink
Post by Kaz Kylheku
Otherwise, there is little difference. In both cases, a program with
root privileges drops into the "news" user ID, and executes the same thing.
Wrong.
--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
Thomas 'PointedEars' Lahn
2014-05-22 01:19:59 UTC
Permalink
Post by Adam Funk
What are the practical differences between the following two ways of
running a job (launched by root from a cron or at job)? I think I've
seen both variations in scripts supplied with packages.
sudo -u news /usr/local/sbin/fetchnews -f 2>/dev/null
su news -c "/usr/local/sbin/fetchnews -f 2>/dev/null"
(I've tried googling for it, but all I find are explanations of the
main differences between sudo & su, not dealing with su -c.)
You want to enter “man man” (sic!) instead.

The practical difference is (which is described in the man pages):

sudo(8) uses /etc/sudoers where you can define rules for users. “-u”
specifies that the *target* user should not be the default “root” (but
“news” here); but *you* may still not have permission to execute
/usr/local/sbin/fetchnews because sudoers(5) says so. And you will have to
enter *your* password in order to find out, *not* that of “news”.

This is different with su(8). The command above will ask for the password
of “news”, if any, and execute /usr/local/sbin/fetchnews unconditionally
(but see below). But, as you omitted “-” and -l, it will mostly use the
environment of the current user, not that of “news” (I observe here that
only some environment variables, like $USER, $MAIL, $HOME, and $LOGNAME,
have changed.)

Also, “sudo -u …” runs the command directly, while “su -c” runs the command
from the login shell of the specified user. Suppose the user does not have
a login shell or it does not support “-c” (the login shell may be
/bin/false), the invocation will fail.

$ sudo 'for i in 1 2 3; do echo $i; done'
sudo: for i in 1 2 3; do echo $i; done: command not found

$ su -c 'for i in 1 2 3; do echo $i; done'
Password:
1
2
3
--
PointedEars

Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
Loading...