web-dev-qa-db-fra.com

BULK INSERT obtenant "Impossible de charger en bloc car ... l'accès est refusé" sur un fichier auquel j'ai accès

J'essaie d'exécuter un BULK INSERT mais j'obtiens une erreur d'accès refusé. Jusqu'à présent, j'ai essayé ce qui suit:

  • Je peux ouvrir le fichier depuis ma machine
  • Je suis connecté à SQL Server (essayé v2008 R2 et v2016) en utilisant l'authentification Windows
  • J'ai des autorisations d'administrateur système
  • Je peux type le fichier en utilisant xp_cmdshell (utilise le compte de service SQL mais il élimine l'idée qu'il s'agit d'un pare-feu)
  • Le chemin est une URL réseau et non un lecteur local

La commande que j'utilise est la suivante:

BULK INSERT ken_temp
FROM '\\network_path\temp\kdf\text_file.txt'
WITH
   (
    FIELDTERMINATOR = ',', ROWTERMINATOR = '\n'
   ,ROWS_PER_BATCH = 50000
   ,MAXERRORS = 10
   )

Des idées?

6
Kenneth Fisher

Le problème est que:

  1. Vous vous connectez à l'aide de l'authentification Windows: cela signifie que SQL Server tentera d'emprunter l'identité de votre compte Windows/domaine pour l'accès au système de fichiers.

  2. Vous vous êtes connecté directement à un poste de travail, puis vous êtes connecté à distance à SQL Server: cela signifie que vous vous êtes connecté au serveur exécutant SQL Server indirectement, en passant votre jeton d'authentification de votre poste de travail au serveur exécutant SQL Server.

  3. Vous n'avez pas activé la délégation pour SQL Server: cela signifie que vous êtes bloqué avec le comportement par défaut de ne pas être autorisé à passer ce jeton au-delà d'une étape à partir de la connexion directe.

  4. Vous essayez de lire un fichier qui existe sur une ressource distante: cela signifie qu'il se trouve à plus d'une étape au-delà de l'endroit où vous vous êtes connecté directement.

C'est pourquoi vous pouvez très bien accéder au fichier depuis votre poste de travail. Et c'est pourquoi l'utilisation de xp_cmdshell Fonctionne également puisque le compte de service est connecté directement au serveur exécutant SQL Server et que la ressource distante n'est qu'à 1 étape au-delà.

Je soupçonne que si vous étiez sur un poste de travail distant directement sur le serveur exécutant SQL Server, exécutez SSMS sur ce serveur, puis exécutez BULK INSERT, Que cela réussirait. Ou, cela devrait également fonctionner si vous configurez une connexion SQL Server, accordez à la connexion l'autorisation "administrateur en bloc", puis EXECUTE AS Login = 'JustReadTheDangFileAlready';, Puis effectuez BULK INSERT. Lors de l'exécution de BULK INSERT/OPENROWSET (BULK...) en tant que connexion SQL Server, il n'y a pas de compte Windows à emprunter, donc l'accès au système de fichiers se fait à l'aide du compte de service, qui sera exactement comme xp_cmdshell.

Vous avez les choix suivants:

  1. Activer la délégation pour SQL Server (je ne me souviens pas si c'est pour le service ou le compte, auquel cas c'est peut-être votre compte Windows qui en a besoin, mais il existe des guides sur la façon de configurer cela, qui comprend la configuration des SPN) . Je crois que c'est le choix préféré/recommandé. Cela permet au processus de transférer les jetons d'authentification vers des ressources plus éloignées de la connexion directe.

  2. Utilisez une connexion SQL Server pour ce processus. Je ne peux pas croire que je suggère cela, mais si vous aviez une connexion SQL Server qui était dans le rôle de serveur fixe "admin en vrac" OR avait la permission "admin en vrac" correcte, vous pouvez ensuite créer l'utilisateur associé pour cette connexion (dans une base de données appropriée) et placer le BULK INSERT dans une procédure stockée créée à l'aide de WITH EXECUTE AS 'JustReadTheDangFileAlready'. Ensuite, vous pouvez exécuter ce proc qui doit masquer que la demande provenait d'un compte Windows.

  3. Ouvrez les autorisations sur ce fichier distant (et peut-être aussi le dossier?). Vous pouvez accorder l'autorisation de "lecture" à "Tout le monde" (et peut-être également "lire" ou une autre autorisation sur le dossier).

  4. Supprimez cette question et utilisez cette "erreur" comme justification pour avoir besoin d'un coûteux SAN qui sera connecté via une carte HBA et apparaîtra comme un lecteur local ????. Dites simplement au directeur financier: "C'est vraiment le seul façon. Internet l'a dit. "

4
Solomon Rutzky