check if user can access /root directory before running command - linux

I have a homework assignment that asks me to print certain things in a linux terminal with bash scripting. I have done most of them but I am stuck on the last thing I need to do...This is how my professor worded it
Checks to see if current user has access to /root
-lists files in the root directory if so
-Hint: try using 'ls'
Any help will be appreciated.

Conditional Expressions and Symbolic Permissions
The simplest solution is to use a Bash conditional expression to check directory read permissions. For example:
[[ -r /root ]] && ls /root
If you'd rather inspect the permissions visually, you can use ls to list the directory (rather than its contents) with the -d flag. For example:
$ ls -lad /root
drwxr-x--- 6 root wheel 204 Oct 25 04:45 /root
You can then parse the permissions using symbolic notation to see if the current user would have access to its contents, but doing it that way just seems like the long way around when you can just use a conditional or handle the exit status of ls directly:
ls /root || echo "Grade: 'F' for effort." > /dev/stderr

Related

How to Create a long listing of all the files in this directory to a file called etcFiles.txt (In Linux)

I started to learn Linux. But I dont know how to solve this problem. I want to Create a long listing of all the files in /etc/ directory to a file called etcFiles.txt.When i try to run this terminal says "Permission denied".enter image description here
To long list a file in Linux, you need to use the command
ls -l
It displays the contents on the console. To store it in the file you need to redirect it using redirection operation > to a file like
ls -l directoryPath > outputFile.txt.
Here, to store the result of long listing /etc/ to file you need to use
ls -l /etc/ > etcFiles.txt
In the image linked, to store the contents of the current directory to a file you need to provide the current directory as the argument to ls command. In Unix/ Linux, the current directory is represented by ., so as shown in the screenshot, you are already in /etc/ directory, to store long listing contents of current directory i.e. /etc/ to the file, you need to use
ls -l . > ~/etcFiles.txt
However ls command takes the current directory as default argument . above can be avoided and the following command will also work
ls -l > ~/etcFiles.txt
Linux /Unix by default does not give any user permission to write/ create files in /etc/ directory and requires elevated permission to make any changes in this directory. Since you do not have permission to create a new file in /etc/ directory, either you need to redirect the output to the file in some directory where you have permission like above, we are storing it in the home directory ~ or else you will have to use sudo for superuser permission to create new file in /etc/ itself.
Since we need redirection operator to write file in /etc/, we can't simply run
sudo ls -l > etcFiles.txt
because ls will run with superuser permission and redirection will be done with default user permission. So you need to club in both to run in elevated permission.
To achieve that spawn a new shell with elevated permission using sudo sh and pass the command as a string with -c option as shown below
Solution 1
sudo sh -c 'ls -l . > etcFiles.txt'
Solution 2
You can make use of pipe | by piping the output of ls -l to a command called tee which basically reads the standard input and writes it to both the standard output and one or more files.
Since you need to write to a file inside /etc/ directory, you need to run tee with sudo for elevated permission.
ls -l | sudo tee etcFiles.txt
This will also print the output to the console. To avoid output to the console, redirect output to /dev/null (take it as dustbin sink to throw unwanted outputs) and your final command becomes
ls -l | sudo tee etcFiles.txt > /dev/null

Execute script relative to another user's home directory

I'm a beginner in Linux scripting. Somehow I can't get the right search string to find the answer.
I want to run a script relative to a specific user's directory like:
~user/rel/path/to/script.sh
but I don't know what "~user" will translate to. It may even contain spaces. Should I quote it? And if so, how? I always get the file or folder does not exist error when I try to use quotes.
Edit
This is not a duplicate I think.
My concern was that running the following with quotes:
"~user/rel/path/to/script.sh"
gives me "file or folder not found" error. But I don't know, what ~user will translate to. (The script will be called on many different computers. The username is given but the home directory may be changed freely by the owner of each computer.) So I was afraid (as a Linux scripting BEGINNER!!!) to run it without quotes like:
~user/rel/path/to/script.sh
The most down-voted answer (Java system properties and environment variables) actually helped me most. I just needed to confirm that it works the same way on Linux. So I installed a test VM in VirtualBox and tried:
cd /
sudo mkdir -p "test home dir/myuser"
sudo adduser myuser
sudo chown myuser:myuser "test home dir/myuser"
sudo usermod -d "/test home dir/myuser" myuser
su myuser
cd ~
echo '#!/bin/bash -x
echo "here!"
' > test.sh
chmod +x test.sh
exit
cd /
~myuser/test.sh
And it worked!
On Mac OS you don't need to quote. I'm not sure about Linux. However, if
ls ~user
would result in /dir with space/user/ then
sh ~user/rel/path/to/script.sh
would be
sh /dir\ with\ space/user/rel/path/to/script.sh
and this executes if you have set the execution flag on script.sh accordingly.

