Piping password to smbpasswd - automation

How can I pipe the new password to smbpasswd so I can automate my installation process.

Thanks to Mark I found the answer:
(echo newpassword; echo confirmNewPassword) | smbpasswd -s
BTW: (echo oldpasswd; echo newpasswd) | smbpasswd -s does not work.

I use the following in one of my scripts:
echo -ne "$PASS\n$PASS\n" | smbpasswd -a -s $LOGIN
With echo:
-e : escape sequences, like \n
-n : don't add implicit newline at end
With smbpasswd:
-a : add new user
-s : silent

Try something like this:
(echo oldpasswd; echo newpasswd) | smbpasswd -s

Use this
echo 'somepassword' | tee - | smbpasswd -s

I had to create a new Samba user in a Puppet 5.x Exec resource and for various reasons none of the above worked. Fortunately this rather silly-looking command worked:
yes vagrant|head -n 2|smbpasswd -a -s vagrant
Password here is of course "vagrant".

This unfortunately is not desirable for two reasons:
1) if the user uses a combination of '\n' in the password there will be a mismatch in the input
2) if there are unix users on the system, then a user using the utility ps may see the password
A better way would be to put the names in a file and read from the file and use python pexpect to read them, not like below, but the simple script is enough to see how to use pexpect
#!/usr/bin/python
#converted from: http://pexpect.sourceforge.net/pexpect.html
#child = pexpect.spawn('scp foo myname#host.example.com:.')
#child.expect ('Password:')
#child.sendline (mypassword)
import pexpect
import sys
user=sys.argv[1]
passwd=sys.argv[2]
child = pexpect.spawn('/usr/bin/smbpasswd -a '+str(user))
child.expect('New SMB password:')
child.sendline (passwd)
child.expect ('Retype new SMB password:')
child.sendline (passwd)
then try: ./smbpasswd.py userName1 'f##(&*(_\n895'

using either pipelines or redirection.

Related

Piping the output of ssh sudo

I sometimes have a need to run commands as root on a remote server, and parse the output of the command on my local server. The remote server does not allow root login by ssh, but has sudo configured in a way that requires a password. A simplified example of what I need to do is
ssh remote sudo echo bar | tr bar foo
(Obviously in this simplified example, there's no good reason to need to run echo on a different machine to tr: this is just a toy example to explain what I'm trying to do.)
If I run the command above, I get an error that sudo has no way to prompt for a password:
richard#local:~$ ssh remote sudo echo bar | tr bar foo
sudo: no tty present and no askpass program specified
One way I can try to fix this is by adding the -t option to ssh. If I do that, sudo does wait for and accept a password, but the output of ssh's pseudo-terminal goes to stdout, meaning the sudo prompt message is piped to tr and not displayed to the user. If the user doesn't know sudo is waiting for a password, they will think the script has hung, and passing the prompt message to the pipe probably breaks further processing:
richard#local:~$ ssh -t remote sudo echo bar | tr bar foo
[sudo] posswood foo oichood:
foo
(This admittedly silly example shows the prompt has been processed by the tr command the output is piped to.)
The other way I can see to try to fix this is by adding the -S option to sudo. If I do that, sudo prompts on stderr for the password, so the prompt is not passed down the pipeline. That's good, but sudo also accepts the password on standard input meaning it's echoed to the terminal where anyone looking over the user's shoulder can read it:
richard#local:~$ ssh remote sudo -S echo bar | tr bar foo
[sudo] password for richard: p8ssw0rd
foo
I've found inelegant ways of working around the problems with these two options, but my workarounds hit a problem if the user gets their password wrong the first time. That in itself is a problem. Examples of this are:
richard#local:~$ echo "[sudo] password for $USER:"; \
ssh -t remote sudo echo bar | tail +2 | tr bar foo
richard#local:~$ (read -s password; echo $password; echo >&2) \
| ssh remote sudo -S echo bar | tr bar foo
I'm sure there must be a good solution to this, as it doesn't seem an uncommon thing to want to do. Any ideas?
The best solution I've come up with is to use sudo -S and disable local echo so the password isn't shown as you type it:
$ { stty -echo; ssh remote sudo -S echo hello; stty echo; echo 1>&2; }
[sudo] password for user:
hello
This leaves sudo in charge of the password prompting, so it works properly if the user types the password wrong.
I don't think any solution using ssh -t can ever work properly, since it combines stderr and stdout.

sudo useradd wont make home directory

I have an automatic script which works, only it just never makes a home directory. The data is extracted from a database.
Heres the script:
$SQL -s -e "SELECT uid, password FROM registrations WHERE processed = 0" \
| while read A B; do
sudo useradd $A -p $B -m /home/
as you can see the -m is there, but it seems to ignore it and never make a home directory and I have no idea why. I must be missing something but i've no idea what
If you run man useradd you'll see that the -m does not expect a parameter.
Running it this way should do the trick (or at least it just did on my Debian Squeeze):
useradd $A -p $B -m
In the man pages you'll also find other useful options such as: -d or -b

