EDN Admin
Well-known member
I have a winforms application and would like to allow the application to open and save files from/to a folder on the network (acting as a document manager). Only one user has access to the folder and I can hard code that users credentials
into the application.
Where using AD on windows server.
How do I allow the application to do this?
I would prefer not to use impersonation but from my research it appear I may have to. I would welcome suggestions for alternative methods. I do have some code for impersonation which seems to work. However I cannot open the file using
process.start I get access denied.
<br/>
<pre lang="x-vbnet <summary>
Implements P/Invoke Interop calls to the operating system.
</summary>
Friend NotInheritable Class NativeMethods
Private Sub New()
End Sub
<summary>
The type of logon operation to perform.
</summary>
Friend Enum LogonType As Integer
<summary>
This logon type is intended for users who will be interactively
using the computer, such as a user being logged on by a
terminal server, remote shell, or similar process.
This logon type has the additional expense of caching logon
information for disconnected operations; therefore, it is
inappropriate for some client/server applications, such as a
mail server.
</summary>
Interactive = 2
<summary>
This logon type is intended for high performance servers to
authenticate plaintext passwords.
The LogonUser function does not cache credentials for this
logon type.
</summary>
Network = 3
<summary>
This logon type is intended for batch servers, where processes
may be executing on behalf of a user without their direct
intervention. This type is also for higher performance servers
that process many plaintext authentication attempts at a time,
such as mail or Web servers.
The LogonUser function does not cache credentials for this
logon type.
</summary>
Batch = 4
<summary>
Indicates a service-type logon. The account provided must have
the service privilege enabled.
</summary>
Service = 5
<summary>
This logon type is for GINA DLLs that log on users who will be
interactively using the computer.
This logon type can generate a unique audit record that shows
when the workstation was unlocked.
</summary>
Unlock = 7
<summary>
This logon type preserves the name and password in the
authentication package, which allows the server to make
connections to other network servers while impersonating the
client. A server can accept plaintext credentials from a
client, call LogonUser, verify that the user can access the
system across the network, and still communicate with other
servers.
NOTE: Windows NT: This value is not supported.
</summary>
NetworkCleartext = 8
<summary>
This logon type allows the caller to clone its current token
and specify new credentials for outbound connections. The new
logon session has the same local identifier but uses different
credentials for other network connections.
NOTE: This logon type is supported only by the
LOGON32_PROVIDER_WINNT50 logon provider.
NOTE: Windows NT: This value is not supported.
</summary>
NewCredentials = 9
End Enum
<summary>
Specifies the logon provider.
</summary>
Friend Enum LogonProvider As Integer
<summary>
Use the standard logon provider for the system.
The default security provider is negotiate, unless you pass
NULL for the domain name and the user name is not in UPN format.
In this case, the default provider is NTLM.
NOTE: Windows 2000/NT: The default security provider is NTLM.
</summary>
[Default] = 0
<summary>
Use this provider if youll be authenticating against a Windows
NT 3.51 domain controller (uses the NT 3.51 logon provider).
</summary>
WinNT35 = 1
<summary>
Use the NTLM logon provider.
</summary>
WinNT40 = 2
<summary>
Use the negotiate logon provider.
</summary>
WinNT50 = 3
End Enum
<summary>
The type of logon operation to perform.
</summary>
Friend Enum SecurityImpersonationLevel As Integer
<summary>
The server process cannot obtain identification information
about the client, and it cannot impersonate the client. It is
defined with no value given, and thus, by ANSI C rules,
defaults to a value of zero.
</summary>
Anonymous = 0
<summary>
The server process can obtain information about the client,
such as security identifiers and privileges, but it cannot
impersonate the client. This is useful for servers that export
their own objects, for example, database products that export
tables and views. Using the retrieved client-security
information, the server can make access-validation decisions
without being able to use other services that are using the
clients security context.
</summary>
Identification = 1
<summary>
The server process can impersonate the clients security
context on its local system. The server cannot impersonate the
client on remote systems.
</summary>
Impersonation = 2
<summary>
The server process can impersonate the clients security
context on remote systems.
NOTE: Windows NT: This impersonation level is not supported.
</summary>
Delegation = 3
End Enum
<summary>
Logs on the user.
</summary>
<param name="userName Name of the user.</param>
<param name="domain The domain.</param>
<param name="password The password.</param>
<param name="logonType Type of the logon.</param>
<param name="logonProvider The logon provider.</param>
<param name="token The token.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function LogonUser(ByVal userName As String, ByVal domain As String, ByVal password As String, ByVal logonType As LogonType, ByVal logonProvider As LogonProvider, ByRef token As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<summary>
Duplicates the token.
</summary>
<param name="existingTokenHandle The existing token
handle.</param>
<param name="securityImpersonationLevel The security impersonation
level.</param>
<param name="duplicateTokenHandle The duplicate token
handle.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function DuplicateToken(ByVal existingTokenHandle As IntPtr, ByVal securityImpersonationLevel As SecurityImpersonationLevel, ByRef duplicateTokenHandle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<summary>
Closes the handle.
</summary>
<param name="handle The handle.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function CloseHandle(ByVal handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
Sub Test()
Dim token As IntPtr
If Not NativeMethods.LogonUser("Username", "Domain", "Password", NativeMethods.LogonType.NewCredentials, NativeMethods.LogonProvider.[Default], token) Then
Throw New System.ComponentModel.Win32Exception()
End If
Try
Dim tokenDuplicate As IntPtr
If Not NativeMethods.DuplicateToken(token, NativeMethods.SecurityImpersonationLevel.Impersonation, tokenDuplicate) Then
Throw New System.ComponentModel.Win32Exception()
End If
Try
Using impersonationContext As System.Security.Principal.WindowsImpersonationContext = New System.Security.Principal.WindowsIdentity(tokenDuplicate).Impersonate()
Do stuff with your share here.
Dim startinfo As New ProcessStartInfo
startinfo.FileName = "\DocumentServerTestFolderTestFile.pdf"
Process.Start(startInfo)
impersonationContext.Undo()
Return
End Using
Finally
If tokenDuplicate <> IntPtr.Zero Then
// Uncomment if you need to know this case.
throw new Win32Exception();
If Not NativeMethods.CloseHandle(tokenDuplicate) Then
End If
End If
End Try
Finally
If token <> IntPtr.Zero Then
// Uncomment if you need to know this case.
throw new Win32Exception();
If Not NativeMethods.CloseHandle(token) Then
End If
End If
End Try
End Sub[/code]
<br/>
View the full article
into the application.
Where using AD on windows server.
How do I allow the application to do this?
I would prefer not to use impersonation but from my research it appear I may have to. I would welcome suggestions for alternative methods. I do have some code for impersonation which seems to work. However I cannot open the file using
process.start I get access denied.
<br/>
<pre lang="x-vbnet <summary>
Implements P/Invoke Interop calls to the operating system.
</summary>
Friend NotInheritable Class NativeMethods
Private Sub New()
End Sub
<summary>
The type of logon operation to perform.
</summary>
Friend Enum LogonType As Integer
<summary>
This logon type is intended for users who will be interactively
using the computer, such as a user being logged on by a
terminal server, remote shell, or similar process.
This logon type has the additional expense of caching logon
information for disconnected operations; therefore, it is
inappropriate for some client/server applications, such as a
mail server.
</summary>
Interactive = 2
<summary>
This logon type is intended for high performance servers to
authenticate plaintext passwords.
The LogonUser function does not cache credentials for this
logon type.
</summary>
Network = 3
<summary>
This logon type is intended for batch servers, where processes
may be executing on behalf of a user without their direct
intervention. This type is also for higher performance servers
that process many plaintext authentication attempts at a time,
such as mail or Web servers.
The LogonUser function does not cache credentials for this
logon type.
</summary>
Batch = 4
<summary>
Indicates a service-type logon. The account provided must have
the service privilege enabled.
</summary>
Service = 5
<summary>
This logon type is for GINA DLLs that log on users who will be
interactively using the computer.
This logon type can generate a unique audit record that shows
when the workstation was unlocked.
</summary>
Unlock = 7
<summary>
This logon type preserves the name and password in the
authentication package, which allows the server to make
connections to other network servers while impersonating the
client. A server can accept plaintext credentials from a
client, call LogonUser, verify that the user can access the
system across the network, and still communicate with other
servers.
NOTE: Windows NT: This value is not supported.
</summary>
NetworkCleartext = 8
<summary>
This logon type allows the caller to clone its current token
and specify new credentials for outbound connections. The new
logon session has the same local identifier but uses different
credentials for other network connections.
NOTE: This logon type is supported only by the
LOGON32_PROVIDER_WINNT50 logon provider.
NOTE: Windows NT: This value is not supported.
</summary>
NewCredentials = 9
End Enum
<summary>
Specifies the logon provider.
</summary>
Friend Enum LogonProvider As Integer
<summary>
Use the standard logon provider for the system.
The default security provider is negotiate, unless you pass
NULL for the domain name and the user name is not in UPN format.
In this case, the default provider is NTLM.
NOTE: Windows 2000/NT: The default security provider is NTLM.
</summary>
[Default] = 0
<summary>
Use this provider if youll be authenticating against a Windows
NT 3.51 domain controller (uses the NT 3.51 logon provider).
</summary>
WinNT35 = 1
<summary>
Use the NTLM logon provider.
</summary>
WinNT40 = 2
<summary>
Use the negotiate logon provider.
</summary>
WinNT50 = 3
End Enum
<summary>
The type of logon operation to perform.
</summary>
Friend Enum SecurityImpersonationLevel As Integer
<summary>
The server process cannot obtain identification information
about the client, and it cannot impersonate the client. It is
defined with no value given, and thus, by ANSI C rules,
defaults to a value of zero.
</summary>
Anonymous = 0
<summary>
The server process can obtain information about the client,
such as security identifiers and privileges, but it cannot
impersonate the client. This is useful for servers that export
their own objects, for example, database products that export
tables and views. Using the retrieved client-security
information, the server can make access-validation decisions
without being able to use other services that are using the
clients security context.
</summary>
Identification = 1
<summary>
The server process can impersonate the clients security
context on its local system. The server cannot impersonate the
client on remote systems.
</summary>
Impersonation = 2
<summary>
The server process can impersonate the clients security
context on remote systems.
NOTE: Windows NT: This impersonation level is not supported.
</summary>
Delegation = 3
End Enum
<summary>
Logs on the user.
</summary>
<param name="userName Name of the user.</param>
<param name="domain The domain.</param>
<param name="password The password.</param>
<param name="logonType Type of the logon.</param>
<param name="logonProvider The logon provider.</param>
<param name="token The token.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function LogonUser(ByVal userName As String, ByVal domain As String, ByVal password As String, ByVal logonType As LogonType, ByVal logonProvider As LogonProvider, ByRef token As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<summary>
Duplicates the token.
</summary>
<param name="existingTokenHandle The existing token
handle.</param>
<param name="securityImpersonationLevel The security impersonation
level.</param>
<param name="duplicateTokenHandle The duplicate token
handle.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function DuplicateToken(ByVal existingTokenHandle As IntPtr, ByVal securityImpersonationLevel As SecurityImpersonationLevel, ByRef duplicateTokenHandle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<summary>
Closes the handle.
</summary>
<param name="handle The handle.</param>
<returns>True if the function succeeds, false if the function fails.
To get extended error information, call GetLastError.</returns>
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Friend Shared Function CloseHandle(ByVal handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
End Class
Sub Test()
Dim token As IntPtr
If Not NativeMethods.LogonUser("Username", "Domain", "Password", NativeMethods.LogonType.NewCredentials, NativeMethods.LogonProvider.[Default], token) Then
Throw New System.ComponentModel.Win32Exception()
End If
Try
Dim tokenDuplicate As IntPtr
If Not NativeMethods.DuplicateToken(token, NativeMethods.SecurityImpersonationLevel.Impersonation, tokenDuplicate) Then
Throw New System.ComponentModel.Win32Exception()
End If
Try
Using impersonationContext As System.Security.Principal.WindowsImpersonationContext = New System.Security.Principal.WindowsIdentity(tokenDuplicate).Impersonate()
Do stuff with your share here.
Dim startinfo As New ProcessStartInfo
startinfo.FileName = "\DocumentServerTestFolderTestFile.pdf"
Process.Start(startInfo)
impersonationContext.Undo()
Return
End Using
Finally
If tokenDuplicate <> IntPtr.Zero Then
// Uncomment if you need to know this case.
throw new Win32Exception();
If Not NativeMethods.CloseHandle(tokenDuplicate) Then
End If
End If
End Try
Finally
If token <> IntPtr.Zero Then
// Uncomment if you need to know this case.
throw new Win32Exception();
If Not NativeMethods.CloseHandle(token) Then
End If
End If
End Try
End Sub[/code]
<br/>
View the full article