line=0
cat userDetails.csv |while IFS="," read -r last first grps
do
line=$((line+1))
if [ $line == 1 ]; then
continue
fi
first=echo "$first"|tr 'A-Z' 'a-z'
last=echo "$last"|tr 'A-Z' 'a-z'
grps=echo "$grps"
for groupName in echo $grps
do
ret=getent group $groupName
if [ -z $ret ]
then
groupadd $groupName
fi
done
passwd=cat /dev/urandom | tr -dc 'a-zA-Z0-9'|head -c10
user1=echo "$last"|tail -c6
user2=echo "$first"|head -c2
grps=echo "$grps"
if [ ! -z $grps]
then
useradd -G $grps $user1$user2 -p $password
else
useradd $user1$user2 -p $password
fi
echo “user id for $first is: $user1$user2, password: $password”
done
This is the code that is reading the CSV file and creating the password, when I run it against the csv File that looks a little like
Smith, John
Doe, Jane
etc.. And the errors coming out are this
./adduser3.sh: line 9: John: command not found
./adduser3.sh: line 10: Smith: command not found
./adduser3.sh: line 11: : command not found
./adduser3.sh: line 14: group: command not found
groupadd: group 'echo' already exists
./adduser3.sh: line 20: /dev/urandom: Permission denied
./adduser3.sh: line 21: Smith: command not found
./adduser3.sh: line 22: John: command not found
./adduser3.sh: line 23: : command not found
useradd: option requires an argument -- 'p'
Usage: useradd [options] LOGIN
useradd -D
useradd -D [options]
Options:
-b, --base-dir BASE_DIR base directory for the home directory of the
new account
-c, --comment COMMENT GECOS field of the new account
-d, --home-dir HOME_DIR home directory of the new account
-D, --defaults print or change default useradd configuration
-e, --expiredate EXPIRE_DATE expiration date of the new account
-f, --inactive INACTIVE password inactivity period of the new account
-g, --gid GROUP name or ID of the primary group of the new
account
-G, --groups GROUPS list of supplementary groups of the new
account
-h, --help display this help message and exit
-k, --skel SKEL_DIR use this alternative skeleton directory
-K, --key KEY=VALUE override /etc/login.defs defaults
-l, --no-log-init do not add the user to the lastlog and
faillog databases
-m, --create-home create the user's home directory
-M, --no-create-home do not create the user's home directory
-N, --no-user-group do not create a group with the same name as
the user
-o, --non-unique allow to create users with duplicate
(non-unique) UID
-p, --password PASSWORD encrypted password of the new account
-r, --system create a system account
-R, --root CHROOT_DIR directory to chroot into
-s, --shell SHELL login shell of the new account
-u, --uid UID user ID of the new account
-U, --user-group create a group with the same name as the user
-Z, --selinux-user SEUSER use a specific SEUSER for the SELinux user mapping
--extrausers Use the extra users database
I cannot figure as to why the dev/urandom permission is messing up with the cat and why it is spitting out the errors it is giving me
The first problem is first=echo "$first" not doing what you think.
To define a variable, you need var=val, with no spaces in val (or you need to quote it). There is also var=val command syntax, where var is defined in a sub-environment created to run command (i.e. temporarily, just for command sake). This is what your command does: first it expands $first to John, then you have the command first=echo John, which defines a variable first with value echo for the duration of the command John. And as the error informs you, there is no command John.
The correct syntax would be first=$(echo $first), which runs the command echo $first and assigns its value to first. Or first="$first", which just assigns the value of first to first. Which makes it very obvious that you are doing something completely unnecessary in the first place.
The rest of the code is peppered with the same kind of error, using echo unnecessarily, wrongly, or both, or failing to quote properly. You should also make sure to indent your code correctly in the future, both for the benefit of the potential answerers, and also for your own sanity when debugging.
Related
I'm new to zenity and would like to create a GUI for creating a new user and password. My code goes like this:
#!/bin/bash
zenity --info --text='Welcome to Account Creation Wizard'
zenity --entry --text='What do you want to set your username as?' > username
zenity --password > test
cat username >> username1
cat username >> username1
cat test >> test1
cat test >> test1
useradd -m < username1
passwd < username1 < test1
rm test test1
rm username username1
exit
But it does not work. In the terminal, I get this:
[root#archevaris Desktop]# ./UserCreator.sh
Usage: useradd [options] LOGIN
useradd -D
useradd -D [options]
Options:
--badnames do not check for bad names
-b, --base-dir BASE_DIR base directory for the home directory of the
new account
--btrfs-subvolume-home use BTRFS subvolume for home directory
-c, --comment COMMENT GECOS field of the new account
-d, --home-dir HOME_DIR home directory of the new account
-D, --defaults print or change default useradd configuration
-e, --expiredate EXPIRE_DATE expiration date of the new account
-f, --inactive INACTIVE password inactivity period of the new account
-g, --gid GROUP name or ID of the primary group of the new
account
-G, --groups GROUPS list of supplementary groups of the new
account
-h, --help display this help message and exit
-k, --skel SKEL_DIR use this alternative skeleton directory
-K, --key KEY=VALUE override /etc/login.defs defaults
-l, --no-log-init do not add the user to the lastlog and
faillog databases
-m, --create-home create the user's home directory
-M, --no-create-home do not create the user's home directory
-N, --no-user-group do not create a group with the same name as
the user
-o, --non-unique allow to create users with duplicate
(non-unique) UID
-p, --password PASSWORD encrypted password of the new account
-r, --system create a system account
-R, --root CHROOT_DIR directory to chroot into
-P, --prefix PREFIX_DIR prefix directory where are located the /etc/* files
-s, --shell SHELL login shell of the new account
-u, --uid UID user ID of the new account
-U, --user-group create a group with the same name as the user
New password: Retype new password: passwd: password updated successfully
[root#archevaris Desktop]#
And what it actually did was change my root password :P (This bash script is kinda dangerous to execute but thankfully I did it in a VM snapshot)
So, how to fix this? What changes should I make in the code?
To get a username and password via zenity, this will work:
export INFO=$(zenity --password --username)
$INFO will be split by a pipe, so if your username is "Fred" and your password is "123abc", $INFO will look like this:
Fred|123abc
From here, just use cut to separate the data:
USERNAME=$(echo $INFO | cut -d"|" -f1)
PASSWORD=$(echo $INFO | cut -d"|" -f2)
I am using Bash on Lubuntu 16.04. LTS, but I'm not sure if this matters much for this question.
I noticed, that when I create a file as standard user, the file has 664 permissions. But when I am root and execute the same command for the same user via the -u argument, it has 644 permissions, so the write permissions for the group are missing.
I suppose this to be a flaw, since the sudo manpages clearly state:
-u user, --user=user
Run the command as a user other than the default target user (usually root). The user may be either a user name or a
numeric user ID (UID) prefixed with the ‘#’ character (e.g. #0 for UID 0). When running commands as a UID, many
shells require that the ‘#’ be escaped with a backslash (‘\’). Some security policies may restrict UIDs to those
listed in the password database. The sudoers policy allows UIDs that are not in the password database as long as the
targetpw option is not set. Other security policies may not support this.
Now that I know that the -u argument's behavior differs from the behavior that has to be expected, my question is:
How can I make sure, that a command that is started in a root shell gets executed exactly as it would be executed from another user's shell?
Remark: I know that I could fix this one problem by tinkering with the umask, but this won't guarantee me that the behavior doesn't differ in an arbitrary amount of other cases.
It looks like the umask depends on whether the shell is interactive:
$ umask
0002
$ sudo -u $USER bash -c umask
0022
$ sudo -u $USER bash -ic umask
0002
This appears to be from from /etc/bashrc, which applies umask 002 only if
it's not a login shell,
the UID is greater than or equal to 200, and
the username is equal to the group name,
or from /etc/profile, which applies umask 002 if the last two criteria are met. I'm not sure if something else is overriding this, because shopt login_shell prints the same whether the shell is interactive or not, and the UID is also the same.
You can get the user's default shell thusly:
$ getent passwd $USER | cut --delimiter=: --fields=7
/bin/bash
Combining them:
$ sudo -u $USER $(getent passwd $USER | cut --delimiter=: --fields=7) -ic umask
0002
A nice and clean solution that shows the expected behavior is this:
sudo su <username> -c '<any commands>'
How can I check if a specific user with no shell assigned can write or read a file ?
As an example we can use apache user... is there any option in touch or any other commands?
Thanks
The "test" command is designed for this use case.
sudo -u otheruser test -r /path/to/file
will return 0 if otheruser can read the file, or 1 if otheruser cannot read the file. You can run test -r /path/to/file; echo "$?" to view the return code of the test command.
Use test -w to test for write permission and test -x to test for execute permission.
Test Read Permission
Attempt to read the beginning of the file and discard the normal output. You can then look for an empty string (success) or a "Permission denied" message (you can also check for other error messages such as "No such file or directory"). For example:
head -1 /path/to/file 2>&1 > /dev/null | grep 'Permission denied'
Test Write Permission
Use the touch command with the -c (--no-create) option. Combine stdout and stderr and again search for an empty string (success) or an error:
touch -c /path/to/file 2>&1 | grep 'Permission denied'
If you're explicitly testing write access of a directory, be sure to test the directory and not a file contained within, since with the -c option, there's no error condition if the file doesn't exist even in a directory you don't have write access to:
From Wikipedia: touch (Unix)
-c, if the file does not exist, do not create it and do not report this condition
Test As Specific User
The final piece of the puzzle is how to check this as a different user. As root execute the test command as the desired user with "sudo -u [username] [command]" so using your suggested user:
sudo -u apache touch -c /path/to/file 2>&1
I'm trying to create a post install script for Linux and I want to have the script edit the sudoers file so that users wont need to do sudo visudo and edit it manually.
In the script I have:
if [[ ! `sudo -l -U "$user" 2>&1 | grep "ALL"` ]]; then
su -c "echo '$user ALL=(ALL) ALL' >> /etc/sudoers"
su -c "echo '$user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"
fi
the problem with this is that when I sudo whoami after I run the script I get this output:
sudo: >>> /etc/sudoers: syntax error near line 31 <<<
sudo: parse error in /etc/sudoers near line 31
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
How do I do this without ruining my sudoers file?
EDIT:
As requested here is my sudoers file:
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
Mind that it is not possible to do cat /etc/sudoers after the script has run.
EDIT 2:
The solution is to define $user as user=$(whoami)
As the comment at the end of the default sudoers file suggests, you should create a new file in /etc/sudoers.d/.
Doing this from a (Debian) package's postinst seems fishy, though. Where does the value of user come from?
Also, any particular reason this user is not simply added to one of the existing groups, admin or sudoers?
My solution is to have the script ask the user to enter his password and store the value in a variable to be used along with Expect. The script installs Expect if it's not installed and then the script does:
read -p "Please enter your password: " PASSWD
export PASSWD
username=$USER
export username
if [[ ! `sudo -l -U "$USER" 2>&1 | grep "ALL"` ]]; then
expect -c '
spawn "su -c \"cat <<EOF >> /etc/sudoers.d/$env(username)
$env(username) ALL=(ALL:ALL) ALL
$env(username) ALL=(ALL) NOPASSWD:ALL
EOF
\"
"
expect "Password:\r"
send $env(PASSWD)
interact
'
fi
You can edit file /etc/sudoers through "pkexec visudo", after when you will delete bad line, sudo will be work.
How to add user on linux bash script with out using useradd or similar command.
Also copy the startup script which located in /etc/skel/, and change password for the user which you have been added.
user1=$1
read -p "Enter your home name" home_name
read -p "Enter your login shell" loginshell
echo "$user1:x:500:500:$user1:/home/$home_name:$loginshell" >> /etc/passwd
echo "$user1:x:500:" >> /etc/group
mkdir /home/$home_name
chmod 744 /home/$home_name
cp -pr /etc/skel/.bashrc /home/$home_name
echo "$user1: " >> /etc/shadow
echo "`passwd` $user1"
The error i have got it after execute this script
passwd: Authentication token manipulation error
Please could you advice me if there any mistakes?
You should explain why you want to do that. In my opnion, it is a bad idea. In particular, because it does not handle well all the various kind of systems (for instance, some Linux system use LDAP for user authentification, etc).
And I believe that your line echo "$user1: " >> /etc/shadow is wrong. Look (with sudo) at the content of the /etc/shadow file, and you'll understand that entries inside are more than just a username followed by a colon.
But really, you should use useradd or adduser to do that. You are risking to break your system entirely.
You should replace
echo "`passwd` $user1"
with
passwd $user1
for entering the first password.
But besides this problem you add all new users with the same user-id and group-id. So there are technically no new users but one user with several "aliases". You have to replace the 500 when writing /etc/passwd and /etc/group to fix that.
Another big problem is, that the user's new home directory and the startup script do not belong to him but to root. You may add a chown -R $user1:$user1 /home/$homename somewhere.
you should also have something like echo "$user1: " >> /etc/gshadow for the group that you are creating. Same as what you have done for the user and the shadow file.