Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
de53f568
Commit
de53f568
authored
Nov 04, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kerberos: Move the ticket cache memory allocation to the PE side.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
b2009d02
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
101 additions
and
116 deletions
+101
-116
krb5_ap.c
dlls/kerberos/krb5_ap.c
+30
-72
unixlib.c
dlls/kerberos/unixlib.c
+70
-36
unixlib.h
dlls/kerberos/unixlib.h
+1
-8
No files found.
dlls/kerberos/krb5_ap.c
View file @
de53f568
...
...
@@ -111,91 +111,47 @@ static NTSTATUS NTAPI kerberos_LsaApInitializePackage(ULONG package_id, PLSA_DIS
return
STATUS_SUCCESS
;
}
static
void
free_ticket_list
(
struct
ticket_list
*
list
)
{
ULONG
i
;
for
(
i
=
0
;
i
<
list
->
count
;
i
++
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
list
->
tickets
[
i
].
RealmName
.
Buffer
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
list
->
tickets
[
i
].
ServerName
.
Buffer
);
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
list
->
tickets
);
}
static
inline
void
init_client_us
(
UNICODE_STRING
*
dst
,
void
*
client_ws
,
const
UNICODE_STRING
*
src
)
{
dst
->
Buffer
=
client_ws
;
dst
->
Length
=
src
->
Length
;
dst
->
MaximumLength
=
src
->
MaximumLength
;
}
static
NTSTATUS
copy_to_client
(
PLSA_CLIENT_REQUEST
lsa_req
,
struct
ticket_list
*
list
,
void
**
out
,
ULONG
*
out_size
)
static
NTSTATUS
copy_to_client
(
PLSA_CLIENT_REQUEST
lsa_req
,
KERB_QUERY_TKT_CACHE_RESPONSE
*
resp
,
void
**
out
,
ULONG
size
)
{
NTSTATUS
status
;
ULONG
i
;
SIZE_T
size
,
client_str_off
;
char
*
client_resp
,
*
client_ticket
,
*
client_str
;
KERB_QUERY_TKT_CACHE_RESPONSE
resp
;
size
=
sizeof
(
resp
);
if
(
list
->
count
)
size
+=
(
list
->
count
-
1
)
*
sizeof
(
KERB_TICKET_CACHE_INFO
);
client_str_off
=
size
;
char
*
client_str
;
KERB_QUERY_TKT_CACHE_RESPONSE
*
client_resp
;
for
(
i
=
0
;
i
<
list
->
count
;
i
++
)
{
size
+=
list
->
tickets
[
i
].
RealmName
.
MaximumLength
;
size
+=
list
->
tickets
[
i
].
ServerName
.
MaximumLength
;
}
status
=
lsa_dispatch
.
AllocateClientBuffer
(
lsa_req
,
size
,
(
void
**
)
&
client_resp
);
status
=
lsa_dispatch
.
AllocateClientBuffer
(
lsa_req
,
size
,
out
);
if
(
status
!=
STATUS_SUCCESS
)
return
status
;
resp
.
MessageType
=
KerbQueryTicketCacheMessage
;
resp
.
CountOfTickets
=
list
->
count
;
size
=
FIELD_OFFSET
(
KERB_QUERY_TKT_CACHE_RESPONSE
,
Tickets
);
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
size
,
client_resp
,
&
resp
);
client_resp
=
*
out
;
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
offsetof
(
KERB_QUERY_TKT_CACHE_RESPONSE
,
Tickets
),
client_resp
,
resp
);
if
(
status
!=
STATUS_SUCCESS
)
goto
fail
;
if
(
!
list
->
count
)
{
*
out
=
client_resp
;
*
out_size
=
sizeof
(
resp
);
return
STATUS_SUCCESS
;
}
*
out_size
=
size
;
client_ticket
=
client_resp
+
size
;
client_str
=
client_resp
+
client_str_off
;
client_str
=
(
char
*
)
&
client_resp
->
Tickets
[
resp
->
CountOfTickets
];
for
(
i
=
0
;
i
<
list
->
count
;
i
++
)
for
(
i
=
0
;
i
<
resp
->
CountOfTickets
;
i
++
)
{
KERB_TICKET_CACHE_INFO
ticket
=
list
->
t
ickets
[
i
];
KERB_TICKET_CACHE_INFO
ticket
=
resp
->
T
ickets
[
i
];
init_client_us
(
&
ticket
.
RealmName
,
client_str
,
&
list
->
tickets
[
i
].
RealmName
);
RtlSecondsSince1970ToTime
(
resp
->
Tickets
[
i
].
StartTime
.
QuadPart
,
&
ticket
.
StartTime
);
RtlSecondsSince1970ToTime
(
resp
->
Tickets
[
i
].
EndTime
.
QuadPart
,
&
ticket
.
EndTime
);
RtlSecondsSince1970ToTime
(
resp
->
Tickets
[
i
].
RenewTime
.
QuadPart
,
&
ticket
.
RenewTime
);
s
ize
=
ticket
.
RealmName
.
MaximumLength
;
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
size
,
client_str
,
list
->
tickets
[
i
]
.
RealmName
.
Buffer
);
s
tatus
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
ticket
.
RealmName
.
MaximumLength
,
client_str
,
ticket
.
RealmName
.
Buffer
);
if
(
status
!=
STATUS_SUCCESS
)
goto
fail
;
client_str
+=
size
;
*
out_size
+=
size
;
init_client_us
(
&
ticket
.
ServerName
,
client_str
,
&
list
->
tickets
[
i
].
ServerName
);
ticket
.
RealmName
.
Buffer
=
(
WCHAR
*
)
client_str
;
client_str
+=
ticket
.
RealmName
.
MaximumLength
;
s
ize
=
ticket
.
ServerName
.
MaximumLength
;
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
size
,
client_str
,
list
->
tickets
[
i
]
.
ServerName
.
Buffer
);
s
tatus
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
ticket
.
ServerName
.
MaximumLength
,
client_str
,
ticket
.
ServerName
.
Buffer
);
if
(
status
!=
STATUS_SUCCESS
)
goto
fail
;
client_str
+=
size
;
*
out_size
+=
size
;
ticket
.
ServerName
.
Buffer
=
(
WCHAR
*
)
client_str
;
client_str
+=
ticket
.
ServerName
.
MaximumLength
;
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
sizeof
(
ticket
),
client_ticket
,
&
ticket
);
status
=
lsa_dispatch
.
CopyToClientBuffer
(
lsa_req
,
sizeof
(
ticket
),
&
client_resp
->
Tickets
[
i
]
,
&
ticket
);
if
(
status
!=
STATUS_SUCCESS
)
goto
fail
;
client_ticket
+=
sizeof
(
ticket
);
*
out_size
+=
sizeof
(
ticket
);
}
*
out
=
client_resp
;
return
STATUS_SUCCESS
;
fail:
...
...
@@ -218,17 +174,19 @@ static NTSTATUS NTAPI kerberos_LsaApCallPackageUntrusted(PLSA_CLIENT_REQUEST req
case
KerbQueryTicketCacheMessage
:
{
KERB_QUERY_TKT_CACHE_REQUEST
*
query
=
(
KERB_QUERY_TKT_CACHE_REQUEST
*
)
in_buf
;
struct
ticket_list
list
;
NTSTATUS
status
;
if
(
!
in_buf
||
in_buf_len
!=
sizeof
(
*
query
)
||
!
out_buf
||
!
out_buf_len
)
return
STATUS_INVALID_PARAMETER
;
if
(
query
->
LogonId
.
HighPart
||
query
->
LogonId
.
LowPart
)
return
STATUS_ACCESS_DENIED
;
status
=
krb5_funcs
->
query_ticket_cache
(
&
list
)
;
if
(
!
status
)
*
out_buf_len
=
1024
;
for
(;;
)
{
status
=
copy_to_client
(
req
,
&
list
,
out_buf
,
out_buf_len
);
free_ticket_list
(
&
list
);
KERB_QUERY_TKT_CACHE_RESPONSE
*
resp
=
malloc
(
*
out_buf_len
);
status
=
krb5_funcs
->
query_ticket_cache
(
resp
,
out_buf_len
);
if
(
status
==
STATUS_SUCCESS
)
status
=
copy_to_client
(
req
,
resp
,
out_buf
,
*
out_buf_len
);
free
(
resp
);
if
(
status
!=
STATUS_BUFFER_TOO_SMALL
)
break
;
}
*
ret_status
=
status
;
break
;
...
...
dlls/kerberos/unixlib.c
View file @
de53f568
...
...
@@ -151,15 +151,21 @@ static NTSTATUS krb5_error_to_status( krb5_error_code err )
}
}
static
WCHAR
*
utf8_to_wstr
(
const
char
*
src
)
struct
ticket_list
{
ULONG
count
;
ULONG
allocated
;
KERB_TICKET_CACHE_INFO
*
tickets
;
};
static
void
utf8_to_wstr
(
UNICODE_STRING
*
strW
,
const
char
*
src
)
{
ULONG
dstlen
,
srclen
=
strlen
(
src
)
+
1
;
WCHAR
*
dst
;
RtlUTF8ToUnicodeN
(
NULL
,
0
,
&
dstlen
,
src
,
srclen
);
if
((
dst
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
dstlen
)))
RtlUTF8ToUnicodeN
(
dst
,
dstlen
,
&
dstlen
,
src
,
srclen
)
;
return
dst
;
strW
->
Buffer
=
malloc
(
srclen
*
sizeof
(
WCHAR
)
);
RtlUTF8ToUnicodeN
(
strW
->
Buffer
,
srclen
*
sizeof
(
WCHAR
),
&
dstlen
,
src
,
srclen
);
strW
->
MaximumLength
=
dstlen
;
strW
->
Length
=
dstlen
-
sizeof
(
WCHAR
)
;
}
static
NTSTATUS
copy_tickets_from_cache
(
krb5_context
ctx
,
krb5_ccache
cache
,
struct
ticket_list
*
list
)
...
...
@@ -170,7 +176,6 @@ static NTSTATUS copy_tickets_from_cache( krb5_context ctx, krb5_ccache cache, st
krb5_creds
creds
;
krb5_ticket
*
ticket
;
char
*
name_with_realm
,
*
name_without_realm
,
*
realm_name
;
WCHAR
*
realm_nameW
,
*
name_without_realmW
;
if
((
err
=
p_krb5_cc_start_seq_get
(
ctx
,
cache
,
&
cursor
)))
return
krb5_error_to_status
(
err
);
for
(;;)
...
...
@@ -192,19 +197,8 @@ static NTSTATUS copy_tickets_from_cache( krb5_context ctx, krb5_ccache cache, st
if
(
list
->
count
==
list
->
allocated
)
{
KERB_TICKET_CACHE_INFO
*
new_tickets
;
ULONG
new_allocated
;
if
(
list
->
allocated
)
{
new_allocated
=
list
->
allocated
*
2
;
new_tickets
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
list
->
tickets
,
sizeof
(
*
new_tickets
)
*
new_allocated
);
}
else
{
new_allocated
=
16
;
new_tickets
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
*
new_tickets
)
*
new_allocated
);
}
ULONG
new_allocated
=
max
(
16
,
list
->
allocated
*
2
);
KERB_TICKET_CACHE_INFO
*
new_tickets
=
realloc
(
list
->
tickets
,
sizeof
(
*
new_tickets
)
*
new_allocated
);
if
(
!
new_tickets
)
{
p_krb5_free_cred_contents
(
ctx
,
&
creds
);
...
...
@@ -233,8 +227,7 @@ static NTSTATUS copy_tickets_from_cache( krb5_context ctx, krb5_ccache cache, st
}
TRACE
(
"name_without_realm: %s
\n
"
,
debugstr_a
(
name_without_realm
)
);
name_without_realmW
=
utf8_to_wstr
(
name_without_realm
);
RtlInitUnicodeString
(
&
list
->
tickets
[
list
->
count
].
ServerName
,
name_without_realmW
);
utf8_to_wstr
(
&
list
->
tickets
[
list
->
count
].
ServerName
,
name_without_realm
);
if
(
!
(
realm_name
=
strchr
(
name_with_realm
,
'@'
)))
{
...
...
@@ -244,17 +237,17 @@ static NTSTATUS copy_tickets_from_cache( krb5_context ctx, krb5_ccache cache, st
else
realm_name
++
;
/* realm_name - now contains only realm! */
realm_nameW
=
utf8_to_wstr
(
realm_name
);
RtlInitUnicodeString
(
&
list
->
tickets
[
list
->
count
].
RealmName
,
realm_nameW
);
utf8_to_wstr
(
&
list
->
tickets
[
list
->
count
].
RealmName
,
realm_name
);
if
(
!
creds
.
times
.
starttime
)
creds
.
times
.
starttime
=
creds
.
times
.
authtime
;
/* TODO: if krb5_is_config_principal = true */
RtlSecondsSince1970ToTime
(
creds
.
times
.
starttime
,
&
list
->
tickets
[
list
->
count
].
StartTime
);
RtlSecondsSince1970ToTime
(
creds
.
times
.
endtime
,
&
list
->
tickets
[
list
->
count
].
EndTime
);
RtlSecondsSince1970ToTime
(
creds
.
times
.
renew_till
,
&
list
->
tickets
[
list
->
count
].
RenewTime
);
list
->
tickets
[
list
->
count
].
TicketFlags
=
creds
.
ticket_flags
;
/* note: store times as seconds, they will be converted to NT timestamps on the PE side */
list
->
tickets
[
list
->
count
].
StartTime
.
QuadPart
=
creds
.
times
.
starttime
;
list
->
tickets
[
list
->
count
].
EndTime
.
QuadPart
=
creds
.
times
.
endtime
;
list
->
tickets
[
list
->
count
].
RenewTime
.
QuadPart
=
creds
.
times
.
renew_till
;
list
->
tickets
[
list
->
count
].
TicketFlags
=
creds
.
ticket_flags
;
err
=
p_krb5_decode_ticket
(
&
creds
.
ticket
,
&
ticket
);
p_krb5_free_unparsed_name
(
ctx
,
name_with_realm
);
...
...
@@ -275,17 +268,50 @@ static NTSTATUS copy_tickets_from_cache( krb5_context ctx, krb5_ccache cache, st
return
status
;
}
static
NTSTATUS
CDECL
query_ticket_cache
(
struct
ticket_list
*
list
)
static
NTSTATUS
copy_tickets_to_client
(
struct
ticket_list
*
list
,
KERB_QUERY_TKT_CACHE_RESPONSE
*
resp
,
ULONG
*
out_size
)
{
char
*
client_str
;
ULONG
i
,
size
=
offsetof
(
KERB_QUERY_TKT_CACHE_RESPONSE
,
Tickets
[
list
->
count
]
);
for
(
i
=
0
;
i
<
list
->
count
;
i
++
)
{
size
+=
list
->
tickets
[
i
].
RealmName
.
MaximumLength
;
size
+=
list
->
tickets
[
i
].
ServerName
.
MaximumLength
;
}
if
(
!
resp
||
size
>
*
out_size
)
{
*
out_size
=
size
;
return
STATUS_BUFFER_TOO_SMALL
;
}
*
out_size
=
size
;
resp
->
MessageType
=
KerbQueryTicketCacheMessage
;
resp
->
CountOfTickets
=
list
->
count
;
memcpy
(
resp
->
Tickets
,
list
->
tickets
,
list
->
count
*
sizeof
(
list
->
tickets
[
0
])
);
client_str
=
(
char
*
)
&
resp
->
Tickets
[
list
->
count
];
for
(
i
=
0
;
i
<
list
->
count
;
i
++
)
{
resp
->
Tickets
[
i
].
RealmName
.
Buffer
=
(
WCHAR
*
)
client_str
;
memcpy
(
client_str
,
list
->
tickets
[
i
].
RealmName
.
Buffer
,
list
->
tickets
[
i
].
RealmName
.
MaximumLength
);
client_str
+=
list
->
tickets
[
i
].
RealmName
.
MaximumLength
;
resp
->
Tickets
[
i
].
ServerName
.
Buffer
=
(
WCHAR
*
)
client_str
;
memcpy
(
client_str
,
list
->
tickets
[
i
].
ServerName
.
Buffer
,
list
->
tickets
[
i
].
ServerName
.
MaximumLength
);
client_str
+=
list
->
tickets
[
i
].
ServerName
.
MaximumLength
;
}
return
STATUS_SUCCESS
;
}
static
NTSTATUS
CDECL
query_ticket_cache
(
KERB_QUERY_TKT_CACHE_RESPONSE
*
resp
,
ULONG
*
out_size
)
{
NTSTATUS
status
;
krb5_error_code
err
;
krb5_context
ctx
;
krb5_cccol_cursor
cursor
=
NULL
;
krb5_ccache
cache
;
list
->
count
=
0
;
list
->
allocated
=
0
;
list
->
tickets
=
NULL
;
ULONG
i
;
struct
ticket_list
list
=
{
0
};
if
((
err
=
p_krb5_init_context
(
&
ctx
)))
return
krb5_error_to_status
(
err
);
if
((
err
=
p_krb5_cccol_cursor_new
(
ctx
,
&
cursor
)))
...
...
@@ -303,7 +329,7 @@ static NTSTATUS CDECL query_ticket_cache( struct ticket_list *list )
}
if
(
!
cache
)
break
;
status
=
copy_tickets_from_cache
(
ctx
,
cache
,
list
);
status
=
copy_tickets_from_cache
(
ctx
,
cache
,
&
list
);
p_krb5_cc_close
(
ctx
,
cache
);
if
(
status
!=
STATUS_SUCCESS
)
goto
done
;
}
...
...
@@ -311,6 +337,14 @@ static NTSTATUS CDECL query_ticket_cache( struct ticket_list *list )
done:
if
(
cursor
)
p_krb5_cccol_cursor_free
(
ctx
,
&
cursor
);
if
(
ctx
)
p_krb5_free_context
(
ctx
);
if
(
status
==
STATUS_SUCCESS
)
status
=
copy_tickets_to_client
(
&
list
,
resp
,
out_size
);
for
(
i
=
0
;
i
<
list
.
count
;
i
++
)
{
free
(
list
.
tickets
[
i
].
RealmName
.
Buffer
);
free
(
list
.
tickets
[
i
].
ServerName
.
Buffer
);
}
return
status
;
}
...
...
@@ -949,12 +983,12 @@ static NTSTATUS unseal_message_no_vector( gss_ctx_id_t ctx, SecBufferDesc *msg,
len_token
=
msg
->
pBuffers
[
token_idx
].
cbBuffer
;
input
.
length
=
len_data
+
len_token
;
if
(
!
(
input
.
value
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
input
.
length
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
if
(
!
(
input
.
value
=
malloc
(
input
.
length
)))
return
SEC_E_INSUFFICIENT_MEMORY
;
memcpy
(
input
.
value
,
msg
->
pBuffers
[
data_idx
].
pvBuffer
,
len_data
);
memcpy
(
(
char
*
)
input
.
value
+
len_data
,
msg
->
pBuffers
[
token_idx
].
pvBuffer
,
len_token
);
ret
=
pgss_unwrap
(
&
minor_status
,
ctx
,
&
input
,
&
output
,
&
conf_state
,
NULL
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
input
.
value
);
free
(
input
.
value
);
TRACE
(
"gss_unwrap returned %08x minor status %08x
\n
"
,
ret
,
minor_status
);
if
(
GSS_ERROR
(
ret
))
trace_gss_status
(
ret
,
minor_status
);
if
(
ret
==
GSS_S_COMPLETE
)
...
...
dlls/kerberos/unixlib.h
View file @
de53f568
...
...
@@ -21,13 +21,6 @@
#define KERBEROS_MAX_BUF 12000
struct
ticket_list
{
ULONG
count
;
ULONG
allocated
;
KERB_TICKET_CACHE_INFO
*
tickets
;
};
struct
krb5_funcs
{
NTSTATUS
(
CDECL
*
accept_context
)(
LSA_SEC_HANDLE
,
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
LSA_SEC_HANDLE
*
,
...
...
@@ -40,7 +33,7 @@ struct krb5_funcs
LSA_SEC_HANDLE
*
,
SecBufferDesc
*
,
ULONG
*
,
TimeStamp
*
);
NTSTATUS
(
CDECL
*
make_signature
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
);
NTSTATUS
(
CDECL
*
query_context_attributes
)(
LSA_SEC_HANDLE
,
ULONG
,
void
*
);
NTSTATUS
(
CDECL
*
query_ticket_cache
)(
struct
ticket_list
*
);
NTSTATUS
(
CDECL
*
query_ticket_cache
)(
KERB_QUERY_TKT_CACHE_RESPONSE
*
resp
,
ULONG
*
out_size
);
NTSTATUS
(
CDECL
*
seal_message
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
);
NTSTATUS
(
CDECL
*
unseal_message
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
*
);
NTSTATUS
(
CDECL
*
verify_signature
)(
LSA_SEC_HANDLE
,
SecBufferDesc
*
,
ULONG
*
);
...
...
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