zsh compinit: insecure directories. Compaudit shows /tmp directory

I'm running zsh on a Raspberry Pi 2 (Raspbian Jessie). zsh compinit is complaining about the /tmp directory being insecure. So, I checked the permissions on the directory:
$ compaudit
There are insecure directories:
/tmp
$ ls -ld /tmp
drwxrwxrwt 13 root root 16384 Apr 10 11:17 /tmp
Apparently anyone can do anything in the /tmp directory. Which makes sense, given it's purpose. So I tried the suggestions on this stackoverflow question. I also tried similar suggestions on other sites. Specifiacally, it suggests turning off group write permissions on that directory. Because of how the permissions looked according to ls -ld, I had to turn off the 'all' write permissions as well. So:
$ sudo su
% chmod g-w /tmp
% chmod a-w /tmp
% exit
$ compaudit
# nothing shows up, zsh is happy
This shut zsh up. However, other programs started to break. For example, gnome-terminal would crash whenever I typed the letter 'l'. Because of this, I had to turn the write permissions back on, and just run compinit -u in my .zshrc.
What I want to know: is there any better way to fix this? I'm not sure that it's a great idea to let compinit use an insecure directory. My dotfiles repo is hosted here, and the file where I now run compinit -u is here.
First, the original permissions on /tmp were correct. Make sure you've restored them correctly: ls -ld /tmp must start with drwxrwxrwt. You can use sudo chmod 1777 /tmp to set the correct permissions. /tmp is supposed to be writable by everyone, and any other permissions is highly likely to break stuff.
compaudit complains about directories in fpath, so one of the directories in your fpath is of the form /tmp/… (not necessarily /tmp itself). Check how fpath is being set. Normally the directories in fpath should be only subdirectories of the zsh installation directory, and places in your home directory. A subdirectory of /tmp wouldn't get in there without something unusual on your part.
If you can't find out where the stray directory is added to fpath, run zsh -x 2>zsh-x.log, and look for fpath in the trace file zsh-x.log.
It can be safe to use a directory under /tmp, but only if you created it securely. The permissions on /tmp allow anybody to create files, but users can only remove or rename their own files (that's what the t at the end of the permissions means). So if a directory is created safely (e.g. with mktemp -d), it's safe to use it in fpath. compaudit isn't sophisticated enough to recognize this case, and in any case it wouldn't have enough information since whether the directory is safe depends on how it was created.

Owner of incrond file products?

Please [1] consider this command: sudo incrontab ~/incron-config where ~/incron-config contains:
/home/zetah/doc IN_CREATE,IN_MOVED_TO /home/zetah/scripts/do_something.sh $#/$#
and do_something.sh consists of [2]:
#! /bin/bash
python /home/zetah/scripts/py_something.py "$1"
Python script accesses some online services and produces 3 new files. They are owned by root.
Why is that and how can I change this behavior. I want to be the owner of those product files
Thanks
[1] Posted on Ask Ubuntu previous - thought to try my chances here, will interlink in any result
[2] Seems lame to wrap Python script in Bash script, but I couldn't do it otherwise
created files are owned by root probably because you run incrontab as root and then python inherit from it through bash
You can run incrontab from your own user, simply add your username in /etc/incron.allow (to allow you to use incron) and then recreate the incron table with your account with "incrontab -e" (don't forget to remove the entry from root)
Second option (if you can't modify incron.allow) is to call python with your username.
In your bash script, modify :
python /home/zetah/scripts/py_something.py "$1"
in
su <username> -c"python /home/zetah/scripts/py_something.py '$1'"
Hope it's help
ericc

Linux: 'transferring'/mirroring read-only permissions for symlinks (for webserver)

Please let me explain what I mean by the question:
This is the context: I'm a user on a webserver, where I have phpicalendar installed; then, I choose a directory, say /webroot/mylogin/phpicalendar/mycals to host my .ics calendar text files.
EDIT: Previously, instead of '/webroot', I had used '/root' - but I really didn't mean the Linux '/root' directory - I'm just wanted to use it as a stand in for the real location on the webserver (so it serves just as a common point of reference). Otherwise, what I mean by common point of reference, is simply /webroot = /media/some/path ..
Then, I can enter this directory in the phpicalendar's config.inc.php:
$configs = array(
'calendar_path' => '/webroot/mylogin/phpicalendar/mycals;
...
Then, phpicalendar will run through this directory, grab the .ics files there (say, mycal.ics and mycal2.ics) and render them - so far, so good.
The thing is, I would now like to add a second calendar directory, located at the same webserver, but where I have read-only permissions, say /webroot/protected/cals. I know that I have read permissions, because I can do in the shell, say
$ less /webroot/protected/cals/maincal.ics
and I can read the contents fine.. So now:
If I enter /webroot/protected/cals as a 'calendar_path', phpicalendar can read and render the files there (say, 'maincal.ics', 'maincal2.ics') without a problem
However, phpicalendar can have only one 'calendar_path', so I can either use the protected calendars, or my customized calendars - but not both
So, I thought, I could symlink the protected calendars in my customized directory - and get the best of both worlds :)
So, here is a shell snippet of what I would do
$ cd /webroot/mylogin/phpicalendar/mycals
$ ls -la
drwxrwxrwx 2 myself myself 4096 2011-03-03 12:50 .
-rw-r--r-- 1 myself myself 1234 2011-01-20 07:32 mycal.ics
-rw-r--r-- 1 myself myself 1234 2011-01-20 07:32 mycal2.ics
...
$ ln /webroot/protected/cals/maincal.ics . # try a hard link first
ln: creating hard link `./maincal.ics' => `/webroot/protected/cals/maincal.ics': Invalid cross-device link'
$ ln -s /webroot/protected/cals/maincal.ics . # symlink - works
$ ln -s ../../../protected/cals/maincal.ics relmaincal.ics # symlink via relative
$ ln -s mycal.ics testcal.ics # try a symlink to a local file
$ ls -la # check contents of dir now
drwxrwxrwx 2 myself myself 4096 .
-rw-r--r-- 1 myself myself 1234 mycal.ics
-rw-r--r-- 1 myself myself 1234 mycal2.ics
lrwxrwxrwx 1 myself myself 21 testcal.ics -> mycal.ics
lrwxrwxrwx 1 myself myself 56 maincal.ics -> /webroot/protected/cals/maincal.ics
lrwxrwxrwx 1 myself myself 66 relmaincal.ics -> ../../../protected/cals/maincal.ics
Ok, so here's what happens:
less maincal.ics works on shell
less relmaincal.ics fails with 'relmaincal.ics: No such file or directory' (even if shell autocompletion for the relative path did work during the execution of the symlink command!)
When you open phpicalendar now, it will render mycal.ics, mycal2.ics and testcal.ics (and they will work)
however, maincal.ics and relmaincal.ics will not be parsed or displayed
Now - this could be that PHP cannot resolve symlinks; however I speculate that the situation is this:
When I do less maincal.ics - it is myself who is user, who has read permission for /webroot/protected/cals
phpicalendar (so Apache webserver user) can otherwise also access /webroot/protected/cals as read-only, when given 'hardcoded' path
phpicalendar is also capable of reading local symlinks fine
Thus, I suspect, that the problem is: when trying to read the symlinks to protected cals, the user that is visible to the shell during that operation is Apache web user, which then doesn't get permissions to access a symlink to the protected/cals location!
The thing now is - I can easily copy the .ics files locally; however they are being changed by someone else, which is why I'd have preferred a symlink.
And my question is: can I do some sort of trickery, so that when phpicalendar/Apache tries to access a symlink to protected/cals, it 'thinks' that it is a local file - and otherwise, the contents of the protected/cals file are being 'piped' back to phpicalendar/Apache?? I guess I'm thinking something in terms of:
$ mkfifo mypipe
$ ln -s mypipe testpipe.ics
$ cat ./testpipe.ics # in one terminal
$ cat /webroot/protected/cals/maincal.ics > mypipe # in other terminal
... which would otherwise (I think) handle the permissions problem - except that, I don't want to cat manually; that would be something that would have to be done in the background, each time an application requests to read testpipe.ics:)
Well, thanks in advance for any comments on this - looking forward to hearing some,
Cheers!
Umm, I really doubt that the account the web server runs under can read anything under /root. That directory is usually mode 0700, user root, group root, or something very similar to that - meaning no non-root access is allowed. If you're running the web server as root, file read permissions are the least of your problems...
Your best bet then would be to place the read-only calendar files somewhere publicly available, and symlink to that location from wherever under /root you want to be able to access them.
Start by checking whether the Apache user can view your calendars:
you#host $ sudo -i -u <apache-user> -s /bin/bash
apache#host $ less /root/protected/cals/maincal.ics

Resources