locked
Can't get User Impersonation to work with network drive RRS feed

  • Question

  • Ok I'm trying to get the following to work with VS 2010 & Win 2K8 Server:
     
    http://www.codeproject.com/KB/system/UserImpersonation.aspx?fid=475719&df=10000&mpp=10&sort=None&noise=4&prof=False&view=Thread&fr=1
     
    If I try a local folder it works fine, but when I choose a network mapped drive I get the following:
    Result:
        Failed to open the file, error: 3
        The system cannot find the path specified.

     
    The reason I'm trying to get this to work is we are working on implementing security for our network (There's an idea huh), and our senior programmer likes to have everything is one big giant directory so we are trying to restrict user access to certain folders, but by doing so our applications won't work. So we would like to give the application the "rights to do so" and this seems like the best way, but I can't get it to work on mapped drives.

    I've tried differnt choices instead of "LOGON32_LOGON_INTERACTIVE" in the LogonUser portion and still no luck.

    Or is there another way we can give the application rights vs the current users right (i.e. one of the administrators).  This is also being done in a terminal services enviroment, not sure if that matters.

    I'm still fairly new to C++ programming so I'll do my best to answer any questions, anything I can't I'll pass along to our senior guy.
    Thanks in advance!!

    Thursday, September 1, 2011 2:47 PM

Answers

  • Well, I guess you'll have to deal with it, so:  Use impersonation + full UNC paths or hire a MCSE to set up a secured and correct Active Directory network.
    MCP
    • Marked as answer by temlehdrol Tuesday, September 6, 2011 10:53 AM
    Friday, September 2, 2011 7:46 PM

