@@ -155,20 +155,43 @@ public static LsaInterop Connect(string package = KerberosPackageName)
155155 /// <param name="realm">The default realm to be used by LSA for the any outbound ticket requests not already cached.</param>
156156 public unsafe void LogonUser ( string username = null , string password = null , string realm = null )
157157 {
158- if ( username == null )
159- {
160- username = DefaultUserName ;
161- }
158+ username ??= DefaultUserName ;
162159
163- if ( password = = null )
160+ if ( this . impersonationContext ! = null )
164161 {
165- password = string . Empty ;
162+ this . impersonationContext . Dispose ( ) ;
163+ this . impersonationContext = null ;
166164 }
167165
168- if ( realm == null )
169- {
170- realm = string . Empty ;
171- }
166+ this . impersonationContext = this . LogonUser ( username , password , realm , LogonType . NewCredentials ) ;
167+
168+
169+ // this call to impersonate will set the current thread token to be the token out of LsaLogonUser
170+ // do we need to do anything special if this gets used within an async context?
171+
172+ this . impersonationContext . Impersonate ( ) ;
173+ }
174+
175+ /// <summary>
176+ /// Create a logon session for the current LSA Handle.
177+ /// </summary>
178+ /// <param name="username">The username to be used.
179+ /// Passing an empty string will cause LSA to treat this as an anonymous user.</param>
180+ /// <param name="password">The password to be used by LSA for any future outbound ticket requests not already cached.</param>
181+ /// <param name="realm">The default realm to be used by LSA for the any outbound ticket requests not already cached.</param>
182+ /// <param name="logonType">The type of logon session to create</param>
183+ public unsafe LsaTokenSafeHandle LogonUser (
184+ string username ,
185+ string password ,
186+ string realm ,
187+ LogonType logonType
188+ )
189+ {
190+ username ??= string . Empty ;
191+
192+ password ??= string . Empty ;
193+
194+ realm ??= string . Empty ;
172195
173196 var originName = new LSA_STRING
174197 {
@@ -182,12 +205,7 @@ public unsafe void LogonUser(string username = null, string password = null, str
182205 ( username . Length * 2 ) +
183206 ( password . Length * 2 ) ;
184207
185- if ( this . impersonationContext != null )
186- {
187- this . impersonationContext . Dispose ( ) ;
188- this . impersonationContext = null ;
189- }
190-
208+ LsaTokenSafeHandle tokenHandle = null ;
191209 LsaBufferSafeHandle profileBuffer = null ;
192210
193211 WithFixedBuffer ( bufferSize , ( p , _ ) =>
@@ -211,7 +229,7 @@ public unsafe void LogonUser(string username = null, string password = null, str
211229 int result = LsaLogonUser (
212230 this . lsaHandle ,
213231 ref originName ,
214- SECURITY_LOGON_TYPE . NewCredentials ,
232+ logonType ,
215233 this . negotiateAuthPackage ,
216234 pLogon ,
217235 bufferSize ,
@@ -220,7 +238,7 @@ public unsafe void LogonUser(string username = null, string password = null, str
220238 out profileBuffer ,
221239 ref profileLength ,
222240 out this . luid ,
223- out this . impersonationContext ,
241+ out tokenHandle ,
224242 out IntPtr pQuotas ,
225243 out int subStatus
226244 ) ;
@@ -233,10 +251,7 @@ out int subStatus
233251 }
234252 } ) ;
235253
236- // this call to impersonate will set the current thread token to be the token out of LsaLogonUser
237- // do we need to do anything special if this gets used within an async context?
238-
239- this . impersonationContext . Impersonate ( ) ;
254+ return tokenHandle ;
240255 }
241256
242257 /// <summary>
0 commit comments