In a bash script executed on boot, how do I get the username of the user just logged-in? - bash

I need to execute a bash script on boot.
To do so I created a file
/etc/init.d/blah
I edited it and added the following lines
#! /bin/sh
# /etc/init.d/blah
touch '/var/lock/blah'
username1=$(id -n -u)
username2=$(whoami)
touch '/var/lock/1'${username1}
touch '/var/lock/2'${username2}
exit 0
The script is execute with root privileges (which is what I need because I have to use mount inside this script) .. but the problem is that I also need to know the username of the user who has just logged-in beacuse my goal is to mount a certain folder to a certain mount-point depending on the username, like
mount -o bind /home/USERNAME/mount-point /media/data/home/USERNAME/to-be-mounted
Going back to the boot script, if I do
sudo update-rc.d blah defaults
and then reboot and log-in with my username (let's say john) both ways to get username in my script produce root in fact I've got 3 files
/var/lock/blah
/var/lock/1root
/var/lock/2root
So, how can I get the username of the user who just logged-in? (john in my example)
EDITED:
I solved in this way:
1. I created a .desktop file for each user I need to perform automount on boot to autostart a script on boot (I'm on LXDE) and put it on /home/{username}/.config/autostart
[Desktop Entry]
Type=Application
Exec=bash "/path/to/mount-bind.sh"
2. I stored in that path a bash script called mount-bind.sh and made it executable:
#!/bin/bash
_username=$1
if [[ -z "${_username}" ]]; then
_username="$(id -u -n)"
fi
mkdir -p "/home/${_username}/mount-folder"
sudo mount -o bind "/media/data/home/${_username}/mount-folder" "/home/${_username}/mount-folder"
exit 0
3. I added the following line to /etc/sudoers
%nopwd ALL=(ALL) NOPASSWD: /bin/mount
4. I created the nopwd group and added to it all the users I need
In his way after login I can mount the path under the user home.
Problem with this method is that I have to create the desktop file for each new user and add him/her to nopwd, but it works.
Any further improvement is welcome! :)

I think you should move from a boot time init script to a script executed at login time under the logged-in user. To allow this, you should look into ways to allow your users to execute the mount command you need. Depending on what you are trying to achieve, one of the following methods may help you:
Assuming you are on Linux or some other UNIX with a similar feature, add the mountpoint to /etc/fstab with the user option, allowing normal users to mount the entry.
Execute mount through sudo with a suitably narrow sudoers configuration as to not allow users to execute any mount commands.
Write a suid-root program in c which executes the required mount commands when called. This however is very tricky to get right without creating gaping security holes.

Login does not happen at boot time. You cannot foretell which user is going to log in when booting.

Try Exporting the logindetails and use it.
export username2=$(whoami)

Related

su to LDAP user in bash script

We have a partial LDAP integration on our RHEL servers. I'm trying to create a setup script to run on new servers. The first thing I need my script to do is log into an LDAP user account so that it's home directory gets created. If I put it in a script like so (and run as root):
#!/bin/bash
su - LDAPaccount
It fails saying the user doesn't exist.
If I just run the su - LDAPacccount command, then it creates the users home directory and switches me to that user. Anyone know why running the su command in a bash script fails and how I can get around this?
For anyone who finds this. My solution was to fully qualify everything:
#!/bin/bash
/bin/su - LDAPaccount -c "/usr/bin/ls"
When I run that, it works fine.

Forcing usermod with running program

I've been looking for a way to force usermod to modify the password/group/... files despite the user being in use.
What I do get now is this:
!! Failed to execute 'usermod --home '...' --password '...' --shell '/bin/false' 'zabbix' 2>&1':
usermod: user zabbix is currently used by process 518
I know that for being secure I need to restart the service. But this is done within a setup script. I am restarting all services at the end.
Is there any way to say --force? (well, except for modifying all necessary files.)
Thanks
If you can get root rights via sudo and are confident enough to change system files using vi then I would change the files manually.
Only a few things need to be changed in
- /etc/passwd
here you could change UID, GID, Homedirectory, Shell ...
- /etc/group
here you might need to change UID/GID as well for the username if there was a change
The File /etc/shadow will be changed automatically when using passwd to set a new password. This you can directly perform if you are root: "passwd username"
You can run usermod in a separate user namespace (with a recent enough linux), but you need to map the root user to root (otherwise you won't have permissions to modify /etc/passwd).
I.e. something like this:
unshare --user --map-root-user usermod ...
Now usermod won't find the processes running with the uid of user you are modifying.
You probably won't be able to modify the root user itself with this.

Allowing users to run script via /etc/sudoers and permissions

I'd like users in staff group who do not have admin/root permissions to run the following script without being prompted for a password. This is in OSX.
Note that /usr/sbin/serveradmin requires root/sudo privileges.
I've tried adding the following to my /etc/sudoers, but it does not work. Script has permissions of 755.
%staff ALL=NOPASSWD: /usr/sbin/serveradmin stop smb,/usr/sbin/serveradmin start smb
%staff ALL=NOPASSWD: /bin/sh /opt/scripts/restart-smb
Here's the shell script:
#!/bin/bash
#
# This script simply restarts SMB (Samba)
#
echo "Stopping SMB..."
/usr/sbin/serveradmin stop smb
echo "Pausing for 30 seconds..."
/bin/sleep 30
echo "Starting SMB..."
/usr/sbin/serveradmin start smb
echo "Script complete!"
Your ideas, suggestions most appreciated!
Dan
WARNING while playing with the /etc/sudoers file managing users privilege and permissions, I CRASHED Ubuntu.
Normal login was not possible anymore. I got a parsing error coming from a simple space missing between # and % character in a line I wrongly commented #%sudo ALL=NOPASSWD: /pathtoscripts/script.sh .
I had to recover it with the install/liveCD mounting again the hardrive filesystem, put back the original file in place and dismount the volume for recording changes.
For the above reason I would NOT RECOMMEND THIS METHOD first because it modifies /etc/sudoers privileges critical file. Choose first alternatives available unless:
you have a good back up of your data outside of your PC
you are not afraid to take the risk to repair/reinstall your system
you know the RIGHT SYNTAX of the /etc/sudoers file, trials and parsing errors could cost you a lot of time and/or efforts/crashes...
Reading the other posts, I managed to get it work on my system, managing permissions through a group:
I created the group mygroup
sudo groupadd mygroup
I added the user myuser which will execute the script
sudo usermod -a -G mygroup myuser
I added at the END of /etc/sudoers the entry, otherwise the privilege are overwritten by the previous lines (be careful with syntax)
%mygroup ALL=NOPASSWD: /mypath/to/myscripts/myscript.sh
The above script myscript.sh must have execute permission
sudo ugo+x /mypath/to/myscripts/myscript.sh
This script will then be able to be launched by the user myuser directly as below wihtout prompting for password anymore
sudo /mypath/to/myscripts/myscript.sh
Alternatively, the script can be launched within another one in a same way
I found another way without creating a group, adding to /etc/sudoers file (at the END of file) the line:
%sudo ALL=NOPASSWD: /mypath/to/myscripts/myscript.sh
In case the script must only be launched by a few existing users myuser1, myuser2, it is always possible to only add to /etc/sudoers (at the END of file) the lines :
myuser1 ALL=(ALL) NOPASSWD: /mypath/to/myscripts/myscript.sh
myuser2 ALL=(ALL) NOPASSWD: /mypath/to/myscripts/myscript.sh
I was able to make this work by adding the following to my /etc/sudoers file:
%staff ALL=/opt/scripts/restart-smb
Then of course making the script executable (I had forgotten that).
Still requires a password (which is okay), but working.

Want execute only shell script

I wrote a shell script to hook into a password protected database. A couple of others want to use the same shell script to share the database access, but I don't want to expose the password that is being used. Is there a way to lock the script so that no one can read it and only execute it? It'd also be ideal for them to enter their sudo password to run the script
Is there a way to lock the script so that no one can read it and only
execute it? It'd also be ideal for them to enter their sudo password
to run the script
Sure. Let's say the script containing the credentials is /usr/local/bin/myscript. Make this file owned by a privileged user. Let's say we have a user named "credentials":
# chown credentials /usr/local/bin/myscript
# chmod 700 /usr/local/bin/myscript
Now only the credentials user can read and execute this script.
Create another script /usr/local/bin/mywrapper that looks like this:
#!/bin/sh
exec sudo -u credentials /usr/local/bin/myscript
And create the appropriate /etc/sudoers entry:
auser ALL=(credentials) /usr/local/bin/myscript
So now, user auser runs "mywrapper". This in turn uses sudo to call the real script, which will prompt auser for their password.
I think this does everything you want. We use a mechanism very much like this at my office to protect credentials (in our case, ssh private keys).
In order to execute a shell script, you have to be able to read it. There are a couple of things you could do:
Who administers this database? Could the users get their own passwords for read only access? That would be ideal because it could limit their access to a small subset of the database.
If they have to have sudo access to run this script, maybe it's possible to remove the password out of the file and into a file that has 600 permissions set. The problem is that this could leak. For example, what if they run the script with set -xv? Then, they could see the password as the script executes.
Can you create a subset of data they might be interested in outside of the database? Then, have your script access that?
Or, you might want to take a look at several read-only modules in Perl. I'm thinking something like Acme::EyeDrops or Acme::Bleach which remove all those unsightly letters and numbers from your Perl script. (And I wonder why Python programmers say Perl is unreadable?)

Writing a bash script that performs operations that require root permissions

I'm trying to write a bash script that sets up my web development environment in ubuntu. As part of the process of setting up the script, it needs to edit files that are owned by root. It also needs to create fields in the public_html directory of the user that runs the script.
Should I therefore require that the script be run as the superuser? If it should, then how do I get it to access the current user's username? I would normally use the $USER variable, but I can't do that if the script is being run as the superuser. If I'm not the superuser, how can I get the script to request super user privileges for certain operations, while not requiring the user to type in a password for every operation that requires super user privileges.
Thanks
You can use the -E flag for sudo to preserve the environment variables, or, you can set up sudoers to preserve the environment on a per-command basis.
You can also set up the sudoers file to not ask for a password on a per-command basis, for example, to allow user xy to use smbmount without asking for a password:
xy ALL=NOPASSWD: /usr/bin/smbmount
In your case, it would be enough to just store the current user in a variable before invoking sudo, and use the already saved username:
CURRENT_USER=$USER
sudo yourscript.sh $CURRENT_USER
Then read the username from $1.
You can also use the SUDO_USER env variable, which is set to the user who is invoking sudo.
Insert a check at the top of the script:
# Make sure only root can run this script
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root" 1>&2
exit 1
fi
In this way when you run it without the root privileges you will be prompted, then you can simply rerun it the right way with:
sudo yourscript.sh
More infos at http://www.cyberciti.biz/tips/shell-root-user-check-script.html
There's a command named sudo for this purpose. It lets you specify that certain users can run certain commands as root (or another user).
If your users have root access anyway, you could just write a script that must be run as root and takes an username as parameter, instead of picking up the username.
Alternatively, one way of picking up the login username in an interactive shell is:
stat -Lc %U /proc/self/fd/0
This retrieves the ovner of the tty associated with stdin.
Just make it a setuid file. Or use sudo which is probably safer, since you can limit who gets to run it.
chmod 4755 script.sh
In Ubuntu, there's the SUDO_USER environment variable.
So, you can just run your script sudo somescript.sh and have it pull the invoking user's username $SUDO_USER.
Not sure on other dists, though.

Resources