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
24 #define WIN32_NO_STATUS
35 //#include "winerror.h"
36 //#include "winternl.h"
37 #include <wine/unicode.h>
42 #include <wine/debug.h>
44 //#include "rpc_binding.h"
45 #include "rpc_assoc.h"
47 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
49 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
53 if (!src
) return NULL
;
54 if (slen
== -1) slen
= strlen(src
);
56 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
62 LPSTR
RPCRT4_strdupWtoA(LPCWSTR src
)
66 if (!src
) return NULL
;
67 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
68 s
= HeapAlloc(GetProcessHeap(), 0, len
);
69 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
73 LPWSTR
RPCRT4_strdupAtoW(LPCSTR src
)
77 if (!src
) return NULL
;
78 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
79 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
80 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
84 static LPWSTR
RPCRT4_strndupAtoW(LPCSTR src
, INT slen
)
88 if (!src
) return NULL
;
89 len
= MultiByteToWideChar(CP_ACP
, 0, src
, slen
, NULL
, 0);
90 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
91 MultiByteToWideChar(CP_ACP
, 0, src
, slen
, s
, len
);
95 LPWSTR
RPCRT4_strndupW(LPCWSTR src
, INT slen
)
99 if (!src
) return NULL
;
100 if (slen
== -1) slen
= strlenW(src
);
102 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
103 memcpy(s
, src
, len
*sizeof(WCHAR
));
108 void RPCRT4_strfree(LPSTR src
)
110 HeapFree(GetProcessHeap(), 0, src
);
113 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
115 RpcBinding
* NewBinding
;
117 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
118 NewBinding
->refs
= 1;
119 NewBinding
->server
= server
;
121 *Binding
= NewBinding
;
126 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
128 RpcBinding
* NewBinding
;
130 RPCRT4_AllocBinding(&NewBinding
, server
);
131 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
133 TRACE("binding: %p\n", NewBinding
);
134 *Binding
= NewBinding
;
139 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
141 RpcBinding
* NewBinding
;
143 RPCRT4_AllocBinding(&NewBinding
, server
);
144 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
146 TRACE("binding: %p\n", NewBinding
);
147 *Binding
= NewBinding
;
152 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
153 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
157 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
158 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
160 RPCRT4_strfree(Binding
->NetworkAddr
);
161 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
162 RPCRT4_strfree(Binding
->Endpoint
);
163 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
164 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
165 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
167 /* only attempt to get an association if the binding is complete */
168 if (Endpoint
&& Endpoint
[0] != '\0')
170 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
171 Binding
->Endpoint
, Binding
->NetworkOptions
,
173 if (status
!= RPC_S_OK
)
180 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
181 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
185 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
186 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
188 RPCRT4_strfree(Binding
->NetworkAddr
);
189 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
190 RPCRT4_strfree(Binding
->Endpoint
);
191 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
192 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
193 Binding
->NetworkOptions
= RPCRT4_strdupW(NetworkOptions
);
195 /* only attempt to get an association if the binding is complete */
196 if (Endpoint
&& Endpoint
[0] != '\0')
198 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
199 Binding
->Endpoint
, Binding
->NetworkOptions
,
201 if (status
!= RPC_S_OK
)
208 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
212 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
214 RPCRT4_strfree(Binding
->Endpoint
);
215 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
217 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
218 Binding
->Assoc
= NULL
;
219 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
220 Binding
->Endpoint
, Binding
->NetworkOptions
,
222 if (status
!= RPC_S_OK
)
228 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
230 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
231 if (ObjectUuid
) Binding
->ObjectUuid
= *ObjectUuid
;
232 else UuidCreateNil(&Binding
->ObjectUuid
);
236 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
238 RpcBinding
* NewBinding
;
239 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
241 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
242 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
243 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
244 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
245 NewBinding
->FromConn
= Connection
;
247 TRACE("binding: %p\n", NewBinding
);
248 *Binding
= NewBinding
;
253 void RPCRT4_AddRefBinding(RpcBinding
* Binding
)
255 InterlockedIncrement(&Binding
->refs
);
258 RPC_STATUS
RPCRT4_ReleaseBinding(RpcBinding
* Binding
)
260 if (InterlockedDecrement(&Binding
->refs
))
263 TRACE("binding: %p\n", Binding
);
264 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
265 RPCRT4_strfree(Binding
->Endpoint
);
266 RPCRT4_strfree(Binding
->NetworkAddr
);
267 RPCRT4_strfree(Binding
->Protseq
);
268 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
269 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
270 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
271 HeapFree(GetProcessHeap(), 0, Binding
);
275 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
276 const RPC_SYNTAX_IDENTIFIER
*TransferSyntax
,
277 const RPC_SYNTAX_IDENTIFIER
*InterfaceId
)
279 TRACE("(Binding == ^%p)\n", Binding
);
281 if (!Binding
->server
) {
282 return RpcAssoc_GetClientConnection(Binding
->Assoc
, InterfaceId
,
283 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
, Connection
);
285 /* we already have a connection with acceptable binding, so use it */
286 if (Binding
->FromConn
) {
287 *Connection
= Binding
->FromConn
;
290 ERR("no connection in binding\n");
291 return RPC_S_INTERNAL_ERROR
;
296 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
298 TRACE("(Binding == ^%p)\n", Binding
);
299 if (!Connection
) return RPC_S_OK
;
300 if (Binding
->server
) {
301 /* don't destroy a connection that is cached in the binding */
302 if (Binding
->FromConn
== Connection
)
304 return RPCRT4_DestroyConnection(Connection
);
307 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
312 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
314 DWORD len
= strlen(dst
), slen
= strlen(src
);
315 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
318 HeapFree(GetProcessHeap(), 0, dst
);
322 memcpy(ndst
+len
+1, src
, slen
+1);
326 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
328 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
329 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
332 HeapFree(GetProcessHeap(), 0, dst
);
336 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
340 /* Copies the escaped version of a component into a string binding.
341 * Note: doesn't nul-terminate the string */
342 static RPC_CSTR
escape_string_binding_component(RPC_CSTR string_binding
,
343 const unsigned char *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 RPC_WSTR
escape_string_binding_componentW(RPC_WSTR string_binding
,
364 const WCHAR
*component
)
366 for (; *component
; component
++) {
367 switch (*component
) {
373 *string_binding
++ = '\\';
374 *string_binding
++ = *component
;
377 *string_binding
++ = *component
;
381 return string_binding
;
384 static const unsigned char *string_binding_find_delimiter(
385 const unsigned char *string_binding
, unsigned char delim
)
387 const unsigned char *next
;
388 for (next
= string_binding
; *next
; next
++) {
399 static const WCHAR
*string_binding_find_delimiterW(
400 const WCHAR
*string_binding
, WCHAR delim
)
403 for (next
= string_binding
; *next
; next
++) {
414 static RPC_CSTR
unescape_string_binding_component(
415 const unsigned char *string_binding
, int len
)
417 RPC_CSTR component
, p
;
419 if (len
== -1) len
= strlen((const char *)string_binding
);
421 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
422 if (!component
) return NULL
;
423 for (p
= component
; len
> 0; string_binding
++, len
--) {
424 if (*string_binding
== '\\') {
427 *p
++ = *string_binding
;
429 *p
++ = *string_binding
;
436 static RPC_WSTR
unescape_string_binding_componentW(
437 const WCHAR
*string_binding
, int len
)
439 RPC_WSTR component
, p
;
441 if (len
== -1) len
= strlenW(string_binding
);
443 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
444 if (!component
) return NULL
;
445 for (p
= component
; len
> 0; string_binding
++, len
--) {
446 if (*string_binding
== '\\') {
449 *p
++ = *string_binding
;
451 *p
++ = *string_binding
;
458 /***********************************************************************
459 * RpcStringBindingComposeA (RPCRT4.@)
461 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
462 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
463 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
468 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
469 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
470 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
471 debugstr_a( (char*)Options
), StringBinding
);
473 /* overestimate for each component for escaping of delimiters */
474 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) * 2 + 1;
475 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) * 2 + 1;
476 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
) * 2;
477 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) * 2 + 2;
478 if (Options
&& *Options
) len
+= strlen((char*)Options
) * 2 + 2;
480 data
= HeapAlloc(GetProcessHeap(), 0, len
);
481 *StringBinding
= data
;
483 if (ObjUuid
&& *ObjUuid
) {
484 data
= escape_string_binding_component(data
, ObjUuid
);
487 if (Protseq
&& *Protseq
) {
488 data
= escape_string_binding_component(data
, Protseq
);
491 if (NetworkAddr
&& *NetworkAddr
)
492 data
= escape_string_binding_component(data
, NetworkAddr
);
494 if ((Endpoint
&& *Endpoint
) ||
495 (Options
&& *Options
)) {
497 if (Endpoint
&& *Endpoint
) {
498 data
= escape_string_binding_component(data
, Endpoint
);
499 if (Options
&& *Options
) *data
++ = ',';
501 if (Options
&& *Options
) {
502 data
= escape_string_binding_component(data
, Options
);
511 /***********************************************************************
512 * RpcStringBindingComposeW (RPCRT4.@)
514 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
515 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
516 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
521 TRACE("(%s,%s,%s,%s,%s,%p)\n",
522 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
523 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
524 debugstr_w( Options
), StringBinding
);
526 /* overestimate for each component for escaping of delimiters */
527 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) * 2 + 1;
528 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) * 2 + 1;
529 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
) * 2;
530 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) * 2 + 2;
531 if (Options
&& *Options
) len
+= strlenW(Options
) * 2 + 2;
533 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
534 *StringBinding
= data
;
536 if (ObjUuid
&& *ObjUuid
) {
537 data
= escape_string_binding_componentW(data
, ObjUuid
);
540 if (Protseq
&& *Protseq
) {
541 data
= escape_string_binding_componentW(data
, Protseq
);
544 if (NetworkAddr
&& *NetworkAddr
) {
545 data
= escape_string_binding_componentW(data
, NetworkAddr
);
547 if ((Endpoint
&& *Endpoint
) ||
548 (Options
&& *Options
)) {
550 if (Endpoint
&& *Endpoint
) {
551 data
= escape_string_binding_componentW(data
, Endpoint
);
552 if (Options
&& *Options
) *data
++ = ',';
554 if (Options
&& *Options
) {
555 data
= escape_string_binding_componentW(data
, Options
);
565 /***********************************************************************
566 * RpcStringBindingParseA (RPCRT4.@)
568 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
569 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
570 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
572 const unsigned char *data
, *next
;
573 static const char ep_opt
[] = "endpoint=";
574 BOOL endpoint_already_found
= FALSE
;
576 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
577 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
579 if (ObjUuid
) *ObjUuid
= NULL
;
580 if (Protseq
) *Protseq
= NULL
;
581 if (NetworkAddr
) *NetworkAddr
= NULL
;
582 if (Endpoint
) *Endpoint
= NULL
;
583 if (Options
) *Options
= NULL
;
585 data
= StringBinding
;
587 next
= string_binding_find_delimiter(data
, '@');
591 RPC_CSTR str_uuid
= unescape_string_binding_component(data
, next
- data
);
592 status
= UuidFromStringA(str_uuid
, &uuid
);
593 if (status
!= RPC_S_OK
) {
594 HeapFree(GetProcessHeap(), 0, str_uuid
);
600 HeapFree(GetProcessHeap(), 0, str_uuid
);
604 next
= string_binding_find_delimiter(data
, ':');
606 if (Protseq
) *Protseq
= unescape_string_binding_component(data
, next
- data
);
610 next
= string_binding_find_delimiter(data
, '[');
612 const unsigned char *close
;
615 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_component(data
, next
- data
);
617 close
= string_binding_find_delimiter(data
, ']');
618 if (!close
) goto fail
;
620 /* tokenize options */
621 while (data
< close
) {
622 next
= string_binding_find_delimiter(data
, ',');
623 if (!next
|| next
> close
) next
= close
;
624 /* FIXME: this is kind of inefficient */
625 opt
= unescape_string_binding_component(data
, next
- data
);
629 next
= string_binding_find_delimiter(opt
, '=');
631 /* not an option, must be an endpoint */
632 if (endpoint_already_found
) goto fail
;
633 if (Endpoint
) *Endpoint
= opt
;
634 else HeapFree(GetProcessHeap(), 0, opt
);
635 endpoint_already_found
= TRUE
;
637 if (strncmp((const char *)opt
, ep_opt
, strlen(ep_opt
)) == 0) {
638 /* endpoint option */
639 if (endpoint_already_found
) goto fail
;
640 if (Endpoint
) *Endpoint
= unescape_string_binding_component(next
+1, -1);
641 HeapFree(GetProcessHeap(), 0, opt
);
642 endpoint_already_found
= TRUE
;
647 /* FIXME: this is kind of inefficient */
648 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, (char *)opt
);
649 HeapFree(GetProcessHeap(), 0, opt
);
653 HeapFree(GetProcessHeap(), 0, opt
);
659 if (*data
) goto fail
;
661 else if (NetworkAddr
)
662 *NetworkAddr
= unescape_string_binding_component(data
, -1);
667 if (ObjUuid
) RpcStringFreeA(ObjUuid
);
668 if (Protseq
) RpcStringFreeA(Protseq
);
669 if (NetworkAddr
) RpcStringFreeA(NetworkAddr
);
670 if (Endpoint
) RpcStringFreeA(Endpoint
);
671 if (Options
) RpcStringFreeA(Options
);
672 return RPC_S_INVALID_STRING_BINDING
;
675 /***********************************************************************
676 * RpcStringBindingParseW (RPCRT4.@)
678 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
679 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
680 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
682 const WCHAR
*data
, *next
;
683 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
684 BOOL endpoint_already_found
= FALSE
;
686 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
687 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
689 if (ObjUuid
) *ObjUuid
= NULL
;
690 if (Protseq
) *Protseq
= NULL
;
691 if (NetworkAddr
) *NetworkAddr
= NULL
;
692 if (Endpoint
) *Endpoint
= NULL
;
693 if (Options
) *Options
= NULL
;
695 data
= StringBinding
;
697 next
= string_binding_find_delimiterW(data
, '@');
701 RPC_WSTR str_uuid
= unescape_string_binding_componentW(data
, next
- data
);
702 status
= UuidFromStringW(str_uuid
, &uuid
);
703 if (status
!= RPC_S_OK
) {
704 HeapFree(GetProcessHeap(), 0, str_uuid
);
710 HeapFree(GetProcessHeap(), 0, str_uuid
);
714 next
= string_binding_find_delimiterW(data
, ':');
716 if (Protseq
) *Protseq
= unescape_string_binding_componentW(data
, next
- data
);
720 next
= string_binding_find_delimiterW(data
, '[');
725 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_componentW(data
, next
- data
);
727 close
= string_binding_find_delimiterW(data
, ']');
728 if (!close
) goto fail
;
730 /* tokenize options */
731 while (data
< close
) {
732 next
= string_binding_find_delimiterW(data
, ',');
733 if (!next
|| next
> close
) next
= close
;
734 /* FIXME: this is kind of inefficient */
735 opt
= unescape_string_binding_componentW(data
, next
- data
);
739 next
= string_binding_find_delimiterW(opt
, '=');
741 /* not an option, must be an endpoint */
742 if (endpoint_already_found
) goto fail
;
743 if (Endpoint
) *Endpoint
= opt
;
744 else HeapFree(GetProcessHeap(), 0, opt
);
745 endpoint_already_found
= TRUE
;
747 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
748 /* endpoint option */
749 if (endpoint_already_found
) goto fail
;
750 if (Endpoint
) *Endpoint
= unescape_string_binding_componentW(next
+1, -1);
751 HeapFree(GetProcessHeap(), 0, opt
);
752 endpoint_already_found
= TRUE
;
757 /* FIXME: this is kind of inefficient */
758 *Options
= RPCRT4_strconcatW(*Options
, opt
);
759 HeapFree(GetProcessHeap(), 0, opt
);
763 HeapFree(GetProcessHeap(), 0, opt
);
769 if (*data
) goto fail
;
770 } else if (NetworkAddr
)
771 *NetworkAddr
= unescape_string_binding_componentW(data
, -1);
776 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
777 if (Protseq
) RpcStringFreeW(Protseq
);
778 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
779 if (Endpoint
) RpcStringFreeW(Endpoint
);
780 if (Options
) RpcStringFreeW(Options
);
781 return RPC_S_INVALID_STRING_BINDING
;
784 /***********************************************************************
785 * RpcBindingFree (RPCRT4.@)
787 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
790 TRACE("(%p) = %p\n", Binding
, *Binding
);
792 status
= RPCRT4_ReleaseBinding(*Binding
);
794 status
= RPC_S_INVALID_BINDING
;
795 if (status
== RPC_S_OK
) *Binding
= NULL
;
799 /***********************************************************************
800 * RpcBindingVectorFree (RPCRT4.@)
802 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
806 TRACE("(%p)\n", BindingVector
);
807 for (c
=0; c
<(*BindingVector
)->Count
; c
++) RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
808 HeapFree(GetProcessHeap(), 0, *BindingVector
);
809 *BindingVector
= NULL
;
813 /***********************************************************************
814 * RpcBindingInqObject (RPCRT4.@)
816 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
818 RpcBinding
* bind
= Binding
;
820 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
821 *ObjectUuid
= bind
->ObjectUuid
;
825 /***********************************************************************
826 * RpcBindingSetObject (RPCRT4.@)
828 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
830 RpcBinding
* bind
= Binding
;
832 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
833 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
834 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
837 /***********************************************************************
838 * RpcBindingFromStringBindingA (RPCRT4.@)
840 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
843 RpcBinding
* bind
= NULL
;
844 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
847 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
849 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
850 &NetworkAddr
, &Endpoint
, &Options
);
851 if (ret
!= RPC_S_OK
) return ret
;
853 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
856 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
857 if (ret
!= RPC_S_OK
) return ret
;
858 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
860 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
862 RpcStringFreeA(&Options
);
863 RpcStringFreeA(&Endpoint
);
864 RpcStringFreeA(&NetworkAddr
);
865 RpcStringFreeA(&Protseq
);
866 RpcStringFreeA(&ObjectUuid
);
869 *Binding
= (RPC_BINDING_HANDLE
)bind
;
871 RPCRT4_ReleaseBinding(bind
);
876 /***********************************************************************
877 * RpcBindingFromStringBindingW (RPCRT4.@)
879 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
882 RpcBinding
* bind
= NULL
;
883 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
886 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
888 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
889 &NetworkAddr
, &Endpoint
, &Options
);
890 if (ret
!= RPC_S_OK
) return ret
;
892 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
895 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
896 if (ret
!= RPC_S_OK
) return ret
;
897 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
899 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
901 RpcStringFreeW(&Options
);
902 RpcStringFreeW(&Endpoint
);
903 RpcStringFreeW(&NetworkAddr
);
904 RpcStringFreeW(&Protseq
);
905 RpcStringFreeW(&ObjectUuid
);
908 *Binding
= (RPC_BINDING_HANDLE
)bind
;
910 RPCRT4_ReleaseBinding(bind
);
915 /***********************************************************************
916 * RpcBindingToStringBindingA (RPCRT4.@)
918 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
921 RpcBinding
* bind
= Binding
;
924 TRACE("(%p,%p)\n", Binding
, StringBinding
);
926 if (UuidIsNil(&bind
->ObjectUuid
, &ret
))
930 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
931 if (ret
!= RPC_S_OK
) return ret
;
934 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
935 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
937 RpcStringFreeA(&ObjectUuid
);
942 /***********************************************************************
943 * RpcBindingToStringBindingW (RPCRT4.@)
945 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
948 unsigned char *str
= NULL
;
949 TRACE("(%p,%p)\n", Binding
, StringBinding
);
950 ret
= RpcBindingToStringBindingA(Binding
, &str
);
951 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
952 RpcStringFreeA(&str
);
956 /***********************************************************************
957 * I_RpcBindingInqTransportType (RPCRT4.@)
959 RPC_STATUS WINAPI
I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding
, unsigned int * Type
)
962 FIXME( "(%p,%p): stub\n", Binding
, Type
);
963 *Type
= TRANSPORT_TYPE_LPC
;
967 /***********************************************************************
968 * I_RpcBindingSetAsync (RPCRT4.@)
970 * Exists in win9x and winNT, but with different number of arguments
971 * (9x version has 3 arguments, NT has 2).
973 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
975 RpcBinding
* bind
= Binding
;
977 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
979 bind
->BlockingFn
= BlockingFn
;
984 /***********************************************************************
985 * RpcBindingCopy (RPCRT4.@)
987 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
988 RPC_BINDING_HANDLE SourceBinding
,
989 RPC_BINDING_HANDLE
* DestinationBinding
)
991 RpcBinding
*DestBinding
;
992 RpcBinding
*SrcBinding
= SourceBinding
;
995 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
997 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
998 if (status
!= RPC_S_OK
) return status
;
1000 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
1001 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
1002 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
1003 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
1004 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
1005 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
1006 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
1007 DestBinding
->Assoc
= SrcBinding
->Assoc
;
1009 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
1010 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
1011 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
1012 DestBinding
->QOS
= SrcBinding
->QOS
;
1014 *DestinationBinding
= DestBinding
;
1018 /***********************************************************************
1019 * RpcBindingReset (RPCRT4.@)
1021 RPC_STATUS RPC_ENTRY
RpcBindingReset(RPC_BINDING_HANDLE Binding
)
1023 RpcBinding
*bind
= Binding
;
1025 TRACE("(%p)\n", Binding
);
1027 RPCRT4_strfree(bind
->Endpoint
);
1028 bind
->Endpoint
= NULL
;
1029 if (bind
->Assoc
) RpcAssoc_Release(bind
->Assoc
);
1035 /***********************************************************************
1036 * RpcImpersonateClient (RPCRT4.@)
1038 * Impersonates the client connected via a binding handle so that security
1039 * checks are done in the context of the client.
1042 * BindingHandle [I] Handle to the binding to the client.
1045 * Success: RPS_S_OK.
1046 * Failure: RPC_STATUS value.
1050 * If BindingHandle is NULL then the function impersonates the client
1051 * connected to the binding handle of the current thread.
1053 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
1057 TRACE("(%p)\n", BindingHandle
);
1059 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1060 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1062 bind
= BindingHandle
;
1064 return rpcrt4_conn_impersonate_client(bind
->FromConn
);
1065 return RPC_S_WRONG_KIND_OF_BINDING
;
1068 /***********************************************************************
1069 * RpcRevertToSelfEx (RPCRT4.@)
1071 * Stops impersonating the client connected to the binding handle so that security
1072 * checks are no longer done in the context of the client.
1075 * BindingHandle [I] Handle to the binding to the client.
1078 * Success: RPS_S_OK.
1079 * Failure: RPC_STATUS value.
1083 * If BindingHandle is NULL then the function stops impersonating the client
1084 * connected to the binding handle of the current thread.
1086 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
1090 TRACE("(%p)\n", BindingHandle
);
1092 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1093 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1095 bind
= BindingHandle
;
1097 return rpcrt4_conn_revert_to_self(bind
->FromConn
);
1098 return RPC_S_WRONG_KIND_OF_BINDING
;
1101 static inline BOOL
has_nt_auth_identity(ULONG AuthnLevel
)
1105 case RPC_C_AUTHN_GSS_NEGOTIATE
:
1106 case RPC_C_AUTHN_WINNT
:
1107 case RPC_C_AUTHN_GSS_KERBEROS
:
1114 RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
1115 CredHandle cred
, TimeStamp exp
,
1117 RPC_AUTH_IDENTITY_HANDLE identity
,
1120 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
1122 return ERROR_OUTOFMEMORY
;
1125 AuthInfo
->AuthnLevel
= AuthnLevel
;
1126 AuthInfo
->AuthnSvc
= AuthnSvc
;
1127 AuthInfo
->cred
= cred
;
1128 AuthInfo
->exp
= exp
;
1129 AuthInfo
->cbMaxToken
= cbMaxToken
;
1130 AuthInfo
->identity
= identity
;
1131 AuthInfo
->server_principal_name
= NULL
;
1133 /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to
1134 * enable better matching in RpcAuthInfo_IsEqual */
1135 if (identity
&& has_nt_auth_identity(AuthnSvc
))
1137 const SEC_WINNT_AUTH_IDENTITY_W
*nt_identity
= identity
;
1138 AuthInfo
->nt_identity
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
->nt_identity
));
1139 if (!AuthInfo
->nt_identity
)
1141 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1142 return ERROR_OUTOFMEMORY
;
1145 AuthInfo
->nt_identity
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1146 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1147 AuthInfo
->nt_identity
->User
= RPCRT4_strndupW(nt_identity
->User
, nt_identity
->UserLength
);
1149 AuthInfo
->nt_identity
->User
= RPCRT4_strndupAtoW((const char *)nt_identity
->User
, nt_identity
->UserLength
);
1150 AuthInfo
->nt_identity
->UserLength
= nt_identity
->UserLength
;
1151 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1152 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupW(nt_identity
->Domain
, nt_identity
->DomainLength
);
1154 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupAtoW((const char *)nt_identity
->Domain
, nt_identity
->DomainLength
);
1155 AuthInfo
->nt_identity
->DomainLength
= nt_identity
->DomainLength
;
1156 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1157 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupW(nt_identity
->Password
, nt_identity
->PasswordLength
);
1159 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupAtoW((const char *)nt_identity
->Password
, nt_identity
->PasswordLength
);
1160 AuthInfo
->nt_identity
->PasswordLength
= nt_identity
->PasswordLength
;
1162 if ((nt_identity
->User
&& !AuthInfo
->nt_identity
->User
) ||
1163 (nt_identity
->Domain
&& !AuthInfo
->nt_identity
->Domain
) ||
1164 (nt_identity
->Password
&& !AuthInfo
->nt_identity
->Password
))
1166 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1167 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1168 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1169 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1170 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1171 return ERROR_OUTOFMEMORY
;
1175 AuthInfo
->nt_identity
= NULL
;
1180 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
1182 return InterlockedIncrement(&AuthInfo
->refs
);
1185 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
1187 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
1191 FreeCredentialsHandle(&AuthInfo
->cred
);
1192 if (AuthInfo
->nt_identity
)
1194 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1195 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1196 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1197 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1199 HeapFree(GetProcessHeap(), 0, AuthInfo
->server_principal_name
);
1200 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1206 BOOL
RpcAuthInfo_IsEqual(const RpcAuthInfo
*AuthInfo1
, const RpcAuthInfo
*AuthInfo2
)
1208 if (AuthInfo1
== AuthInfo2
)
1211 if (!AuthInfo1
|| !AuthInfo2
)
1214 if ((AuthInfo1
->AuthnLevel
!= AuthInfo2
->AuthnLevel
) ||
1215 (AuthInfo1
->AuthnSvc
!= AuthInfo2
->AuthnSvc
))
1218 if (AuthInfo1
->identity
== AuthInfo2
->identity
)
1221 if (!AuthInfo1
->identity
|| !AuthInfo2
->identity
)
1224 if (has_nt_auth_identity(AuthInfo1
->AuthnSvc
))
1226 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= AuthInfo1
->nt_identity
;
1227 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= AuthInfo2
->nt_identity
;
1228 /* compare user names */
1229 if (identity1
->UserLength
!= identity2
->UserLength
||
1230 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1232 /* compare domain names */
1233 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1234 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1236 /* compare passwords */
1237 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1238 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1247 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1249 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1252 return RPC_S_OUT_OF_RESOURCES
;
1255 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1256 if (!qos
->qos
) goto error
;
1257 qos
->qos
->Version
= qos_src
->Version
;
1258 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1259 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1260 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1261 qos
->qos
->AdditionalSecurityInfoType
= 0;
1263 if (qos_src
->Version
>= 2)
1265 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1266 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1267 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1269 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1270 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1272 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1273 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1274 if (!http_credentials_dst
) goto error
;
1275 http_credentials_dst
->TransportCredentials
= NULL
;
1276 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1277 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1278 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1279 http_credentials_dst
->AuthnSchemes
= NULL
;
1280 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1281 if (http_credentials_src
->TransportCredentials
)
1283 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1284 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1285 if (!cred_dst
) goto error
;
1286 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1289 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1290 cred_dst
->UserLength
= cred_src
->UserLength
;
1291 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1292 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1293 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1294 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1295 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1299 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1300 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1301 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1302 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1303 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1304 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1305 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1306 if (!cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1307 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1308 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1309 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1312 if (http_credentials_src
->NumberOfAuthnSchemes
)
1314 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1315 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1316 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1318 if (http_credentials_src
->ServerCertificateSubject
)
1321 http_credentials_dst
->ServerCertificateSubject
=
1322 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1323 strlenW(http_credentials_src
->ServerCertificateSubject
));
1325 http_credentials_dst
->ServerCertificateSubject
=
1326 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1327 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1337 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1338 qos
->qos
->u
.HttpCredentials
)
1340 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1342 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1343 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1344 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1345 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1347 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1348 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1349 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1351 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1353 HeapFree(GetProcessHeap(), 0, qos
);
1354 return RPC_S_OUT_OF_RESOURCES
;
1357 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1359 return InterlockedIncrement(&qos
->refs
);
1362 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1364 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1368 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1370 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1372 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1373 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1374 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1375 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1377 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1378 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1379 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1381 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1382 HeapFree(GetProcessHeap(), 0, qos
);
1387 BOOL
RpcQualityOfService_IsEqual(const RpcQualityOfService
*qos1
, const RpcQualityOfService
*qos2
)
1395 TRACE("qos1 = { %d %d %d %d }, qos2 = { %d %d %d %d }\n",
1396 qos1
->qos
->Capabilities
, qos1
->qos
->IdentityTracking
,
1397 qos1
->qos
->ImpersonationType
, qos1
->qos
->AdditionalSecurityInfoType
,
1398 qos2
->qos
->Capabilities
, qos2
->qos
->IdentityTracking
,
1399 qos2
->qos
->ImpersonationType
, qos2
->qos
->AdditionalSecurityInfoType
);
1401 if ((qos1
->qos
->Capabilities
!= qos2
->qos
->Capabilities
) ||
1402 (qos1
->qos
->IdentityTracking
!= qos2
->qos
->IdentityTracking
) ||
1403 (qos1
->qos
->ImpersonationType
!= qos2
->qos
->ImpersonationType
) ||
1404 (qos1
->qos
->AdditionalSecurityInfoType
!= qos2
->qos
->AdditionalSecurityInfoType
))
1407 if (qos1
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1409 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials1
= qos1
->qos
->u
.HttpCredentials
;
1410 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials2
= qos2
->qos
->u
.HttpCredentials
;
1412 if (http_credentials1
->Flags
!= http_credentials2
->Flags
)
1415 if (http_credentials1
->AuthenticationTarget
!= http_credentials2
->AuthenticationTarget
)
1418 /* authentication schemes and server certificate subject not currently used */
1420 if (http_credentials1
->TransportCredentials
!= http_credentials2
->TransportCredentials
)
1422 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= http_credentials1
->TransportCredentials
;
1423 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= http_credentials2
->TransportCredentials
;
1425 if (!identity1
|| !identity2
)
1428 /* compare user names */
1429 if (identity1
->UserLength
!= identity2
->UserLength
||
1430 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1432 /* compare domain names */
1433 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1434 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1436 /* compare passwords */
1437 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1438 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1446 /***********************************************************************
1447 * RpcRevertToSelf (RPCRT4.@)
1449 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1452 return RpcRevertToSelfEx(NULL
);
1455 /***********************************************************************
1456 * RpcMgmtSetComTimeout (RPCRT4.@)
1458 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1460 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1464 /***********************************************************************
1465 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1467 RPCRTAPI RPC_STATUS RPC_ENTRY
1468 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1469 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1470 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1475 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1476 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1478 status
= RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
? &principal
: NULL
, AuthnLevel
,
1479 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1480 if (status
== RPC_S_OK
&& ServerPrincName
)
1482 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1483 RpcStringFreeW(&principal
);
1484 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1490 /***********************************************************************
1491 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1493 RPCRTAPI RPC_STATUS RPC_ENTRY
1494 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1495 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1496 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1498 RpcBinding
*bind
= Binding
;
1500 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1501 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1503 if (!bind
->AuthInfo
) return RPC_S_BINDING_HAS_NO_AUTH
;
1507 FIXME("QOS not implemented\n");
1508 return RPC_S_INVALID_BINDING
;
1511 if (ServerPrincName
)
1513 if (bind
->AuthInfo
->server_principal_name
)
1515 *ServerPrincName
= RPCRT4_strdupW(bind
->AuthInfo
->server_principal_name
);
1516 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1518 else *ServerPrincName
= NULL
;
1520 if (AuthnLevel
) *AuthnLevel
= bind
->AuthInfo
->AuthnLevel
;
1521 if (AuthnSvc
) *AuthnSvc
= bind
->AuthInfo
->AuthnSvc
;
1522 if (AuthIdentity
) *AuthIdentity
= bind
->AuthInfo
->identity
;
1525 FIXME("authorization service not implemented\n");
1526 *AuthzSvc
= RPC_C_AUTHZ_NONE
;
1532 /***********************************************************************
1533 * RpcBindingInqAuthInfoA (RPCRT4.@)
1535 RPCRTAPI RPC_STATUS RPC_ENTRY
1536 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1537 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1539 return RpcBindingInqAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1543 /***********************************************************************
1544 * RpcBindingInqAuthInfoW (RPCRT4.@)
1546 RPCRTAPI RPC_STATUS RPC_ENTRY
1547 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1548 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1550 return RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1554 /***********************************************************************
1555 * RpcBindingInqAuthClientA (RPCRT4.@)
1557 RPCRTAPI RPC_STATUS RPC_ENTRY
1558 RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1559 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1562 return RpcBindingInqAuthClientExA(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1563 AuthnSvc
, AuthzSvc
, 0);
1566 /***********************************************************************
1567 * RpcBindingInqAuthClientW (RPCRT4.@)
1569 RPCRTAPI RPC_STATUS RPC_ENTRY
1570 RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1571 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1574 return RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1575 AuthnSvc
, AuthzSvc
, 0);
1578 /***********************************************************************
1579 * RpcBindingInqAuthClientExA (RPCRT4.@)
1581 RPCRTAPI RPC_STATUS RPC_ENTRY
1582 RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1583 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1584 ULONG
*AuthzSvc
, ULONG Flags
)
1589 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1590 AuthnSvc
, AuthzSvc
, Flags
);
1592 status
= RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
? &principal
: NULL
,
1593 AuthnLevel
, AuthnSvc
, AuthzSvc
, Flags
);
1594 if (status
== RPC_S_OK
&& ServerPrincName
)
1596 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1597 if (!*ServerPrincName
&& principal
) status
= ERROR_OUTOFMEMORY
;
1598 RpcStringFreeW(&principal
);
1604 /***********************************************************************
1605 * RpcBindingInqAuthClientExW (RPCRT4.@)
1607 RPCRTAPI RPC_STATUS RPC_ENTRY
1608 RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1609 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1610 ULONG
*AuthzSvc
, ULONG Flags
)
1612 RpcBinding
*bind
= ClientBinding
;
1614 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1615 AuthnSvc
, AuthzSvc
, Flags
);
1617 if (!bind
->FromConn
) return RPC_S_INVALID_BINDING
;
1619 return rpcrt4_conn_inquire_auth_client(bind
->FromConn
, Privs
,
1620 ServerPrincName
, AuthnLevel
,
1621 AuthnSvc
, AuthzSvc
, Flags
);
1624 /***********************************************************************
1625 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1627 RPCRTAPI RPC_STATUS RPC_ENTRY
1628 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1629 ULONG AuthnLevel
, ULONG AuthnSvc
,
1630 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1631 RPC_SECURITY_QOS
*SecurityQos
)
1633 RpcBinding
* bind
= Binding
;
1637 ULONG package_count
;
1639 PSecPkgInfoA packages
;
1642 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1643 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1649 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1650 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1651 if (SecurityQos
->Version
>= 2)
1653 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1654 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1655 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1656 TRACE(", { %p, 0x%x, %d, %d, %p, %s }",
1657 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1658 SecurityQos2
->u
.HttpCredentials
->Flags
,
1659 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1660 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1661 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1662 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1665 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1666 if (status
!= RPC_S_OK
)
1671 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1675 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1676 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1678 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1679 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1680 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1682 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1684 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1685 bind
->AuthInfo
= NULL
;
1689 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1691 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1692 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1695 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1696 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1698 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1699 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1702 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1705 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1706 return RPC_S_SEC_PKG_ERROR
;
1709 for (i
= 0; i
< package_count
; i
++)
1710 if (packages
[i
].wRPCID
== AuthnSvc
)
1713 if (i
== package_count
)
1715 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1716 FreeContextBuffer(packages
);
1717 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1720 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1721 r
= AcquireCredentialsHandleA(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1722 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1723 cbMaxToken
= packages
[i
].cbMaxToken
;
1724 FreeContextBuffer(packages
);
1725 if (r
== ERROR_SUCCESS
)
1727 RpcAuthInfo
*new_auth_info
;
1728 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1729 AuthIdentity
, &new_auth_info
);
1732 new_auth_info
->server_principal_name
= RPCRT4_strdupAtoW((char *)ServerPrincName
);
1733 if (new_auth_info
->server_principal_name
)
1735 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1736 bind
->AuthInfo
= new_auth_info
;
1740 RpcAuthInfo_Release(new_auth_info
);
1741 r
= ERROR_OUTOFMEMORY
;
1745 FreeCredentialsHandle(&cred
);
1750 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1751 return RPC_S_SEC_PKG_ERROR
;
1755 /***********************************************************************
1756 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1758 RPCRTAPI RPC_STATUS RPC_ENTRY
1759 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1760 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1761 RPC_SECURITY_QOS
*SecurityQos
)
1763 RpcBinding
* bind
= Binding
;
1767 ULONG package_count
;
1769 PSecPkgInfoW packages
;
1772 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w(ServerPrincName
),
1773 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1779 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1780 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1781 if (SecurityQos
->Version
>= 2)
1783 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1784 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1785 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1786 TRACE(", { %p, 0x%x, %d, %d, %p, %s }",
1787 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1788 SecurityQos2
->u
.HttpCredentials
->Flags
,
1789 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1790 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1791 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1792 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1795 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1796 if (status
!= RPC_S_OK
)
1801 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1805 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1806 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1808 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1809 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1810 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1812 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1814 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1815 bind
->AuthInfo
= NULL
;
1819 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1821 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1822 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1825 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1826 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1828 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1829 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1832 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1835 ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n", r
);
1836 return RPC_S_SEC_PKG_ERROR
;
1839 for (i
= 0; i
< package_count
; i
++)
1840 if (packages
[i
].wRPCID
== AuthnSvc
)
1843 if (i
== package_count
)
1845 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1846 FreeContextBuffer(packages
);
1847 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1850 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1851 r
= AcquireCredentialsHandleW(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1852 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1853 cbMaxToken
= packages
[i
].cbMaxToken
;
1854 FreeContextBuffer(packages
);
1855 if (r
== ERROR_SUCCESS
)
1857 RpcAuthInfo
*new_auth_info
;
1858 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1859 AuthIdentity
, &new_auth_info
);
1862 new_auth_info
->server_principal_name
= RPCRT4_strdupW(ServerPrincName
);
1863 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1865 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1866 bind
->AuthInfo
= new_auth_info
;
1870 RpcAuthInfo_Release(new_auth_info
);
1871 r
= ERROR_OUTOFMEMORY
;
1875 FreeCredentialsHandle(&cred
);
1880 ERR("AcquireCredentialsHandleW failed with error 0x%08x\n", r
);
1881 return RPC_S_SEC_PKG_ERROR
;
1885 /***********************************************************************
1886 * RpcBindingSetAuthInfoA (RPCRT4.@)
1888 RPCRTAPI RPC_STATUS RPC_ENTRY
1889 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1890 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1892 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1893 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1894 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1897 /***********************************************************************
1898 * RpcBindingSetAuthInfoW (RPCRT4.@)
1900 RPCRTAPI RPC_STATUS RPC_ENTRY
1901 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1902 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1904 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w(ServerPrincName
),
1905 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1906 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1909 /***********************************************************************
1910 * RpcBindingSetOption (RPCRT4.@)
1912 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG_PTR OptionValue
)
1914 FIXME("(%p, %d, %ld): stub\n", BindingHandle
, Option
, OptionValue
);