2016-10-10 2 views
-1

Ich baue eine Website, die ein Formular hat, das Benutzerdaten erfasst und einige CGI auf den Benutzerdaten ausführt. Einer der ersten Schritte des CGI ist, dass es Dateien vom Linux-Webserver auf Windows-Maschinen kopieren muss. Der Server würde ein Active Directory-Rollenkonto für den Kopierberechtigungsnachweis verwenden. Ich hatte gehofft, einfach so etwas wie folgt zu verwenden:Python kopiert Dateien von Linux nach Windows

mount -t cifs -o username=someUsername,password=somePasword //someMachine/someShare /someMountPoint 

Leider bekomme ich Fehler über das Passwort ungültig zuschreibt, wenn ich diesen Befehl in bash laufen. Im Idealfall würde ich diese Methode verwenden, um die remote Windows c $ share zu mounten und dann die Dateien zu kopieren, aber ich bin bereit, andere Module auszuprobieren, wenn sie sinnvoller sind.

Ich hatte so etwas, aber es funktioniert nicht, erstellt die notwendigen temporären Verzeichnisse, aber nie mounts. Ich bin froh, etwas anderes zu versuchen, würde aber gerne wissen, was hier los ist.

import subprocess 
import random 


def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    try: 
     subprocess.Popen(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
    except: 
     print("Mounting failed") 

+0

Sie möchten eine Website mit Administratorrechten für den Windows-Server (benötigt für die C $ -Freigabe) und Root-Berechtigungen zum Mounten von Dateisystemen auf dem Linux-Server für den alltäglichen normalen Betrieb ausführen? Ew. Es ist viel besser, einen eingeschränkten Benutzeraccount auf dem Windows-Server mit nur den richtigen Ordner- und Freigabeberechtigungen und etwas wie [smbclient] (http://superuser.com/a/562728) auf der Linux-Seite zu verwenden, um zu vermeiden, dass der Teilen Sie überhaupt. (Überprüfen Sie auch das [tempfile] (https://docs.python.org/3/library/tempfile.html) Modul, um Ihre random.randrange bodge zu vermeiden) – TessellatingHeckler

+0

Ja, ich stimme mit den Konten überein und würde ideal mounten Gemieden werden. Diese Seite wird auf eine kleine Gruppe von Personen beschränkt sein und ist intern, aber Sicherheit ist offensichtlich wichtig. Ich kann Freigaben auf Remote-Computern nicht wirklich verwenden, da sie im laufenden Betrieb erstellt werden müssten. Es ist jedoch möglicherweise möglich, dass der Benutzer die Anmeldeinformationen dafür bereitstellt. Danke für die Eingabe, ich werde mir sicherlich die Möglichkeit ansehen smbclient zu benutzen, ich mag auch das Aussehen dieses Tempfilemoduls. Danke –

Antwort

0

Ich verwendete die SMBConnection-Klasse in Pysmb gefunden (https://pythonhosted.org/pysmb/api/smb_SMBConnection.html). Sehr einfach und keine Notwendigkeit für die Montage.

conn = SMBConnection(user, pw, myname, srv, use_ntlm_v2 = True) 
conn.connect(ip, port=139) 
file2transfer = open(filename,"r") 
conn.storeFile(share,path + filename, file2transfer, timeout=30) 

Stellen Sie sicher, dass der Benutzer Anmelderechte für die Dateifreigabe hat.

+0

Dies ist absolut die perfekte Lösung. Ich habe den anderen Code entfernt und ihn damit ersetzt. Ich finde es viel zuverlässiger und schneller. Vielen Dank! –

0

Dieser Ansatz hat zwei Nachteile: Die erste ist, dass Sie Windows-Freigabe von Ihrem Webserver montieren. Sie müssen es nicht dynamisch mounten und auf keinen Fall sollten Sie es für jede Anfrage mounten. Trennen Sie Ihre Implementierung und Infrastruktur. Hängen Sie das erforderliche Verzeichnis in/etc/fstab ein und lassen Sie Ihren Webserver auf die Existenz des Verzeichnisses vertrauen.

Aber dann gibt es ein anderes Problem: Was für Sie kopieren die Dateien auf eine andere Maschine? Willst du sie dort bearbeiten? Wie möchten Sie Windows-Rechner benachrichtigen, dass es Daten verarbeiten muss? Warum nicht einen anderen Webserver darauf laufen lassen und Anfragen senden, wenn Sie etwas verarbeiten müssen. Und an diesem Punkt können Sie alle Netzwerk-Dateisysteme löschen und die Dateien innerhalb der Anforderungen senden. Sie werden also einen Linux-basierten Frontend-Server haben, der einige Aktionen ausführt, indem er HTTP-Anfragen an den Windows-Backend-Server sendet. Dies ermöglicht Ihnen auch, das Frontend zu benachrichtigen, wenn die Verarbeitung bereit ist.

+0

Danke, ich sehe was du meinst. Ich denke du verstehst die Grundidee. Der Linux-Apache-Server führt ein Formular aus, das https verwendet und Benutzeranmeldungen benötigt. Die Daten, die durch das Formular gesammelt werden, sind ein Benutzername, einige andere einfache Variablen und ein Remote-Windows-Desktop-Rechner-Hostname. Die Daten werden verwendet, um eine Antwortdatei zu erstellen, die auf den Remote-Desktop-Computer kopiert wird, sowie eine zusätzliche Softwarekomponente, für die ich nicht verantwortlich bin. Ich muss dann eine exe auf dem Remote-Rechner auslösen. Während des Vorgangs wird alles gelöscht. –

0

Zuerst fallen den Block Ausnahme, da es die Fehlerdetails versteckt, sowieso Popen und andere subprocess Methoden nur Ausnahmen auslösen, wenn sie keine Befehle beginnen (wegen des Befehls nicht gefunden), was bedeutet, dass mount tatsächlich genannt.

Zweitens, die Sie wirklich nicht Popen brauchen, aber call (und als Bonus Sie den Return-Code direkt erhalten)

rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         "/mntDir/"+mountDir]) 
if rc: 
    print("mount failed") 

In Ihrem Fall ist das Problem ist der allgemeine Ausnahmeblock.

Diese Methode:

def makeDir(): 
    tempDir = random.randrange(111111,999999) 
    subprocess.Popen(["mkdir","/mntDir/"+str(tempDir)]) 
    return tempDir 

gibt eine ganze Zahl , wenn Sie also den Ausnahmeblock Du Fehler erhalten entfernen, weil Sie eine Zeichenfolge mit einer ganzen Zahl sind das Hinzufügen (TypeError: Can't convert 'int' object to str implicitly). Es ist ein einfacher Fehler, den Sie hätten sehen können, wenn er nicht die dumme Ausnahme hätte, die Sie in die Irre führt.

Aber mit dem generischen try/except Block ohne irgendein Argument, erhalten Sie nur mount failed nutzlose Nachricht. nie schützen Sie Ihre Aussagen mit try:/except:, das ist kontraproduktiv.

Wenn Sie wirklich das tun wollen, dies tun:

try: 
    some_command 
except Exception as e: 
    # print detailed exception, not just "error" 
    print("Something went wrong "+str(e)) 

Nun um es zusammenzufassen, ist hier eine feste Version des Codes (mit einigen geringfügigen Verbesserungen als Bonus):

import subprocess,os 
import random 


def makeDir(): 
    # directly create directory name as a string 
    tempDir = "/mntDir/{}".format(random.randrange(111111,999999)) 
    # no need for a subprocess, python handles this well! 
    os.mkdir(tempDir) 
    # returns the absolute directory name, as string 
    return tempDir 

def mountShare(hostname, username, password): 
    mountDir = makeDir() 
    rc = subprocess.call(["mount","-t","cifs", "-o", 
         "username="+username+",password="+password, 
         "//"+hostname+"/c$", 
         mountDir]) 
    if rc!=0: 
     print("Mounting failed") 
+0

Vielen Dank für die Änderungen. Was Sie sagen, macht viel Sinn, danke für den guten Rat! –

0

Die Lösung war nicht, die Freigabe zu mounten, sondern mit smbclient on the fly zu kopieren. Der Befehl Ich verwende bezieht sich auf eine authfile, die ein Konto mit den entsprechenden Berechtigungen in Form enthält:

username = yourUsername 
password = yourPassword 
domain = yourDomain 

Die Berechtigungen für diese Datei werden auf 500

Der smbclient-Befehl wird dann verwendet, um Erstellen Sie ein Verzeichnis auf dem Remote-Computer und kopieren Sie Dateien in dieses Verzeichnis.

smbclient //hostname/c$ -A /authfile -c "mkdir someDir; cd someDir/; lcd /folderToCopyFrom; prompt; recurse; mput *; exit;" 

Vielen Dank für den Rat, sehr hilfreich!

Verwandte Themen