1

After reading tons of similar posts I decided to came up with this one. Well, basically this problem is similar to many others, but somehow I can't make it work.

Here's the scenario, I have load balancing over 2 servers (servA and servB) and I need to force the app to create just on 1 of them. So I want to put the UNC path when I save files. I, obviously, have a problem creating files on the directory over the net.

If I run it with Cassini it's all good, I can access to the path cause it's logged with my account. As soon as I migrate the app on the development server it doesn't work anymore. I know IIS uses the user associated with the app pool, so I checked that account (which is network_service) and added write privileges write on that folder.
Still not enough. What you think on "Everyone"?! It must work!
Oh, well, it's not.

Let's see some code:
Directory.CreateDirectory("\\\\my.ip.over.da.net\\c$\\inetpub\\wwwroot\\projfolder\\otherprojfolder\\test");

And this is the message I got when I try to create that folder.

{"Message":"Access to the path \u0027\\\\\\\\my.ip.over.da.net\\\\c$\\\\inetpub
\\\\wwwroot\\\\projfolder\\\\otherprojfolder\\\\test\u0027 is denied.","StackTrace":" 
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at 
System.IO.Directory.InternalCreateDirectory(String fullPath, String path, 
DirectorySecurity dirSecurity)\r\n at System.IO.Directory.CreateDirectory(String path, 
DirectorySecurity directorySecurity)\r\n at 
NSC.Ajax.GetData.testgrid()","ExceptionType":"System.UnauthorizedAccessException"}

It's called via AJAX for easier testing, this is why the response is formatted that way.

Johan
  • 74,508
  • 24
  • 191
  • 319
Sballerio
  • 21
  • 1
  • 1
  • 7

2 Answers2

2

The problem is you're not going to have access to that location using the IIS credentials, the dev server is going to be on a separate domain somewhere else, and accessing back to your machine going to the c$ admin share isn't going to work, changing permissions at that level is.. a bit risky...

If you really have to access files on your local machine from your dev server, you'd probably be better off creating a share called test (C:\inetpub\wwwroot\projfolder\otherprojfolder\test) on your machine and set the permissions on this for Everyone to read (if you're going to need to create files and folders you'll need more, but I'd suggest only giving the minimum access you can get away with), pretty insecure though, but since your dev machine won't have any way of authenticating an account on a different network (your machine you're sharing the files from) you don't have much to play with!

So create a local shared folder, then just point your code to \\\\my.ip.over.da.net\\test.

Note, you'll need to set the permissions on the share and on the folder itself, if the share has enough permissions but the ACL on the folder doesn't agree you'll still get permissions denied.

Daniel Morritt
  • 1,787
  • 17
  • 25
  • Thanks Daniel, I tried this too but i had the same access denied problem. I'm gonna retry it just right now, cause it's impossible nothing is working. I edited the question cause I don't need to access files on my pc, and this is what come out of the question. I'll let you know how it's going :D. – Sballerio Dec 20 '11 at 16:44
  • Ok, i tried mapping the path to a unit, and it's not working. If i'm right the problem is that when you create the share, it is only visible to the user who created the share. Said that it means that the application user cannot access the share, hence the following error msg--> {"Message":"Could not find a part of the path \u0027Y:\\otherprojfolder\\test\u0027.","StackTrace":" at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at [...] at NSC.Ajax.GetData.testgrid()","ExceptionType":"System.IO.DirectoryNotFoundException"} – Sballerio Dec 20 '11 at 16:58
  • If you create the share, go into the permissions for the share and update the permissions, if you're on Windows 7 then you'll need to go into "Advanced Sharing" I think. You will probably need to change the ACL's for the Windows permissions as well as the permissions on the share itself. – Daniel Morritt Dec 20 '11 at 17:03
  • I'm editing the owner tab, it's applying changes atm. let's see =) – Sballerio Dec 20 '11 at 17:11
  • Modified, i made network_service like jesus christ in that share. Still got da message =(. Gonna debug a bit which logical drives are mapped. – Sballerio Dec 20 '11 at 17:18
  • And mapped Drives are A:\ , C:\ , D:\ , S:\ , Z:\. There's no Y:\ in the listing From Directory.GetLogicalDrives() – Sballerio Dec 20 '11 at 17:21
  • Tried using System.Diagnostics.Process.Start("net.exe", @"USE Y: \\\\my.ip.over.da.net\\c$\\inetpub\\wwwroot\\Projfolder").WaitForExit(); but it doesn't work and Directory.GetLogicalDrives() returns the same as before. – Sballerio Dec 20 '11 at 17:42
  • Well Daniel, i wasted your time. Your first reply was the good one. I realized I was not doing what you said. I mapped the folder to a logical unit... that's not a share! So i did what you said and it worked as expected. Thanks Daniel, good job! – Sballerio Dec 21 '11 at 11:17
  • Ahh that would be because you map a drive as "you", services etc can't see it, good to hear it worked :) – Daniel Morritt Dec 21 '11 at 14:00
0

You can impersonate a different user when creating the directory

public static void CreateDirectory(string myDirectory)
    {
        SafeTokenHandle safeTokenHandle;

        bool returnValue = LogonUser(@Username, @Domain, @Password, 2, 0, out safeTokenHandle);

        if (returnValue == true)
        {
            WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
            using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
            {
                System.IO.Directory.CreateDirectory(myDirectory);
            }
        }
    }
    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
        int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true)
        {
        }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}

More details here : http://msdn.microsoft.com/en-us/library/system.security.principal.windowsimpersonationcontext.aspx

msmucker0527
  • 5,164
  • 2
  • 22
  • 36
  • Thanks msmucker, but I already tried it, it's not working either. Still i think this should not be the solution, i mean, why should i logon with a right user instead of correcting the wrong one? Plus i got no user in production environment with that role. I mean i should create one. – Sballerio Dec 20 '11 at 16:22