Archives de la catégorie ‘script’

#!/bin/bash
# System-wide crontab file and cron job directory. Change these for your system. 
CRONTAB='/etc/crontab' 
CRONDIR='/etc/cron.d' 
# Single tab character. Annoyingly necessary. 
tab=$(echo -en "\t") 
# Given a stream of crontab lines, exclude non-cron job lines, replace 
# whitespace characters with a single space, and remove any spaces from the 
# beginning of each line. 
function clean_cron_lines() { 
    while read line ; do 
        echo "${line}" | 
            egrep --invert-match '^($|\s*#|\s*[[:alnum:]_]+=)' | 
            sed --regexp-extended "s/\s+/ /g" | 
            sed --regexp-extended "s/^ //" 
    done; 
} 
# Given a stream of cleaned crontab lines, echo any that don't include the 
# run-parts command, and for those that do, show each job file in the run-parts 
# directory as if it were scheduled explicitly. 
function lookup_run_parts() { 
    while read line ; do 
        match=$(echo "${line}" | egrep -o 'run-parts (-{1,2}\S+ )*\S+') 
        if [[ -z "${match}" ]] ; then 
            echo "${line}" 
        else 
            cron_fields=$(echo "${line}" | cut -f1-6 -d' ') 
            cron_job_dir=$(echo  "${match}" | awk '{print $NF}') 
            if [[ -d "${cron_job_dir}" ]] ; then 
                for cron_job_file in "${cron_job_dir}"/* ; do  # */ <not a comment> 
                    [[ -f "${cron_job_file}" ]] && echo "${cron_fields} ${cron_job_file}" 
                done 
            fi 
        fi 
    done; 
} 
# Temporary file for crontab lines. 
temp=$(mktemp) || exit 1 
# Add all of the jobs from the system-wide crontab file. 
[[ -f ${CRONTAB} ]] && cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}"  
# Add all of the jobs from the system-wide cron directory. 
[[ -f ${CRONTAB} ]] && cat "${CRONTAB}" | clean_cron_lines | lookup_run_parts >"${temp}"  
# Add all of the jobs from the system-wide cron directory. 
[[ -d ${CRONDIR} ]] && ( cat "${CRONDIR}"/* 2> /dev/null | clean_cron_lines >>"${temp}" ||  true ) # */ <not a com
ment>
# Add each user's crontab (if it exists). Insert the user's name between the 
# five time fields and the command. 
while read user ; do 
    crontab -l -u "${user}" 2>/dev/null | 
        clean_cron_lines | 
        sed --regexp-extended "s/^((\S+ +){5})(.+)$/\1${user} \3/" >>"${temp}" 
done < <(cut --fields=1 --delimiter=: /etc/passwd) 
# Output the collected crontab lines. Replace the single spaces between the 
# fields with tab characters, sort the lines by hour and minute, insert the 
# header line, and format the results as a table. 
cat "${temp}" | 
    sed --regexp-extended "s/^(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(\S+) +(.*)$/\1\t\2\t\3\t\4\t\5\t\6\t\7/" | 
    sort --numeric-sort --field-separator="${tab}" --key=2,1 | 
    sed "1i\mi\th\td\tm\tw\tuser\tcommand" | 
    column -s"${tab}" -t 
rm --force "${temp}"

1. Gestion des utilisateurs sous Unix/Linux

Unix est multi-utilisateurs. Pour cette raison, tout le monde ne peut pas tout faire, à part l’administrateur système (traditionnellement nommé root), qui à le droit de lire et d’écrire tous les fichiers de tous les répertoires.

Chaque utilisateur est désigné de manière unique par son login (son « nom »). De plus, chaque utilisateur appartient à un ou plusieurs groupes. Par exemple, sous Red Hat Linux, chaque utilisateur est par défaut seul membre de son groupe personnel et membre du groupe users. Ainsi, sur ma machine, j’ai un utilisateur damien qui est membre des groupes damien et users. L’intêret d’avoir chaque utilisateur unique membre d’un groupe dépasse le cadre de cet article.

Un fichier ou un répertoire appartient toujours à un utilisateur et à un groupe. D’autre part, un fichier peut être accessible en lecture, en écriture et en exécution. Les permissions sont distinctes pour l’utilisateur propriétaire du fichier, pour le groupe propriétaire et pour le reste du monde. Ces permissions sont affichées par la commande ls quand on lui passe l’option -l:

-rw-r--r--  1 damien   users  297 Jun 07 10:31 toto

Cette ligne signifie que le fichier toto appartient à l’utilisateur damien et au groupe users, avec les droits -rw-r--r--. Les autres valeurs (1, 297 et la date) ne nous intéressent pas ici.

Décryptage des droits -rw-r–r– : le premier caractère représente le type de fichier: « – » pour un fichier normal, « d » pour un répertoire, « p » pour un tube, « b » ou « c » pour un périphérique, « l » pour un lien symbolique.

Les trois suivants représentent les droits de l’utilisateur propriétaire du fichier.

  • « r » représente le droit de lecture,
  • « w » le droit d’écriture
  • « x » le droit d’exécution

Ici, « rw- » signifie que l’utilisateur damien peut lire et écrire dans le fichier, mais pas l’exécuter.
Les trois caractères suivants représentent les permissions du groupe; ici, tous les membres du groupe users peuvent lire le fichier, mais pas y écrire.
Enfin, les trois derniers caractères ont une signification analogue pour le reste du monde.

Une astruce mnémotechnique : pensez au prénom HUGO et vous retrouverez UGO : User, Group, Other

Une petite nuance pour les répertoires: si un utilisateur a le droit d' »exécution » sur un répertoire, cela signifie qu’il peut y entrer avec la commande cd ou équivalent.

Comment fixer les droits : on a vu que les droits d’accès sont fixés pour UGO et sont en rwx.

  rwx
  ||+-- 1
  |+--- 2
  +---- 4

Ainsi, fixer les droits sur un répertoire ou un fichier peut être synthétiser par en additionnant les valeurs pour chaque UGO.

Par exemple, un groupe « rwx » est représenté par 4+2+1=7. Un groupe « r– » par 4+0+0=4. Un groupe « –x » par 0+0+1=1. Ainsi, les permissions rw-r--r-- de notre fichier toto s’écrivent 644.

Fixer les droits :

chmod 644 toto

2. Setuid sur un script Shell ou un programme

Rappel : une ligne de commande précédée par $ indique un utilisateur lambda. Une ligne de commande précédée par # indique que cette commande est exécutée par l’utilisateur ROOT

Dans l’exemple ci-dessous, on modifie les droits du script monshell.sh par un SETUID=4 (on fixe l’utilisateur d’exécution à ROOT) :

# chown root:root monshell.sh
# chmod 4755 monshell.sh
# exit
$ ./monshell.sh

L’utilisateur exécute ici le script monshell.sh avec les droits ROOT et ce, bien que n’étant pas dans le groupe ROOT !

Ce script a pour objectif de changer le mot de passe d’un compte passé en paramètre sur l’ensemble des serveurs UNIX de votre parc.
Pré-requis :
  • Se connecter en tant que ROOT sur votre serveur
  • Configurer un échange de clés SSH entre votre serveur et l’ensemble des serveurs de votre parc
  • Une liste des serveurs cibles dans le fichier /root/scripts/listedesserveursatraiter
Utilisation :
#ChangePasswd.sh <nom du compte>

ex : #ChangePasswd.sh root
Code :
#!/bin/bash

compte = $1

echo "Modification du mot de passe $compte sur l'ensemble des serveurs"
read -s -p "Nouveau mot de passe : " mdp
echo ""
if test -z "$mdp" ; then
        echo "Le mot de passe ne peut pas être vide"
        exit
fi
read -s -p "Vérification du mot de passe saisi : " mdp2
if test "$mdp" != "$mdp2" ; then
        echo "Les mots de passe saisis ne correspondent pas"
        exit
fi

echo "Modification du mot de passe du compte $compte"

SERVEUR=/root/scripts/listedesserveursatraiter
for serveur in `cat $SERVEUR|grep "^[^#].*$"`
do
        echo "Traitement du serveur : $serveur"
        ssh $serveur "echo $compte:$mdp|chpasswd"
done

echo "Après avoir VERIFIE LES CONNEXIONS sur CHAQUE SERVEUR, vous pouvez fermer ce shell"

echo "Après avoir VERIFIE LES CONNEXIONS sur CHAQUE SERVEUR, vous pouvez fermer ce shell"
 
Commentaires :  le fichier /root/scripts/listedesserveursatraiter contient la liste des serveurs :
serveur1
serveur2
#ce serveur ne sera pas traité
Parce que la connexion SSH est configurée par échange de clés, le script se charge d’envoyer, sans authentification, la commande chpasswd <nom du compte>:<mot de passe> à tous les serveurs.