Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
021547ca
Commit
021547ca
authored
Jul 31, 2023
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
Aug 03, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
secur32: Convert "Negotiate" to an LSA package.
Signed-off-by:
Dmitry Timoshkov
<
dmitry@baikal.ru
>
parent
ef1b9648
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
353 additions
and
455 deletions
+353
-455
lsa.c
dlls/secur32/lsa.c
+66
-32
negotiate.c
dlls/secur32/negotiate.c
+282
-418
secur32.c
dlls/secur32/secur32.c
+0
-4
secur32_priv.h
dlls/secur32/secur32_priv.h
+5
-1
No files found.
dlls/secur32/lsa.c
View file @
021547ca
...
...
@@ -71,6 +71,24 @@ static const char *debugstr_as(const LSA_STRING *str)
return
debugstr_an
(
str
->
Buffer
,
str
->
Length
);
}
SECPKG_FUNCTION_TABLE
*
lsa_find_package
(
const
char
*
name
,
SECPKG_USER_FUNCTION_TABLE
**
user_api
)
{
LSA_STRING
package_name
;
ULONG
i
;
RtlInitString
(
&
package_name
,
name
);
for
(
i
=
0
;
i
<
loaded_packages_count
;
i
++
)
{
if
(
!
RtlCompareString
(
loaded_packages
[
i
].
name
,
&
package_name
,
FALSE
))
{
*
user_api
=
loaded_packages
[
i
].
user_api
;
return
loaded_packages
[
i
].
lsa_api
;
}
}
return
NULL
;
}
NTSTATUS
WINAPI
LsaCallAuthenticationPackage
(
HANDLE
lsa_handle
,
ULONG
package_id
,
PVOID
in_buffer
,
ULONG
in_buffer_length
,
PVOID
*
out_buffer
,
PULONG
out_buffer_length
,
PNTSTATUS
status
)
...
...
@@ -860,48 +878,56 @@ static void add_package(struct lsa_package *package)
}
}
static
BOOL
load_package
(
const
WCHAR
*
name
,
struct
lsa_package
*
package
,
ULONG
package_id
)
static
BOOL
initialize_package
(
struct
lsa_package
*
package
,
NTSTATUS
(
NTAPI
*
pSpLsaModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_FUNCTION_TABLE
*
,
PULONG
),
NTSTATUS
(
NTAPI
*
pSpUserModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_USER_FUNCTION_TABLE
*
,
PULONG
))
{
NTSTATUS
(
NTAPI
*
pSpLsaModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_FUNCTION_TABLE
*
,
PULONG
);
NTSTATUS
(
NTAPI
*
pSpUserModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_USER_FUNCTION_TABLE
*
,
PULONG
);
memset
(
package
,
0
,
sizeof
(
*
package
));
NTSTATUS
status
;
package
->
mod
=
LoadLibraryW
(
name
);
if
(
!
package
->
mod
)
return
FALSE
;
if
(
!
pSpLsaModeInitialize
||
!
pSpUserModeInitialize
)
return
FALSE
;
pSpLsaModeInitialize
=
(
void
*
)
GetProcAddress
(
package
->
mod
,
"SpLsaModeInitialize"
);
if
(
pSpLsaModeInitialize
)
status
=
pSpLsaModeInitialize
(
SECPKG_INTERFACE_VERSION
,
&
package
->
lsa_api_version
,
&
package
->
lsa_api
,
&
package
->
lsa_table_count
);
if
(
status
==
STATUS_SUCCESS
)
{
NTSTATUS
status
;
status
=
pSpLsaModeInitialize
(
SECPKG_INTERFACE_VERSION
,
&
package
->
lsa_api_version
,
&
package
->
lsa_api
,
&
package
->
lsa_table_count
);
status
=
package
->
lsa_api
->
InitializePackage
(
package
->
package_id
,
&
lsa_dispatch
,
NULL
,
NULL
,
&
package
->
name
);
if
(
status
==
STATUS_SUCCESS
)
{
status
=
package
->
lsa_api
->
InitializePackage
(
package_id
,
&
lsa_dispatch
,
NULL
,
NULL
,
&
package
->
name
);
TRACE
(
"name %s, version %#lx, api table %p, table count %lu
\n
"
,
debugstr_an
(
package
->
name
->
Buffer
,
package
->
name
->
Length
),
package
->
lsa_api_version
,
package
->
lsa_api
,
package
->
lsa_table_count
);
status
=
package
->
lsa_api
->
Initialize
(
package
->
package_id
,
NULL
/* FIXME: params */
,
NULL
);
if
(
status
==
STATUS_SUCCESS
)
{
TRACE
(
"%s => %p, name %s, version %#lx, api table %p, table count %lu
\n
"
,
debugstr_w
(
name
),
package
->
mod
,
debugstr_an
(
package
->
name
->
Buffer
,
package
->
name
->
Length
),
package
->
lsa_api_version
,
package
->
lsa_api
,
package
->
lsa_table_count
);
package
->
package_id
=
package_id
;
status
=
package
->
lsa_api
->
Initialize
(
package_id
,
NULL
/* FIXME: params */
,
NULL
);
status
=
pSpUserModeInitialize
(
SECPKG_INTERFACE_VERSION
,
&
package
->
user_api_version
,
&
package
->
user_api
,
&
package
->
user_table_count
);
if
(
status
==
STATUS_SUCCESS
)
{
pSpUserModeInitialize
=
(
void
*
)
GetProcAddress
(
package
->
mod
,
"SpUserModeInitialize"
);
if
(
pSpUserModeInitialize
)
{
status
=
pSpUserModeInitialize
(
SECPKG_INTERFACE_VERSION
,
&
package
->
user_api_version
,
&
package
->
user_api
,
&
package
->
user_table_count
);
if
(
status
==
STATUS_SUCCESS
)
package
->
user_api
->
InstanceInit
(
SECPKG_INTERFACE_VERSION
,
&
lsa_dll_dispatch
,
NULL
);
}
}
return
TRUE
;
package
->
user_api
->
InstanceInit
(
SECPKG_INTERFACE_VERSION
,
&
lsa_dll_dispatch
,
NULL
);
}
}
return
TRUE
;
}
return
FALSE
;
}
static
BOOL
load_package
(
const
WCHAR
*
name
,
struct
lsa_package
*
package
,
ULONG
package_id
)
{
NTSTATUS
(
NTAPI
*
pSpLsaModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_FUNCTION_TABLE
*
,
PULONG
);
NTSTATUS
(
NTAPI
*
pSpUserModeInitialize
)(
ULONG
,
PULONG
,
PSECPKG_USER_FUNCTION_TABLE
*
,
PULONG
);
memset
(
package
,
0
,
sizeof
(
*
package
));
package
->
package_id
=
package_id
;
package
->
mod
=
LoadLibraryW
(
name
);
if
(
!
package
->
mod
)
return
FALSE
;
pSpLsaModeInitialize
=
(
void
*
)
GetProcAddress
(
package
->
mod
,
"SpLsaModeInitialize"
);
pSpUserModeInitialize
=
(
void
*
)
GetProcAddress
(
package
->
mod
,
"SpUserModeInitialize"
);
if
(
initialize_package
(
package
,
pSpLsaModeInitialize
,
pSpUserModeInitialize
))
return
TRUE
;
FreeLibrary
(
package
->
mod
);
return
FALSE
;
}
...
...
@@ -913,6 +939,14 @@ void load_auth_packages(void)
DWORD
err
,
i
;
HKEY
root
;
SecureProvider
*
provider
;
struct
lsa_package
package
;
memset
(
&
package
,
0
,
sizeof
(
package
));
/* "Negotiate" has package id 0, .Net depends on this. */
package
.
package_id
=
0
;
if
(
initialize_package
(
&
package
,
nego_SpLsaModeInitialize
,
nego_SpUserModeInitialize
))
add_package
(
&
package
);
err
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
L"System
\\
CurrentControlSet
\\
Control
\\
Lsa"
,
0
,
KEY_READ
,
&
root
);
if
(
err
!=
ERROR_SUCCESS
)
return
;
...
...
@@ -921,19 +955,19 @@ void load_auth_packages(void)
for
(;;)
{
WCHAR
name
[
MAX_SERVICE_NAME
];
struct
lsa_package
package
;
err
=
RegEnumKeyW
(
root
,
i
++
,
name
,
MAX_SERVICE_NAME
);
err
=
RegEnumKeyW
(
root
,
i
,
name
,
MAX_SERVICE_NAME
);
if
(
err
==
ERROR_NO_MORE_ITEMS
)
break
;
if
(
err
!=
ERROR_SUCCESS
)
continue
;
if
(
!
load_package
(
name
,
&
package
,
i
))
if
(
!
load_package
(
name
,
&
package
,
i
+
1
))
continue
;
add_package
(
&
package
);
i
++
;
}
RegCloseKey
(
root
);
...
...
dlls/secur32/negotiate.c
View file @
021547ca
...
...
@@ -19,88 +19,153 @@
#include <stdarg.h>
#include <stdlib.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "sspi.h"
#include "rpc.h"
#include "wincred.h"
#include "ntsecapi.h"
#include "ntsecpkg.h"
#include "winternl.h"
#include "wine/debug.h"
#include "secur32_priv.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
secur32
);
/***********************************************************************
* QueryCredentialsAttributesA
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_QueryCredentialsAttributesA
(
PCredHandle
phCredential
,
ULONG
ulAttribute
,
PVOID
pBuffer
)
struct
sec_handle
{
FIXME
(
"%p, %lu, %p
\n
"
,
phCredential
,
ulAttribute
,
pBuffer
);
SECPKG_FUNCTION_TABLE
*
krb
;
SECPKG_FUNCTION_TABLE
*
ntlm
;
SECPKG_USER_FUNCTION_TABLE
*
user_krb
;
SECPKG_USER_FUNCTION_TABLE
*
user_ntlm
;
LSA_SEC_HANDLE
handle_krb
;
LSA_SEC_HANDLE
handle_ntlm
;
};
#define WINE_NO_CACHED_CREDENTIALS 0x10000000
#define NEGO_MAX_TOKEN 12000
static
WCHAR
nego_name_W
[]
=
{
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'e'
,
0
};
static
char
nego_name_A
[]
=
"Negotiate"
;
static
WCHAR
negotiate_comment_W
[]
=
{
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
' '
,
'P'
,
'a'
,
'c'
,
'k'
,
'a'
,
'g'
,
'e'
,
' '
,
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'o'
,
'r'
,
0
};
#define CAPS ( \
SECPKG_FLAG_INTEGRITY | \
SECPKG_FLAG_PRIVACY | \
SECPKG_FLAG_CONNECTION | \
SECPKG_FLAG_MULTI_REQUIRED | \
SECPKG_FLAG_EXTENDED_ERROR | \
SECPKG_FLAG_IMPERSONATION | \
SECPKG_FLAG_ACCEPT_WIN32_NAME | \
SECPKG_FLAG_NEGOTIABLE | \
SECPKG_FLAG_GSS_COMPATIBLE | \
SECPKG_FLAG_LOGON | \
SECPKG_FLAG_RESTRICTED_TOKENS )
static
NTSTATUS
NTAPI
nego_LsaApCallPackageUntrusted
(
PLSA_CLIENT_REQUEST
req
,
void
*
in_buf
,
void
*
client_buf_base
,
ULONG
in_buf_len
,
void
**
out_buf
,
ULONG
*
out_buf_len
,
NTSTATUS
*
ret_status
)
{
FIXME
(
"%p, %p, %p, %lu, %p, %p, %p: stub
\n
"
,
req
,
in_buf
,
client_buf_base
,
in_buf_len
,
out_buf
,
out_buf_len
,
ret_status
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
}
/***********************************************************************
* QueryCredentialsAttributesW
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_QueryCredentialsAttributesW
(
PCredHandle
phCredential
,
ULONG
ulAttribute
,
PVOID
pBuffer
)
static
NTSTATUS
NTAPI
nego_LsaApInitializePackage
(
ULONG
package_id
,
PLSA_DISPATCH_TABLE
dispatch
,
PLSA_STRING
database
,
PLSA_STRING
confidentiality
,
PLSA_STRING
*
package_name
)
{
FIXME
(
"%p, %lu, %p
\n
"
,
phCredential
,
ulAttribute
,
pBuffer
);
return
SEC_E_UNSUPPORTED_FUNCTION
;
char
*
name
;
name
=
dispatch
->
AllocateLsaHeap
(
sizeof
(
nego_name_A
)
);
if
(
!
name
)
return
STATUS_NO_MEMORY
;
memcpy
(
name
,
nego_name_A
,
sizeof
(
nego_name_A
));
*
package_name
=
dispatch
->
AllocateLsaHeap
(
sizeof
(
**
package_name
)
);
if
(
!*
package_name
)
{
dispatch
->
FreeLsaHeap
(
name
);
return
STATUS_NO_MEMORY
;
}
RtlInitString
(
*
package_name
,
name
);
return
STATUS_SUCCESS
;
}
struct
sec_handle
static
NTSTATUS
NTAPI
nego_SpInitialize
(
ULONG_PTR
package_id
,
SECPKG_PARAMETERS
*
params
,
LSA_SECPKG_FUNCTION_TABLE
*
lsa_function_table
)
{
SecureProvider
*
krb
;
SecureProvider
*
ntlm
;
SecHandle
handle_krb
;
SecHandle
handle_ntlm
;
};
TRACE
(
"%Iu, %p, %p
\n
"
,
package_id
,
params
,
lsa_function_table
);
return
STATUS_SUCCESS
;
}
#define WINE_NO_CACHED_CREDENTIALS 0x10000000
static
NTSTATUS
NTAPI
nego_SpShutdown
(
void
)
{
TRACE
(
"
\n
"
);
return
STATUS_SUCCESS
;
}
/***********************************************************************
* AcquireCredentialsHandleW
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_AcquireCredentialsHandleW
(
SEC_WCHAR
*
pszPrincipal
,
SEC_WCHAR
*
pszPackage
,
ULONG
fCredentialUse
,
PLUID
pLogonID
,
PVOID
pAuthData
,
SEC_GET_KEY_FN
pGetKeyFn
,
PVOID
pGetKeyArgument
,
PCredHandle
phCredential
,
PTimeStamp
ptsExpiry
)
static
NTSTATUS
NTAPI
nego_SpGetInfo
(
SecPkgInfoW
*
info
)
{
static
SEC_WCHAR
ntlmW
[]
=
{
'N'
,
'T'
,
'L'
,
'M'
,
0
};
static
SEC_WCHAR
kerberosW
[]
=
{
'K'
,
'e'
,
'r'
,
'b'
,
'e'
,
'r'
,
'o'
,
's'
,
0
};
SECURITY_STATUS
ret
=
SEC_E_NO_CREDENTIALS
;
const
SecPkgInfoW
infoW
=
{
CAPS
,
1
,
RPC_C_AUTHN_GSS_NEGOTIATE
,
NEGO_MAX_TOKEN
,
nego_name_W
,
negotiate_comment_W
};
TRACE
(
"%p
\n
"
,
info
);
/* LSA will make a copy before forwarding the structure, so
* it's safe to put pointers to dynamic or constant data there.
*/
*
info
=
infoW
;
return
STATUS_SUCCESS
;
}
static
NTSTATUS
NTAPI
nego_SpAcquireCredentialsHandle
(
UNICODE_STRING
*
principal_us
,
ULONG
credential_use
,
LUID
*
logon_id
,
void
*
auth_data
,
void
*
get_key_fn
,
void
*
get_key_arg
,
LSA_SEC_HANDLE
*
credential
,
TimeStamp
*
expiry
)
{
NTSTATUS
ret
=
SEC_E_NO_CREDENTIALS
;
struct
sec_handle
*
cred
;
SecurePackage
*
package
;
SECPKG_FUNCTION_TABLE
*
package
;
SECPKG_USER_FUNCTION_TABLE
*
user
;
TRACE
(
"%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p
\n
"
,
debugstr_w
(
pszPrincipal
),
debugstr_w
(
pszPackage
),
fCredentialUse
,
pLogonID
,
pAuthData
,
pGetKeyFn
,
pGetKeyArgument
,
phCredential
,
ptsExpiry
);
TRACE
(
"%p, %#lx, %p, %p, %p, %p, %p, %p
\n
"
,
principal_us
,
credential_use
,
logon_id
,
auth_data
,
get_key_fn
,
get_key_arg
,
credential
,
expiry
);
if
(
!
pszPackage
)
return
SEC_E_SECPKG_NOT_FOUND
;
if
(
!
(
cred
=
calloc
(
1
,
sizeof
(
*
cred
)
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
if
((
package
=
SECUR32_findPackageW
(
kerberosW
)))
if
((
package
=
lsa_find_package
(
"Kerberos"
,
&
user
)))
{
ret
=
package
->
provider
->
fnTableW
.
AcquireCredentialsHandleW
(
pszPrincipal
,
kerberosW
,
fCredentialUse
,
pLogonID
,
pAuthData
,
pGetKeyFn
,
pGetKeyArgument
,
&
cred
->
handle_krb
,
ptsExpiry
);
if
(
ret
==
SEC_E_OK
)
cred
->
krb
=
package
->
provider
;
ret
=
package
->
SpAcquireCredentialsHandle
(
principal_us
,
credential_use
,
logon_id
,
auth_data
,
get_key_fn
,
get_key_arg
,
&
cred
->
handle_krb
,
expiry
);
if
(
ret
==
SEC_E_OK
)
{
cred
->
krb
=
package
;
cred
->
user_krb
=
user
;
}
}
if
((
package
=
SECUR32_findPackageW
(
ntlmW
)))
if
((
package
=
lsa_find_package
(
"NTLM"
,
&
user
)))
{
ULONG
cred_use
=
pAuthData
?
fCredentialUse
:
fCredentialU
se
|
WINE_NO_CACHED_CREDENTIALS
;
ULONG
cred_use
=
auth_data
?
credential_use
:
credential_u
se
|
WINE_NO_CACHED_CREDENTIALS
;
ret
=
package
->
provider
->
fnTableW
.
AcquireCredentialsHandleW
(
pszPrincipal
,
ntlmW
,
cred_use
,
pLogonID
,
pAuthData
,
pGetKeyFn
,
pGetKeyArgument
,
&
cred
->
handle_ntlm
,
ptsExpiry
);
if
(
ret
==
SEC_E_OK
)
cred
->
ntlm
=
package
->
provider
;
ret
=
package
->
SpAcquireCredentialsHandle
(
principal_us
,
cred_use
,
logon_id
,
auth_data
,
get_key_fn
,
get_key_arg
,
&
cred
->
handle_ntlm
,
expiry
);
if
(
ret
==
SEC_E_OK
)
{
cred
->
ntlm
=
package
;
cred
->
user_ntlm
=
user
;
}
}
if
(
cred
->
krb
||
cred
->
ntlm
)
{
phCredential
->
dwLower
=
(
ULONG_PTR
)
cred
;
phCredential
->
dwUpper
=
0
;
*
credential
=
(
LSA_SEC_HANDLE
)
cred
;
return
SEC_E_OK
;
}
...
...
@@ -108,78 +173,41 @@ static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
return
ret
;
}
/***********************************************************************
* AcquireCredentialsHandleA
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_AcquireCredentialsHandleA
(
SEC_CHAR
*
pszPrincipal
,
SEC_CHAR
*
pszPackage
,
ULONG
fCredentialUse
,
PLUID
pLogonID
,
PVOID
pAuthData
,
SEC_GET_KEY_FN
pGetKeyFn
,
PVOID
pGetKeyArgument
,
PCredHandle
phCredential
,
PTimeStamp
ptsExpiry
)
static
NTSTATUS
NTAPI
nego_SpFreeCredentialsHandle
(
LSA_SEC_HANDLE
credential
)
{
SECURITY_STATUS
ret
=
SEC_E_INSUFFICIENT_MEMORY
;
SEC_WCHAR
*
package
=
NULL
;
SEC_WINNT_AUTH_IDENTITY_A
*
id
=
pAuthData
;
SEC_WINNT_AUTH_IDENTITY_W
idW
=
{};
TRACE
(
"%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p
\n
"
,
debugstr_a
(
pszPrincipal
),
debugstr_a
(
pszPackage
),
fCredentialUse
,
pLogonID
,
pAuthData
,
pGetKeyFn
,
pGetKeyArgument
,
phCredential
,
ptsExpiry
);
if
(
pszPackage
)
{
int
package_len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
pszPackage
,
-
1
,
NULL
,
0
);
if
(
!
(
package
=
malloc
(
package_len
*
sizeof
(
SEC_WCHAR
)
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
MultiByteToWideChar
(
CP_ACP
,
0
,
pszPackage
,
-
1
,
package
,
package_len
);
}
if
(
id
&&
id
->
Flags
==
SEC_WINNT_AUTH_IDENTITY_ANSI
)
{
idW
.
UserLength
=
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
User
,
id
->
UserLength
,
NULL
,
0
);
if
(
!
(
idW
.
User
=
malloc
(
idW
.
UserLength
*
sizeof
(
SEC_WCHAR
)
)))
goto
done
;
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
User
,
id
->
UserLength
,
idW
.
User
,
idW
.
UserLength
);
struct
sec_handle
*
cred
;
idW
.
DomainLength
=
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
Domain
,
id
->
DomainLength
,
NULL
,
0
);
if
(
!
(
idW
.
Domain
=
malloc
(
idW
.
DomainLength
*
sizeof
(
SEC_WCHAR
)
)))
goto
done
;
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
Domain
,
id
->
DomainLength
,
idW
.
Domain
,
idW
.
DomainLength
);
TRACE
(
"%Ix
\n
"
,
credential
);
idW
.
PasswordLength
=
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
Password
,
id
->
PasswordLength
,
NULL
,
0
);
if
(
!
(
idW
.
Password
=
malloc
(
idW
.
PasswordLength
*
sizeof
(
SEC_WCHAR
)
)))
goto
done
;
MultiByteToWideChar
(
CP_ACP
,
0
,
(
const
char
*
)
id
->
Password
,
id
->
PasswordLength
,
idW
.
Password
,
idW
.
PasswordLength
);
if
(
!
credential
)
return
SEC_E_INVALID_HANDLE
;
idW
.
Flags
=
SEC_WINNT_AUTH_IDENTITY_UNICODE
;
pAuthData
=
&
idW
;
}
cred
=
(
struct
sec_handle
*
)
credential
;
if
(
cred
->
krb
)
cred
->
krb
->
FreeCredentialsHandle
(
cred
->
handle_krb
)
;
if
(
cred
->
ntlm
)
cred
->
ntlm
->
FreeCredentialsHandle
(
cred
->
handle_ntlm
);
ret
=
nego_AcquireCredentialsHandleW
(
NULL
,
package
,
fCredentialUse
,
pLogonID
,
pAuthData
,
pGetKeyFn
,
pGetKeyArgument
,
phCredential
,
ptsExpiry
);
done:
free
(
package
);
return
ret
;
free
(
cred
);
return
SEC_E_OK
;
}
/***********************************************************************
* InitializeSecurityContextW
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_InitializeSecurityContextW
(
PCredHandle
phCredential
,
PCtxtHandle
phContext
,
SEC_WCHAR
*
pszTargetName
,
ULONG
fContextReq
,
ULONG
Reserved1
,
ULONG
TargetDataRep
,
PSecBufferDesc
pInput
,
ULONG
Reserved2
,
PCtxtHandle
phNewContext
,
PSecBufferDesc
pOutput
,
ULONG
*
pfContextAttr
,
PTimeStamp
ptsExpiry
)
static
NTSTATUS
NTAPI
nego_SpInitLsaModeContext
(
LSA_SEC_HANDLE
credential
,
LSA_SEC_HANDLE
context
,
UNICODE_STRING
*
target_name
,
ULONG
context_req
,
ULONG
target_data_rep
,
SecBufferDesc
*
input
,
LSA_SEC_HANDLE
*
new_context
,
SecBufferDesc
*
output
,
ULONG
*
context_attr
,
TimeStamp
*
expiry
,
BOOLEAN
*
mapped_context
,
SecBuffer
*
context_data
)
{
SECURITY_
STATUS
ret
=
SEC_E_INVALID_HANDLE
;
NT
STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
handle
=
NULL
,
*
ctxt
,
*
new_ctxt
=
NULL
,
*
cred
=
NULL
;
TRACE
(
"%p, %p, %s, 0x%08lx, %lu, %lu, %p, %lu, %p, %p, %p, %p
\n
"
,
phCredential
,
phContext
,
debugstr_w
(
pszTargetName
),
fContextReq
,
Reserved1
,
TargetDataRep
,
pInput
,
Reserved1
,
phNewContext
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
TRACE
(
"%Ix, %Ix, %p, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p
\n
"
,
credential
,
context
,
target_name
,
context_req
,
target_data_rep
,
input
,
new_context
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
(
phC
ontext
)
if
(
c
ontext
)
{
handle
=
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
handle
=
ctxt
=
(
struct
sec_handle
*
)
context
;
}
else
if
(
phC
redential
)
else
if
(
c
redential
)
{
handle
=
cred
=
(
struct
sec_handle
*
)
phCredential
->
dwLower
;
handle
=
cred
=
(
struct
sec_handle
*
)
credential
;
if
(
!
(
new_ctxt
=
ctxt
=
calloc
(
1
,
sizeof
(
*
ctxt
)
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
ctxt
->
krb
=
cred
->
krb
;
ctxt
->
ntlm
=
cred
->
ntlm
;
...
...
@@ -188,28 +216,26 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
if
(
handle
->
krb
)
{
ret
=
handle
->
krb
->
fnTableW
.
InitializeSecurityContextW
(
phCredential
?
&
cred
->
handle_krb
:
NULL
,
phContext
?
&
ctxt
->
handle_krb
:
NULL
,
pszTargetName
,
fContextReq
,
Reserved1
,
TargetDataRep
,
pI
nput
,
Reserved2
,
phNewContext
?
&
ctxt
->
handle_krb
:
NULL
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
phNewC
ontext
)
ret
=
handle
->
krb
->
InitLsaModeContext
(
credential
?
cred
->
handle_krb
:
0
,
context
?
ctxt
->
handle_krb
:
0
,
target_name
,
context_req
,
target_data_rep
,
i
nput
,
new_context
?
&
ctxt
->
handle_krb
:
NULL
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
new_c
ontext
)
{
ctxt
->
ntlm
=
NULL
;
phNewContext
->
dwLower
=
(
ULONG_PTR
)
ctxt
;
phNewContext
->
dwUpper
=
0
;
*
new_context
=
(
LSA_SEC_HANDLE
)
ctxt
;
if
(
new_ctxt
==
ctxt
)
new_ctxt
=
NULL
;
}
}
if
(
ret
!=
SEC_E_OK
&&
ret
!=
SEC_I_CONTINUE_NEEDED
&&
handle
->
ntlm
)
{
ret
=
handle
->
ntlm
->
fnTableW
.
InitializeSecurityContextW
(
phCredential
?
&
cred
->
handle_ntlm
:
NULL
,
phContext
?
&
ctxt
->
handle_ntlm
:
NULL
,
pszTargetName
,
fContextReq
,
Reserved1
,
TargetDataRep
,
pI
nput
,
Reserved2
,
phNewContext
?
&
ctxt
->
handle_ntlm
:
NULL
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
phNewC
ontext
)
ret
=
handle
->
ntlm
->
InitLsaModeContext
(
credential
?
cred
->
handle_ntlm
:
0
,
context
?
ctxt
->
handle_ntlm
:
0
,
target_name
,
context_req
,
target_data_rep
,
i
nput
,
new_context
?
&
ctxt
->
handle_ntlm
:
NULL
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
new_c
ontext
)
{
ctxt
->
krb
=
NULL
;
phNewContext
->
dwLower
=
(
ULONG_PTR
)
ctxt
;
phNewContext
->
dwUpper
=
0
;
*
new_context
=
(
LSA_SEC_HANDLE
)
ctxt
;
if
(
new_ctxt
==
ctxt
)
new_ctxt
=
NULL
;
}
}
...
...
@@ -218,58 +244,23 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
return
ret
;
}
/***********************************************************************
* InitializeSecurityContextA
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_InitializeSecurityContextA
(
PCredHandle
phCredential
,
PCtxtHandle
phContext
,
SEC_CHAR
*
pszTargetName
,
ULONG
fContextReq
,
ULONG
Reserved1
,
ULONG
TargetDataRep
,
PSecBufferDesc
pInput
,
ULONG
Reserved2
,
PCtxtHandle
phNewContext
,
PSecBufferDesc
pOutput
,
ULONG
*
pfContextAttr
,
PTimeStamp
ptsExpiry
)
{
SECURITY_STATUS
ret
;
SEC_WCHAR
*
target
=
NULL
;
TRACE
(
"%p, %p, %s, 0x%08lx, %lu, %lu, %p, %lu, %p, %p, %p, %p
\n
"
,
phCredential
,
phContext
,
debugstr_a
(
pszTargetName
),
fContextReq
,
Reserved1
,
TargetDataRep
,
pInput
,
Reserved1
,
phNewContext
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
if
(
pszTargetName
)
{
int
target_len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
pszTargetName
,
-
1
,
NULL
,
0
);
if
(
!
(
target
=
malloc
(
target_len
*
sizeof
(
SEC_WCHAR
)
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
MultiByteToWideChar
(
CP_ACP
,
0
,
pszTargetName
,
-
1
,
target
,
target_len
);
}
ret
=
nego_InitializeSecurityContextW
(
phCredential
,
phContext
,
target
,
fContextReq
,
Reserved1
,
TargetDataRep
,
pInput
,
Reserved2
,
phNewContext
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
free
(
target
);
return
ret
;
}
/***********************************************************************
* AcceptSecurityContext
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_AcceptSecurityContext
(
PCredHandle
phCredential
,
PCtxtHandle
phContext
,
PSecBufferDesc
pInput
,
ULONG
fContextReq
,
ULONG
TargetDataRep
,
PCtxtHandle
phNewContext
,
PSecBufferDesc
pOutput
,
ULONG
*
pfContextAttr
,
PTimeStamp
ptsExpiry
)
static
NTSTATUS
NTAPI
nego_SpAcceptLsaModeContext
(
LSA_SEC_HANDLE
credential
,
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
input
,
ULONG
context_req
,
ULONG
target_data_rep
,
LSA_SEC_HANDLE
*
new_context
,
SecBufferDesc
*
output
,
ULONG
*
context_attr
,
TimeStamp
*
expiry
,
BOOLEAN
*
mapped_context
,
SecBuffer
*
context_data
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
handle
=
NULL
,
*
ctxt
,
*
new_ctxt
=
NULL
,
*
cred
=
NULL
;
TRACE
(
"%p, %p, %p, 0x%08lx, %lu, %p, %p, %p, %p
\n
"
,
phCredential
,
phContext
,
pInput
,
fContextReq
,
TargetDataRep
,
phNewContext
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
TRACE
(
"%Ix, %Ix, %#lx, %lu, %p, %p, %p, %p, %p, %p, %p
\n
"
,
credential
,
context
,
context_req
,
target_data_rep
,
input
,
new_context
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
(
phC
ontext
)
if
(
c
ontext
)
{
handle
=
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
handle
=
ctxt
=
(
struct
sec_handle
*
)
context
;
}
else
if
(
phC
redential
)
else
if
(
c
redential
)
{
handle
=
cred
=
(
struct
sec_handle
*
)
phCredential
->
dwLower
;
handle
=
cred
=
(
struct
sec_handle
*
)
credential
;
if
(
!
(
new_ctxt
=
ctxt
=
calloc
(
1
,
sizeof
(
*
ctxt
)
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
ctxt
->
krb
=
cred
->
krb
;
ctxt
->
ntlm
=
cred
->
ntlm
;
...
...
@@ -278,28 +269,28 @@ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
if
(
handle
->
krb
)
{
ret
=
handle
->
krb
->
fnTableW
.
AcceptSecurityContext
(
phCredential
?
&
cred
->
handle_krb
:
NULL
,
phContext
?
&
ctxt
->
handle_krb
:
NULL
,
pInput
,
fContextReq
,
TargetDataRep
,
phNewContext
?
&
ctxt
->
handle_krb
:
NULL
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
phNewContext
)
ret
=
handle
->
krb
->
AcceptLsaModeContext
(
credential
?
cred
->
handle_krb
:
0
,
context
?
ctxt
->
handle_krb
:
0
,
input
,
context_req
,
target_data_rep
,
new_context
?
&
ctxt
->
handle_krb
:
NULL
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
new_context
)
{
ctxt
->
ntlm
=
NULL
;
phNewContext
->
dwLower
=
(
ULONG_PTR
)
ctxt
;
phNewContext
->
dwUpper
=
0
;
*
new_context
=
(
LSA_SEC_HANDLE
)
ctxt
;
if
(
new_ctxt
==
ctxt
)
new_ctxt
=
NULL
;
}
}
if
(
ret
!=
SEC_E_OK
&&
ret
!=
SEC_I_CONTINUE_NEEDED
&&
handle
->
ntlm
)
{
ret
=
handle
->
ntlm
->
fnTableW
.
AcceptSecurityContext
(
phCredential
?
&
cred
->
handle_ntlm
:
NULL
,
phContext
?
&
ctxt
->
handle_ntlm
:
NULL
,
pInput
,
fContextReq
,
TargetDataRep
,
phNewContext
?
&
ctxt
->
handle_ntlm
:
NULL
,
pOutput
,
pfContextAttr
,
ptsExpiry
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
phNewContext
)
ret
=
handle
->
ntlm
->
AcceptLsaModeContext
(
credential
?
cred
->
handle_ntlm
:
0
,
context
?
ctxt
->
handle_ntlm
:
0
,
input
,
context_req
,
target_data_rep
,
new_context
?
&
ctxt
->
handle_ntlm
:
NULL
,
output
,
context_attr
,
expiry
,
mapped_context
,
context_data
);
if
((
ret
==
SEC_E_OK
||
ret
==
SEC_I_CONTINUE_NEEDED
)
&&
new_context
)
{
ctxt
->
krb
=
NULL
;
phNewContext
->
dwLower
=
(
ULONG_PTR
)
ctxt
;
phNewContext
->
dwUpper
=
0
;
*
new_context
=
(
LSA_SEC_HANDLE
)
ctxt
;
if
(
new_ctxt
==
ctxt
)
new_ctxt
=
NULL
;
}
}
...
...
@@ -308,347 +299,220 @@ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
return
ret
;
}
/***********************************************************************
* CompleteAuthToken
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_CompleteAuthToken
(
PCtxtHandle
phContext
,
PSecBufferDesc
pToken
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
TRACE
(
"%p %p
\n
"
,
phContext
,
pToken
);
if
(
phContext
)
ret
=
SEC_E_UNSUPPORTED_FUNCTION
;
return
ret
;
}
/***********************************************************************
* DeleteSecurityContext
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_DeleteSecurityContext
(
PCtxtHandle
phContext
)
static
NTSTATUS
NTAPI
nego_SpDeleteContext
(
LSA_SEC_HANDLE
context
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p
\n
"
,
phContext
);
TRACE
(
"%Ix
\n
"
,
context
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
DeleteSecurityContext
(
&
ctxt
->
handle_krb
);
ret
=
ctxt
->
krb
->
DeleteContext
(
ctxt
->
handle_krb
);
}
else
if
(
ctxt
->
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
DeleteSecurityContext
(
&
ctxt
->
handle_ntlm
);
ret
=
ctxt
->
ntlm
->
DeleteContext
(
ctxt
->
handle_ntlm
);
}
TRACE
(
"freeing %p
\n
"
,
ctxt
);
free
(
ctxt
);
return
ret
;
}
/***********************************************************************
* ApplyControlToken
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_ApplyControlToken
(
PCtxtHandle
phContext
,
PSecBufferDesc
pInput
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
TRACE
(
"%p %p
\n
"
,
phContext
,
pInput
);
if
(
phContext
)
ret
=
SEC_E_UNSUPPORTED_FUNCTION
;
return
ret
;
}
/***********************************************************************
* QueryContextAttributesW
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_QueryContextAttributesW
(
PCtxtHandle
phContext
,
ULONG
ulAttribute
,
void
*
pBuffer
)
static
NTSTATUS
NTAPI
nego_SpQueryContextAttributes
(
LSA_SEC_HANDLE
context
,
ULONG
attribute
,
void
*
buffer
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, %lu, %p
\n
"
,
phContext
,
ulAttribute
,
pBuffer
);
TRACE
(
"%Ix, %lu, %p
\n
"
,
context
,
attribute
,
buffer
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
QueryContextAttributesW
(
&
ctxt
->
handle_krb
,
ulAttribute
,
pB
uffer
);
ret
=
ctxt
->
krb
->
SpQueryContextAttributes
(
ctxt
->
handle_krb
,
attribute
,
b
uffer
);
}
else
if
(
ctxt
->
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
QueryContextAttributesW
(
&
ctxt
->
handle_ntlm
,
ulAttribute
,
pB
uffer
);
ret
=
ctxt
->
ntlm
->
SpQueryContextAttributes
(
ctxt
->
handle_ntlm
,
attribute
,
b
uffer
);
}
return
ret
;
}
/***********************************************************************
* QueryContextAttributesA
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_QueryContextAttributesA
(
PCtxtHandle
phContext
,
ULONG
ulAttribute
,
void
*
pBuffer
)
static
SECPKG_FUNCTION_TABLE
nego_lsa_table
=
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, %lu, %p
\n
"
,
phContext
,
ulAttribute
,
pBuffer
);
if
(
!
phContext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
if
(
ctxt
->
krb
)
{
ret
=
ctxt
->
krb
->
fnTableA
.
QueryContextAttributesA
(
&
ctxt
->
handle_krb
,
ulAttribute
,
pBuffer
);
}
else
if
(
ctxt
->
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableA
.
QueryContextAttributesA
(
&
ctxt
->
handle_ntlm
,
ulAttribute
,
pBuffer
);
}
return
ret
;
}
nego_LsaApInitializePackage
,
NULL
,
/* LsaLogonUser */
NULL
,
/* CallPackage */
NULL
,
/* LogonTerminated */
nego_LsaApCallPackageUntrusted
,
NULL
,
/* CallPackagePassthrough */
NULL
,
/* LogonUserEx */
NULL
,
/* LogonUserEx2 */
nego_SpInitialize
,
nego_SpShutdown
,
nego_SpGetInfo
,
NULL
,
/* AcceptCredentials */
nego_SpAcquireCredentialsHandle
,
NULL
,
/* SpQueryCredentialsAttributes */
nego_SpFreeCredentialsHandle
,
NULL
,
/* SaveCredentials */
NULL
,
/* GetCredentials */
NULL
,
/* DeleteCredentials */
nego_SpInitLsaModeContext
,
nego_SpAcceptLsaModeContext
,
nego_SpDeleteContext
,
NULL
,
/* ApplyControlToken */
NULL
,
/* GetUserInfo */
NULL
,
/* GetExtendedInformation */
nego_SpQueryContextAttributes
,
NULL
,
/* SpAddCredentials */
NULL
,
/* SetExtendedInformation */
NULL
,
/* SetContextAttributes */
NULL
,
/* SetCredentialsAttributes */
NULL
,
/* ChangeAccountPassword */
NULL
,
/* QueryMetaData */
NULL
,
/* ExchangeMetaData */
NULL
,
/* GetCredUIContext */
NULL
,
/* UpdateCredentials */
NULL
,
/* ValidateTargetInfo */
NULL
,
/* PostLogonUser */
};
/***********************************************************************
* ImpersonateSecurityContext
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_ImpersonateSecurityContext
(
PCtxtHandle
phContext
)
NTSTATUS
NTAPI
nego_SpLsaModeInitialize
(
ULONG
lsa_version
,
PULONG
package_version
,
PSECPKG_FUNCTION_TABLE
*
table
,
PULONG
table_count
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
TRACE
(
"%#lx, %p, %p, %p
\n
"
,
lsa_version
,
package_version
,
table
,
table_count
)
;
TRACE
(
"%p
\n
"
,
phContext
)
;
if
(
phContext
)
ret
=
SEC_E_UNSUPPORTED_FUNCTION
;
return
ret
;
*
package_version
=
SECPKG_INTERFACE_VERSION
;
*
table
=
&
nego_lsa_table
;
*
table_count
=
1
;
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RevertSecurityContext
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_RevertSecurityContext
(
PCtxtHandle
phContext
)
static
NTSTATUS
NTAPI
nego_SpInstanceInit
(
ULONG
version
,
SECPKG_DLL_FUNCTIONS
*
dll_function_table
,
void
**
user_functions
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
TRACE
(
"%p
\n
"
,
phContext
);
if
(
phContext
)
ret
=
SEC_E_UNSUPPORTED_FUNCTION
;
return
ret
;
TRACE
(
"%#lx, %p, %p
\n
"
,
version
,
dll_function_table
,
user_functions
);
return
STATUS_SUCCESS
;
}
/***********************************************************************
* MakeSignature
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_MakeSignature
(
PCtxtHandle
phContext
,
ULONG
fQOP
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
)
static
NTSTATUS
NTAPI
nego_SpMakeSignature
(
LSA_SEC_HANDLE
context
,
ULONG
quality_of_protection
,
SecBufferDesc
*
message
,
ULONG
message_seq_no
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, 0x%08lx, %p, %lu
\n
"
,
phContext
,
fQOP
,
pMessage
,
MessageSeqNo
);
TRACE
(
"%Ix, %#lx, %p, %lu
\n
"
,
context
,
quality_of_protection
,
message
,
message_seq_no
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
if
(
ctxt
->
krb
)
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
user_
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
MakeSignature
(
&
ctxt
->
handle_krb
,
fQOP
,
pMessage
,
MessageSeqN
o
);
ret
=
ctxt
->
user_krb
->
MakeSignature
(
ctxt
->
handle_krb
,
quality_of_protection
,
message
,
message_seq_n
o
);
}
else
if
(
ctxt
->
ntlm
)
else
if
(
ctxt
->
user_
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
MakeSignature
(
&
ctxt
->
handle_ntlm
,
fQOP
,
pMessage
,
MessageSeqN
o
);
ret
=
ctxt
->
user_ntlm
->
MakeSignature
(
ctxt
->
handle_ntlm
,
quality_of_protection
,
message
,
message_seq_n
o
);
}
return
ret
;
}
/***********************************************************************
* VerifySignature
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_VerifySignature
(
PCtxtHandle
phContext
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
,
PULONG
pfQOP
)
static
NTSTATUS
NTAPI
nego_SpVerifySignature
(
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
message
,
ULONG
message_seq_no
,
ULONG
*
quality_of_protection
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, %p, %lu, %p
\n
"
,
phContext
,
pMessage
,
MessageSeqNo
,
pfQOP
);
TRACE
(
"%Ix, %p, %lu, %p
\n
"
,
context
,
message
,
message_seq_no
,
quality_of_protection
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
if
(
ctxt
->
krb
)
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
user_
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
VerifySignature
(
&
ctxt
->
handle_krb
,
pMessage
,
MessageSeqNo
,
pfQOP
);
ret
=
ctxt
->
user_krb
->
VerifySignature
(
ctxt
->
handle_krb
,
message
,
message_seq_no
,
quality_of_protection
);
}
else
if
(
ctxt
->
ntlm
)
else
if
(
ctxt
->
user_
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
VerifySignature
(
&
ctxt
->
handle_ntlm
,
pMessage
,
MessageSeqNo
,
pfQOP
);
ret
=
ctxt
->
user_ntlm
->
VerifySignature
(
ctxt
->
handle_ntlm
,
message
,
message_seq_no
,
quality_of_protection
);
}
return
ret
;
}
/***********************************************************************
* FreeCredentialsHandle
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_FreeCredentialsHandle
(
PCredHandle
phCredential
)
{
struct
sec_handle
*
cred
;
TRACE
(
"%p
\n
"
,
phCredential
);
if
(
!
phCredential
)
return
SEC_E_INVALID_HANDLE
;
cred
=
(
struct
sec_handle
*
)
phCredential
->
dwLower
;
if
(
cred
->
krb
)
cred
->
krb
->
fnTableW
.
FreeCredentialsHandle
(
&
cred
->
handle_krb
);
if
(
cred
->
ntlm
)
cred
->
ntlm
->
fnTableW
.
FreeCredentialsHandle
(
&
cred
->
handle_ntlm
);
free
(
cred
);
return
SEC_E_OK
;
}
/***********************************************************************
* EncryptMessage
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_EncryptMessage
(
PCtxtHandle
phContext
,
ULONG
fQOP
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
)
static
NTSTATUS
NTAPI
nego_SpSealMessage
(
LSA_SEC_HANDLE
context
,
ULONG
quality_of_protection
,
SecBufferDesc
*
message
,
ULONG
message_seq_no
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, 0x%08lx, %p, %lu
\n
"
,
phContext
,
fQOP
,
pMessage
,
MessageSeqNo
);
TRACE
(
"%Ix, %#lx, %p, %lu
\n
"
,
context
,
quality_of_protection
,
message
,
message_seq_no
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
if
(
ctxt
->
krb
)
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
user_
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
EncryptMessage
(
&
ctxt
->
handle_krb
,
fQOP
,
pMessage
,
MessageSeqN
o
);
ret
=
ctxt
->
user_krb
->
SealMessage
(
ctxt
->
handle_krb
,
quality_of_protection
,
message
,
message_seq_n
o
);
}
else
if
(
ctxt
->
ntlm
)
else
if
(
ctxt
->
user_
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
EncryptMessage
(
&
ctxt
->
handle_ntlm
,
fQOP
,
pMessage
,
MessageSeqN
o
);
ret
=
ctxt
->
user_ntlm
->
SealMessage
(
ctxt
->
handle_ntlm
,
quality_of_protection
,
message
,
message_seq_n
o
);
}
return
ret
;
}
/***********************************************************************
* DecryptMessage
*/
static
SECURITY_STATUS
SEC_ENTRY
nego_DecryptMessage
(
PCtxtHandle
phContext
,
PSecBufferDesc
pMessage
,
ULONG
MessageSeqNo
,
PULONG
pfQOP
)
static
NTSTATUS
NTAPI
nego_SpUnsealMessage
(
LSA_SEC_HANDLE
context
,
SecBufferDesc
*
message
,
ULONG
message_seq_no
,
ULONG
*
quality_of_protection
)
{
SECURITY_STATUS
ret
=
SEC_E_INVALID_HANDLE
;
struct
sec_handle
*
ctxt
;
TRACE
(
"%p, %p, %lu, %p
\n
"
,
phContext
,
pMessage
,
MessageSeqNo
,
pfQOP
);
TRACE
(
"%Ix, %p, %lu, %p
\n
"
,
context
,
message
,
message_seq_no
,
quality_of_protection
);
if
(
!
phC
ontext
)
return
SEC_E_INVALID_HANDLE
;
if
(
!
c
ontext
)
return
SEC_E_INVALID_HANDLE
;
ctxt
=
(
struct
sec_handle
*
)
phContext
->
dwLower
;
if
(
ctxt
->
krb
)
ctxt
=
(
struct
sec_handle
*
)
context
;
if
(
ctxt
->
user_
krb
)
{
ret
=
ctxt
->
krb
->
fnTableW
.
DecryptMessage
(
&
ctxt
->
handle_krb
,
pMessage
,
MessageSeqNo
,
pfQOP
);
ret
=
ctxt
->
user_krb
->
UnsealMessage
(
ctxt
->
handle_krb
,
message
,
message_seq_no
,
quality_of_protection
);
}
else
if
(
ctxt
->
ntlm
)
else
if
(
ctxt
->
user_
ntlm
)
{
ret
=
ctxt
->
ntlm
->
fnTableW
.
DecryptMessage
(
&
ctxt
->
handle_ntlm
,
pMessage
,
MessageSeqNo
,
pfQOP
);
ret
=
ctxt
->
user_ntlm
->
UnsealMessage
(
ctxt
->
handle_ntlm
,
message
,
message_seq_no
,
quality_of_protection
);
}
return
ret
;
}
static
const
SecurityFunctionTableA
negoTableA
=
{
1
,
NULL
,
/* EnumerateSecurityPackagesA */
nego_QueryCredentialsAttributesA
,
/* QueryCredentialsAttributesA */
nego_AcquireCredentialsHandleA
,
/* AcquireCredentialsHandleA */
nego_FreeCredentialsHandle
,
/* FreeCredentialsHandle */
NULL
,
/* Reserved2 */
nego_InitializeSecurityContextA
,
/* InitializeSecurityContextA */
nego_AcceptSecurityContext
,
/* AcceptSecurityContext */
nego_CompleteAuthToken
,
/* CompleteAuthToken */
nego_DeleteSecurityContext
,
/* DeleteSecurityContext */
nego_ApplyControlToken
,
/* ApplyControlToken */
nego_QueryContextAttributesA
,
/* QueryContextAttributesA */
nego_ImpersonateSecurityContext
,
/* ImpersonateSecurityContext */
nego_RevertSecurityContext
,
/* RevertSecurityContext */
nego_MakeSignature
,
/* MakeSignature */
nego_VerifySignature
,
/* VerifySignature */
FreeContextBuffer
,
/* FreeContextBuffer */
NULL
,
/* QuerySecurityPackageInfoA */
NULL
,
/* Reserved3 */
NULL
,
/* Reserved4 */
NULL
,
/* ExportSecurityContext */
NULL
,
/* ImportSecurityContextA */
NULL
,
/* AddCredentialsA */
NULL
,
/* Reserved8 */
NULL
,
/* QuerySecurityContextToken */
nego_EncryptMessage
,
/* EncryptMessage */
nego_DecryptMessage
,
/* DecryptMessage */
NULL
,
/* SetContextAttributesA */
};
static
const
SecurityFunctionTableW
negoTableW
=
{
1
,
NULL
,
/* EnumerateSecurityPackagesW */
nego_QueryCredentialsAttributesW
,
/* QueryCredentialsAttributesW */
nego_AcquireCredentialsHandleW
,
/* AcquireCredentialsHandleW */
nego_FreeCredentialsHandle
,
/* FreeCredentialsHandle */
NULL
,
/* Reserved2 */
nego_InitializeSecurityContextW
,
/* InitializeSecurityContextW */
nego_AcceptSecurityContext
,
/* AcceptSecurityContext */
nego_CompleteAuthToken
,
/* CompleteAuthToken */
nego_DeleteSecurityContext
,
/* DeleteSecurityContext */
nego_ApplyControlToken
,
/* ApplyControlToken */
nego_QueryContextAttributesW
,
/* QueryContextAttributesW */
nego_ImpersonateSecurityContext
,
/* ImpersonateSecurityContext */
nego_RevertSecurityContext
,
/* RevertSecurityContext */
nego_MakeSignature
,
/* MakeSignature */
nego_VerifySignature
,
/* VerifySignature */
FreeContextBuffer
,
/* FreeContextBuffer */
NULL
,
/* QuerySecurityPackageInfoW */
NULL
,
/* Reserved3 */
NULL
,
/* Reserved4 */
NULL
,
/* ExportSecurityContext */
NULL
,
/* ImportSecurityContextW */
NULL
,
/* AddCredentialsW */
NULL
,
/* Reserved8 */
NULL
,
/* QuerySecurityContextToken */
nego_EncryptMessage
,
/* EncryptMessage */
nego_DecryptMessage
,
/* DecryptMessage */
NULL
,
/* SetContextAttributesW */
static
SECPKG_USER_FUNCTION_TABLE
nego_user_table
=
{
nego_SpInstanceInit
,
NULL
,
/* SpInitUserModeContext */
nego_SpMakeSignature
,
nego_SpVerifySignature
,
nego_SpSealMessage
,
nego_SpUnsealMessage
,
NULL
,
/* SpGetContextToken */
NULL
,
/* SpQueryContextAttributes */
NULL
,
/* SpCompleteAuthToken */
NULL
,
/* SpDeleteContext */
NULL
,
/* SpFormatCredentialsFn */
NULL
,
/* SpMarshallSupplementalCreds */
NULL
,
/* SpExportSecurityContext */
NULL
/* SpImportSecurityContext */
};
#define NEGO_MAX_TOKEN 12000
static
WCHAR
nego_name_W
[]
=
{
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'e'
,
0
};
static
char
nego_name_A
[]
=
"Negotiate"
;
static
WCHAR
negotiate_comment_W
[]
=
{
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
' '
,
'P'
,
'a'
,
'c'
,
'k'
,
'a'
,
'g'
,
'e'
,
' '
,
'N'
,
'e'
,
'g'
,
'o'
,
't'
,
'i'
,
'a'
,
't'
,
'o'
,
'r'
,
0
};
static
CHAR
negotiate_comment_A
[]
=
"Microsoft Package Negotiator"
;
#define CAPS ( \
SECPKG_FLAG_INTEGRITY | \
SECPKG_FLAG_PRIVACY | \
SECPKG_FLAG_CONNECTION | \
SECPKG_FLAG_MULTI_REQUIRED | \
SECPKG_FLAG_EXTENDED_ERROR | \
SECPKG_FLAG_IMPERSONATION | \
SECPKG_FLAG_ACCEPT_WIN32_NAME | \
SECPKG_FLAG_NEGOTIABLE | \
SECPKG_FLAG_GSS_COMPATIBLE | \
SECPKG_FLAG_LOGON | \
SECPKG_FLAG_RESTRICTED_TOKENS )
void
SECUR32_initNegotiateSP
(
void
)
NTSTATUS
NTAPI
nego_SpUserModeInitialize
(
ULONG
lsa_version
,
PULONG
package_version
,
PSECPKG_USER_FUNCTION_TABLE
*
table
,
PULONG
table_count
)
{
SecureProvider
*
provider
=
SECUR32_addProvider
(
&
negoTableA
,
&
negoTableW
,
NULL
);
TRACE
(
"%#lx, %p, %p, %p
\n
"
,
lsa_version
,
package_version
,
table
,
table_count
);
const
SecPkgInfoW
infoW
=
{
CAPS
,
1
,
RPC_C_AUTHN_GSS_NEGOTIATE
,
NEGO_MAX_TOKEN
,
nego_name_W
,
negotiate_comment_W
};
const
SecPkgInfoA
infoA
=
{
CAPS
,
1
,
RPC_C_AUTHN_GSS_NEGOTIATE
,
NEGO_MAX_TOKEN
,
nego_name_A
,
negotiate_comment_A
};
SECUR32_addPackages
(
provider
,
1L
,
&
infoA
,
&
infoW
);
*
package_version
=
SECPKG_INTERFACE_VERSION
;
*
table
=
&
nego_user_table
;
*
table_count
=
1
;
return
STATUS_SUCCESS
;
}
dlls/secur32/secur32.c
View file @
021547ca
...
...
@@ -501,10 +501,6 @@ static void SECUR32_initializeProviders(void)
SECUR32_initSchannelSP
();
/* Load SSP/AP packages (Kerberos and others) */
load_auth_packages
();
/* Load the Negotiate provider last so apps stumble over the working NTLM
* provider first. Attempting to fix bug #16905 while keeping the
* application reported on wine-users on 2006-09-12 working. */
SECUR32_initNegotiateSP
();
/* Now load providers from registry */
apiRet
=
RegOpenKeyExW
(
HKEY_LOCAL_MACHINE
,
L"SYSTEM
\\
CurrentControlSet
\\
Control
\\
SecurityProviders"
,
0
,
KEY_READ
,
&
key
);
...
...
dlls/secur32/secur32_priv.h
View file @
021547ca
...
...
@@ -24,6 +24,8 @@
#include <sys/types.h>
#include <limits.h>
#include "schannel.h"
#include "ntsecapi.h"
#include "ntsecpkg.h"
#include "wine/list.h"
typedef
struct
_SecureProvider
...
...
@@ -70,8 +72,10 @@ SecurePackage *SECUR32_findPackageA(PCSTR packageName) DECLSPEC_HIDDEN;
/* Initialization functions for built-in providers */
void
SECUR32_initSchannelSP
(
void
)
DECLSPEC_HIDDEN
;
void
SECUR32_initNegotiateSP
(
void
)
DECLSPEC_HIDDEN
;
void
load_auth_packages
(
void
)
DECLSPEC_HIDDEN
;
NTSTATUS
NTAPI
nego_SpLsaModeInitialize
(
ULONG
,
PULONG
,
PSECPKG_FUNCTION_TABLE
*
,
PULONG
)
DECLSPEC_HIDDEN
;
NTSTATUS
NTAPI
nego_SpUserModeInitialize
(
ULONG
,
PULONG
,
PSECPKG_USER_FUNCTION_TABLE
*
,
PULONG
)
DECLSPEC_HIDDEN
;
SECPKG_FUNCTION_TABLE
*
lsa_find_package
(
const
char
*
name
,
SECPKG_USER_FUNCTION_TABLE
**
user_api
)
DECLSPEC_HIDDEN
;
/* Cleanup functions for built-in providers */
void
SECUR32_deinitSchannelSP
(
void
)
DECLSPEC_HIDDEN
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment