xp_cmdshell (Transact-SQL)
Engendre une commande d'environnement Windows et lui transmet une chaîne à traiter. Toute sortie est retournée sous forme de lignes de texte.
Syntaxe
xp_cmdshell { 'command_string' } [ , no_output ]
Arguments
'command_string'
Désigne la chaîne contenant une commande à transmettre au système d'exploitation. command_string est de type varchar(8000) ou nvarchar(4000), sans valeur par défaut. command_string ne peut contenir qu'un seul jeu de guillemets doubles. Une seule paire de guillemets est nécessaire si des espaces figurent dans les chemins d'accès de fichiers ou les noms de programmes référencés dans command_string. Si l'incorporation d'espaces est source de problèmes, recourez à des noms de fichiers FAT 8.3.no_output
Paramètre facultatif indiquant qu'aucune sortie ne doit être retournée au client.
Valeurs des codes renvoyés
0 (succès) ou 1 (échec)
Ensembles de résultats
L'exécution de l'instruction xp_cmdshell ci-dessous retourne le contenu du répertoire en cours.
EXEC xp_cmdshell 'dir *.exe';
GO
Les lignes sont retournées dans une colonne nvarchar(255). Si l'option no_output est utilisée, seule la sortie suivante est retournée :
The command(s) completed successfully.
Notes
Le processus Windows engendré par xp_cmdshell possède les mêmes droits de sécurité que le compte de service SQL Server.
xp_cmdshell fonctionne de manière synchrone. Le contrôle n'est renvoyé à l'appelant que lorsque la commande de l'interpréteur de commandes est terminée.
L'instruction xp_cmdshell peut être activée et désactivée à l'aide de la gestion basée sur une stratégie ou en exécutant sp_configure. Pour plus d'informations, consultez Présentation de la configuration de la surface d'exposition et xp_cmdshell (option).
Important
Si l'instruction xp_cmdshell est exécutée au sein d'un lot et retourne une erreur, le lot échoue. Cela représente un changement de comportement. Dans les versions antérieures de MicrosoftSQL Server, le lot continue de s'exécuter.
Compte proxy xp_cmdshell
Lorsqu'elle est appelée par un utilisateur qui n'est pas membre du rôle de serveur fixe sysadmin, l'instruction xp_cmdshell permet de se connecter à Windows à l'aide du nom de compte et du mot de passe stockés dans les informations d'identification nommées ##xp_cmdshell_proxy_account##. Si ces informations d'identification du proxy n'existent pas, xp_cmdshell échoue.
Il est possible de créer les informations d'identification du proxy en exécutant sp_xp_cmdshell_proxy_account. Cette procédure stockée accepte comme arguments un nom d'utilisateur et un mot de passe Windows. Par exemple, la commande ci-dessous crée des informations d'identification de proxy pour l'utilisateur de domaine Windows SHIPPING\KobeR qui possède le mot de passe Windows sdfh%dkc93vcMt0.
EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR','sdfh%dkc93vcMt0'
Pour plus d'informations, consultez sp_xp_cmdshell_proxy_account (Transact-SQL).
Autorisations
Étant donné que des utilisateurs malveillants essaient quelquefois d'élever leurs privilèges à l'aide de xp_cmdshell, xp_cmdshell est désactivé par défaut. Utilisez sp_configure ou la gestion basée sur des stratégies pour l'activer. Pour plus d'informations, consultez xp_cmdshell (option).
Lorsqu'il est activé pour la première fois, xp_cmdshell requiert l'autorisation CONTROL SERVER pour l'exécution et le processus Windows créé par xp_cmdshell a le même contexte de sécurité que le compte de service SQL Server. Le compte de service SQL Server a souvent plus d'autorisations que nécessaire pour le travail effectué par le processus créé par xp_cmdshell. Pour améliorer la sécurité, l'accès à xp_cmdshell doit être restreint aux utilisateurs disposant de privilèges élevés.
Pour permettre aux utilisateurs qui ne sont pas administrateurs d'utiliser xp_cmdshell et permettre à SQL Server de créer des processus enfants avec le jeton de sécurité d'un compte avec moins de privilèges, procédez comme suit :
Créez et personnalisez un compte d'utilisateur local Windows ou un compte de domaine avec les privilèges minimaux requis par vos processus.
Utilisez la procédure système sp_xp_cmdshell_proxy_account pour configurer xp_cmdshell pour utiliser ce compte doté de privilèges minimaux.
[!REMARQUE]
Vous pouvez également configurer ce compte proxy à l'aide de SQL Server Management Studio en cliquant avec le bouton droit sur Propriétés sur le nom de votre serveur dans l'Explorateur d'objets, puis en recherchant la section Compte proxy du serveur sous l'onglet Sécurité.
Dans Management Studio, à l'aide de la base de données master, exécutez l'instruction GRANT exec ON xp_cmdshell TO '<somelogin>' pour accorder à des utilisateurs qui ne sont pas membres du rôle sysadmin spécifiques la capacité d'exécuter xp_cmdshell. La connexion spécifiée doit être mappée à un utilisateur dans la base de données master.
À présent, les utilisateurs qui ne sont pas administrateurs peuvent lancer des processus de système d'exploitation avec xp_cmdshell et ces processus sont exécutés avec les autorisations du compte proxy que vous avez configuré. Les utilisateurs avec l'autorisation CONTROL SERVER (membres du rôle serveur fixe sysadmin) continuent de recevoir les autorisations du compte de service SQL Server pour les processus enfants lancés par xp_cmdshell.
Pour identifier le compte Windows qui est utilisé par xp_cmdshell lors du lancement des processus de système d'exploitation, exécutez l'instruction suivante :
xp_cmdshell 'whoami.exe'
Pour déterminer le contexte de sécurité pour une autre connexion, exécutez ce qui suit :
EXECUTE AS LOGIN = '<other_login>' ;
GO
xp_cmdshell 'whoami.exe' ;
REVERT ;
Exemples
A. Renvoi d'une liste de fichiers exécutables
L'exemple ci-dessous montre la procédure stockée étendue xp_cmdshell exécutant une commande de répertoire.
EXEC master..xp_cmdshell 'dir *.exe'
B. Utilisation des commandes net Windows
L'exemple ci-dessous montre l'utilisation de xp_cmdshell dans une procédure stockée. Cet exemple signale aux utilisateurs à l'aide de net send qu'une instance de SQL Server va être arrêtée, interrompt le serveur à l'aide de net pause, puis arrête le serveur à l'aide de net stop.
CREATE PROC shutdown10
AS
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server
shutting down in 10 minutes. No more connections
allowed.', no_output
EXEC xp_cmdshell 'net pause sqlserver'
WAITFOR DELAY '00:05:00'
EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server
shutting down in 5 minutes.', no_output
WAITFOR DELAY '00:04:00'
EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server
shutting down in 1 minute. Log off now.', no_output
WAITFOR DELAY '00:01:00'
EXEC xp_cmdshell 'net stop sqlserver', no_output
C. Aucun renvoi d'information en sortie
L'exemple ci-dessous utilise xp_cmdshell pour exécuter une chaîne de commande sans retourner les informations en sortie au client.
USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
\\server2\backups\SQLbcks, NO_OUTPUT';
GO
D. Utilisation de l'état de retour
Dans l'exemple ci-dessous, la procédure stockée étendue xp_cmdshell propose également un état de retour. La valeur du code de retour est stockée dans la variable @result.
DECLARE @result int
EXEC @result = xp_cmdshell 'dir *.exe'
IF (@result = 0)
PRINT 'Success'
ELSE
PRINT 'Failure'
E. Écriture du contenu des variables dans un fichier
Dans l'exemple ci-dessous, le contenu de la variable @var est écrit dans un fichier nommé var_out.txt dans le répertoire en cours sur le serveur.
DECLARE @cmd sysname, @var sysname
SET @var = 'Hello world'
SET @cmd = 'echo ' + @var + ' > var_out.txt'
EXEC master..xp_cmdshell @cmd
F. Capture du résultat d’une commande dans un fichier
Dans l'exemple ci-dessous, le contenu du répertoire en cours est écrit dans un fichier nommé dir_out.txt dans le répertoire en cours du serveur.
DECLARE @cmd sysname, @var sysname
SET @var = 'dir/p'
SET @cmd = @var + ' > dir_out.txt'
EXEC master..xp_cmdshell @cmd
Historique des modifications
Mise à jour du contenu |
---|
Amélioration de la section Autorisations. |