How Do I Create A User & Set Password Without User Interaction? - linux

I have been recently working on a project named: arch loop, which is an automated installer for Arch Linux. I have seen a few installers and scripts to make Arch installation easier, but I am someone who installs Arch Linux, more than three times a day, so following the Arch-way takes a long time and constantly requires user interaction.
The Problem:
The password is, the information about non-root user is to be created is taken before itself, and when the appropriate time comes, we will be using the following command:
arch-chroot /mnt useradd -m -g users -G wheel -s /usr/bin/bash archuser
arch-chroot /mnt bash -c "echo -e 'password\npassword\n' | passwd
arch-chroot /mnt bash -c "echo -e 'rootpassword\nrootpassword\n' | passwd root
to send the password to passwd binary in the chroot system. But I don't know why it does not work. When the password is being verified by the sudo command after the installation is finished. The password seems to be perfectly working. But when tried to log in with the non-root user from tty, the password seems to be incorrect.
Things I Have Already Tried:
Manually encrypting the provided password with the below code and passing it to the useradd binary with -p option:
perl -e 'print crypt("password", "\$6\$SALTsalt\$") . "\n"'"
Please guide me on how to set a user's provided password at a later time, without requiring any user interaction.
Thank You :)

There exists the chpasswd command. It is just there only to make passwd available in batch scripts. Just do:
echo "root:rootpassword" | arch-chroot /mnt chpasswd
or maybe better, without the need for mount -o bind the sys proc and dev directories:
echo "root:rootpassword" | chpasswd -R /mnt
#subjective: Sorry for the opinion, the project looks ok, however much more work is to be done. I guess the aim is to bring Archlinux closer to "normal" users. However, I don't like the choose of python for the project. Going with plain POSIX sh would make this available for all. I don't like hardcoded partitions, mlocate (do you really use mlocate?), multiple arch-chroot calls where you could just do a single big script, not handling os.system error codes (!), multiple pacman calls without even -Sy (!) (pacman can fail if upstream updates the repos), and few more things I don't like. Except for that, nice python abstraction and cool aim. I remember the old archlinux installation scripts few (or more) years ago, they were nice, however I think used commands themselves anyway. Good luck.

The way as below works for Ubuntu, I think it should work for Arch too.
First, you should have had a machine, which has installed the Arch. Then you add the user that you need with the two commands: useradd and passwd. After that, you could cat /etc/shadow | grep [username] to get the information of the password of the user added by you, it should be a string, let's say it is XXX.
Now, on your target system, after arch-chroot /mnt useradd -m -g users -G wheel -s /usr/bin/bash archuser, you add the string coming from cat /etc/shadow | grep [username] into the /etc/shadow of the target system. The command should be like arch-chroot /mnt sed -i "XXX" /etc/shadow.
One more thing, you must make sure that the version of the Arch which you get the information of the password and the version of the target system are the same.

Related

The difference between "sudo sh -c" and "su -c"

I want to start a program as root when booting, and will add one of the following lines to rc.local:
sudo /path/my_prog
sudo sh -c "/path/my_prog"
su -c "/path/my_prog"
What is the difference between this three lines, and which is the correct one?
You don't need any of them; rc.local runs with root privileges. The correct answer is to simply run your command.
/path/my_prog
su makes sense if you are root and want to switch to a different account.
sudo makes sense if you are running on an unprivileged account, and have been granted the rights to switch to another account (often, but not always, root), usually with the requirement to be able to interactively supply your password (though this can be turned off if you really have to; obviously, you need to understand what you are doing before you mess with security-related stuff).
sh -c "command" is just an inefficient way to run command. Running a shell makes sense when you actually require shell features such as wildcard expansion, redirection, etc, or shell builtins like cd.
Ideally, you might want to make sure that my_prog runs on a dedicated unprivileged system account; then, the syntax would be
su otheraccount -c /path/my_prog
where obviously you need to create otheraccount and make sure it has the privileges that are required for performing this particular task.
su optionally lets you add a lone dash before the account name to have it run a login session; but for a service account, this probably does not make sense.
sudo /path/my_prog will execute /path/my_prog with sudo privileges.
sudo sh -c "/path/my_prog" will execute /path/my_prog (specified by the flag -c) with sh using sudo privileges.
su -c "/path/my_prog" will execute /path/my_prog (specified by the flag -c) with your current shell using sudo privileges.
The correct one to use depends on your use case, so actually it's up to you. IMHO, sudo foo and su -c foo are basically the same.

