diff --git a/src/driver/index.js b/src/driver/index.js index 84d5cc7..a1db307 100644 --- a/src/driver/index.js +++ b/src/driver/index.js @@ -1300,6 +1300,7 @@ class CsiBaseDriver { filesystem.covertUnixSeparatorToWindowsSeparator(device) ); if (!result) { + // check for mount option cache=none and set -UseWriteThrough $true await wutils.NewSmbGlobalMapping( filesystem.covertUnixSeparatorToWindowsSeparator(device), `${volume_context.server}\\${username}`, @@ -2290,11 +2291,16 @@ class CsiBaseDriver { switch (node_attach_driver) { case "smb": + // remove symlink *before* disconnecting + await removePath(win_normalized_staging_path); let parts = target.split("\\"); - await wutils.RemoveSmbGlobalMapping( - `\\\\${parts[1]}\\${parts[2]}` - ); - + // only remove global mapping if we certain there may not be other + // consumers of the mapping/share (ie: smb-client scenarios, etc) + if (!parts[3]) { + await wutils.RemoveSmbGlobalMapping( + `\\\\${parts[1]}\\${parts[2]}` + ); + } break; case "iscsi": // write volume cache diff --git a/src/utils/windows.js b/src/utils/windows.js index 7b591c3..90a530d 100644 --- a/src/utils/windows.js +++ b/src/utils/windows.js @@ -41,6 +41,20 @@ class Windows { } } + uncPathToShare(path) { + // UNC\\[\\] + if (path.startsWith("UNC")) { + path = path.replace("UNC", "\\"); + } + + if (!path.startsWith("\\\\")) { + path = `\\\\${path}`; + } + + let parts = path.split("\\"); + return `\\\\${parts[2]}\\${parts[3]}`; + } + async GetRealTarget(path) { let item; let target; @@ -77,6 +91,9 @@ class Windows { async GetSmbGlobalMapping(remotePath) { let command; + // cannot have trailing slash nor a path + // must be \\\ + remotePath = this.uncPathToShare(remotePath); command = "Get-SmbGlobalMapping -RemotePath $Env:smbremotepath | ConvertTo-Json"; try { @@ -88,23 +105,41 @@ class Windows { } catch (err) {} } + /** + * Global in this context is allowed access by all users + * + * @param {*} remotePath + * @param {*} username + * @param {*} password + */ async NewSmbGlobalMapping(remotePath, username, password) { + let result; let command; + // -UseWriteThrough $true + // cannot have trailing slash nor a path + // must be \\\ + remotePath = this.uncPathToShare(remotePath); command = "$PWord = ConvertTo-SecureString -String $Env:smbpassword -AsPlainText -Force;$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Env:smbuser, $PWord;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential -RequirePrivacy $true"; - await this.ps.exec(command, { - env: { - smbuser: username, - smbpassword: password, - smbremotepath: remotePath, - }, - }); + result = await this.GetSmbGlobalMapping(remotePath); + if (!result) { + await this.ps.exec(command, { + env: { + smbuser: username, + smbpassword: password, + smbremotepath: remotePath, + }, + }); + } } async RemoveSmbGlobalMapping(remotePath) { let result; let command; + // cannot have trailing slash nor a path + // must be \\\ + remotePath = this.uncPathToShare(remotePath); command = "Remove-SmbGlobalMapping -RemotePath $Env:smbremotepath -Force"; do { @@ -121,6 +156,8 @@ class Windows { async NewSmbLink(remotePath, localPath) { let command; + // trailing slash required + // may include subdirectories on the share if desired if (!remotePath.endsWith("\\")) { remotePath = `${remotePath}\\`; }