Some background: We currently receive files from multiple data-vendors on a FTP server hosted by our hosting partner. As part of a new project we are setting up an Azure Function. This function runs in a ressource-group that our hosting partner has set up for VPN/private network access. This function is the first step in a process of replacing multiple legacy programs in Excel/VBA with Azure functions.
What we need is to move files from the FTP server to another internal (file-)server (to support some of the legacy programs). The FTP server is in DMZ and therefore not part of the domain like the file-server.
Now I have googled around for hours finding a solution and believe I have found it using https://stackoverflow.com/a/295703/998791 and https://stackoverflow.com/a/1197430/998791
public sealed class NetworkConnection : IDisposable
{
private string _uncShare;
public NetworkConnection(string uncShare, NetworkCredential credentials)
{
var nr = new Native.NETRESOURCE
{
dwType = Native.RESOURCETYPE_DISK,
lpRemoteName = uncShare
};
var userName = string.IsNullOrEmpty(credentials.Domain) ? credentials.UserName : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);
int result = Native.WNetUseConnection(IntPtr.Zero, nr, credentials.Password, userName, 0, null, null, null);
if (result != Native.NO_ERROR)
{
throw new Win32Exception(result);
}
_uncShare = uncShare;
}
public void Dispose()
{
if (!string.IsNullOrEmpty(_uncShare))
{
Native.WNetCancelConnection2(_uncShare, Native.CONNECT_UPDATE_PROFILE, false);
_uncShare = null;
}
}
private class Native
{
public const int RESOURCETYPE_DISK = 0x00000001;
public const int CONNECT_UPDATE_PROFILE = 0x00000001;
public const int NO_ERROR = 0;
[DllImport("mpr.dll")]
public static extern int WNetUseConnection(IntPtr hwndOwner, NETRESOURCE lpNetResource, string lpPassword, string lpUserID,
int dwFlags, string lpAccessName, string lpBufferSize, string lpResult);
[DllImport("mpr.dll")]
public static extern int WNetCancelConnection2(string lpName, int dwFlags, bool fForce);
[StructLayout(LayoutKind.Sequential)]
public class NETRESOURCE
{
public int dwScope = 0;
public int dwType = 0;
public int dwDisplayType = 0;
public int dwUsage = 0;
public string lpLocalName = "";
public string lpRemoteName = "";
public string lpComment = "";
public string lpProvider = "";
}
}
}
Usage:
using (new NetworkConnection(ftpServerSettings.UNCPath, new NetworkCredential(ftpServerSettings.UserName, ftpServerSettings.Password, ftpServerSettings.Domain)))
{
using (new NetworkConnection(fileServerSettings.UNCPath, new NetworkCredential(fileServerSettings.UserName, fileServerSettings.Password, fileServerSettings.Domain)))
{
handler.HandleFolders(bankDataRepository.GetFolderSettings());
}
}
When running this locally it works fine, but running from Azure I get a System.ComponentModel.Win32Exception with the message "Access denied".
I'm not sure wether DllImport is allowed in Azure Functions, if I need FullTrust (I saw something about this somwhere) or if the problem is with the permissions on the server.
Can someone please enlighten me?