Added option to re-authenticate file-based shares.
Thanks to Siyu Wu for making the basic patch.
This commit is contained in:
@@ -29,12 +29,14 @@ namespace Duplicati.Library.Backend
|
||||
private const string OPTION_DESTINATION_MARKER = "alternate-destination-marker";
|
||||
private const string OPTION_ALTERNATE_PATHS = "alternate-target-paths";
|
||||
private const string OPTION_MOVE_FILE = "use-move-for-put";
|
||||
private const string OPTION_FORCE_REAUTH = "force-smb-authentication";
|
||||
|
||||
private string m_path;
|
||||
private string m_username;
|
||||
private string m_password;
|
||||
private bool m_moveFile;
|
||||
private bool m_hasAutenticated;
|
||||
private bool m_forceReauth;
|
||||
|
||||
public File()
|
||||
{
|
||||
@@ -111,6 +113,7 @@ namespace Duplicati.Library.Backend
|
||||
}
|
||||
|
||||
m_moveFile = Utility.Utility.ParseBoolOption(options, OPTION_MOVE_FILE);
|
||||
m_forceReauth = Utility.Utility.ParseBoolOption(options, OPTION_FORCE_REAUTH);
|
||||
m_hasAutenticated = false;
|
||||
}
|
||||
|
||||
@@ -122,7 +125,7 @@ namespace Duplicati.Library.Backend
|
||||
{
|
||||
if (!m_hasAutenticated)
|
||||
{
|
||||
Win32.PreAuthenticate(m_path, m_username, m_password);
|
||||
Win32.PreAuthenticate(m_path, m_username, m_password, m_forceReauth);
|
||||
m_hasAutenticated = true;
|
||||
}
|
||||
}
|
||||
@@ -243,6 +246,7 @@ namespace Duplicati.Library.Backend
|
||||
new CommandLineArgument(OPTION_DESTINATION_MARKER, CommandLineArgument.ArgumentType.String, Strings.FileBackend.AlternateDestinationMarkerShort, string.Format(Strings.FileBackend.AlternateDestinationMarkerLong, OPTION_ALTERNATE_PATHS)),
|
||||
new CommandLineArgument(OPTION_ALTERNATE_PATHS, CommandLineArgument.ArgumentType.Path, Strings.FileBackend.AlternateTargetPathsShort, string.Format(Strings.FileBackend.AlternateTargetPathsLong, OPTION_DESTINATION_MARKER, System.IO.Path.PathSeparator)),
|
||||
new CommandLineArgument(OPTION_MOVE_FILE, CommandLineArgument.ArgumentType.Boolean, Strings.FileBackend.UseMoveForPutShort, Strings.FileBackend.UseMoveForPutLong),
|
||||
new CommandLineArgument(OPTION_FORCE_REAUTH, CommandLineArgument.ArgumentType.Boolean, Strings.FileBackend.ForceReauthShort, Strings.FileBackend.ForceReauthLong),
|
||||
});
|
||||
|
||||
}
|
||||
@@ -283,9 +287,9 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
#endregion
|
||||
|
||||
public static bool PreAuthenticate(string path, string username, string password)
|
||||
public static bool PreAuthenticate(string path, string username, string password, bool forceReauth)
|
||||
{
|
||||
return Win32.PreAuthenticate(path, username, password);
|
||||
return Win32.PreAuthenticate(path, username, password, forceReauth);
|
||||
}
|
||||
|
||||
private System.IO.DriveInfo GetDrive()
|
||||
|
||||
+145
-189
@@ -1,189 +1,145 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Duplicati.Library.Backend.Strings {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class FileBackend {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal FileBackend() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Duplicati.Library.Backend.Strings.FileBackend", typeof(FileBackend).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This option only works when the --{0} option is also specified. If there are alternate paths specified, this option indicates the name of a marker file that must be present in the folder. This can be used to handle situations where an external drive changes drive letter or mount point. By ensuring that a certain file exists, it is possible to prevent writing data to an unwanted external drive. The contents of the file are never examined, only file existence..
|
||||
/// </summary>
|
||||
internal static string AlternateDestinationMarkerLong {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateDestinationMarkerLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Look for a file in the destination folder.
|
||||
/// </summary>
|
||||
internal static string AlternateDestinationMarkerShort {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateDestinationMarkerShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This option allows multiple targets to be specified. The primary target path is placed before the list of paths supplied with this option. Before starting the backup, each folder in the list is checked for existence and optionally the presence of the marker file supplied by --{0}. The first existing path that optionally contains the marker file is then used as the destination. Multiple destinations are separated with a {1},. On Windows, the path may be a UNC path, and the drive letter may be substituted with an asterisk (*), eg.: "*:\backup", which will examine all drive letters. If a username and password is supplied, the same credentials are used for all destinations..
|
||||
/// </summary>
|
||||
internal static string AlternateTargetPathsLong {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateTargetPathsLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A list of secondary target paths.
|
||||
/// </summary>
|
||||
internal static string AlternateTargetPathsShort {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateTargetPathsShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This backend can read and write data to an file based backend. Allowed formats are "file://hostname/folder" or "file://username:password@hostname/folder". You may supply UNC paths (eg: "file://\\server\folder") or local paths (eg: (win) "file://c:\folder", (linux) "file:///usr/pub/files").
|
||||
/// </summary>
|
||||
internal static string Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The password used to connect to the server. This may also be supplied as the environment variable "AUTH_PASSWORD"..
|
||||
/// </summary>
|
||||
internal static string DescriptionAuthPasswordLong {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthPasswordLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supplies the password used to connect to the server.
|
||||
/// </summary>
|
||||
internal static string DescriptionAuthPasswordShort {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthPasswordShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The username used to connect to the server. This may also be supplied as the environment variable "AUTH_USERNAME"..
|
||||
/// </summary>
|
||||
internal static string DescriptionAuthUsernameLong {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthUsernameLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Supplies the username used to connect to the server.
|
||||
/// </summary>
|
||||
internal static string DescriptionAuthUsernameShort {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthUsernameShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to File based.
|
||||
/// </summary>
|
||||
internal static string DisplayName {
|
||||
get {
|
||||
return ResourceManager.GetString("DisplayName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The folder {0} does not exist.
|
||||
/// </summary>
|
||||
internal static string FolderMissingError {
|
||||
get {
|
||||
return ResourceManager.GetString("FolderMissingError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The marker file "{0}" was not found in any of the examined destinations: {1}.
|
||||
/// </summary>
|
||||
internal static string NoDestinationWithMarkerFileError {
|
||||
get {
|
||||
return ResourceManager.GetString("NoDestinationWithMarkerFileError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to When storing the file, the standard operation is to copy the file and delete the original. This sequence ensures that the operation can be retried if something goes wrong. Activating this option may cause the retry operation to fail. This option has no effect unless the --disable-streaming-transfers options is activated..
|
||||
/// </summary>
|
||||
internal static string UseMoveForPutLong {
|
||||
get {
|
||||
return ResourceManager.GetString("UseMoveForPutLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Move the file instead of copying it.
|
||||
/// </summary>
|
||||
internal static string UseMoveForPutShort {
|
||||
get {
|
||||
return ResourceManager.GetString("UseMoveForPutShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------------------
|
||||
// <autogenerated>
|
||||
// This code was generated by a tool.
|
||||
// Mono Runtime Version: 4.0.30319.17020
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </autogenerated>
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
namespace Duplicati.Library.Backend.Strings {
|
||||
using System;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class FileBackend {
|
||||
|
||||
private static System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal FileBackend() {
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.Equals(null, resourceMan)) {
|
||||
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Duplicati.Library.Backend.Strings.FileBackend", typeof(FileBackend).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string DescriptionAuthPasswordShort {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthPasswordShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string DescriptionAuthUsernameShort {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthUsernameShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string ForceReauthLong {
|
||||
get {
|
||||
return ResourceManager.GetString("ForceReauthLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string DescriptionAuthUsernameLong {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthUsernameLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string NoDestinationWithMarkerFileError {
|
||||
get {
|
||||
return ResourceManager.GetString("NoDestinationWithMarkerFileError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string DescriptionAuthPasswordLong {
|
||||
get {
|
||||
return ResourceManager.GetString("DescriptionAuthPasswordLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string ForceReauthShort {
|
||||
get {
|
||||
return ResourceManager.GetString("ForceReauthShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AlternateDestinationMarkerLong {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateDestinationMarkerLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AlternateTargetPathsLong {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateTargetPathsLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string Description {
|
||||
get {
|
||||
return ResourceManager.GetString("Description", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string FolderMissingError {
|
||||
get {
|
||||
return ResourceManager.GetString("FolderMissingError", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AlternateDestinationMarkerShort {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateDestinationMarkerShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string DisplayName {
|
||||
get {
|
||||
return ResourceManager.GetString("DisplayName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string UseMoveForPutLong {
|
||||
get {
|
||||
return ResourceManager.GetString("UseMoveForPutLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string UseMoveForPutShort {
|
||||
get {
|
||||
return ResourceManager.GetString("UseMoveForPutShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
internal static string AlternateTargetPathsShort {
|
||||
get {
|
||||
return ResourceManager.GetString("AlternateTargetPathsShort", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,4 +159,10 @@
|
||||
<data name="UseMoveForPutShort" xml:space="preserve">
|
||||
<value>Move the file instead of copying it</value>
|
||||
</data>
|
||||
<data name="ForceReauthShort" xml:space="preserve">
|
||||
<value>Force authentication against remote share</value>
|
||||
</data>
|
||||
<data name="ForceReauthLong" xml:space="preserve">
|
||||
<value>If this option is set, any existing authentication against the remote share is dropped before attempting to authenticate</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -30,6 +30,9 @@ namespace Duplicati.Library.Backend
|
||||
private static extern int WNetAddConnection2(ref NETRESOURCE netResource,
|
||||
string password, string username, int flags);
|
||||
|
||||
[DllImport("mpr.dll")]
|
||||
public static extern int WNetCancelConnection2(string sharename, int dwFlags, int fForce);
|
||||
|
||||
private struct NETRESOURCE
|
||||
{
|
||||
public ResourceScope dwScope;
|
||||
@@ -87,7 +90,7 @@ namespace Duplicati.Library.Backend
|
||||
|
||||
private const int CONNECT_UPDATE_PROFILE = 0x1;
|
||||
|
||||
internal static bool PreAuthenticate(string path, string username, string password)
|
||||
internal static bool PreAuthenticate(string path, string username, string password, bool forceReauth)
|
||||
{
|
||||
//Strip it down from \\server\share\folder1\folder2\filename.extension to
|
||||
// \\server\share
|
||||
@@ -115,7 +118,13 @@ namespace Duplicati.Library.Backend
|
||||
rsc.LocalName = null;
|
||||
rsc.RemoteName = minpath;
|
||||
|
||||
return WNetAddConnection2(ref rsc, password, username, CONNECT_UPDATE_PROFILE) == 0;
|
||||
// Forces close an existing network connection
|
||||
if (forceReauth)
|
||||
WNetCancelConnection2(minpath, CONNECT_UPDATE_PROFILE, 1);
|
||||
|
||||
int retCode = WNetAddConnection2(ref rsc, password, username, CONNECT_UPDATE_PROFILE);
|
||||
|
||||
return retCode == 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user