shell script to shutdown/restart Linux system

Is there any suitable shell script for shutting down or restarting a Linux machine? I have tried a shell script for shutdown, but when I enter sudo shutdown it will ask for the password. How we can enter the password using the script?
Another, in my opinion cleaner approach:
Create a new file in /etc/sudoers.d/ with content:
%users ALL=NOPASSWD: /sbin/shutdown
%users ALL=NOPASSWD: /sbin/reboot
This causes sudo to not ask for the password, if any user of group "users" tries to execute a shutdown or reboot. Of course you can also specify another group, maybe a newly created group for finer control of reboot permissions.
More information about the other possible settings for sudo can be found in the Manpage.
Yes, use the -S switch which reads the password from STDIN:
$echo <password> | sudo -S <command>
So to shut down the machine, your command would be like this (just replace <password> with your password):
$echo <password> | sudo -S poweroff
Exposing your password is generally bad idea search for something that can protect / hide it. In the past I've used Jenkins plugins to do this while executing the scripts regularly.
if you really want to achieve it, you should write a script containing the shutdown command; make root be its owner, then set the SUID bit with the chmod command and give to it executable permission for everybody. When executed, the owner of the script would become root and no password should be asked.

Why this linux command can affect the environment variables?

When I changed my current user to admin using
sudo su admin
I found that the environment variable changed too. What I intend to do is to change my user to admin with the env not changed.
Then I found a command as follows:
sudo bash -c "su - admin"
This command does indeed what I want, but I googled about bash -c, with no clue to why this command can do that for me. Could anyone give me a clear explanation? Thanks a lot.
first you should read the sudo manpage and set theses options in the /etc/sudoers file or you can do it interactively (see second below).
default sudoers file may not preserve the existing $USER environment unless you set the config options to do so. You'll want to read up on env_reset because depending on your OS distribution the sudo config will be different in most cases.
I dont mean to be terse but I am on a mobile device..
I do not recommend using sudo su .. for anything. whomever is sharing sudo su with the public is a newb, and you can accomplish the same cleaner with just sudo.
with your example whats happining is you are starting a subshell owned by the original user ("not admin") . you are starting the subshell with -c "string" sudo has the equivelant of the shell's -c using -s which either reads the shell from the arg passed to -s or the shell defined in the passwd file.
second you should use:
$ sudo -u admin -E -s
much cleaner right ? :)
-u sets the user, obviously
-s we just explained
-E preserves the orig user env
see for yourself just
$ echo $HOME # should show the original users /home/orig_user
$ env
your original env is preserved with none of that sudo su ugliness.
if you were interested in simulating a users login without preserving the env..
$ sudo -u user -i
or for root:
Might require -E depending on distro sudoers file
$ sudo -s
or
$ sudo -i
-i simulates the login and uses the users env.
hopefully this helps and someone will kindly format it to be more readable since im on my mobile.
bash with -c argument defines below.
-c string
If the -c option is present, then commands are read from string. If there are arguments after the string, they are assigned to the positional parameters, starting with $0.
Thanks & Regards,
Alok

How to pipe a variable as password in a bash script when requiring root access [duplicate]

