Is it possible to change a user's default group inside a script for the duration of that script's execution?
I need to generate files in a script that have the proper user and group but my user's primary group is not who should own the resultant output.
$ groups
groupa groupb
$ ./myscript.sh
$ ls -l
-rw-r--r-- 1 me groupa 0 Sep 17 09:42 myscript_output.txt
But I want "groupb".
myscript.sh:
#!/bin/bash
touch "myscript_output.txt"
Try the newgrp command, which changes the primary group of a user into another group of which that user is a member:
#!/bin/bash
newgrp groupb << END
touch "myscript_output.txt"
END
The sg command can do this pretty well.
#!/bin/bash
sg groupb "touch myscript-output.txt"
The group can be set from a script. It only requires the "if"
statement below. The group is checked and if it is incorrect, then
the script is restarted with the sg command Nate mentioned.
A check for looping is employed(just in case the unforeseeable happens.)
To use, just change the group from "wheel" to the desired. Replace the "DEMO" section with the regular code.
Read on, below(after the script.)
#! /bin/sh
#
# If the group(set with NEEDGRP) is already correct, or this code has already
# run, then this section is skipped and the rest of the
# script is run; otherwise sg is called to restart the script with the
# desired group. Assumes the command "id -ng" returns the group.
if ! [ "${SBREADY:=false}" = true -o $(id -ng) = ${NEEDGRP:=wheel} ] ; then
export SBREADY=true
exec sg $NEEDGRP "$0" "$#"
fi
# ---------------------- DEMO: CUT HERE ---------------------------
# This is a demonstration of creating files.
echo HELLO my group is $(id -ng), GID=$(id -g)
# NOTE: files are created with the current group only if the directory
# is not sgid.
# Show current directory and permissions on it
echo
pwd -P
ls -ld .
echo
# Create and list some new files, the remove them.
touch my-$$.{a,b,c}
echo Created my-$$.{a,b,c}...
ls -l my-$$.{a,b,c}
echo
rm -v my-$$.{a,b,c}
Following are printouts of some tests run in order to explain why just changing groups my not be sufficient to ensure files have the right group ownership. Directory permissions also come into play.
This first log is the output from ruining in a regular directory. The script is run as user frayser, and group frayser. Files are created
with the desired group. Compare to the next listing:
frayser#gentoo ~/src/Answers $ (cd /tmp; $OLDPWD/set-group.sh)
HELLO my group is wheel, GID=10
/tmp
drwxrwxrwt 16 root root 976 Sep 24 04:45 .
Created my-19201.a... my-19201.b... my-19201.c...
-rw-r----- 1 frayser wheel 0 Sep 24 04:53 my-19201.a
-rw-r----- 1 frayser wheel 0 Sep 24 04:53 my-19201.b
-rw-r----- 1 frayser wheel 0 Sep 24 04:53 my-19201.c
removed `my-19201.a'
removed `my-19201.b'
removed `my-19201.c'
Now this next run happens in a director that is sgid "conman" because as a policy, Configuration Management is given group ownership of all src directories.
NOTE: The files inherit the group of the directory.
frayser#gentoo ~/src/Answers $ ./set-group.sh
HELLO my group is wheel, GID=10
/usr/lucho/src/frayser/practice
drwxr-s--- 6 frayser conman 768 Sep 24 04:51 .
Created my-19214.a... my-19214.b... my-19214.c...
-rw-r----- 1 frayser conman 0 Sep 24 04:54 my-19214.a
-rw-r----- 1 frayser conman 0 Sep 24 04:54 my-19214.b
-rw-r----- 1 frayser conman 0 Sep 24 04:54 my-19214.c
removed `my-19214.a'
removed `my-19214.b'
removed `my-19214.c'
frayser#gentoo ~/src/Answers $
Because of directory permissions, it may be necessary for a script to
explicitly set permissions and ownership.
Normally that can be accomplished by applying to a program the modifications:
chgrp groupb myprog
chmod g+s myprog
But that works with normal programs - not with the shell scripts (for security reasons). For a shell script there is no other way (at least I'm not aware (*)) other than from inside script itself to call the chgrp:
#!/bin/bash
FNAME="myscript_output.txt"
GRP=groupb
touch $FNAME
chgrp $GRP $FNAME || { echo 2>&1 "Can't change group of $FNAME to $GRP"; exit 1; }
(*) Some people for the purpose write a tiny wrapper C program. But that is kludgy. Search net for "setuid shell scripts" - there would be lots of such example C programs and replace most commonly found there setuid(0) with getgrnam() + setgid().
Related
To grant read and write permissions to the owner and to remove execution permission from the group should it be two commands as,
chmod u +rw Test
chmod g -x Test
or could it be can done in a single command?
To change directory permissions in Linux, use the following:
chmod +rwx filename to add permissions.
chmod -rwx directoryname to remove permissions.
chmod +x filename to allow executable permissions.
chmod -wx filename to take out write and executable permissions.
r: Read permissions. The file can be opened, and its content viewed.
w: Write permissions. The file can be edited, modified, and deleted.
x: Execute permissions. If the file is a script or a program, it can be run (executed).
We can change Using numbers as well
chmod 754 filename 7 for owner (read write and execute), 5 for group(read and execute), 4 for other users (only read)
$ chmod u+rw,g-x Test
$ ls -ls Test
0 -rwx-----x 1 dave dave 0 Sep 30 09:28 Test
$ chmod -u-rw,g+x Test
$ ls -ls Test
0 ------x--- 1 dave dave 0 Sep 30 09:28 Test
$ chmod u+rw,g-x Test
$ ls -ls Test
0 -rw------- 1 dave dave 0 Sep 30 09:28 Test
I would like to edit a file with a shell script which is in the same group but not the "caller" user.
-rwsr-xr-x 1 root root 4896 Oct 21 00:59 /usr/bin/luxus
-rw-rw-r-- 1 root root 4096 Oct 20 23:01 <path>/file1
lrwxrwxrwx 1 root root 0 Oct 20 23:00 <path>/dir1
/usr/bin/luxus: the shell script
file1: the file to edit
dir1: file1's parent directory (symlink)
In the shell script, this is the line where the permission issue is:
echo "string" > /usr/bin/tee <path>/file1
Output:
/usr/bin/tee: <path>/file1: Permission denied
I am trying to create an AUR package for the shell script. The latter is meant to be install on the system from a PKGBUILD. In vain, I attempted to give enough permissions to the script to edit the targeted file.
This is a PKGBUILD's sample:
install -Dm755 src/${pkgname} "${pkgdir}/usr/bin/${pkgname}"
chown root.root "${pkgdir}/usr/bin/${pkgname}"
chmod 4755 "${pkgdir}/usr/bin/${pkgname}"
After investigating, I think it is quite simply impossible because of security or because of the parent dir's rights.
Nevertheless I am asking you for a solution.
As you said "you can't do anything".
The following post quite simply explains why it won't work:
https://unix.stackexchange.com/questions/364/allow-setuid-on-shell-scripts
I can't understand how exactly this works in Linux.
For example, I want only users in some group have access to execute some file (I hope this is possible without visudo).
I create a system user and system group like:
useradd -K UID_MIN=100 -K UID_MAX=499 -K GID_MIN=100 -K GID_MAX=499 -p \* -s /sbin/nologin -c "testusr daemon,,," -d "/var/testusr" testusr
I add my current user user to the group testusr (may be not cross platform):
adduser user testusr
I create some test shell file and set permissions:
touch test.sh
chmod ug+x test.sh
sudo chown testusr:testusr test.sh
But I still can't start test.sh as user:
./test.sh
-> Error
Now I look for some system groups like cdrom to check how they work. My user is in cdrom group and can use the cd rom on my computer:
$ ls -al /dev/cdrom
lrwxrwxrwx 1 root root 3 апр. 17 12:55 /dev/cdrom -> sr0
$ ls -al /dev/sr0
brw-rw----+ 1 root cdrom 11, 0 апр. 17 12:55 /dev/sr0
Addition:
./test.sh command starts to work as I want after system reboot. Strange...
I'm on Ubuntu Studio 15.10
The group changes are reflected only upon re-login.
I am very puzzled by this problem I am having. I am trying to execute a file in Ubuntu 12.04 LTS via command line. I have a script that calls a program to run and write the results in a hard drive. I changed the permissions and ownership of everything to be wxr. Here is the ls -l of my script (called TEST-star):
-rwxrwxrwx 1 root root 950 Nov 15 13:16 TEST-star
Here is the ls -l of the package my script calls:
-rwxrwxrwx 1 root root 1931414 Nov 10 12:37 STAR
Finally the ls -l of the hard drive mounted in /media/CLC"
drwxrwxrwx 1 root root 8192 Nov 15 13:04 CLC
I have been trying to run it since yesterday and always get a message that I don't have permission to write the results:
EXITING because of FATAL ERROR: could not create output file ./_STARtmp//Unmapped.out.mate1.thread14
Solution: check that you have permission to write this file
I thought if I change the permissions to rwx and run my script as root it would not have a problem (using sudo). Right now I run out of options. Any suggestion would be appreciated. Please let me know what other information you would need solve this issue.
Thank you.
Here is the first line of script I am trying to run:
#!/bin/sh
cd /media/CLC/ANOPHELES-STAR-v2.4f1/; mkdir GambFemAnt1 && cd GambFemAnt1; echo $PWD && echo Starting mapping of GambFemAnt1; /home/aedes/Documents/STAR_2.4.0f1/STAR --genomeDir /media/Galaxy/Galaxy_data/Anopheles/STAR/Genome --readFilesIn /media/Galaxy/Galaxy_data/Anopheles/QC/GambFemAnt1/GambFemAnt1.fastq --runThreadN 23 --outFilterMismatchNmax 4 --outFilterMatchNminOverLread 0.75 --seedSearchLmax 30 --seedSearchStartLmax 30 --seedPerReadNmax 100000 --seedPerWindowNmax 100 --alignTranscriptsPerReadNmax 100000 --alignTranscriptsPerWindowNmax 10000 --outSAMstrandField intronMotif --outFilterIntronMotifs RemoveNoncanonical --outSAMtype BAM SortedByCoordinate --outReadsUnmapped Fastx; mv Aligned.sortedByCoord.out.bam GambFemAnt1.bam; mv Unmapped.out.mate1 GambFemAnt1-unmapped.fastq; cp *.fastq /media/CLC/ANOPHELES-STAR-v2.4f1/UNMAPED-reads/; cd /media/CLC/ANOPHELES-STAR-v2.4f1 && echo $PWD && echo GambFemAnt1 mapping finished;
I also posted a question for the authors of the package.
Turns out all the permissions were set correctly. The problem resigns within the package. I found out that it works using --runThreadN 12 instead of --runThreadN 23.
To start learning BASH scripting, I've created a trivial script that curls down a stock price from YAHOO and prints it to STDOUT. I've set the permissions to rwx for everyone, and moved the file into my path:
Script:
root#raspberrypi:~/code/scripts$ cat quote
#!/bin/bash
while getopts "s:" opt; do
case $opt in
s)STOCK="$OPTARG";;
\?) echo "ERROR"; exit 1;;
esac
done
PRICE=$(curl -s "http://download.finance.yahoo.com/d/quotes.csv?s=${STOCK}&f=l1")
echo "${STOCK}: ${PRICE}"; exit 0
exit 0
I then set the permissions for all users:
root#raspberrypi:~/code/scripts$ chmod 777 quote
Here is my $PATH:
root#raspberrypi:~/code/scripts$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
I now move it into my path in what I read was the appropriate location for custom user scripts:
root#raspberrypi:~/code/scripts$ ls -la /usr/local/bin
total 12K
drwxrwsr-x 2 root staff 4.0K Apr 30 01:28 ./
drwxrwsr-x 10 root staff 4.0K Jan 1 1970 ../
-rwxrwxrwx 1 root root 433 Apr 30 01:22 quote*
The which command will find it (expected):
root#raspberrypi:~/code/scripts$ which quote
/usr/local/bin/quote
PROBLEM: when I run the script, it returns the first option on the next line followed by my prompt:
root#raspberrypi:~/code/scripts$ quote -s aapl
'-s'root#raspberrypi:~/code/scripts$
But, when I run the script with a full path, it works just fine:
root#raspberrypi:~/code/scripts$ /usr/local/bin/quote -s aapl
-s: 592.33
Apologies if this less a programming question and more a Unix question, but I want to make sure I rule out a problem with my code before I do anything else.
I'm sure this is something very easy, so thanks in advance for the extra set of eyes.
You just chose an unfortunate name for your script. quote is also the name of a function from the bash_completion package, and functions override external scripts.
type quote will show that it's a function (whereis doesn't know about these things).
Either rename it or disable bash_completion. Or run command quote every time.