Create a file as a different user and group

53,364

Solution 1

If you want to create a file as a specific user and group without using chown, you can use sudo and specify the user and group:

sudo -u \#49 -g \#58 touch /tmp/something

Note that the user you specify must have permission to write to the directory where you attempt this.


Or, you can start a shell as the current user, with the group set to something else:

sudo runuser "$USER" -g somegroup

I tried this on a Vagrant box with success:

[vagrant@localhost ~]$ sudo runuser "$USER" -g floppy
[vagrant@localhost ~]$ touch testfile
[vagrant@localhost ~]$ ls -l testfile
-rw-r--r--. 1 vagrant floppy 0 Nov  9 15:57 testfile
[vagrant@localhost ~]$ 

This is despite the "vagrant" user not being part of the "floppy" group.

Solution 2

$ sudo install -o angelo -g apache /dev/null angelo-file

Works for me on centos 6, install version 8.4. Here the install is "copying" the (known to always be empty) /dev/null file to the target, thereby creating your empty file, while in same/single command setting target file's owner and group, because it's run as root via sudo.

Read more about it via: man install or install --help. It can create directories, and set permission modes too, in same/single command. The install command is frequently used in build tools, like makefiles.

You may like to use option -T too, so if target preexists but is a directory, it will fail with an error, and not create empty angelo-file/null instead.

EDIT: OP asked about rsync, duh. Since rsync 3.1.2 see the options like --chmod, --chown, --usermap, --groupmap. (For centos 6 I can get the newer rsync from the iUS repo).

Solution 3

As long as you run the script with elevated privileges, there should be no problem. For example:

#!/usr/bin/env bash 
touch foobar
chown www-data:sudo foobar

If you run as a normal user, it will fail:

$ ./foo.sh 
chown: changing ownership of `foobar': Operation not permitted

But if you run it as root, it works fine:

$ sudo foo.sh
$ ls -l foobar
-rw-r--r-- 1 www-data sudo 26M Sep 17 17:34 foobar
Share:
53,364
Angelo
Author by

Angelo

Updated on September 18, 2022

Comments

  • Angelo
    Angelo over 1 year

    I have a bash script that has to rsync to download files writing them locally, and then needs to set the owner to apache, and the group to a particular user group (that apache is not a member of).

    Is there a way to create those files with those ownerships as they're being written by the rsync process, without having to go through and change them after the fact using chown? There are so many files that the time it takes to go through them later is prohibitive.

    I have to do this for multiple user groups, so I shouldn't be adding apache to these groups, and certainly can't make all of them the default group.

    In other words: is there a way root can create a file as user X and group Y when X is not a member of Y?

    I've tried using runuser, but I'm unable to set the group (presumably because apache doesn't belong to the group).

    I know you can use chmod to change permissions and add any user/group combination. What I'm asking is if there is a way to open a file for writing and use any user/group combo while creating it.

    Attempt using sudo:

    [root@centos7 tmp]# groups angelo
    angelo : angelo wheel
    [root@centos7 tmp]# groups apache
    apache : apache
    [root@centos7 tmp]# sudo -u angelo -g apache touch angelo-file
    Sorry, user root is not allowed to execute '/bin/touch angelo-file' as angelo:apache on centos7
    [root@centos7 tmp]# ls -ld angelo-file
    ls: cannot access angelo-file: No such file or directory
    [root@centos7 tmp]# sudo -u angelo -g angelo touch angelo-file
    [root@centos7 tmp]# ls -ld angelo-file
    -rw-r--r-- 1 angelo angelo 0 Nov 12 03:13 angelo-file
    
    • Wildcard
      Wildcard over 7 years
    • Angelo
      Angelo over 7 years
      That question is asking about the filesystem. You can chmod the file to give any user/group you want. I want to know if you can open a file descriptor acting as any user/group combo. If it is possible, then I haven't found out how.
    • Wildcard
      Wildcard over 7 years
      Do you mean from C? Or from Bash? Have you tried just using sudo with the -g switch?
    • Angelo
      Angelo over 7 years
      I mean using normal Linux tools or commands. I would accept an answer that could verify that you could only do this in C because no tools exist. But I also wouldn't be surprised if you can't even do it in C and this is not an available request through the API. sudo with -g will work if the user is a member of the group, but seems to be disallowed if not.
  • Angelo
    Angelo over 7 years
    I want to do it without chown: "rather than having to go through and change them"
  • Angelo
    Angelo over 7 years
    Oh snap. You did it with a combination of runuser and sudo. I don't know how you figured that out. sudo -u and -g doesn't seem to work though
  • Angelo
    Angelo over 7 years
    Not sure why I can't just run touch in-line, but this seems to work: sudo runuser "$USER" -g floppy bash -c "touch testfile"
  • Angelo
    Angelo over 4 years
    This would be another solution in my case if I could run install in such a way that it allowed another process to write the files. (In my case, I needed the files to be rsync'd and written with the right owner/group on the first shot.)