All replies

  • It sounds like a bad idea, although I haven't enough knowledge on your set up to actually be sure.

    Regarding your problem, I think the issue here is that the folder has been mapped with a particular username.  When you impersonate (I assume this is what you are doing) the mapped drive is probably not there anymore.  You should try to access the network path using the network UNC path instead of the mapped drive letter.

    Still, I don't know if it will be enough for you to solve the issue because your security setup seem to be a very bad one.  But then again, I stress the fact that I don't really know this for sure.


    MCP
    Thursday, September 1, 2011 3:21 PM
  • On our current network everyone has access to everything (bad idea), so we are trying to get it so users don't have access to certain folders (on our new system/network).  The only problem is the application will still need access to those folders and contents.

    I'll try the UNC path like you mention.

    Thursday, September 1, 2011 3:25 PM
  • If I use the UNC path (realized that I forgot to take the ':' out after the $ when I first did it) it does work (good news and bad news).  The drive is mapped as an administrative share, not really sure about any particular user name though.  I have already gotten a lot of grumbling about having to change everything over to UNC paths.

    If you can think of or suggest a better way of doing this I'm open to suggestions.

    Thursday, September 1, 2011 4:01 PM
  • I'd temporarily map a drive using WNetAddConnection2() or WNetAddConnection3() using the required credentials and therefore avoiding the need to impersonate.  Check it out.
    MCP
    Thursday, September 1, 2011 4:05 PM
  • Ok this one will probably take a bit, I'll get back to you on that... Thanks!!
    Thursday, September 1, 2011 4:34 PM
  • I'm guessing you are talking about something like this article? http://msdn.microsoft.com/en-us/library/aa385327(v=vs.85).aspx

    however I get 4 errors similar to this: Error 4 error C2440: 'initializing' : cannot convert from 'const char [27]' to 'TCHAR [260]' 

    in this section:

    TCHAR szUserName[32] = "MyUserName",
      szPassword[32] = "MyPassword",
      szLocalName[32] = "Q:",
      szRemoteName[MAX_PATH] = "\\\\products2\\relsys";
    
    


    I'm also not really sure what it means where it says: Link the library MPR.LIB to the compiler list of libraries

    I'll ask our other programmer about the linking part while I have a few min.

    Thursday, September 1, 2011 5:52 PM
  • It is not a good thing to specify the length of the char array if you initialize it with a string literal.  Because the NETRESOURCE structure uses LPTSTR instead of LPCTSTR, you cannot directly assign the string literals to the members of the structure (the compiler should complain because literals are const and LPTSTR is not const).  So just copy the literals into your buffers:

     

    const TCHAR c_userName = TEXT("MyUserName");
    const TCHAR c_password = TEXT("MyPassword");
    const TCHAR c_localName = TEXT("Q:");
    const TCHAR c_remoteName = TEXT("\\\\products2\\relsys");
    
    void CopyString(LPTSTR dest, LPCTSTR source, size_t buffSize, size_t sourceSize)
    {
     _tcsncpy(dest, source, min(buffSize, sourceSize));
     dest[buffSize - 1] = TEXT('\0');
    }
    
    ...
    
    TCHAR szUsername[32];
    TCHAR szPassword[32];
    TCHAR szLocalName[3];
    TCHAR szRemoteName[MAX_PATH];
    
    CopyString(szUsername, c_userName, _countof(szUsername), _tcslen(c_userName));
    CopyString(szPassword, c_password, _countof(szPassword), _tcslen(c_password));
    CopyString(szLocalName, c_localName, _countof(szLocalName), _tcslen(c_localName));
    CopyString(szRemoteName, c_remoteName, _countof(szRemoteName), _tcslen(c_remoteName));
    

     


    Note that CopyString() could be converted to a templated function so you don't have to pass around the sizes of fixed buffers such as the above ones.

    Also note that I have used _tcsncpy() because I prefer this method over the Microsoft-specific _s() functions (you'll see what I mean in the warnings you'll get) in order to keep the code portable between C++ compilers.  It is up to you to change that copy function to the _s() function if you like.  The code inside CopyString() should provide the same level of security, though.

    Also note that all string literals are enclosed by the TEXT() macro.  This is a MUST when working with TCHAR and related data types like LPTSTR.  If you want to use ANSI strings, then use char and not TCHAR, and explicitly use the "A" versions of the structs and functions, such as NETRESOURCEA and WNetAddConnection2A().


    MCP
    Thursday, September 1, 2011 6:49 PM
  • Ok, that's a bit above me so I'll pass this along. we did however make the change to be:

    TCHAR szUserName[32] = _T(

    "user"), szPassword[32] = _T("password"), szLocalName[32] = _T("G:"), szRemoteName[MAX_PATH] = _T(\\\\server\\D$\\Test);

    and that got rid of the errors, which I believe is pretty close to what you were doing?  However I'm getting a Error: 85 of which I need to look up

    Thursday, September 1, 2011 7:11 PM
  • Ok after doing more reading it appears this method won't work as you aren't allowed more than one connection at a time to a network resource.  Don't remember the exact working but basically you can't access the same share drive twice.
    Friday, September 2, 2011 1:18 PM
  • Ah, ok.  Yes.  It is because how Kerberos works.  You have one ticket per service, in this case you have a kerberos ticket to cifs\servername under the username that connected first to the drive.  If you would be willing to, you could disconnect the current mapping, then clear the tickets (I know the command-line tool klist can purge the tickets) and then connecting with the new credentials, then remove the the mapping and recreate the original one under the context of the logged on user.

    But in all honesty, I would rather just use full UNC paths OR:  I would do security the right way, which is granting correct access rights to the correct people.  If this person running this piece of software needs to access the data in a shared location, just grant access to them.  Why is that you need some covert account to do this?  Note that by using a generic ID you lose the ability to audit changes as you won't know who really did what.  All changes will be under the application account, so there goes accountability.


    MCP
    Friday, September 2, 2011 5:03 PM
  • It's because it's not just the files they are using in that directory, just about everything under the sun is located in there (again I didn't set this up I just have to deal with it).  It would be nice if i could just block them from deleting files, but that doesn't work because the applicaiton needs to delete files in some instances.  It's basically a total nightmare and the only responses I get is "we tried security 10 years ago and that stuff doesn't work", or "No one uses that stuff because it doesn't work".
    Friday, September 2, 2011 5:41 PM
  • Well, I guess you'll have to deal with it, so:  Use impersonation + full UNC paths or hire a MCSE to set up a secured and correct Active Directory network.
    MCP
    • Marked as answer by temlehdrol Tuesday, September 6, 2011 10:53 AM
    Friday, September 2, 2011 7:46 PM
  • I'll pass along your suggestion though I can tell you it's not going to get very far, but I'll keep fighting the good fight in trying to do things "right".  Thanks for your help.
    Tuesday, September 6, 2011 10:53 AM