File.Copy : Access Denied

  • Thread starter Thread starter Shailesh Gajare
  • Start date Start date
S

Shailesh Gajare

Hi All,
I have creating an ASP.Net application with two web servers. I am
uploading a file which is being uploaded on one of the server, I want to
copy the uploaded file on the other server at the same time.

It says Access Denied.

I am using File.Copy ( Source , Destination , true ) command in my code,
where
Source : the current physical location of the uploaded file
Destination : the physical location of the other server i.e.
\\IPAddress\SharedFolder
True : To overwrite the file if it exists

I have given rights for everyone on SharedFolder, but still it says Access
denied.

Is it that I have to provide login and pwd in my code.
Is it that I have to NetworkCredential class in my code? if Yes how do I
do.

What is that I am missing?
How do i give rights of ASPNet user of one machine to shared folder of other
machine.

Thanks for your help,
Shailesh Gajare
 
The ASP.NET applications threads don't run as the person logged in. They
usually run another another account that you have configured in your ASP.NET
machine.config file in the <processModel>

So you'll either have to change who is running the ASP.NET thread or
impersonate the current thread as the person who is logged in.

Here's some impersonation code:

using System;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Threading;

namespace Impersonate
{
/// <summary>
/// Summary description for ImpersonateUser.
/// </summary>
public class ImpersonateUser
{

[DllImport("advapi32.dll", SetLastError=true)]
private static extern bool LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);

// constants used by LogonUser() method
private const int LOGON32_LOGON_NETWORK = 3;
private const int LOGON32_PROVIDER_DEFAULT = 0;

private WindowsImpersonationContext wic = null;
private WindowsIdentity currentIdentity = null;

public ImpersonateUser(string login, string password, string domain)
{
// Get current Identity
currentIdentity = WindowsIdentity.GetCurrent();
// handle returned from the LogonUser() method
IntPtr handle = new IntPtr(0);
handle = IntPtr.Zero;
// try to login to the domain
bool logonUser = LogonUser(login, domain, password,
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, ref handle);
// login unsuccessful
if(!logonUser)
{
// get the error
int lastWin32Error = Marshal.GetLastWin32Error();
throw new Exception("ImpersonateUser failed<br>Win32Error: " +
lastWin32Error);
}
// create a new WindowsIdentity, set the CurrentPrincipal and Impersonate
the user
WindowsIdentity wi
= new WindowsIdentity(handle, "NTLM", WindowsAccountType.Normal, true);
Thread.CurrentPrincipal = new WindowsPrincipal(wi);
wic = wi.Impersonate();
// close the handle
CloseHandle(handle);
}

public void Undo()
{
// Impersonate back to original identity
wic.Undo();
Thread.CurrentPrincipal = new WindowsPrincipal(currentIdentity);
currentIdentity.Impersonate();
}

}

}
 
by default, the asp.net account is a local account and cannot access network
shares. change the account to a domain account either up setting the identiy
in the app pool (2003) or in the web config:

<identity impersonate="true" userName="domain\account"
password="password" />

note: to access a network share, you cannot impersonate the autheication
account unless you are using basic or kerberos (with delegation turned on)
authenication.

-- bruce (sqlwork.com)
 
Back
Top