From ecc5aab0e747fd33597bc286b0ba2cc6458021d6 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Tue, 21 Dec 2021 19:40:46 +0100 Subject: [PATCH 1/7] feat(adduser): add adduser plugin (#10441) Automatic "Oh My ZSH" installation when adding new users --- plugins/adduser/README.md | 26 ++++++++++++++ plugins/adduser/adduser.plugin.zsh | 55 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 plugins/adduser/README.md create mode 100644 plugins/adduser/adduser.plugin.zsh diff --git a/plugins/adduser/README.md b/plugins/adduser/README.md new file mode 100644 index 000000000..836459405 --- /dev/null +++ b/plugins/adduser/README.md @@ -0,0 +1,26 @@ +# adduser + +This plugin adds support for installing "Oh My ZSH" when adding new users. + +To use it, add `adduser` to the plugins array of your `~/.zshrc` file: + +```zsh +plugins=(... adduser) +``` + +## Usage + +Just run `adduser` as you normally would do and now: + +1. The regular `adduser` command will run. +2. The shell of the new user will switch to zsh +3. "Oh My zsh will be installed (as if he would have ran `install.sh` himself). + +## NOTES + +- It is assumed that the last argument will be the username.
*(In rare cases people provide the group as last argument)* +- `useradd` behaviour is not changed. + +## Author + +[Nikolas Garofil](https://github.com/ngaro) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh new file mode 100644 index 000000000..f6b8a4daf --- /dev/null +++ b/plugins/adduser/adduser.plugin.zsh @@ -0,0 +1,55 @@ +# Copyright (c) 2021 Nikolas Garofil + +adduser() { + local returncode + local result_string="Installation of 'Oh My Zsh' " + local temp_installscript + local path_installscript="$ZSH/tools/install.sh" + + + #Create user, errors will be reported by the 'real' adduser + #Use which/tail combination to call the binary instead of this function + $(which -a adduser | tail -1) $@ || return 1 + + + echo "\nUser '${@[$#]}' has been created. I will now try to install 'Oh My Zsh'" + if [[ -f $path_installscript ]] ; then + + #copy install.sh to a new file in temp that we can give the right owner to execute + #and also make sure that after the install script we are no longer the new user + temp_installscript=$(mktemp) + cat $path_installscript | \ + sed 's/exec zsh -l//' | + sed 's/read -r opt/opt=y; echo "\n--- This time I am answering \\"yes\\" for you, but you will still have to type in the password of that user ---"/' \ + > $temp_installscript + chown ${@[$#]} $temp_installscript && chmod +x $temp_installscript + + #try installing with sudo or su when not available + if [[ -x $(which sudo) ]] ; then + sudo -u ${@[$#]} $temp_installscript + returncode=$? + else + if [[ -x $(which su) ]] ; then + su -l ${@[$#]} -c $temp_installscript + returncode=$? + else + echo "You can't become ${@[$#]} (no 'sudo' or 'su' available)" > /dev/stderr; + returncode=1 + fi + fi + #cleanup + rm $temp_installscript + else + echo "Installationscript '$path_installscript' not available" 2> /dev/stderr; + returncode=1 + fi + + #mention the result + if [[ $returncode -eq 0 ]]; then + echo "$result_string succeeded." + else + echo "$result_string failed." 2> /dev/stderr + fi + + return $returncode +} From 510d7a778a3cd358bb99d87f09a7f6d81beed27d Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 22 Dec 2021 19:15:09 +0100 Subject: [PATCH 2/7] Fix(adduser): better way to avoid adduser() recursion --- plugins/adduser/adduser.plugin.zsh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index f6b8a4daf..b01e87ee1 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -9,7 +9,7 @@ adduser() { #Create user, errors will be reported by the 'real' adduser #Use which/tail combination to call the binary instead of this function - $(which -a adduser | tail -1) $@ || return 1 + command adduser $@ || return 1 echo "\nUser '${@[$#]}' has been created. I will now try to install 'Oh My Zsh'" From 8ceff21474377b7be42cd87c5737b19438b58b1a Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 22 Dec 2021 19:15:49 +0100 Subject: [PATCH 3/7] Fix(adduser): correct echo redirect --- plugins/adduser/adduser.plugin.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index b01e87ee1..02dfb556b 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -40,7 +40,7 @@ adduser() { #cleanup rm $temp_installscript else - echo "Installationscript '$path_installscript' not available" 2> /dev/stderr; + echo "Installationscript '$path_installscript' not available" > /dev/stderr; returncode=1 fi @@ -48,7 +48,7 @@ adduser() { if [[ $returncode -eq 0 ]]; then echo "$result_string succeeded." else - echo "$result_string failed." 2> /dev/stderr + echo "$result_string failed." > /dev/stderr fi return $returncode From 70edfaf348640f923f6f6b73f9332c5cbdd8554e Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 22 Dec 2021 19:16:50 +0100 Subject: [PATCH 4/7] Fix(adduser): better binary check --- plugins/adduser/adduser.plugin.zsh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index 02dfb556b..6df23bc77 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -25,11 +25,11 @@ adduser() { chown ${@[$#]} $temp_installscript && chmod +x $temp_installscript #try installing with sudo or su when not available - if [[ -x $(which sudo) ]] ; then + if [[ -x "$commands[sudo]" ]] ; then sudo -u ${@[$#]} $temp_installscript returncode=$? else - if [[ -x $(which su) ]] ; then + if [[ -x "$commands[su]" ]] ; then su -l ${@[$#]} -c $temp_installscript returncode=$? else From f26b428f8edd27e0020a8efbf371832d8cef7f74 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 22 Dec 2021 19:18:04 +0100 Subject: [PATCH 5/7] Fix(adduser): better returning to shell of original user --- plugins/adduser/adduser.plugin.zsh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index 6df23bc77..35a8af16f 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -19,18 +19,17 @@ adduser() { #and also make sure that after the install script we are no longer the new user temp_installscript=$(mktemp) cat $path_installscript | \ - sed 's/exec zsh -l//' | sed 's/read -r opt/opt=y; echo "\n--- This time I am answering \\"yes\\" for you, but you will still have to type in the password of that user ---"/' \ > $temp_installscript chown ${@[$#]} $temp_installscript && chmod +x $temp_installscript #try installing with sudo or su when not available if [[ -x "$commands[sudo]" ]] ; then - sudo -u ${@[$#]} $temp_installscript + sudo -u ${@[$#]} RUNZSH=no $temp_installscript returncode=$? else if [[ -x "$commands[su]" ]] ; then - su -l ${@[$#]} -c $temp_installscript + su -l ${@[$#]} -c "$temp_installscript --unattended" returncode=$? else echo "You can't become ${@[$#]} (no 'sudo' or 'su' available)" > /dev/stderr; From 8b5f01a22c2da374f550afa4b53b5d938a15a64c Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Wed, 22 Dec 2021 20:02:11 +0100 Subject: [PATCH 6/7] Fix(adduser): better changing of shell --- plugins/adduser/adduser.plugin.zsh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index 35a8af16f..f6b2f35b7 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -18,19 +18,28 @@ adduser() { #copy install.sh to a new file in temp that we can give the right owner to execute #and also make sure that after the install script we are no longer the new user temp_installscript=$(mktemp) - cat $path_installscript | \ - sed 's/read -r opt/opt=y; echo "\n--- This time I am answering \\"yes\\" for you, but you will still have to type in the password of that user ---"/' \ - > $temp_installscript + cp $path_installscript $temp_installscript chown ${@[$#]} $temp_installscript && chmod +x $temp_installscript #try installing with sudo or su when not available if [[ -x "$commands[sudo]" ]] ; then - sudo -u ${@[$#]} RUNZSH=no $temp_installscript + sudo -u ${@[$#]} sh -c "$temp_installscript --unattended" + returncode=$? + if [[ -x "$commands[chsh]" ]] ; then + sudo chsh -s $commands[zsh] ${@[$#]} + else + echo "'chsh' is not available, change the shell manually." > /dev/stderr + fi returncode=$? else if [[ -x "$commands[su]" ]] ; then su -l ${@[$#]} -c "$temp_installscript --unattended" returncode=$? + if [[ -x "$commands[chsh]" ]] ; then + su -c "chsh -s $commands[zsh] ${@[$#]}" + else + echo "'chsh' is not available, change the shell manually." > /dev/stderr + fi else echo "You can't become ${@[$#]} (no 'sudo' or 'su' available)" > /dev/stderr; returncode=1 From 01808b3aae7f6293221b1cc8ab0bdb38cff942c4 Mon Sep 17 00:00:00 2001 From: Nikolas Garofil Date: Thu, 23 Dec 2021 21:52:55 +0100 Subject: [PATCH 7/7] Fix(adduser): Better code structure --- plugins/adduser/adduser.plugin.zsh | 107 +++++++++++++++-------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/plugins/adduser/adduser.plugin.zsh b/plugins/adduser/adduser.plugin.zsh index f6b2f35b7..aa89528f3 100644 --- a/plugins/adduser/adduser.plugin.zsh +++ b/plugins/adduser/adduser.plugin.zsh @@ -1,63 +1,70 @@ # Copyright (c) 2021 Nikolas Garofil -adduser() { - local returncode - local result_string="Installation of 'Oh My Zsh' " - local temp_installscript - local path_installscript="$ZSH/tools/install.sh" +_adduser_result() { + local result_string="Installation of 'Oh My Zsh' for '$new_user'" - - #Create user, errors will be reported by the 'real' adduser - #Use which/tail combination to call the binary instead of this function - command adduser $@ || return 1 - - - echo "\nUser '${@[$#]}' has been created. I will now try to install 'Oh My Zsh'" - if [[ -f $path_installscript ]] ; then - - #copy install.sh to a new file in temp that we can give the right owner to execute - #and also make sure that after the install script we are no longer the new user - temp_installscript=$(mktemp) - cp $path_installscript $temp_installscript - chown ${@[$#]} $temp_installscript && chmod +x $temp_installscript - - #try installing with sudo or su when not available - if [[ -x "$commands[sudo]" ]] ; then - sudo -u ${@[$#]} sh -c "$temp_installscript --unattended" - returncode=$? - if [[ -x "$commands[chsh]" ]] ; then - sudo chsh -s $commands[zsh] ${@[$#]} - else - echo "'chsh' is not available, change the shell manually." > /dev/stderr - fi - returncode=$? - else - if [[ -x "$commands[su]" ]] ; then - su -l ${@[$#]} -c "$temp_installscript --unattended" - returncode=$? - if [[ -x "$commands[chsh]" ]] ; then - su -c "chsh -s $commands[zsh] ${@[$#]}" - else - echo "'chsh' is not available, change the shell manually." > /dev/stderr - fi - else - echo "You can't become ${@[$#]} (no 'sudo' or 'su' available)" > /dev/stderr; - returncode=1 - fi - fi - #cleanup + #Erase the temporary copy of the installscript when necessary + if [[ ! -z $temp_installscript ]] ; then rm $temp_installscript - else - echo "Installationscript '$path_installscript' not available" > /dev/stderr; - returncode=1 fi #mention the result - if [[ $returncode -eq 0 ]]; then + if [[ $1 -eq 0 ]]; then echo "$result_string succeeded." else echo "$result_string failed." > /dev/stderr fi - return $returncode +} + +adduser() { + local path_installscript="$ZSH/tools/install.sh" + local unattended_options=" --unattended" + + local new_user=${@[$#]} + local temp_installscript; local unattended_installer; local install_as_user; local change_shell; + + #Create user, errors will be reported by the 'real' adduser + #Don't use $new_user so that we have all args + command adduser $@ || return 1 + + echo "\nUser '$new_user' has been created. I will now try to install 'Oh My Zsh'" + + if [[ ! -f $path_installscript ]] ; then + echo "Installationscript '$path_installscript' not available" > /dev/stderr; + _adduser_result 1 + return 1; + fi + + #copy install.sh to a new file in temp that we can give the right owner to execute + #and also make sure that after the install script we are no longer the new user + temp_installscript=$(mktemp) + cp $path_installscript $temp_installscript + chown $new_user $temp_installscript && chmod +x $temp_installscript + unattended_installer="$temp_installscript $unattended_options" + + if [[ ( ! -x "$commands[sudo]" ) && ( ! -x "$commands[su]" ) ]] ; then + echo "You can't become $new_user (no 'sudo' or 'su' available)" > /dev/stderr; + _adduser_result 1 + return 1; + fi + if [[ -x "$commands[sudo]" ]] ; then + install_as_user="sudo -u $new_user sh -c '$unattended_installer'" + change_shell="sudo chsh -s $commands[zsh] $new_user" + else + install_as_user="su -l $new_user -c '$unattended_installer'" + change_shell="su -c 'chsh -s $commands[zsh] $new_user'" + fi + + eval ${install_as_user} + #mention the result before changing the shell (even with a bad result it's still installed) + if [ ! $? -eq 0 ] ; then + _adduser_result 1 + return 1 + fi + + if [[ ! -x "$commands[chsh]" ]] ; then + echo "'chsh' is not available, change the shell manually." > /dev/stderr + fi + eval ${change_shell} }