4 * Copyright 2001 Ove Kåven, TransGaming Technologies
5 * Copyright 2003 Mike Hearn
6 * Copyright 2004 Filip Navara
7 * Copyright 2006 CodeWeavers
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
28 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
32 if (!src
) return NULL
;
33 if (slen
== -1) slen
= strlen(src
);
35 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
41 LPSTR
RPCRT4_strdupWtoA(LPCWSTR src
)
45 if (!src
) return NULL
;
46 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
47 s
= HeapAlloc(GetProcessHeap(), 0, len
);
48 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
52 LPWSTR
RPCRT4_strdupAtoW(LPCSTR src
)
56 if (!src
) return NULL
;
57 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
58 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
59 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
63 static LPWSTR
RPCRT4_strndupAtoW(LPCSTR src
, INT slen
)
67 if (!src
) return NULL
;
68 len
= MultiByteToWideChar(CP_ACP
, 0, src
, slen
, NULL
, 0);
69 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
70 MultiByteToWideChar(CP_ACP
, 0, src
, slen
, s
, len
);
74 LPWSTR
RPCRT4_strndupW(LPCWSTR src
, INT slen
)
78 if (!src
) return NULL
;
79 if (slen
== -1) slen
= strlenW(src
);
81 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
82 memcpy(s
, src
, len
*sizeof(WCHAR
));
87 void RPCRT4_strfree(LPSTR src
)
89 HeapFree(GetProcessHeap(), 0, src
);
92 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
94 RpcBinding
* NewBinding
;
96 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
98 NewBinding
->server
= server
;
100 *Binding
= NewBinding
;
105 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
107 RpcBinding
* NewBinding
;
109 RPCRT4_AllocBinding(&NewBinding
, server
);
110 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
112 TRACE("binding: %p\n", NewBinding
);
113 *Binding
= NewBinding
;
118 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
120 RpcBinding
* NewBinding
;
122 RPCRT4_AllocBinding(&NewBinding
, server
);
123 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
125 TRACE("binding: %p\n", NewBinding
);
126 *Binding
= NewBinding
;
131 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
132 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
136 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
137 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
139 RPCRT4_strfree(Binding
->NetworkAddr
);
140 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
141 RPCRT4_strfree(Binding
->Endpoint
);
142 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
143 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
144 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
146 /* only attempt to get an association if the binding is complete */
147 if (Endpoint
&& Endpoint
[0] != '\0')
149 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
150 Binding
->Endpoint
, Binding
->NetworkOptions
,
152 if (status
!= RPC_S_OK
)
159 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
160 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
164 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
165 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
167 RPCRT4_strfree(Binding
->NetworkAddr
);
168 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
169 RPCRT4_strfree(Binding
->Endpoint
);
170 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
171 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
172 Binding
->NetworkOptions
= RPCRT4_strdupW(NetworkOptions
);
174 /* only attempt to get an association if the binding is complete */
175 if (Endpoint
&& Endpoint
[0] != '\0')
177 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
178 Binding
->Endpoint
, Binding
->NetworkOptions
,
180 if (status
!= RPC_S_OK
)
187 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
191 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
193 RPCRT4_strfree(Binding
->Endpoint
);
194 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
196 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
197 Binding
->Assoc
= NULL
;
198 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
199 Binding
->Endpoint
, Binding
->NetworkOptions
,
201 if (status
!= RPC_S_OK
)
207 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
209 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
210 if (ObjectUuid
) Binding
->ObjectUuid
= *ObjectUuid
;
211 else UuidCreateNil(&Binding
->ObjectUuid
);
215 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
217 RpcBinding
* NewBinding
;
218 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
220 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
221 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
222 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
223 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
224 NewBinding
->FromConn
= Connection
;
226 TRACE("binding: %p\n", NewBinding
);
227 *Binding
= NewBinding
;
232 void RPCRT4_AddRefBinding(RpcBinding
* Binding
)
234 InterlockedIncrement(&Binding
->refs
);
237 RPC_STATUS
RPCRT4_ReleaseBinding(RpcBinding
* Binding
)
239 if (InterlockedDecrement(&Binding
->refs
))
242 TRACE("binding: %p\n", Binding
);
243 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
244 RPCRT4_strfree(Binding
->Endpoint
);
245 RPCRT4_strfree(Binding
->NetworkAddr
);
246 RPCRT4_strfree(Binding
->Protseq
);
247 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
248 HeapFree(GetProcessHeap(), 0, Binding
->CookieAuth
);
249 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
250 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
251 HeapFree(GetProcessHeap(), 0, Binding
);
255 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
256 const RPC_SYNTAX_IDENTIFIER
*TransferSyntax
,
257 const RPC_SYNTAX_IDENTIFIER
*InterfaceId
)
259 TRACE("(Binding == ^%p)\n", Binding
);
261 if (!Binding
->server
) {
262 return RpcAssoc_GetClientConnection(Binding
->Assoc
, InterfaceId
,
263 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
, Binding
->CookieAuth
, Connection
);
265 /* we already have a connection with acceptable binding, so use it */
266 if (Binding
->FromConn
) {
267 *Connection
= Binding
->FromConn
;
270 ERR("no connection in binding\n");
271 return RPC_S_INTERNAL_ERROR
;
276 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
278 TRACE("(Binding == ^%p)\n", Binding
);
279 if (!Connection
) return RPC_S_OK
;
280 if (Binding
->server
) {
281 /* don't destroy a connection that is cached in the binding */
282 if (Binding
->FromConn
!= Connection
)
283 RPCRT4_ReleaseConnection(Connection
);
286 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
291 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
293 DWORD len
= strlen(dst
), slen
= strlen(src
);
294 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
297 HeapFree(GetProcessHeap(), 0, dst
);
301 memcpy(ndst
+len
+1, src
, slen
+1);
305 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
307 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
308 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
311 HeapFree(GetProcessHeap(), 0, dst
);
315 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
319 /* Copies the escaped version of a component into a string binding.
320 * Note: doesn't nul-terminate the string */
321 static RPC_CSTR
escape_string_binding_component(RPC_CSTR string_binding
,
322 const unsigned char *component
)
324 for (; *component
; component
++) {
325 switch (*component
) {
331 *string_binding
++ = '\\';
332 *string_binding
++ = *component
;
335 *string_binding
++ = *component
;
339 return string_binding
;
342 static RPC_WSTR
escape_string_binding_componentW(RPC_WSTR string_binding
,
343 const WCHAR
*component
)
345 for (; *component
; component
++) {
346 switch (*component
) {
352 *string_binding
++ = '\\';
353 *string_binding
++ = *component
;
356 *string_binding
++ = *component
;
360 return string_binding
;
363 static const unsigned char *string_binding_find_delimiter(
364 const unsigned char *string_binding
, unsigned char delim
)
366 const unsigned char *next
;
367 for (next
= string_binding
; *next
; next
++) {
378 static const WCHAR
*string_binding_find_delimiterW(
379 const WCHAR
*string_binding
, WCHAR delim
)
382 for (next
= string_binding
; *next
; next
++) {
393 static RPC_CSTR
unescape_string_binding_component(
394 const unsigned char *string_binding
, int len
)
396 RPC_CSTR component
, p
;
398 if (len
== -1) len
= strlen((const char *)string_binding
);
400 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
401 if (!component
) return NULL
;
402 for (p
= component
; len
> 0; string_binding
++, len
--) {
403 if (*string_binding
== '\\') {
406 *p
++ = *string_binding
;
408 *p
++ = *string_binding
;
415 static RPC_WSTR
unescape_string_binding_componentW(
416 const WCHAR
*string_binding
, int len
)
418 RPC_WSTR component
, p
;
420 if (len
== -1) len
= strlenW(string_binding
);
422 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
423 if (!component
) return NULL
;
424 for (p
= component
; len
> 0; string_binding
++, len
--) {
425 if (*string_binding
== '\\') {
428 *p
++ = *string_binding
;
430 *p
++ = *string_binding
;
437 /***********************************************************************
438 * RpcStringBindingComposeA (RPCRT4.@)
440 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
441 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
442 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
447 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
448 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
449 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
450 debugstr_a( (char*)Options
), StringBinding
);
452 /* overestimate for each component for escaping of delimiters */
453 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) * 2 + 1;
454 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) * 2 + 1;
455 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
) * 2;
456 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) * 2 + 2;
457 if (Options
&& *Options
) len
+= strlen((char*)Options
) * 2 + 2;
459 data
= HeapAlloc(GetProcessHeap(), 0, len
);
460 *StringBinding
= data
;
462 if (ObjUuid
&& *ObjUuid
) {
463 data
= escape_string_binding_component(data
, ObjUuid
);
466 if (Protseq
&& *Protseq
) {
467 data
= escape_string_binding_component(data
, Protseq
);
470 if (NetworkAddr
&& *NetworkAddr
)
471 data
= escape_string_binding_component(data
, NetworkAddr
);
473 if ((Endpoint
&& *Endpoint
) ||
474 (Options
&& *Options
)) {
476 if (Endpoint
&& *Endpoint
) {
477 data
= escape_string_binding_component(data
, Endpoint
);
478 if (Options
&& *Options
) *data
++ = ',';
480 if (Options
&& *Options
) {
481 data
= escape_string_binding_component(data
, Options
);
490 /***********************************************************************
491 * RpcStringBindingComposeW (RPCRT4.@)
493 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
494 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
495 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
500 TRACE("(%s,%s,%s,%s,%s,%p)\n",
501 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
502 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
503 debugstr_w( Options
), StringBinding
);
505 /* overestimate for each component for escaping of delimiters */
506 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) * 2 + 1;
507 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) * 2 + 1;
508 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
) * 2;
509 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) * 2 + 2;
510 if (Options
&& *Options
) len
+= strlenW(Options
) * 2 + 2;
512 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
513 *StringBinding
= data
;
515 if (ObjUuid
&& *ObjUuid
) {
516 data
= escape_string_binding_componentW(data
, ObjUuid
);
519 if (Protseq
&& *Protseq
) {
520 data
= escape_string_binding_componentW(data
, Protseq
);
523 if (NetworkAddr
&& *NetworkAddr
) {
524 data
= escape_string_binding_componentW(data
, NetworkAddr
);
526 if ((Endpoint
&& *Endpoint
) ||
527 (Options
&& *Options
)) {
529 if (Endpoint
&& *Endpoint
) {
530 data
= escape_string_binding_componentW(data
, Endpoint
);
531 if (Options
&& *Options
) *data
++ = ',';
533 if (Options
&& *Options
) {
534 data
= escape_string_binding_componentW(data
, Options
);
544 /***********************************************************************
545 * RpcStringBindingParseA (RPCRT4.@)
547 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
548 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
549 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
551 const unsigned char *data
, *next
;
552 static const char ep_opt
[] = "endpoint=";
553 BOOL endpoint_already_found
= FALSE
;
555 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
556 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
558 if (ObjUuid
) *ObjUuid
= NULL
;
559 if (Protseq
) *Protseq
= NULL
;
560 if (NetworkAddr
) *NetworkAddr
= NULL
;
561 if (Endpoint
) *Endpoint
= NULL
;
562 if (Options
) *Options
= NULL
;
564 data
= StringBinding
;
566 next
= string_binding_find_delimiter(data
, '@');
570 RPC_CSTR str_uuid
= unescape_string_binding_component(data
, next
- data
);
571 status
= UuidFromStringA(str_uuid
, &uuid
);
572 if (status
!= RPC_S_OK
) {
573 HeapFree(GetProcessHeap(), 0, str_uuid
);
579 HeapFree(GetProcessHeap(), 0, str_uuid
);
583 next
= string_binding_find_delimiter(data
, ':');
585 if (Protseq
) *Protseq
= unescape_string_binding_component(data
, next
- data
);
589 next
= string_binding_find_delimiter(data
, '[');
591 const unsigned char *close
;
594 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_component(data
, next
- data
);
596 close
= string_binding_find_delimiter(data
, ']');
597 if (!close
) goto fail
;
599 /* tokenize options */
600 while (data
< close
) {
601 next
= string_binding_find_delimiter(data
, ',');
602 if (!next
|| next
> close
) next
= close
;
603 /* FIXME: this is kind of inefficient */
604 opt
= unescape_string_binding_component(data
, next
- data
);
608 next
= string_binding_find_delimiter(opt
, '=');
610 /* not an option, must be an endpoint */
611 if (endpoint_already_found
) goto fail
;
612 if (Endpoint
) *Endpoint
= opt
;
613 else HeapFree(GetProcessHeap(), 0, opt
);
614 endpoint_already_found
= TRUE
;
616 if (strncmp((const char *)opt
, ep_opt
, strlen(ep_opt
)) == 0) {
617 /* endpoint option */
618 if (endpoint_already_found
) goto fail
;
619 if (Endpoint
) *Endpoint
= unescape_string_binding_component(next
+1, -1);
620 HeapFree(GetProcessHeap(), 0, opt
);
621 endpoint_already_found
= TRUE
;
626 /* FIXME: this is kind of inefficient */
627 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, (char *)opt
);
628 HeapFree(GetProcessHeap(), 0, opt
);
632 HeapFree(GetProcessHeap(), 0, opt
);
638 if (*data
) goto fail
;
640 else if (NetworkAddr
)
641 *NetworkAddr
= unescape_string_binding_component(data
, -1);
646 if (ObjUuid
) RpcStringFreeA(ObjUuid
);
647 if (Protseq
) RpcStringFreeA(Protseq
);
648 if (NetworkAddr
) RpcStringFreeA(NetworkAddr
);
649 if (Endpoint
) RpcStringFreeA(Endpoint
);
650 if (Options
) RpcStringFreeA(Options
);
651 return RPC_S_INVALID_STRING_BINDING
;
654 /***********************************************************************
655 * RpcStringBindingParseW (RPCRT4.@)
657 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
658 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
659 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
661 const WCHAR
*data
, *next
;
662 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
663 BOOL endpoint_already_found
= FALSE
;
665 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
666 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
668 if (ObjUuid
) *ObjUuid
= NULL
;
669 if (Protseq
) *Protseq
= NULL
;
670 if (NetworkAddr
) *NetworkAddr
= NULL
;
671 if (Endpoint
) *Endpoint
= NULL
;
672 if (Options
) *Options
= NULL
;
674 data
= StringBinding
;
676 next
= string_binding_find_delimiterW(data
, '@');
680 RPC_WSTR str_uuid
= unescape_string_binding_componentW(data
, next
- data
);
681 status
= UuidFromStringW(str_uuid
, &uuid
);
682 if (status
!= RPC_S_OK
) {
683 HeapFree(GetProcessHeap(), 0, str_uuid
);
689 HeapFree(GetProcessHeap(), 0, str_uuid
);
693 next
= string_binding_find_delimiterW(data
, ':');
695 if (Protseq
) *Protseq
= unescape_string_binding_componentW(data
, next
- data
);
699 next
= string_binding_find_delimiterW(data
, '[');
704 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_componentW(data
, next
- data
);
706 close
= string_binding_find_delimiterW(data
, ']');
707 if (!close
) goto fail
;
709 /* tokenize options */
710 while (data
< close
) {
711 next
= string_binding_find_delimiterW(data
, ',');
712 if (!next
|| next
> close
) next
= close
;
713 /* FIXME: this is kind of inefficient */
714 opt
= unescape_string_binding_componentW(data
, next
- data
);
718 next
= string_binding_find_delimiterW(opt
, '=');
720 /* not an option, must be an endpoint */
721 if (endpoint_already_found
) goto fail
;
722 if (Endpoint
) *Endpoint
= opt
;
723 else HeapFree(GetProcessHeap(), 0, opt
);
724 endpoint_already_found
= TRUE
;
726 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
727 /* endpoint option */
728 if (endpoint_already_found
) goto fail
;
729 if (Endpoint
) *Endpoint
= unescape_string_binding_componentW(next
+1, -1);
730 HeapFree(GetProcessHeap(), 0, opt
);
731 endpoint_already_found
= TRUE
;
736 /* FIXME: this is kind of inefficient */
737 *Options
= RPCRT4_strconcatW(*Options
, opt
);
738 HeapFree(GetProcessHeap(), 0, opt
);
742 HeapFree(GetProcessHeap(), 0, opt
);
748 if (*data
) goto fail
;
749 } else if (NetworkAddr
)
750 *NetworkAddr
= unescape_string_binding_componentW(data
, -1);
755 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
756 if (Protseq
) RpcStringFreeW(Protseq
);
757 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
758 if (Endpoint
) RpcStringFreeW(Endpoint
);
759 if (Options
) RpcStringFreeW(Options
);
760 return RPC_S_INVALID_STRING_BINDING
;
763 /***********************************************************************
764 * RpcBindingFree (RPCRT4.@)
766 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
769 TRACE("(%p) = %p\n", Binding
, *Binding
);
771 status
= RPCRT4_ReleaseBinding(*Binding
);
773 status
= RPC_S_INVALID_BINDING
;
774 if (status
== RPC_S_OK
) *Binding
= NULL
;
778 /***********************************************************************
779 * RpcBindingVectorFree (RPCRT4.@)
781 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
785 TRACE("(%p)\n", BindingVector
);
786 for (c
=0; c
<(*BindingVector
)->Count
; c
++) RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
787 HeapFree(GetProcessHeap(), 0, *BindingVector
);
788 *BindingVector
= NULL
;
792 /***********************************************************************
793 * RpcBindingInqObject (RPCRT4.@)
795 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
797 RpcBinding
* bind
= Binding
;
799 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
800 *ObjectUuid
= bind
->ObjectUuid
;
804 /***********************************************************************
805 * RpcBindingSetObject (RPCRT4.@)
807 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
809 RpcBinding
* bind
= Binding
;
811 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
812 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
813 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
816 /***********************************************************************
817 * RpcBindingFromStringBindingA (RPCRT4.@)
819 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
822 RpcBinding
* bind
= NULL
;
823 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
826 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
828 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
829 &NetworkAddr
, &Endpoint
, &Options
);
830 if (ret
!= RPC_S_OK
) return ret
;
832 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
835 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
836 if (ret
== RPC_S_OK
) {
837 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
839 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
842 *Binding
= (RPC_BINDING_HANDLE
)bind
;
844 RPCRT4_ReleaseBinding(bind
);
847 RpcStringFreeA(&Options
);
848 RpcStringFreeA(&Endpoint
);
849 RpcStringFreeA(&NetworkAddr
);
850 RpcStringFreeA(&Protseq
);
851 RpcStringFreeA(&ObjectUuid
);
856 /***********************************************************************
857 * RpcBindingFromStringBindingW (RPCRT4.@)
859 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
862 RpcBinding
* bind
= NULL
;
863 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
866 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
868 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
869 &NetworkAddr
, &Endpoint
, &Options
);
870 if (ret
!= RPC_S_OK
) return ret
;
872 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
875 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
876 if (ret
== RPC_S_OK
) {
877 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
879 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
882 *Binding
= (RPC_BINDING_HANDLE
)bind
;
884 RPCRT4_ReleaseBinding(bind
);
887 RpcStringFreeW(&Options
);
888 RpcStringFreeW(&Endpoint
);
889 RpcStringFreeW(&NetworkAddr
);
890 RpcStringFreeW(&Protseq
);
891 RpcStringFreeW(&ObjectUuid
);
896 /***********************************************************************
897 * RpcBindingToStringBindingA (RPCRT4.@)
899 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
902 RpcBinding
* bind
= Binding
;
905 TRACE("(%p,%p)\n", Binding
, StringBinding
);
907 if (UuidIsNil(&bind
->ObjectUuid
, &ret
))
911 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
912 if (ret
!= RPC_S_OK
) return ret
;
915 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
916 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
918 RpcStringFreeA(&ObjectUuid
);
923 /***********************************************************************
924 * RpcBindingToStringBindingW (RPCRT4.@)
926 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
929 unsigned char *str
= NULL
;
930 TRACE("(%p,%p)\n", Binding
, StringBinding
);
931 ret
= RpcBindingToStringBindingA(Binding
, &str
);
932 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
933 RpcStringFreeA(&str
);
937 /***********************************************************************
938 * I_RpcBindingInqTransportType (RPCRT4.@)
940 RPC_STATUS WINAPI
I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding
, unsigned int * Type
)
943 FIXME( "(%p,%p): stub\n", Binding
, Type
);
944 *Type
= TRANSPORT_TYPE_LPC
;
948 /***********************************************************************
949 * I_RpcBindingSetAsync (RPCRT4.@)
951 * Exists in win9x and winNT, but with different number of arguments
952 * (9x version has 3 arguments, NT has 2).
954 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
956 RpcBinding
* bind
= Binding
;
958 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
960 bind
->BlockingFn
= BlockingFn
;
965 /***********************************************************************
966 * RpcBindingCopy (RPCRT4.@)
968 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
969 RPC_BINDING_HANDLE SourceBinding
,
970 RPC_BINDING_HANDLE
* DestinationBinding
)
972 RpcBinding
*DestBinding
;
973 RpcBinding
*SrcBinding
= SourceBinding
;
976 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
978 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
979 if (status
!= RPC_S_OK
) return status
;
981 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
982 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
983 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
984 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
985 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
986 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
987 DestBinding
->CookieAuth
= RPCRT4_strdupW(SrcBinding
->CookieAuth
);
988 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
989 DestBinding
->Assoc
= SrcBinding
->Assoc
;
991 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
992 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
993 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
994 DestBinding
->QOS
= SrcBinding
->QOS
;
996 *DestinationBinding
= DestBinding
;
1000 /***********************************************************************
1001 * RpcBindingReset (RPCRT4.@)
1003 RPC_STATUS RPC_ENTRY
RpcBindingReset(RPC_BINDING_HANDLE Binding
)
1005 RpcBinding
*bind
= Binding
;
1007 TRACE("(%p)\n", Binding
);
1009 RPCRT4_strfree(bind
->Endpoint
);
1010 bind
->Endpoint
= NULL
;
1011 if (bind
->Assoc
) RpcAssoc_Release(bind
->Assoc
);
1017 /***********************************************************************
1018 * RpcImpersonateClient (RPCRT4.@)
1020 * Impersonates the client connected via a binding handle so that security
1021 * checks are done in the context of the client.
1024 * BindingHandle [I] Handle to the binding to the client.
1027 * Success: RPS_S_OK.
1028 * Failure: RPC_STATUS value.
1032 * If BindingHandle is NULL then the function impersonates the client
1033 * connected to the binding handle of the current thread.
1035 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
1039 TRACE("(%p)\n", BindingHandle
);
1041 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1042 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1044 bind
= BindingHandle
;
1046 return rpcrt4_conn_impersonate_client(bind
->FromConn
);
1047 return RPC_S_WRONG_KIND_OF_BINDING
;
1050 /***********************************************************************
1051 * RpcRevertToSelfEx (RPCRT4.@)
1053 * Stops impersonating the client connected to the binding handle so that security
1054 * checks are no longer done in the context of the client.
1057 * BindingHandle [I] Handle to the binding to the client.
1060 * Success: RPS_S_OK.
1061 * Failure: RPC_STATUS value.
1065 * If BindingHandle is NULL then the function stops impersonating the client
1066 * connected to the binding handle of the current thread.
1068 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
1072 TRACE("(%p)\n", BindingHandle
);
1074 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1075 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1077 bind
= BindingHandle
;
1079 return rpcrt4_conn_revert_to_self(bind
->FromConn
);
1080 return RPC_S_WRONG_KIND_OF_BINDING
;
1083 static inline BOOL
has_nt_auth_identity(ULONG AuthnLevel
)
1087 case RPC_C_AUTHN_GSS_NEGOTIATE
:
1088 case RPC_C_AUTHN_WINNT
:
1089 case RPC_C_AUTHN_GSS_KERBEROS
:
1096 RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
1097 CredHandle cred
, TimeStamp exp
,
1099 RPC_AUTH_IDENTITY_HANDLE identity
,
1102 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
1104 return RPC_S_OUT_OF_MEMORY
;
1107 AuthInfo
->AuthnLevel
= AuthnLevel
;
1108 AuthInfo
->AuthnSvc
= AuthnSvc
;
1109 AuthInfo
->cred
= cred
;
1110 AuthInfo
->exp
= exp
;
1111 AuthInfo
->cbMaxToken
= cbMaxToken
;
1112 AuthInfo
->identity
= identity
;
1113 AuthInfo
->server_principal_name
= NULL
;
1115 /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to
1116 * enable better matching in RpcAuthInfo_IsEqual */
1117 if (identity
&& has_nt_auth_identity(AuthnSvc
))
1119 const SEC_WINNT_AUTH_IDENTITY_W
*nt_identity
= identity
;
1120 AuthInfo
->nt_identity
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
->nt_identity
));
1121 if (!AuthInfo
->nt_identity
)
1123 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1124 return RPC_S_OUT_OF_MEMORY
;
1127 AuthInfo
->nt_identity
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1128 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1129 AuthInfo
->nt_identity
->User
= RPCRT4_strndupW(nt_identity
->User
, nt_identity
->UserLength
);
1131 AuthInfo
->nt_identity
->User
= RPCRT4_strndupAtoW((const char *)nt_identity
->User
, nt_identity
->UserLength
);
1132 AuthInfo
->nt_identity
->UserLength
= nt_identity
->UserLength
;
1133 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1134 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupW(nt_identity
->Domain
, nt_identity
->DomainLength
);
1136 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupAtoW((const char *)nt_identity
->Domain
, nt_identity
->DomainLength
);
1137 AuthInfo
->nt_identity
->DomainLength
= nt_identity
->DomainLength
;
1138 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1139 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupW(nt_identity
->Password
, nt_identity
->PasswordLength
);
1141 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupAtoW((const char *)nt_identity
->Password
, nt_identity
->PasswordLength
);
1142 AuthInfo
->nt_identity
->PasswordLength
= nt_identity
->PasswordLength
;
1144 if ((nt_identity
->User
&& !AuthInfo
->nt_identity
->User
) ||
1145 (nt_identity
->Domain
&& !AuthInfo
->nt_identity
->Domain
) ||
1146 (nt_identity
->Password
&& !AuthInfo
->nt_identity
->Password
))
1148 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1149 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1150 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1151 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1152 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1153 return RPC_S_OUT_OF_MEMORY
;
1157 AuthInfo
->nt_identity
= NULL
;
1162 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
1164 return InterlockedIncrement(&AuthInfo
->refs
);
1167 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
1169 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
1173 FreeCredentialsHandle(&AuthInfo
->cred
);
1174 if (AuthInfo
->nt_identity
)
1176 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1177 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1178 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1179 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1181 HeapFree(GetProcessHeap(), 0, AuthInfo
->server_principal_name
);
1182 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1188 BOOL
RpcAuthInfo_IsEqual(const RpcAuthInfo
*AuthInfo1
, const RpcAuthInfo
*AuthInfo2
)
1190 if (AuthInfo1
== AuthInfo2
)
1193 if (!AuthInfo1
|| !AuthInfo2
)
1196 if ((AuthInfo1
->AuthnLevel
!= AuthInfo2
->AuthnLevel
) ||
1197 (AuthInfo1
->AuthnSvc
!= AuthInfo2
->AuthnSvc
))
1200 if (AuthInfo1
->identity
== AuthInfo2
->identity
)
1203 if (!AuthInfo1
->identity
|| !AuthInfo2
->identity
)
1206 if (has_nt_auth_identity(AuthInfo1
->AuthnSvc
))
1208 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= AuthInfo1
->nt_identity
;
1209 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= AuthInfo2
->nt_identity
;
1210 /* compare user names */
1211 if (identity1
->UserLength
!= identity2
->UserLength
||
1212 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1214 /* compare domain names */
1215 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1216 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1218 /* compare passwords */
1219 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1220 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1229 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1231 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1234 return RPC_S_OUT_OF_RESOURCES
;
1237 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1238 if (!qos
->qos
) goto error
;
1239 qos
->qos
->Version
= qos_src
->Version
;
1240 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1241 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1242 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1243 qos
->qos
->AdditionalSecurityInfoType
= 0;
1245 if (qos_src
->Version
>= 2)
1247 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1248 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1249 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1251 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1252 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1254 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1255 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1256 if (!http_credentials_dst
) goto error
;
1257 http_credentials_dst
->TransportCredentials
= NULL
;
1258 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1259 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1260 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1261 http_credentials_dst
->AuthnSchemes
= NULL
;
1262 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1263 if (http_credentials_src
->TransportCredentials
)
1265 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1266 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1267 if (!cred_dst
) goto error
;
1268 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1271 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1272 cred_dst
->UserLength
= cred_src
->UserLength
;
1273 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1274 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1275 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1276 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1277 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1281 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1282 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1283 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1284 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1285 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1286 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1287 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1288 if (!cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1289 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1290 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1291 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1294 if (http_credentials_src
->NumberOfAuthnSchemes
)
1296 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1297 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1298 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1300 if (http_credentials_src
->ServerCertificateSubject
)
1303 http_credentials_dst
->ServerCertificateSubject
=
1304 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1305 strlenW(http_credentials_src
->ServerCertificateSubject
));
1307 http_credentials_dst
->ServerCertificateSubject
=
1308 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1309 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1319 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1320 qos
->qos
->u
.HttpCredentials
)
1322 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1324 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1325 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1326 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1327 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1329 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1330 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1331 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1333 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1335 HeapFree(GetProcessHeap(), 0, qos
);
1336 return RPC_S_OUT_OF_RESOURCES
;
1339 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1341 return InterlockedIncrement(&qos
->refs
);
1344 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1346 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1350 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1352 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1354 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1355 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1356 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1357 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1359 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1360 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1361 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1363 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1364 HeapFree(GetProcessHeap(), 0, qos
);
1369 BOOL
RpcQualityOfService_IsEqual(const RpcQualityOfService
*qos1
, const RpcQualityOfService
*qos2
)
1377 TRACE("qos1 = { %d %d %d %d }, qos2 = { %d %d %d %d }\n",
1378 qos1
->qos
->Capabilities
, qos1
->qos
->IdentityTracking
,
1379 qos1
->qos
->ImpersonationType
, qos1
->qos
->AdditionalSecurityInfoType
,
1380 qos2
->qos
->Capabilities
, qos2
->qos
->IdentityTracking
,
1381 qos2
->qos
->ImpersonationType
, qos2
->qos
->AdditionalSecurityInfoType
);
1383 if ((qos1
->qos
->Capabilities
!= qos2
->qos
->Capabilities
) ||
1384 (qos1
->qos
->IdentityTracking
!= qos2
->qos
->IdentityTracking
) ||
1385 (qos1
->qos
->ImpersonationType
!= qos2
->qos
->ImpersonationType
) ||
1386 (qos1
->qos
->AdditionalSecurityInfoType
!= qos2
->qos
->AdditionalSecurityInfoType
))
1389 if (qos1
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1391 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials1
= qos1
->qos
->u
.HttpCredentials
;
1392 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials2
= qos2
->qos
->u
.HttpCredentials
;
1394 if (http_credentials1
->Flags
!= http_credentials2
->Flags
)
1397 if (http_credentials1
->AuthenticationTarget
!= http_credentials2
->AuthenticationTarget
)
1400 if (http_credentials1
->NumberOfAuthnSchemes
!= http_credentials2
->NumberOfAuthnSchemes
)
1403 if ((!http_credentials1
->AuthnSchemes
&& http_credentials2
->AuthnSchemes
) ||
1404 (http_credentials1
->AuthnSchemes
&& !http_credentials2
->AuthnSchemes
))
1407 if (memcmp(http_credentials1
->AuthnSchemes
, http_credentials2
->AuthnSchemes
,
1408 http_credentials1
->NumberOfAuthnSchemes
* sizeof(http_credentials1
->AuthnSchemes
[0])))
1411 /* server certificate subject not currently used */
1413 if (http_credentials1
->TransportCredentials
!= http_credentials2
->TransportCredentials
)
1415 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= http_credentials1
->TransportCredentials
;
1416 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= http_credentials2
->TransportCredentials
;
1418 if (!identity1
|| !identity2
)
1421 /* compare user names */
1422 if (identity1
->UserLength
!= identity2
->UserLength
||
1423 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1425 /* compare domain names */
1426 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1427 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1429 /* compare passwords */
1430 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1431 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1439 /***********************************************************************
1440 * RpcRevertToSelf (RPCRT4.@)
1442 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1445 return RpcRevertToSelfEx(NULL
);
1448 /***********************************************************************
1449 * RpcMgmtSetComTimeout (RPCRT4.@)
1451 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1453 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1457 /***********************************************************************
1458 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1460 RPCRTAPI RPC_STATUS RPC_ENTRY
1461 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1462 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1463 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1468 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1469 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1471 status
= RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
? &principal
: NULL
, AuthnLevel
,
1472 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1473 if (status
== RPC_S_OK
&& ServerPrincName
)
1475 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1476 RpcStringFreeW(&principal
);
1477 if (!*ServerPrincName
) return RPC_S_OUT_OF_MEMORY
;
1483 /***********************************************************************
1484 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1486 RPCRTAPI RPC_STATUS RPC_ENTRY
1487 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1488 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1489 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1491 RpcBinding
*bind
= Binding
;
1493 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1494 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1496 if (!bind
->AuthInfo
) return RPC_S_BINDING_HAS_NO_AUTH
;
1500 FIXME("QOS not implemented\n");
1501 return RPC_S_INVALID_BINDING
;
1504 if (ServerPrincName
)
1506 if (bind
->AuthInfo
->server_principal_name
)
1508 *ServerPrincName
= RPCRT4_strdupW(bind
->AuthInfo
->server_principal_name
);
1509 if (!*ServerPrincName
) return RPC_S_OUT_OF_MEMORY
;
1511 else *ServerPrincName
= NULL
;
1513 if (AuthnLevel
) *AuthnLevel
= bind
->AuthInfo
->AuthnLevel
;
1514 if (AuthnSvc
) *AuthnSvc
= bind
->AuthInfo
->AuthnSvc
;
1515 if (AuthIdentity
) *AuthIdentity
= bind
->AuthInfo
->identity
;
1518 FIXME("authorization service not implemented\n");
1519 *AuthzSvc
= RPC_C_AUTHZ_NONE
;
1525 /***********************************************************************
1526 * RpcBindingInqAuthInfoA (RPCRT4.@)
1528 RPCRTAPI RPC_STATUS RPC_ENTRY
1529 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1530 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1532 return RpcBindingInqAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1536 /***********************************************************************
1537 * RpcBindingInqAuthInfoW (RPCRT4.@)
1539 RPCRTAPI RPC_STATUS RPC_ENTRY
1540 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1541 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1543 return RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1547 /***********************************************************************
1548 * RpcBindingInqAuthClientA (RPCRT4.@)
1550 RPCRTAPI RPC_STATUS RPC_ENTRY
1551 RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1552 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1555 return RpcBindingInqAuthClientExA(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1556 AuthnSvc
, AuthzSvc
, 0);
1559 /***********************************************************************
1560 * RpcBindingInqAuthClientW (RPCRT4.@)
1562 RPCRTAPI RPC_STATUS RPC_ENTRY
1563 RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1564 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1567 return RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1568 AuthnSvc
, AuthzSvc
, 0);
1571 /***********************************************************************
1572 * RpcBindingInqAuthClientExA (RPCRT4.@)
1574 RPCRTAPI RPC_STATUS RPC_ENTRY
1575 RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1576 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1577 ULONG
*AuthzSvc
, ULONG Flags
)
1582 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1583 AuthnSvc
, AuthzSvc
, Flags
);
1585 status
= RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
? &principal
: NULL
,
1586 AuthnLevel
, AuthnSvc
, AuthzSvc
, Flags
);
1587 if (status
== RPC_S_OK
&& ServerPrincName
)
1589 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1590 if (!*ServerPrincName
&& principal
) status
= RPC_S_OUT_OF_MEMORY
;
1591 RpcStringFreeW(&principal
);
1597 /***********************************************************************
1598 * RpcBindingInqAuthClientExW (RPCRT4.@)
1600 RPCRTAPI RPC_STATUS RPC_ENTRY
1601 RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1602 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1603 ULONG
*AuthzSvc
, ULONG Flags
)
1607 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1608 AuthnSvc
, AuthzSvc
, Flags
);
1610 if (!ClientBinding
) ClientBinding
= I_RpcGetCurrentCallHandle();
1611 if (!ClientBinding
) return RPC_S_INVALID_BINDING
;
1613 bind
= ClientBinding
;
1614 if (!bind
->FromConn
) return RPC_S_INVALID_BINDING
;
1616 return rpcrt4_conn_inquire_auth_client(bind
->FromConn
, Privs
,
1617 ServerPrincName
, AuthnLevel
,
1618 AuthnSvc
, AuthzSvc
, Flags
);
1621 /***********************************************************************
1622 * RpcBindingServerFromClient (RPCRT4.@)
1624 RPCRTAPI RPC_STATUS RPC_ENTRY
1625 RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding
, RPC_BINDING_HANDLE
* ServerBinding
)
1627 RpcBinding
* bind
= ClientBinding
;
1628 RpcBinding
* NewBinding
;
1631 bind
= I_RpcGetCurrentCallHandle();
1634 return RPC_S_INVALID_BINDING
;
1636 RPCRT4_AllocBinding(&NewBinding
, TRUE
);
1637 NewBinding
->Protseq
= RPCRT4_strdupA(bind
->Protseq
);
1638 NewBinding
->NetworkAddr
= RPCRT4_strdupA(bind
->NetworkAddr
);
1640 *ServerBinding
= NewBinding
;
1645 /***********************************************************************
1646 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1648 RPCRTAPI RPC_STATUS RPC_ENTRY
1649 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1650 ULONG AuthnLevel
, ULONG AuthnSvc
,
1651 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1652 RPC_SECURITY_QOS
*SecurityQos
)
1654 RpcBinding
* bind
= Binding
;
1658 ULONG package_count
;
1660 PSecPkgInfoA packages
;
1663 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1664 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1670 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1671 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1672 if (SecurityQos
->Version
>= 2)
1674 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1675 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1676 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1677 TRACE(", { %p, 0x%x, %d, %d, %p(%u), %s }",
1678 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1679 SecurityQos2
->u
.HttpCredentials
->Flags
,
1680 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1681 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1682 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1683 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1684 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1687 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1688 if (status
!= RPC_S_OK
)
1693 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1697 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1698 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1700 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1701 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1702 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1704 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1706 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1707 bind
->AuthInfo
= NULL
;
1711 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1713 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1714 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1717 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1718 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1720 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1721 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1724 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1727 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1728 return RPC_S_SEC_PKG_ERROR
;
1731 for (i
= 0; i
< package_count
; i
++)
1732 if (packages
[i
].wRPCID
== AuthnSvc
)
1735 if (i
== package_count
)
1737 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1738 FreeContextBuffer(packages
);
1739 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1742 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1743 r
= AcquireCredentialsHandleA(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1744 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1745 cbMaxToken
= packages
[i
].cbMaxToken
;
1746 FreeContextBuffer(packages
);
1747 if (r
== ERROR_SUCCESS
)
1749 RpcAuthInfo
*new_auth_info
;
1750 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1751 AuthIdentity
, &new_auth_info
);
1754 new_auth_info
->server_principal_name
= RPCRT4_strdupAtoW((char *)ServerPrincName
);
1755 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1757 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1758 bind
->AuthInfo
= new_auth_info
;
1762 RpcAuthInfo_Release(new_auth_info
);
1763 r
= RPC_S_OUT_OF_MEMORY
;
1767 FreeCredentialsHandle(&cred
);
1772 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1773 return RPC_S_SEC_PKG_ERROR
;
1777 /***********************************************************************
1778 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1780 RPCRTAPI RPC_STATUS RPC_ENTRY
1781 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1782 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1783 RPC_SECURITY_QOS
*SecurityQos
)
1785 RpcBinding
* bind
= Binding
;
1789 ULONG package_count
;
1791 PSecPkgInfoW packages
;
1794 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w(ServerPrincName
),
1795 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1801 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1802 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1803 if (SecurityQos
->Version
>= 2)
1805 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1806 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1807 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1808 TRACE(", { %p, 0x%x, %d, %d, %p(%u), %s }",
1809 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1810 SecurityQos2
->u
.HttpCredentials
->Flags
,
1811 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1812 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1813 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1814 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1815 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1818 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1819 if (status
!= RPC_S_OK
)
1824 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1828 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1829 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1831 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1832 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1833 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1835 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1837 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1838 bind
->AuthInfo
= NULL
;
1842 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1844 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1845 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1848 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1849 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1851 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1852 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1855 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1858 ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n", r
);
1859 return RPC_S_SEC_PKG_ERROR
;
1862 for (i
= 0; i
< package_count
; i
++)
1863 if (packages
[i
].wRPCID
== AuthnSvc
)
1866 if (i
== package_count
)
1868 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1869 FreeContextBuffer(packages
);
1870 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1873 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1874 r
= AcquireCredentialsHandleW(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1875 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1876 cbMaxToken
= packages
[i
].cbMaxToken
;
1877 FreeContextBuffer(packages
);
1878 if (r
== ERROR_SUCCESS
)
1880 RpcAuthInfo
*new_auth_info
;
1881 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1882 AuthIdentity
, &new_auth_info
);
1885 new_auth_info
->server_principal_name
= RPCRT4_strdupW(ServerPrincName
);
1886 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1888 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1889 bind
->AuthInfo
= new_auth_info
;
1893 RpcAuthInfo_Release(new_auth_info
);
1894 r
= RPC_S_OUT_OF_MEMORY
;
1898 FreeCredentialsHandle(&cred
);
1903 ERR("AcquireCredentialsHandleW failed with error 0x%08x\n", r
);
1904 return RPC_S_SEC_PKG_ERROR
;
1908 /***********************************************************************
1909 * RpcBindingSetAuthInfoA (RPCRT4.@)
1911 RPCRTAPI RPC_STATUS RPC_ENTRY
1912 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1913 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1915 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1916 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1917 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1920 /***********************************************************************
1921 * RpcBindingSetAuthInfoW (RPCRT4.@)
1923 RPCRTAPI RPC_STATUS RPC_ENTRY
1924 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1925 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1927 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w(ServerPrincName
),
1928 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1929 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1932 /***********************************************************************
1933 * RpcBindingSetOption (RPCRT4.@)
1935 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG_PTR OptionValue
)
1937 TRACE("(%p, %d, %ld)\n", BindingHandle
, Option
, OptionValue
);
1941 case RPC_C_OPT_COOKIE_AUTH
:
1943 RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*cookie
= (RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*)OptionValue
;
1944 RpcBinding
*binding
= BindingHandle
;
1945 int len
= MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, NULL
, 0);
1948 if (!(str
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
)))) return RPC_S_OUT_OF_MEMORY
;
1949 MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, str
, len
);
1951 HeapFree(GetProcessHeap(), 0, binding
->CookieAuth
);
1952 binding
->CookieAuth
= str
;
1956 FIXME("option %u not supported\n", Option
);
1962 /***********************************************************************
1963 * I_RpcBindingInqLocalClientPID (RPCRT4.@)
1966 RPC_STATUS WINAPI
I_RpcBindingInqLocalClientPID(RPC_BINDING_HANDLE ClientBinding
, ULONG
*ClientPID
)
1968 FIXME("%p %p: stub\n", ClientBinding
, ClientPID
);
1969 return RPC_S_INVALID_BINDING
;