set environment variable SSH_ASKPASS or askpass in sudoers, resp

I'm trying to login to a ssh server and to execute something like:
ssh user#domain.com 'sudo echo "foobar"'
Unfortunately I'm getting an error:
sudo: no tty present and no askpass program specified
Google told me to either set the environment variable SSH_ASKPASS or to set askpass in the sudoers file. My remote machine is running on Debian 6 and I've installed the packages ssh-askpass and ssh-askpass-gnome and my sudoers file looks like this:
Defaults env_reset
Defaults askpass=/usr/bin/ssh-askpass
# User privilege specification
root ALL=(ALL) ALL
user ALL=(ALL) ALL
Can someone tell what I'm doing wrong and how to do it better.
There are two ways to get rid of this error message. The easy way is to provide a pseudo terminal for the remote sudo process. You can do this with the option -t:
ssh -t user#domain.com 'sudo echo "foobar"'
Rather than allocating a TTY, or setting a password that can be seen in the command line, do something like this.
Create a shell file that echo's out your password like:
#!/bin/bash
echo "mypassword"
then copy that to the node you want using scp like this:
scp SudoPass.sh somesystem:~/bin
Then when you ssh do the following:
ssh somesystem "export SUDO_ASKPASS=~/bin/SudoPass.sh;sudo -A command -parameter"
Another way is to run sudo -S in order to "Write the prompt to the standard error and read the password from the standard input instead of using the terminal device" (according to man) together with cat:
cat | ssh user#domain.com 'sudo -S echo "foobar"'
Just input the password when being prompted to.
One advantage is that you can redirect the output of the remote command to a file without "[sudo] password for …" in it:
cat | ssh user#domain.com 'sudo -S tar c --one-file-system /' > backup.tar
Defaults askpass=/usr/bin/ssh-askpass
ssh-askpass requires X server, so instead of providing a terminal (via -t, as suggested by nosid), you may forward X connection via -X:
ssh -X user#domain.com 'sudo echo "foobar"'
However, according to current documentation, askpass is set in sudo.conf as Path, not in sudoers.
How about adding this in the sudoers file:
user ALL=(ALL) NOPASSWD: ALL

using different database at redis command prompt

dThe following works as expected. But how do I insert the data into forth database instead of default "0" from command prompt?
# echo -n "testing" | /home/shantanu/redis-2.4.2/src/redis-cli -x set my_pass
OK
# echo -n "testing" | /home/shantanu/redis-2.4.2/src/redis-cli -x select 4; set my_pass
(error) ERR wrong number of arguments for 'select' command
Just use the -n argument to choose DB number. It available since Redis 2.4.2.
echo -n "testing" | redis-cli -n 4 -x set my_pass
or
redis-cli -n 4 set my_pass testing
Launch the CLI by issuing command:
redis-cli
Then use the following command:
select <db number>
For example:
select 4

tput: unknown terminal

I'm on AIX-6.1 and I'm trying to make use of tput inside my $PS1.
I've confirmed I can't even run tput from the commandline. Following is my session:
# tput
unknown terminal "xterm"
# echo $TERM
xterm
# tput -T ansi
unknown terminal "ansi"
In fact, ...
# ls /usr/lib/terminfo/x
x1700 xl83 xterm+pcc3 xterm+pcfkeys xterm-88color xterm-hp xterm-old xterm-vi
x1720 xtalk xterm+pcf0 xterm+pcfn xterm-8bit xterm-ic xterm-r5 xterm-vt220
x1750 xterm xterm+pcf1 xterm-16color xterm-basic xterm-mono xterm-r6 xterm-vt52
x820 xterm+pcc0 xterm+pcf2 xterm-24 xterm-bold xterm-new xterm-rep xterm-xfree86
xdku xterm+pcc1 xterm+pcf3 xterm-256color xterm-boldso xterm-noapp xterm-sco xterm-xmc
xitex xterm+pcc2 xterm+pcfN xterm-65 xterm-color xterm-nrc xterm-sun xterms
# ls /usr/lib/terminfo/x | wc -l
48
# for term in $(ls /usr/lib/terminfo/x) ; do tput -T $term ; done 2>&1 | grep 'unknown terminal' | wc -l
48
# for term in $(ls /usr/lib/terminfo/x) ; do TERM=$term tput ; done 2>&1 | grep 'unknown terminal' | wc -l
48
Any ideas? Thanks in advance.
Is your TERMINFO variable set? Without it, I believe the system won't find your terminfo files. Or perhaps it is set incorrectly?
If you're running sh, ksh, bash or similar, try:
export TERMINFO=/usr/lib/terminfo
If you're not sure what shell you're using (I'm pretty sure you do, but others might read this too), type:
echo $SHELL
If you're using csh, tcsh or similar, then you should instead type:
setenv TERMINFO /usr/lib/terminfo
After that, try running tput again.
I fixed this in Mac OS Catalina with,
export TERMINFO=/usr/share/terminfo