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
)
284 return RPCRT4_ReleaseConnection(Connection
);
287 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
292 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
294 DWORD len
= strlen(dst
), slen
= strlen(src
);
295 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
298 HeapFree(GetProcessHeap(), 0, dst
);
302 memcpy(ndst
+len
+1, src
, slen
+1);
306 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
308 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
309 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
312 HeapFree(GetProcessHeap(), 0, dst
);
316 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
320 /* Copies the escaped version of a component into a string binding.
321 * Note: doesn't nul-terminate the string */
322 static RPC_CSTR
escape_string_binding_component(RPC_CSTR string_binding
,
323 const unsigned char *component
)
325 for (; *component
; component
++) {
326 switch (*component
) {
332 *string_binding
++ = '\\';
333 *string_binding
++ = *component
;
336 *string_binding
++ = *component
;
340 return string_binding
;
343 static RPC_WSTR
escape_string_binding_componentW(RPC_WSTR string_binding
,
344 const WCHAR
*component
)
346 for (; *component
; component
++) {
347 switch (*component
) {
353 *string_binding
++ = '\\';
354 *string_binding
++ = *component
;
357 *string_binding
++ = *component
;
361 return string_binding
;
364 static const unsigned char *string_binding_find_delimiter(
365 const unsigned char *string_binding
, unsigned char delim
)
367 const unsigned char *next
;
368 for (next
= string_binding
; *next
; next
++) {
379 static const WCHAR
*string_binding_find_delimiterW(
380 const WCHAR
*string_binding
, WCHAR delim
)
383 for (next
= string_binding
; *next
; next
++) {
394 static RPC_CSTR
unescape_string_binding_component(
395 const unsigned char *string_binding
, int len
)
397 RPC_CSTR component
, p
;
399 if (len
== -1) len
= strlen((const char *)string_binding
);
401 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
402 if (!component
) return NULL
;
403 for (p
= component
; len
> 0; string_binding
++, len
--) {
404 if (*string_binding
== '\\') {
407 *p
++ = *string_binding
;
409 *p
++ = *string_binding
;
416 static RPC_WSTR
unescape_string_binding_componentW(
417 const WCHAR
*string_binding
, int len
)
419 RPC_WSTR component
, p
;
421 if (len
== -1) len
= strlenW(string_binding
);
423 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
424 if (!component
) return NULL
;
425 for (p
= component
; len
> 0; string_binding
++, len
--) {
426 if (*string_binding
== '\\') {
429 *p
++ = *string_binding
;
431 *p
++ = *string_binding
;
438 /***********************************************************************
439 * RpcStringBindingComposeA (RPCRT4.@)
441 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
442 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
443 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
448 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
449 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
450 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
451 debugstr_a( (char*)Options
), StringBinding
);
453 /* overestimate for each component for escaping of delimiters */
454 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) * 2 + 1;
455 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) * 2 + 1;
456 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
) * 2;
457 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) * 2 + 2;
458 if (Options
&& *Options
) len
+= strlen((char*)Options
) * 2 + 2;
460 data
= HeapAlloc(GetProcessHeap(), 0, len
);
461 *StringBinding
= data
;
463 if (ObjUuid
&& *ObjUuid
) {
464 data
= escape_string_binding_component(data
, ObjUuid
);
467 if (Protseq
&& *Protseq
) {
468 data
= escape_string_binding_component(data
, Protseq
);
471 if (NetworkAddr
&& *NetworkAddr
)
472 data
= escape_string_binding_component(data
, NetworkAddr
);
474 if ((Endpoint
&& *Endpoint
) ||
475 (Options
&& *Options
)) {
477 if (Endpoint
&& *Endpoint
) {
478 data
= escape_string_binding_component(data
, Endpoint
);
479 if (Options
&& *Options
) *data
++ = ',';
481 if (Options
&& *Options
) {
482 data
= escape_string_binding_component(data
, Options
);
491 /***********************************************************************
492 * RpcStringBindingComposeW (RPCRT4.@)
494 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
495 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
496 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
501 TRACE("(%s,%s,%s,%s,%s,%p)\n",
502 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
503 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
504 debugstr_w( Options
), StringBinding
);
506 /* overestimate for each component for escaping of delimiters */
507 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) * 2 + 1;
508 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) * 2 + 1;
509 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
) * 2;
510 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) * 2 + 2;
511 if (Options
&& *Options
) len
+= strlenW(Options
) * 2 + 2;
513 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
514 *StringBinding
= data
;
516 if (ObjUuid
&& *ObjUuid
) {
517 data
= escape_string_binding_componentW(data
, ObjUuid
);
520 if (Protseq
&& *Protseq
) {
521 data
= escape_string_binding_componentW(data
, Protseq
);
524 if (NetworkAddr
&& *NetworkAddr
) {
525 data
= escape_string_binding_componentW(data
, NetworkAddr
);
527 if ((Endpoint
&& *Endpoint
) ||
528 (Options
&& *Options
)) {
530 if (Endpoint
&& *Endpoint
) {
531 data
= escape_string_binding_componentW(data
, Endpoint
);
532 if (Options
&& *Options
) *data
++ = ',';
534 if (Options
&& *Options
) {
535 data
= escape_string_binding_componentW(data
, Options
);
545 /***********************************************************************
546 * RpcStringBindingParseA (RPCRT4.@)
548 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
549 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
550 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
552 const unsigned char *data
, *next
;
553 static const char ep_opt
[] = "endpoint=";
554 BOOL endpoint_already_found
= FALSE
;
556 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
557 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
559 if (ObjUuid
) *ObjUuid
= NULL
;
560 if (Protseq
) *Protseq
= NULL
;
561 if (NetworkAddr
) *NetworkAddr
= NULL
;
562 if (Endpoint
) *Endpoint
= NULL
;
563 if (Options
) *Options
= NULL
;
565 data
= StringBinding
;
567 next
= string_binding_find_delimiter(data
, '@');
571 RPC_CSTR str_uuid
= unescape_string_binding_component(data
, next
- data
);
572 status
= UuidFromStringA(str_uuid
, &uuid
);
573 if (status
!= RPC_S_OK
) {
574 HeapFree(GetProcessHeap(), 0, str_uuid
);
580 HeapFree(GetProcessHeap(), 0, str_uuid
);
584 next
= string_binding_find_delimiter(data
, ':');
586 if (Protseq
) *Protseq
= unescape_string_binding_component(data
, next
- data
);
590 next
= string_binding_find_delimiter(data
, '[');
592 const unsigned char *close
;
595 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_component(data
, next
- data
);
597 close
= string_binding_find_delimiter(data
, ']');
598 if (!close
) goto fail
;
600 /* tokenize options */
601 while (data
< close
) {
602 next
= string_binding_find_delimiter(data
, ',');
603 if (!next
|| next
> close
) next
= close
;
604 /* FIXME: this is kind of inefficient */
605 opt
= unescape_string_binding_component(data
, next
- data
);
609 next
= string_binding_find_delimiter(opt
, '=');
611 /* not an option, must be an endpoint */
612 if (endpoint_already_found
) goto fail
;
613 if (Endpoint
) *Endpoint
= opt
;
614 else HeapFree(GetProcessHeap(), 0, opt
);
615 endpoint_already_found
= TRUE
;
617 if (strncmp((const char *)opt
, ep_opt
, strlen(ep_opt
)) == 0) {
618 /* endpoint option */
619 if (endpoint_already_found
) goto fail
;
620 if (Endpoint
) *Endpoint
= unescape_string_binding_component(next
+1, -1);
621 HeapFree(GetProcessHeap(), 0, opt
);
622 endpoint_already_found
= TRUE
;
627 /* FIXME: this is kind of inefficient */
628 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, (char *)opt
);
629 HeapFree(GetProcessHeap(), 0, opt
);
633 HeapFree(GetProcessHeap(), 0, opt
);
639 if (*data
) goto fail
;
641 else if (NetworkAddr
)
642 *NetworkAddr
= unescape_string_binding_component(data
, -1);
647 if (ObjUuid
) RpcStringFreeA(ObjUuid
);
648 if (Protseq
) RpcStringFreeA(Protseq
);
649 if (NetworkAddr
) RpcStringFreeA(NetworkAddr
);
650 if (Endpoint
) RpcStringFreeA(Endpoint
);
651 if (Options
) RpcStringFreeA(Options
);
652 return RPC_S_INVALID_STRING_BINDING
;
655 /***********************************************************************
656 * RpcStringBindingParseW (RPCRT4.@)
658 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
659 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
660 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
662 const WCHAR
*data
, *next
;
663 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
664 BOOL endpoint_already_found
= FALSE
;
666 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
667 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
669 if (ObjUuid
) *ObjUuid
= NULL
;
670 if (Protseq
) *Protseq
= NULL
;
671 if (NetworkAddr
) *NetworkAddr
= NULL
;
672 if (Endpoint
) *Endpoint
= NULL
;
673 if (Options
) *Options
= NULL
;
675 data
= StringBinding
;
677 next
= string_binding_find_delimiterW(data
, '@');
681 RPC_WSTR str_uuid
= unescape_string_binding_componentW(data
, next
- data
);
682 status
= UuidFromStringW(str_uuid
, &uuid
);
683 if (status
!= RPC_S_OK
) {
684 HeapFree(GetProcessHeap(), 0, str_uuid
);
690 HeapFree(GetProcessHeap(), 0, str_uuid
);
694 next
= string_binding_find_delimiterW(data
, ':');
696 if (Protseq
) *Protseq
= unescape_string_binding_componentW(data
, next
- data
);
700 next
= string_binding_find_delimiterW(data
, '[');
705 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_componentW(data
, next
- data
);
707 close
= string_binding_find_delimiterW(data
, ']');
708 if (!close
) goto fail
;
710 /* tokenize options */
711 while (data
< close
) {
712 next
= string_binding_find_delimiterW(data
, ',');
713 if (!next
|| next
> close
) next
= close
;
714 /* FIXME: this is kind of inefficient */
715 opt
= unescape_string_binding_componentW(data
, next
- data
);
719 next
= string_binding_find_delimiterW(opt
, '=');
721 /* not an option, must be an endpoint */
722 if (endpoint_already_found
) goto fail
;
723 if (Endpoint
) *Endpoint
= opt
;
724 else HeapFree(GetProcessHeap(), 0, opt
);
725 endpoint_already_found
= TRUE
;
727 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
728 /* endpoint option */
729 if (endpoint_already_found
) goto fail
;
730 if (Endpoint
) *Endpoint
= unescape_string_binding_componentW(next
+1, -1);
731 HeapFree(GetProcessHeap(), 0, opt
);
732 endpoint_already_found
= TRUE
;
737 /* FIXME: this is kind of inefficient */
738 *Options
= RPCRT4_strconcatW(*Options
, opt
);
739 HeapFree(GetProcessHeap(), 0, opt
);
743 HeapFree(GetProcessHeap(), 0, opt
);
749 if (*data
) goto fail
;
750 } else if (NetworkAddr
)
751 *NetworkAddr
= unescape_string_binding_componentW(data
, -1);
756 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
757 if (Protseq
) RpcStringFreeW(Protseq
);
758 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
759 if (Endpoint
) RpcStringFreeW(Endpoint
);
760 if (Options
) RpcStringFreeW(Options
);
761 return RPC_S_INVALID_STRING_BINDING
;
764 /***********************************************************************
765 * RpcBindingFree (RPCRT4.@)
767 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
770 TRACE("(%p) = %p\n", Binding
, *Binding
);
772 status
= RPCRT4_ReleaseBinding(*Binding
);
774 status
= RPC_S_INVALID_BINDING
;
775 if (status
== RPC_S_OK
) *Binding
= NULL
;
779 /***********************************************************************
780 * RpcBindingVectorFree (RPCRT4.@)
782 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
786 TRACE("(%p)\n", BindingVector
);
787 for (c
=0; c
<(*BindingVector
)->Count
; c
++) RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
788 HeapFree(GetProcessHeap(), 0, *BindingVector
);
789 *BindingVector
= NULL
;
793 /***********************************************************************
794 * RpcBindingInqObject (RPCRT4.@)
796 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
798 RpcBinding
* bind
= Binding
;
800 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
801 *ObjectUuid
= bind
->ObjectUuid
;
805 /***********************************************************************
806 * RpcBindingSetObject (RPCRT4.@)
808 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
810 RpcBinding
* bind
= Binding
;
812 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
813 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
814 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
817 /***********************************************************************
818 * RpcBindingFromStringBindingA (RPCRT4.@)
820 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
823 RpcBinding
* bind
= NULL
;
824 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
827 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
829 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
830 &NetworkAddr
, &Endpoint
, &Options
);
831 if (ret
!= RPC_S_OK
) return ret
;
833 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
836 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
837 if (ret
== RPC_S_OK
) {
838 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
840 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
843 *Binding
= (RPC_BINDING_HANDLE
)bind
;
845 RPCRT4_ReleaseBinding(bind
);
848 RpcStringFreeA(&Options
);
849 RpcStringFreeA(&Endpoint
);
850 RpcStringFreeA(&NetworkAddr
);
851 RpcStringFreeA(&Protseq
);
852 RpcStringFreeA(&ObjectUuid
);
857 /***********************************************************************
858 * RpcBindingFromStringBindingW (RPCRT4.@)
860 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
863 RpcBinding
* bind
= NULL
;
864 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
867 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
869 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
870 &NetworkAddr
, &Endpoint
, &Options
);
871 if (ret
!= RPC_S_OK
) return ret
;
873 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
876 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
877 if (ret
== RPC_S_OK
) {
878 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
880 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
883 *Binding
= (RPC_BINDING_HANDLE
)bind
;
885 RPCRT4_ReleaseBinding(bind
);
888 RpcStringFreeW(&Options
);
889 RpcStringFreeW(&Endpoint
);
890 RpcStringFreeW(&NetworkAddr
);
891 RpcStringFreeW(&Protseq
);
892 RpcStringFreeW(&ObjectUuid
);
897 /***********************************************************************
898 * RpcBindingToStringBindingA (RPCRT4.@)
900 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
903 RpcBinding
* bind
= Binding
;
906 TRACE("(%p,%p)\n", Binding
, StringBinding
);
908 if (UuidIsNil(&bind
->ObjectUuid
, &ret
))
912 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
913 if (ret
!= RPC_S_OK
) return ret
;
916 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
917 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
919 RpcStringFreeA(&ObjectUuid
);
924 /***********************************************************************
925 * RpcBindingToStringBindingW (RPCRT4.@)
927 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
930 unsigned char *str
= NULL
;
931 TRACE("(%p,%p)\n", Binding
, StringBinding
);
932 ret
= RpcBindingToStringBindingA(Binding
, &str
);
933 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
934 RpcStringFreeA(&str
);
938 /***********************************************************************
939 * I_RpcBindingInqTransportType (RPCRT4.@)
941 RPC_STATUS WINAPI
I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding
, unsigned int * Type
)
944 FIXME( "(%p,%p): stub\n", Binding
, Type
);
945 *Type
= TRANSPORT_TYPE_LPC
;
949 /***********************************************************************
950 * I_RpcBindingSetAsync (RPCRT4.@)
952 * Exists in win9x and winNT, but with different number of arguments
953 * (9x version has 3 arguments, NT has 2).
955 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
957 RpcBinding
* bind
= Binding
;
959 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
961 bind
->BlockingFn
= BlockingFn
;
966 /***********************************************************************
967 * RpcBindingCopy (RPCRT4.@)
969 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
970 RPC_BINDING_HANDLE SourceBinding
,
971 RPC_BINDING_HANDLE
* DestinationBinding
)
973 RpcBinding
*DestBinding
;
974 RpcBinding
*SrcBinding
= SourceBinding
;
977 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
979 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
980 if (status
!= RPC_S_OK
) return status
;
982 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
983 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
984 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
985 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
986 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
987 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
988 DestBinding
->CookieAuth
= RPCRT4_strdupW(SrcBinding
->CookieAuth
);
989 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
990 DestBinding
->Assoc
= SrcBinding
->Assoc
;
992 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
993 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
994 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
995 DestBinding
->QOS
= SrcBinding
->QOS
;
997 *DestinationBinding
= DestBinding
;
1001 /***********************************************************************
1002 * RpcBindingReset (RPCRT4.@)
1004 RPC_STATUS RPC_ENTRY
RpcBindingReset(RPC_BINDING_HANDLE Binding
)
1006 RpcBinding
*bind
= Binding
;
1008 TRACE("(%p)\n", Binding
);
1010 RPCRT4_strfree(bind
->Endpoint
);
1011 bind
->Endpoint
= NULL
;
1012 if (bind
->Assoc
) RpcAssoc_Release(bind
->Assoc
);
1018 /***********************************************************************
1019 * RpcImpersonateClient (RPCRT4.@)
1021 * Impersonates the client connected via a binding handle so that security
1022 * checks are done in the context of the client.
1025 * BindingHandle [I] Handle to the binding to the client.
1028 * Success: RPS_S_OK.
1029 * Failure: RPC_STATUS value.
1033 * If BindingHandle is NULL then the function impersonates the client
1034 * connected to the binding handle of the current thread.
1036 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
1040 TRACE("(%p)\n", BindingHandle
);
1042 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1043 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1045 bind
= BindingHandle
;
1047 return rpcrt4_conn_impersonate_client(bind
->FromConn
);
1048 return RPC_S_WRONG_KIND_OF_BINDING
;
1051 /***********************************************************************
1052 * RpcRevertToSelfEx (RPCRT4.@)
1054 * Stops impersonating the client connected to the binding handle so that security
1055 * checks are no longer done in the context of the client.
1058 * BindingHandle [I] Handle to the binding to the client.
1061 * Success: RPS_S_OK.
1062 * Failure: RPC_STATUS value.
1066 * If BindingHandle is NULL then the function stops impersonating the client
1067 * connected to the binding handle of the current thread.
1069 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
1073 TRACE("(%p)\n", BindingHandle
);
1075 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1076 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1078 bind
= BindingHandle
;
1080 return rpcrt4_conn_revert_to_self(bind
->FromConn
);
1081 return RPC_S_WRONG_KIND_OF_BINDING
;
1084 static inline BOOL
has_nt_auth_identity(ULONG AuthnLevel
)
1088 case RPC_C_AUTHN_GSS_NEGOTIATE
:
1089 case RPC_C_AUTHN_WINNT
:
1090 case RPC_C_AUTHN_GSS_KERBEROS
:
1097 RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
1098 CredHandle cred
, TimeStamp exp
,
1100 RPC_AUTH_IDENTITY_HANDLE identity
,
1103 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
1105 return ERROR_OUTOFMEMORY
;
1108 AuthInfo
->AuthnLevel
= AuthnLevel
;
1109 AuthInfo
->AuthnSvc
= AuthnSvc
;
1110 AuthInfo
->cred
= cred
;
1111 AuthInfo
->exp
= exp
;
1112 AuthInfo
->cbMaxToken
= cbMaxToken
;
1113 AuthInfo
->identity
= identity
;
1114 AuthInfo
->server_principal_name
= NULL
;
1116 /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to
1117 * enable better matching in RpcAuthInfo_IsEqual */
1118 if (identity
&& has_nt_auth_identity(AuthnSvc
))
1120 const SEC_WINNT_AUTH_IDENTITY_W
*nt_identity
= identity
;
1121 AuthInfo
->nt_identity
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
->nt_identity
));
1122 if (!AuthInfo
->nt_identity
)
1124 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1125 return ERROR_OUTOFMEMORY
;
1128 AuthInfo
->nt_identity
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1129 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1130 AuthInfo
->nt_identity
->User
= RPCRT4_strndupW(nt_identity
->User
, nt_identity
->UserLength
);
1132 AuthInfo
->nt_identity
->User
= RPCRT4_strndupAtoW((const char *)nt_identity
->User
, nt_identity
->UserLength
);
1133 AuthInfo
->nt_identity
->UserLength
= nt_identity
->UserLength
;
1134 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1135 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupW(nt_identity
->Domain
, nt_identity
->DomainLength
);
1137 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupAtoW((const char *)nt_identity
->Domain
, nt_identity
->DomainLength
);
1138 AuthInfo
->nt_identity
->DomainLength
= nt_identity
->DomainLength
;
1139 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1140 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupW(nt_identity
->Password
, nt_identity
->PasswordLength
);
1142 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupAtoW((const char *)nt_identity
->Password
, nt_identity
->PasswordLength
);
1143 AuthInfo
->nt_identity
->PasswordLength
= nt_identity
->PasswordLength
;
1145 if ((nt_identity
->User
&& !AuthInfo
->nt_identity
->User
) ||
1146 (nt_identity
->Domain
&& !AuthInfo
->nt_identity
->Domain
) ||
1147 (nt_identity
->Password
&& !AuthInfo
->nt_identity
->Password
))
1149 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1150 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1151 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1152 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1153 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1154 return ERROR_OUTOFMEMORY
;
1158 AuthInfo
->nt_identity
= NULL
;
1163 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
1165 return InterlockedIncrement(&AuthInfo
->refs
);
1168 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
1170 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
1174 FreeCredentialsHandle(&AuthInfo
->cred
);
1175 if (AuthInfo
->nt_identity
)
1177 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1178 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1179 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1180 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1182 HeapFree(GetProcessHeap(), 0, AuthInfo
->server_principal_name
);
1183 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1189 BOOL
RpcAuthInfo_IsEqual(const RpcAuthInfo
*AuthInfo1
, const RpcAuthInfo
*AuthInfo2
)
1191 if (AuthInfo1
== AuthInfo2
)
1194 if (!AuthInfo1
|| !AuthInfo2
)
1197 if ((AuthInfo1
->AuthnLevel
!= AuthInfo2
->AuthnLevel
) ||
1198 (AuthInfo1
->AuthnSvc
!= AuthInfo2
->AuthnSvc
))
1201 if (AuthInfo1
->identity
== AuthInfo2
->identity
)
1204 if (!AuthInfo1
->identity
|| !AuthInfo2
->identity
)
1207 if (has_nt_auth_identity(AuthInfo1
->AuthnSvc
))
1209 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= AuthInfo1
->nt_identity
;
1210 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= AuthInfo2
->nt_identity
;
1211 /* compare user names */
1212 if (identity1
->UserLength
!= identity2
->UserLength
||
1213 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1215 /* compare domain names */
1216 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1217 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1219 /* compare passwords */
1220 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1221 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1230 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1232 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1235 return RPC_S_OUT_OF_RESOURCES
;
1238 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1239 if (!qos
->qos
) goto error
;
1240 qos
->qos
->Version
= qos_src
->Version
;
1241 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1242 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1243 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1244 qos
->qos
->AdditionalSecurityInfoType
= 0;
1246 if (qos_src
->Version
>= 2)
1248 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1249 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1250 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1252 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1253 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1255 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1256 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1257 if (!http_credentials_dst
) goto error
;
1258 http_credentials_dst
->TransportCredentials
= NULL
;
1259 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1260 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1261 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1262 http_credentials_dst
->AuthnSchemes
= NULL
;
1263 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1264 if (http_credentials_src
->TransportCredentials
)
1266 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1267 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1268 if (!cred_dst
) goto error
;
1269 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1272 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1273 cred_dst
->UserLength
= cred_src
->UserLength
;
1274 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1275 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1276 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1277 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1278 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1282 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1283 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1284 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1285 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1286 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1287 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1288 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1289 if (!cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1290 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1291 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1292 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1295 if (http_credentials_src
->NumberOfAuthnSchemes
)
1297 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1298 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1299 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1301 if (http_credentials_src
->ServerCertificateSubject
)
1304 http_credentials_dst
->ServerCertificateSubject
=
1305 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1306 strlenW(http_credentials_src
->ServerCertificateSubject
));
1308 http_credentials_dst
->ServerCertificateSubject
=
1309 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1310 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1320 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1321 qos
->qos
->u
.HttpCredentials
)
1323 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1325 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1326 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1327 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1328 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1330 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1331 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1332 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1334 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1336 HeapFree(GetProcessHeap(), 0, qos
);
1337 return RPC_S_OUT_OF_RESOURCES
;
1340 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1342 return InterlockedIncrement(&qos
->refs
);
1345 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1347 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1351 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1353 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1355 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1356 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1357 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1358 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1360 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1361 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1362 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1364 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1365 HeapFree(GetProcessHeap(), 0, qos
);
1370 BOOL
RpcQualityOfService_IsEqual(const RpcQualityOfService
*qos1
, const RpcQualityOfService
*qos2
)
1378 TRACE("qos1 = { %d %d %d %d }, qos2 = { %d %d %d %d }\n",
1379 qos1
->qos
->Capabilities
, qos1
->qos
->IdentityTracking
,
1380 qos1
->qos
->ImpersonationType
, qos1
->qos
->AdditionalSecurityInfoType
,
1381 qos2
->qos
->Capabilities
, qos2
->qos
->IdentityTracking
,
1382 qos2
->qos
->ImpersonationType
, qos2
->qos
->AdditionalSecurityInfoType
);
1384 if ((qos1
->qos
->Capabilities
!= qos2
->qos
->Capabilities
) ||
1385 (qos1
->qos
->IdentityTracking
!= qos2
->qos
->IdentityTracking
) ||
1386 (qos1
->qos
->ImpersonationType
!= qos2
->qos
->ImpersonationType
) ||
1387 (qos1
->qos
->AdditionalSecurityInfoType
!= qos2
->qos
->AdditionalSecurityInfoType
))
1390 if (qos1
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1392 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials1
= qos1
->qos
->u
.HttpCredentials
;
1393 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials2
= qos2
->qos
->u
.HttpCredentials
;
1395 if (http_credentials1
->Flags
!= http_credentials2
->Flags
)
1398 if (http_credentials1
->AuthenticationTarget
!= http_credentials2
->AuthenticationTarget
)
1401 if (http_credentials1
->NumberOfAuthnSchemes
!= http_credentials2
->NumberOfAuthnSchemes
)
1404 if ((!http_credentials1
->AuthnSchemes
&& http_credentials2
->AuthnSchemes
) ||
1405 (http_credentials1
->AuthnSchemes
&& !http_credentials2
->AuthnSchemes
))
1408 if (memcmp(http_credentials1
->AuthnSchemes
, http_credentials2
->AuthnSchemes
,
1409 http_credentials1
->NumberOfAuthnSchemes
* sizeof(http_credentials1
->AuthnSchemes
[0])))
1412 /* server certificate subject not currently used */
1414 if (http_credentials1
->TransportCredentials
!= http_credentials2
->TransportCredentials
)
1416 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= http_credentials1
->TransportCredentials
;
1417 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= http_credentials2
->TransportCredentials
;
1419 if (!identity1
|| !identity2
)
1422 /* compare user names */
1423 if (identity1
->UserLength
!= identity2
->UserLength
||
1424 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1426 /* compare domain names */
1427 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1428 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1430 /* compare passwords */
1431 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1432 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1440 /***********************************************************************
1441 * RpcRevertToSelf (RPCRT4.@)
1443 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1446 return RpcRevertToSelfEx(NULL
);
1449 /***********************************************************************
1450 * RpcMgmtSetComTimeout (RPCRT4.@)
1452 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1454 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1458 /***********************************************************************
1459 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1461 RPCRTAPI RPC_STATUS RPC_ENTRY
1462 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1463 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1464 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1469 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1470 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1472 status
= RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
? &principal
: NULL
, AuthnLevel
,
1473 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1474 if (status
== RPC_S_OK
&& ServerPrincName
)
1476 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1477 RpcStringFreeW(&principal
);
1478 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1484 /***********************************************************************
1485 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1487 RPCRTAPI RPC_STATUS RPC_ENTRY
1488 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1489 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1490 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1492 RpcBinding
*bind
= Binding
;
1494 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1495 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1497 if (!bind
->AuthInfo
) return RPC_S_BINDING_HAS_NO_AUTH
;
1501 FIXME("QOS not implemented\n");
1502 return RPC_S_INVALID_BINDING
;
1505 if (ServerPrincName
)
1507 if (bind
->AuthInfo
->server_principal_name
)
1509 *ServerPrincName
= RPCRT4_strdupW(bind
->AuthInfo
->server_principal_name
);
1510 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1512 else *ServerPrincName
= NULL
;
1514 if (AuthnLevel
) *AuthnLevel
= bind
->AuthInfo
->AuthnLevel
;
1515 if (AuthnSvc
) *AuthnSvc
= bind
->AuthInfo
->AuthnSvc
;
1516 if (AuthIdentity
) *AuthIdentity
= bind
->AuthInfo
->identity
;
1519 FIXME("authorization service not implemented\n");
1520 *AuthzSvc
= RPC_C_AUTHZ_NONE
;
1526 /***********************************************************************
1527 * RpcBindingInqAuthInfoA (RPCRT4.@)
1529 RPCRTAPI RPC_STATUS RPC_ENTRY
1530 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1531 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1533 return RpcBindingInqAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1537 /***********************************************************************
1538 * RpcBindingInqAuthInfoW (RPCRT4.@)
1540 RPCRTAPI RPC_STATUS RPC_ENTRY
1541 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1542 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1544 return RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1548 /***********************************************************************
1549 * RpcBindingInqAuthClientA (RPCRT4.@)
1551 RPCRTAPI RPC_STATUS RPC_ENTRY
1552 RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1553 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1556 return RpcBindingInqAuthClientExA(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1557 AuthnSvc
, AuthzSvc
, 0);
1560 /***********************************************************************
1561 * RpcBindingInqAuthClientW (RPCRT4.@)
1563 RPCRTAPI RPC_STATUS RPC_ENTRY
1564 RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1565 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1568 return RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1569 AuthnSvc
, AuthzSvc
, 0);
1572 /***********************************************************************
1573 * RpcBindingInqAuthClientExA (RPCRT4.@)
1575 RPCRTAPI RPC_STATUS RPC_ENTRY
1576 RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1577 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1578 ULONG
*AuthzSvc
, ULONG Flags
)
1583 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1584 AuthnSvc
, AuthzSvc
, Flags
);
1586 status
= RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
? &principal
: NULL
,
1587 AuthnLevel
, AuthnSvc
, AuthzSvc
, Flags
);
1588 if (status
== RPC_S_OK
&& ServerPrincName
)
1590 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1591 if (!*ServerPrincName
&& principal
) status
= ERROR_OUTOFMEMORY
;
1592 RpcStringFreeW(&principal
);
1598 /***********************************************************************
1599 * RpcBindingInqAuthClientExW (RPCRT4.@)
1601 RPCRTAPI RPC_STATUS RPC_ENTRY
1602 RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1603 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1604 ULONG
*AuthzSvc
, ULONG Flags
)
1606 RpcBinding
*bind
= ClientBinding
;
1608 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1609 AuthnSvc
, AuthzSvc
, Flags
);
1611 if (!bind
->FromConn
) return RPC_S_INVALID_BINDING
;
1613 return rpcrt4_conn_inquire_auth_client(bind
->FromConn
, Privs
,
1614 ServerPrincName
, AuthnLevel
,
1615 AuthnSvc
, AuthzSvc
, Flags
);
1618 /***********************************************************************
1619 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1621 RPCRTAPI RPC_STATUS RPC_ENTRY
1622 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1623 ULONG AuthnLevel
, ULONG AuthnSvc
,
1624 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1625 RPC_SECURITY_QOS
*SecurityQos
)
1627 RpcBinding
* bind
= Binding
;
1631 ULONG package_count
;
1633 PSecPkgInfoA packages
;
1636 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1637 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1643 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1644 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1645 if (SecurityQos
->Version
>= 2)
1647 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1648 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1649 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1650 TRACE(", { %p, 0x%x, %d, %d, %p(%u), %s }",
1651 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1652 SecurityQos2
->u
.HttpCredentials
->Flags
,
1653 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1654 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1655 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1656 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1657 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1660 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1661 if (status
!= RPC_S_OK
)
1666 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1670 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1671 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1673 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1674 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1675 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1677 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1679 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1680 bind
->AuthInfo
= NULL
;
1684 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1686 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1687 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1690 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1691 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1693 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1694 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1697 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1700 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1701 return RPC_S_SEC_PKG_ERROR
;
1704 for (i
= 0; i
< package_count
; i
++)
1705 if (packages
[i
].wRPCID
== AuthnSvc
)
1708 if (i
== package_count
)
1710 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1711 FreeContextBuffer(packages
);
1712 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1715 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1716 r
= AcquireCredentialsHandleA(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1717 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1718 cbMaxToken
= packages
[i
].cbMaxToken
;
1719 FreeContextBuffer(packages
);
1720 if (r
== ERROR_SUCCESS
)
1722 RpcAuthInfo
*new_auth_info
;
1723 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1724 AuthIdentity
, &new_auth_info
);
1727 new_auth_info
->server_principal_name
= RPCRT4_strdupAtoW((char *)ServerPrincName
);
1728 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1730 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1731 bind
->AuthInfo
= new_auth_info
;
1735 RpcAuthInfo_Release(new_auth_info
);
1736 r
= ERROR_OUTOFMEMORY
;
1740 FreeCredentialsHandle(&cred
);
1745 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1746 return RPC_S_SEC_PKG_ERROR
;
1750 /***********************************************************************
1751 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1753 RPCRTAPI RPC_STATUS RPC_ENTRY
1754 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1755 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1756 RPC_SECURITY_QOS
*SecurityQos
)
1758 RpcBinding
* bind
= Binding
;
1762 ULONG package_count
;
1764 PSecPkgInfoW packages
;
1767 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w(ServerPrincName
),
1768 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1774 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1775 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1776 if (SecurityQos
->Version
>= 2)
1778 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1779 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1780 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1781 TRACE(", { %p, 0x%x, %d, %d, %p(%u), %s }",
1782 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1783 SecurityQos2
->u
.HttpCredentials
->Flags
,
1784 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1785 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1786 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1787 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1788 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1791 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1792 if (status
!= RPC_S_OK
)
1797 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1801 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1802 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1804 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1805 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1806 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1808 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1810 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1811 bind
->AuthInfo
= NULL
;
1815 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1817 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1818 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1821 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1822 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1824 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1825 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1828 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1831 ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n", r
);
1832 return RPC_S_SEC_PKG_ERROR
;
1835 for (i
= 0; i
< package_count
; i
++)
1836 if (packages
[i
].wRPCID
== AuthnSvc
)
1839 if (i
== package_count
)
1841 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1842 FreeContextBuffer(packages
);
1843 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1846 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1847 r
= AcquireCredentialsHandleW(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1848 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1849 cbMaxToken
= packages
[i
].cbMaxToken
;
1850 FreeContextBuffer(packages
);
1851 if (r
== ERROR_SUCCESS
)
1853 RpcAuthInfo
*new_auth_info
;
1854 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1855 AuthIdentity
, &new_auth_info
);
1858 new_auth_info
->server_principal_name
= RPCRT4_strdupW(ServerPrincName
);
1859 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1861 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1862 bind
->AuthInfo
= new_auth_info
;
1866 RpcAuthInfo_Release(new_auth_info
);
1867 r
= ERROR_OUTOFMEMORY
;
1871 FreeCredentialsHandle(&cred
);
1876 ERR("AcquireCredentialsHandleW failed with error 0x%08x\n", r
);
1877 return RPC_S_SEC_PKG_ERROR
;
1881 /***********************************************************************
1882 * RpcBindingSetAuthInfoA (RPCRT4.@)
1884 RPCRTAPI RPC_STATUS RPC_ENTRY
1885 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1886 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1888 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1889 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1890 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1893 /***********************************************************************
1894 * RpcBindingSetAuthInfoW (RPCRT4.@)
1896 RPCRTAPI RPC_STATUS RPC_ENTRY
1897 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1898 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1900 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w(ServerPrincName
),
1901 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1902 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1905 /***********************************************************************
1906 * RpcBindingSetOption (RPCRT4.@)
1908 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG_PTR OptionValue
)
1910 TRACE("(%p, %d, %ld)\n", BindingHandle
, Option
, OptionValue
);
1914 case RPC_C_OPT_COOKIE_AUTH
:
1916 RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*cookie
= (RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*)OptionValue
;
1917 RpcBinding
*binding
= BindingHandle
;
1918 int len
= MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, NULL
, 0);
1921 if (!(str
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(WCHAR
)))) return ERROR_OUTOFMEMORY
;
1922 MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, str
, len
);
1924 HeapFree(GetProcessHeap(), 0, binding
->CookieAuth
);
1925 binding
->CookieAuth
= str
;
1929 FIXME("option %u not supported\n", Option
);