2

I am using Bash on Lubuntu 16.04. LTS, but I'm not sure if this matters much for this question.

I noticed, that when I create a file as standard user, the file has 664 permissions. But when I am root and execute the same command for the same user via the -u argument, it has 644 permissions, so the write permissions for the group are missing.

I suppose this to be a flaw, since the sudo manpages clearly state:

     -u user, --user=user
             Run the command as a user other than the default target user (usually root).  The user may be either a user name or a
             numeric user ID (UID) prefixed with the ‘#’ character (e.g.  #0 for UID 0).  When running commands as a UID, many
             shells require that the ‘#’ be escaped with a backslash (‘\’).  Some security policies may restrict UIDs to those
             listed in the password database.  The sudoers policy allows UIDs that are not in the password database as long as the
             targetpw option is not set.  Other security policies may not support this.

Now that I know that the -u argument's behavior differs from the behavior that has to be expected, my question is:

How can I make sure, that a command that is started in a root shell gets executed exactly as it would be executed from another user's shell?

Remark: I know that I could fix this one problem by tinkering with the umask, but this won't guarantee me that the behavior doesn't differ in an arbitrary amount of other cases.

Wanderer
  • 272
  • 5
  • 15
  • " gets executed exactly as it would be executed from another user's shell?" -- execute that user's shell. e.g. "`sudo -u user sh -c 'some command'`". Note that each user specifies their own shell. `getent passwd user` for details – Brian Cain Jun 30 '17 at 13:58
  • Interestingly, this doesn't work - file permissions are still 644 – Wanderer Jun 30 '17 at 14:05
  • 1
    Stack Overflow is a site for programming and development questions. This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Unix & Linux Stack Exchange](http://unix.stackexchange.com/) would be a better place to ask. – jww Jun 30 '17 at 19:14
  • I don't see why this question should be off-topic. Yes it might fit on some other exchange sites as well, since the intersection of the sets of accepted topics is non-empty between multiple exchange sites. Talking in terms of the link you provided, this question indeed covers a specific programming problem in the context of scripting as well as software tools commonly used by programmers and is a practical, answerable problem that is unique to software development. In addition, it does not ask for debugging help, is obviously not homework, can be reproduced and does not ask for a book or tool. – Wanderer Jul 01 '17 at 09:04
  • I am really glad you asked this question @Wanderer, I have JUST learned about file permissions from a book and was running into the same type of problems trying different things out. Was going crazy. Kept having to log into another user instead of executing the command using `sudo -u mkdir` to get the permissions I wanted which was ridiculous. – bmcentee148 Feb 22 '18 at 23:32

2 Answers2

2

It looks like the umask depends on whether the shell is interactive:

$ umask
0002
$ sudo -u $USER bash -c umask
0022
$ sudo -u $USER bash -ic umask
0002

This appears to be from from /etc/bashrc, which applies umask 002 only if

  • it's not a login shell,
  • the UID is greater than or equal to 200, and
  • the username is equal to the group name,

or from /etc/profile, which applies umask 002 if the last two criteria are met. I'm not sure if something else is overriding this, because shopt login_shell prints the same whether the shell is interactive or not, and the UID is also the same.

You can get the user's default shell thusly:

$ getent passwd $USER | cut --delimiter=: --fields=7
/bin/bash

Combining them:

$ sudo -u $USER $(getent passwd $USER | cut --delimiter=: --fields=7) -ic umask
0002
l0b0
  • 55,365
  • 30
  • 138
  • 223
  • 1
    For me, this doesn't work out: Using your combined command, I always get the `umask` 0022, no matter if started from a standard user shell or a root shell, so it does the opposite of what I want to achieve. In addition, I get an error, if started in a root shell: `bash: /root/.bashrc: Permission denied` – Wanderer Jun 30 '17 at 14:38
  • Well, `$USER` evaluates to "root" if you run this in a root shell, so you'd have to replace *both* occurrences of it with the user you're interested in to get the expected result. – l0b0 Jun 30 '17 at 14:41
  • Then it seems something is broken on your system - Running Bash as a normal user should never attempt to read `/root/.bashrc`. – l0b0 Jun 30 '17 at 14:52
  • I'm doing the experimenting in a freshly set up virtual machine to exclude this possibility. What I'm doing is: Opening a terminal, now I'm standard user. Executing the command with the standard user name instead of `$USER`. Then `sudo su` to get a root shell. Executing the command in the same way. That's it, nothing else, on a freshly installed OS. – Wanderer Jun 30 '17 at 15:00
  • If some shell is trying to read `/root/.bashrc` when it shouldn't that's probably enough for another question (maybe on unix.SE or superuser.SE). It should never happen when running a non-root shell. And I can't reproduce this problem on a Fedora 25 desktop. – l0b0 Jun 30 '17 at 15:11
  • It seems to be related to how the root shell gets invoked: `sudo su`, `sudo su -` and `sudo -i` cause the described behavior, while if invoked via `sudo -s` no error occurs. Anyways, it's a vanilla (L)Ubuntu 16.04. LTS installation, and I get `umask` 0022 back in all cases, so this problem is currently not my focus. – Wanderer Jun 30 '17 at 15:16
-1

A nice and clean solution that shows the expected behavior is this:

sudo su <username> -c '<any commands>'

Wanderer
  • 272
  • 5
  • 15