@@ -8,6 +8,10 @@ import (
88 "github.com/kubernetes-csi/csi-proxy/pkg/utils"
99)
1010
11+ const (
12+ credentialDelimiter = ":"
13+ )
14+
1115type API interface {
1216 IsSmbMapped (remotePath string ) (bool , error )
1317 NewSmbLink (remotePath , localPath string ) error
@@ -31,6 +35,13 @@ func remotePathForQuery(remotePath string) string {
3135 return strings .ReplaceAll (remotePath , "\\ " , "\\ \\ " )
3236}
3337
38+ func escapeUserName (userName string ) string {
39+ // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L169-L170
40+ escaped := strings .ReplaceAll (userName , "\\ " , "\\ \\ " )
41+ escaped = strings .ReplaceAll (escaped , credentialDelimiter , "\\ " + credentialDelimiter )
42+ return escaped
43+ }
44+
3445func (* SmbAPI ) IsSmbMapped (remotePath string ) (bool , error ) {
3546 inst , err := cim .QuerySmbGlobalMappingByRemotePath (remotePathForQuery (remotePath ))
3647 if err != nil {
@@ -69,32 +80,22 @@ func (*SmbAPI) NewSmbLink(remotePath, localPath string) error {
6980}
7081
7182func (api * SmbAPI ) NewSmbGlobalMapping (remotePath , username , password string ) error {
72- // use PowerShell Environment Variables to store user input string to prevent command line injection
73- // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables?view=powershell-5.1
74- cmdLine := fmt .Sprintf (`$PWord = ConvertTo-SecureString -String $Env:smbpassword -AsPlainText -Force` +
75- `;$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Env:smbuser, $PWord` +
76- `;New-SmbGlobalMapping -RemotePath $Env:smbremotepath -Credential $Credential -RequirePrivacy $%t` , api .RequirePrivacy )
77-
78- if output , err := utils .RunPowershellCmd (cmdLine ,
79- fmt .Sprintf ("smbuser=%s" , username ),
80- fmt .Sprintf ("smbpassword=%s" , password ),
81- fmt .Sprintf ("smbremotepath=%s" , remotePath )); err != nil {
82- return fmt .Errorf ("NewSmbGlobalMapping failed. output: %q, err: %v" , string (output ), err )
83+ params := map [string ]interface {}{
84+ "RemotePath" : remotePath ,
85+ "RequirePrivacy" : api .RequirePrivacy ,
86+ }
87+ if username != "" {
88+ // refer to https://github.com/PowerShell/PowerShell/blob/9303de597da55963a6e26a8fe164d0b256ca3d4d/src/Microsoft.PowerShell.Commands.Management/cimSupport/cmdletization/cim/cimConverter.cs#L166-L178
89+ // on how SMB credential is handled in PowerShell
90+ params ["Credential" ] = escapeUserName (username ) + credentialDelimiter + password
8391 }
92+
93+ result , _ , err := cim .InvokeCimMethod (cim .WMINamespaceSmb , "MSFT_SmbGlobalMapping" , "Create" , params )
94+ if err != nil {
95+ return fmt .Errorf ("NewSmbGlobalMapping failed. result: %d, err: %v" , result , err )
96+ }
97+
8498 return nil
85- //TODO: move to use WMI when the credentials could be correctly handled
86- //params := map[string]interface{}{
87- // "RemotePath": remotePath,
88- // "RequirePrivacy": api.RequirePrivacy,
89- //}
90- //if username != "" {
91- // params["Credential"] = fmt.Sprintf("%s:%s", username, password)
92- //}
93- //result, _, err := cim.InvokeCimMethod(cim.WMINamespaceSmb, "MSFT_SmbGlobalMapping", "Create", params)
94- //if err != nil {
95- // return fmt.Errorf("NewSmbGlobalMapping failed. result: %d, err: %v", result, err)
96- //}
97- //return nil
9899}
99100
100101func (* SmbAPI ) RemoveSmbGlobalMapping (remotePath string ) error {
0 commit comments