EUID is not the same as UID. At what context are these both are used in the script?
I tried to get the values by echo "UID is $UID and EUID is $EUID", but only space came as output. My machine runs Ubuntu 12.04 LTS. Seen at some sites that this is usually used to check whether it is root user and all but not able to get proper difference.
They're different when a program is running set-uid. Effective UID is the user you changed to, UID is the original user.
UID is the ID of the user that executed the program.
EUID (Effective UID) is the user ID the process is executing. Usually both are equal, unless using a program with SetUID to for example increase your privileges. A common case where UID and EUID are different would be executing sudo.
EUID and UID variables only work on bash, not in dash (in Debian based distros as Ubuntu sh is usually a symlink to dash).
If you are running the script interactively you might not have bash configured as your default shell, run bash before trying.
If you are running it from console:
bash script.sh
If you are running it using its path (for example ./script.sh) ensure the first line of the script is:
#!/bin/bash
And not:
#!/bin/sh
For a more generic way to do it -that works on any shell- check: https://askubuntu.com/questions/15853/how-can-a-script-check-if-its-being-run-as-root
In that post the command id is mentioned, where:
id -u # is the EUID
id -u -r # is the UID
Related
if /usr/bin/bash has the suid bit set
why does my euid change to root only when I use the -p option like so /usr/bin/bash -p
what does this -p option stand for?
and when you spawn a bash shell from a suid binary why euid is set to root and why not uid?
From the documentation:
-p
Turn on privileged mode. In this mode, the $BASH_ENV and $ENV files are not processed, shell functions are not inherited from the environment, and the SHELLOPTS, BASHOPTS, CDPATH and GLOBIGNORE variables, if they appear in the environment, are ignored. If the shell is started with the effective user (group) id not equal to the real user (group) id, and the -p option is not supplied, these actions are taken and the effective user id is set to the real user id. If the -p option is supplied at startup, the effective user id is not reset. Turning this option off causes the effective user and group ids to be set to the real user and group ids.
This is done because setuid shell scripts have been a common source of security bugs. So the programmer is required to use the -p option to indicate that they really need the privilege escalation, e.g. by using
#!/usr/bin/bash -p
Without this, setting the suid bit on /usr/bin/bash itself would be an enormous security hole, since most scripts don't take the necessary precautions needed when running with elevated permissions.
I have to execute a process on a cluster of machines. Size of cluster is of order 100. So I cannot execute processes manually, I have to execute them by script(which uses ssh, currently I am using python-paramiko for this). Number of tcp sockets these processes open is more than 1024(default limit of linux.) So I need to change that using {ulimit -n 10000}. This makes the changes for that shell session only. And this command works only with root user. So my script is not able to do that.
I tried to execute this command
sudo su && ulimit -n 10000 && <commandToExecuteMyProcess>
But this didn't work. The commands after "sudo su" didn't execute at all. They execute only when I logout of the su session.
This article shows way to make the changes permanently. But when I open limits.conf, I didn't find anything there. It only has some commented notes.
Please suggest me some way to increase the limit permanently or change it by script for each session.
That's not how it works: sudo su just opens a new shell so you can introduce commands as root, and after you exit that shell it executes the rest of the line as normal user.
Second: your this is a special case because ulimit is not actually a program, but a bash shell built-in command, so it must be used within bash, that is why something like sudo ulimit -n 10000 won't work: sudo can't find that program because it doesn't exist.
So, the only alternative is a bit ugly but works:
sudo bash -c 'ulimit -n 10000 && <command>'
Everything inside '...' will execute in a bash session of the root user.
Note that you can replace && with ; in this case: that's because it is being executed as root and ulimit -n 10000 will always complete successfully.
I have an Ubuntu machine with a native Hadoop client installed on it, meaning i can run for example:hadoop fs -ls as long as I'm on a certain user, let's say userA.Now i have a scala application running on this machine under root (cannot change this) and i need to be able to switch to userA and then run hadoop fs -lsI'm working with scala.process in order to run my commands but I'm unable to run them in way they'll be connected to each other, so if run:Process(Seq("bash","-c","su userA && hadoop fs -ls")).! i will get an error since the 2nd command is actually executed on root, i know this because when i do: Process(Seq("bash","-c","su userA && whoami")).! I get root and not userAAny idea how to tie them together (exmple in linux command will suffice, i'll be able to replicate it in scala.process i believe)
Your question has nothing to do with Scala, Ubuntu or Hadoop per se. It is all about shell scripting and understanding the way shell works.
First of all, you don't need to invoke bash, in your case it is just another (unnecessary) layer of indirection. Removing bash with leave you with this:
Process("su userA && hadoop fs -ls").!
... which will fail. Why? Because this code is equivalent to this:
Process(Seq("su", "userA", "&&", "hadoop", "fs", "-ls")).!
As you can see all the pieces of your command including && are passed to su as command line arguments. Naturally su doesn't know what to do with it and thus would fail.
Now let's forget about Scala code for a while and drop to bash shell and try the command there. Let's use whoami to test whether the user has changed to userA:
su userA && whoami
The fist thing that you would notice is that su when invoked this way provides interactive shell prompt (asking for password first, unless you run it from root). This is probably not what you want when running su from a program. Moreover, after you log out of that shell you will see that the user was not changed to userA.
Here's why. The notion of effective user is tied to a process. Each process has exactly one effective user at a given point of time. The initial effective user of a process is inherited from the spawning process.
So here's what's happening when you run su userA && whoami from the bash prompt:
bash spawns su as a child process, su inherits the effective user from its parent:
bash (root)
+- su (root)
su changes its effective user via setuid:
bash (root)
+- su (userA)
by default su spawns the default shell of a specified user as given in /etc/passwd as a child process (e.g. sh); sh inherits the effective user from its parent:
bash (root)
+- su (userA)
+- sh (userA)
Now let's get to the the && part. It turns out to be part of the shell syntax. command1 && command2 asks shell to run command1 first and then only after command1 exists without any errors (i.e. its exit code is zero) run command2. It is crucial to understand two things:
command2 is run only after command1 has finished successfully;
both command1 and command2 are spawned by the same shell process, and thus they both inherit its effective user.
So here's what we would get for su userA && whoami invocation:
bash (root)
+- su (userA, already exited by the time whoami started)
| +- sh (userA, already exited by the time whoami started)
+- whoami (root)
So no matter what user would you change to via su process whoami wouldn't be affected.
In order to fix the issue you should make whoami to be spawned by su so that it could inherit the changed user.
To make this happen invoke su like this:
su -c whoami
This would yield the following process tree:
bash (root)
+- su (userA)
+- whoami (userA)
Now let's get back to Scala. Unfortunately if you run the command above from Scala you would get su: must be run from a terminal. To be honest I don't know how to cope with this problem properly, so I would suggest to switch to sudo instead.
So the final solution would be:
Process(Seq("sudo", "-u", "userA", "hadoop fs -ls")).!
What is a cross-platform way of getting the username of the current user in R? I am currently using
system('whoami', intern=TRUE)
However this assumes that the user has shell access, and that the whoami program is available. Is there a more native to get this information in R?
I would do this :
Sys.getenv("USERNAME") ## works under windows
or better more robust:
Sys.info()[["user"]]
But under unix-like system the result is sometimes different of system('whoami', intern=TRUE) :
whoami outputs the username that the user is working under, whereas
$USER outputs the username that was used to login.
For example, if the user logged in as John and su into root, whoami displays root and echo
$USER displays John. This is because the su command does not invoke a
login shell by default.
I have the following "root-file" with the following contents:
$ cat root-file
#!/bin/bash
echo $EUID
id
Following are the permissions for this file:
$ ls -l root-file
-rwsr-sr-x 1 root root 15 Nov 18 02:20 root-file
Since the set-user-id bit is set for this file, I would expect that on executing this
file, the effective uid would be displayed as 0 even when a non-root user executes it (since set-user-id bit causes the process to be executed with the effective user-id of the owner of the file, which in this case is root). However, instead I get the following output on executing "root-file" from a non-root shell.
$ ./root-file
1000
uid=1000(chanakya) gid=1000(chanakya) groups=1000(chanakya),4(adm),20(dialout),24(cdrom),46(plugdev),105(lpadmin),119(admin),122(sambashare)
This file/or script is not being executed with effective user-id 0. Why is that so?
you cannot use setuid on shell scripts...
if you absolutely need to use setuid checkout http://isptools.sourceforge.net/suid-wrap.html
Normally something like this could also be established using some custom sudo configuration...