File.Copy() problem

  • Thread starter Thread starter Code Monkey
  • Start date Start date
C

Code Monkey

I've written a windows service in C#.

The service copies certain files using a FileSystemWatcher.

However, where it copies the files to is a windows share (\\ipaddress
\sharename).

If I set the service up and run it as a user who has access to this
share -

Services > Service Name > Log On As etc,etc

it copies the files.

If I leave the default settings, the copy does not take place.

How do I impersonate a user who has access to the network share from
with in the service?
 
Code said:
I've written a windows service in C#.

The service copies certain files using a FileSystemWatcher.

However, where it copies the files to is a windows share (\\ipaddress
\sharename).

If I set the service up and run it as a user who has access to this
share -

Services > Service Name > Log On As etc,etc

it copies the files.

If I leave the default settings, the copy does not take place.

How do I impersonate a user who has access to the network share from
with in the service?

Why do you want to? You can just run the service under its own account,
which has exactly the permissions it needs. This is the most secure setup.

Alternatively, run the service under "Network service" credentials and give
the local machine account the service runs on (<MACHINENAME>$) permissions
on the share.

Impersonation is quite annoying in .NET, and you don't want to bother with
it unless there's a solid reason. You don't need to go that route just to be
able to access a share.
 
Code Monkey said:
How do I impersonate a user who has access to the network share from
with in the service?

Without knowing who the user is in advance (otherwise you could just have
the service run under their account)?

There are likely several approaches and I would try them in this order:

(1)Change your process' token and give yourself more privileges:

[DllImport( "advapi32.dll", EntryPoint = "AdjustTokenPrivileges",
SetLastError = true )]
public static extern bool AdjustTokenPrivileges( IntPtr in_hToken,
[MarshalAs( UnmanagedType.Bool )]bool DisableAllPrivileges, ref
TOKEN_PRIVILEGES NewState, UInt32 BufferLength, IntPtr PreviousState, IntPtr
ReturnLength );

[DllImport( "advapi32.dll", EntryPoint = "OpenProcessToken", SetLastError
= true )]
public static extern bool OpenProcessToken( IntPtr ProcessHandle, UInt32
DesiredAccess, out IntPtr TokenHandle );

[DllImport( "advapi32.dll", EntryPoint = "LookupPrivilegeValue",
SetLastError = true, CharSet = CharSet.Auto )]
public static extern bool LookupPrivilegeValue( string lpSystemName,
string lpName, out LUID lpLuid );

[StructLayout( LayoutKind.Sequential )]
public struct LUID
{
public uint m_nLowPart;
public uint m_nHighPart;
}

/*
If you need to give yourself permissions to inspect processes for their
modules,
and create tokens without worrying about what account you're running under,
this is the method for you :) (such as the token privilege
"SeDebugPrivilege")
*/
static public bool AdjustProcessTokenPrivileges( IntPtr in_ptrProcessHandle,
string in_strTokenToEnable )
{
IntPtr l_hProcess = IntPtr.Zero;
IntPtr l_hToken = IntPtr.Zero;
LUID l_oRestoreLUID;
TOKEN_PRIVILEGES l_oTokenPrivileges;

Debug.Assert( in_ptrProcessHandle != IntPtr.Zero );

//Get the process security token
if( false == OpenProcessToken( in_ptrProcessHandle, TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY, out l_hToken ) )
{
return false;
}

//Lookup the LUID for the privilege we need
if( false == LookupPrivilegeValue( String.Empty, in_strTokenToEnable, out
l_oRestoreLUID ) )
{
return false;
}

//Adjust the privileges of the current process to include the new privilege
l_oTokenPrivileges.m_nPrivilegeCount = 1;
l_oTokenPrivileges.m_oLUID = l_oRestoreLUID;
l_oTokenPrivileges.m_nAttributes = SE_PRIVILEGE_ENABLED;

if( false == AdjustTokenPrivileges( l_hToken, false, ref
l_oTokenPrivileges, 0, IntPtr.Zero, IntPtr.Zero ) )
{
return false;
}

return true;
}

(2)Spawn another process to do it (ugly but effective) and use impersonation
on the process. Doing this from a service can be problematic, but I blogged
about it when I ran into a similar problem recently (and I posted what I
hope is a very helpful and complete class for spawning processes from a
service on Vista and earlier systems [and allowing for UI interaction on the
logged in user's desktop].)
http://18and5.blogspot.com/2008/01/i-hope-my-frustration-can-help-someone.html

(3)Try to adjust your process' DACL and (if on Vista) SACL - but that's
hairier.

(4)The rest of the approaches that spring to mind are even uglier than #3.

Good luck, hope #1 works for you.

WTH:)
 
Code Monkey said:
I've written a windows service in C#.

The service copies certain files using a FileSystemWatcher.

However, where it copies the files to is a windows share (\\ipaddress
\sharename).

If I set the service up and run it as a user who has access to this
share -

Services > Service Name > Log On As etc,etc

it copies the files.

If I leave the default settings, the copy does not take place.

How do I impersonate a user who has access to the network share from
with in the service?



Do as Jeroen suggest, run your service in the account that has access to the
share. Stay away from Impersonation whenever you can.

Willy.
 
I used another way, not a M$ computer connecting, using FTPand then it
all works.. tried samba, nfs and a lot of other but ftp seems to work
best.. rather that than writing something of my own,,,
//CY
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top