I'm writing a UNIX shell function that is going to execute a command that will prompt the user for a password. I want to hard-code the password into the script and provide it to the command. I've tried piping the password into the command like this:
function() {
echo "password" | command
}
This may not work for some commands as the command may flush the input buffer before prompting for the password.
I've also tried redirecting standard input to a file containing the password like this, but that doesn't work either:
function() {
echo "password" > pass.tmp
command < pass.tmp
rm pass.tmp
}
I know that some commands allow for the password to be provided as an argument, but I'd rather go through standard input.
I'm looking for a quick and dirty way of piping a password into a command in bash.
How to use autoexpect to pipe a password into a command:
These steps are illustrated with an Ubuntu 12.10 desktop. The exact commands for your distribution may be slightly different.
This is dangerous because you risk exposing whatever password you use to anyone who can read the autoexpect script file.
DO NOT expose your root password or power user passwords by piping them through expect like this. Root kits WILL find this in an instant and your box is owned.
EXPECT spawns a process, reads text that comes in then sends text predefined in the script file.
Make sure you have expect and autoexpect installed:
sudo apt-get install expect
sudo apt-get install expect-dev
Read up on it:
man expect
man autoexpect
Go to your home directory:
cd /home/el
User el cannot chown a file to root and must enter a password:
touch testfile.txt
sudo chown root:root testfile.txt
[enter password to authorize the changing of the owner]
This is the password entry we want to automate. Restart the terminal to ensure that sudo asks us for the password again. Go to /home/el again and do this:
touch myfile.txt
autoexpect -f my_test_expect.exp sudo chown root:root myfile.txt
[enter password which authorizes the chown to root]
autoexpect done, file is my_test_expect.exp
You have created my_test_expect.exp file. Your super secret password is stored plaintext in this file. This should make you VERY uncomfortable. Mitigate some discomfort by restricting permissions and ownership as much as possible:
sudo chown el my_test_expect.exp //make el the owner.
sudo chmod 700 my_test_expect.exp //make file only readable by el.
You see these sorts of commands at the bottom of my_test_expect.exp:
set timeout -1
spawn sudo chown root:root myfile.txt
match_max 100000
expect -exact "\[sudo\] password for el: "
send -- "YourPasswordStoredInPlaintext\r"
expect eof
You will need to verify that the above expect commands are appropriate. If the autoexpect script is being overly sensitive or not sensitive enough then it will hang. In this case it's acceptable because the expect is waiting for text that will always arrive.
Run the expect script as user el:
expect my_test_expect.exp
spawn sudo chown root:root myfile.txt
[sudo] password for el:
The password contained in my_test_expect.exp was piped into a chown to root by user el. To see if the password was accepted, look at myfile.txt:
ls -l
-rw-r--r-- 1 root root 0 Dec 2 14:48 myfile.txt
It worked because it is root, and el never entered a password. If you expose your root, sudo, or power user password with this script, then acquiring root on your box will be easy. Such is the penalty for a security system that lets everybody in no questions asked.
Take a look at autoexpect (decent tutorial HERE). It's about as quick-and-dirty as you can get without resorting to trickery.
You can use the -S flag to read from std input. Find below an example:
function shutd()
{
echo "mySuperSecurePassword" | sudo -S shutdown -h now
}
Secure commands will not allow this, and rightly so, I'm afraid - it's a security hole you could drive a truck through.
If your command does not allow it using input redirection, or a command-line parameter, or a configuration file, then you're going to have to resort to serious trickery.
Some applications will actually open up /dev/tty to ensure you will have a hard time defeating security. You can get around them by temporarily taking over /dev/tty (creating your own as a pipe, for example) but this requires serious privileges and even it can be defeated.
with read
Here's an example that uses read to get the password and store it in the variable pass. Then, 7z uses the password to create an encrypted archive:
read -s -p "Enter password: " pass && 7z a archive.zip a_file -p"$pass"; unset pass
But be aware that the password can easily be sniffed.
Programs that prompt for passwords usually set the tty into "raw" mode, and read input directly from the tty. If you spawn the subprocess in a pty you can make that work. That is what Expect does...
Simply use :
echo "password" | sudo -S mount -t vfat /dev/sda1 /media/usb/;
if [ $? -eq 0 ]; then
echo -e '[ ok ] Usb key mounted'
else
echo -e '[warn] The USB key is not mounted'
fi
This code is working for me, and its in /etc/init.d/myscriptbash.sh
That's a really insecure idea, but:
Using the passwd command from within a shell script

sudoers NOPASSWD ineffective in desktop launcher script

I have a launcher script in Linux Mint 13 so that I can click an icon on the desktop to mount my NAS. In order to use /bin/mount without a password I must add this line to sudoers:
<username> ALL = NOPASSWD: /bin/mount
The script to mount the NAS is very simple:
#!/bin/bash
if [ 0 = `sudo mount |grep -c nasbox` ]
then
sudo mount -a
fi
If I use a terminal my script works without the need to enter a password but when it is run from a launcher (using "Application in Terminal") it asks for the password. If I give the password it accepts it and runs - so it must know which user is running it and allow the user to use sudo, so it does honour part of sudoers, but it doesn't honour the NOPASSWD keyword for /bin/mount. How do I get the NOPASSWD to work here?
Delete /var/run/sudo, /var/lib/sudo, and /var/db/sudo to flush out anything that sudo may have cached. Then make sure that your system's time and date are set correctly. As a (paranoid) security measure, sudo may prompt for the password if it determines that the system clock is unreliable.
This actually happened to me once on a system without a persistent RTC clock. I think I solved it by removing those directories and setting the system clock to a future value at startup. The sudo utility may have changed by now, so I'm not sure if this still applies, but give it a try!

Resources