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
34 #include "wine/unicode.h"
39 #include "wine/debug.h"
41 #include "rpc_binding.h"
42 #include "rpc_assoc.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
46 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
50 if (!src
) return NULL
;
51 if (slen
== -1) slen
= strlen(src
);
53 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
59 LPSTR
RPCRT4_strdupWtoA(LPCWSTR src
)
63 if (!src
) return NULL
;
64 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
65 s
= HeapAlloc(GetProcessHeap(), 0, len
);
66 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
70 LPWSTR
RPCRT4_strdupAtoW(LPCSTR src
)
74 if (!src
) return NULL
;
75 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
76 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
77 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
81 static LPWSTR
RPCRT4_strndupAtoW(LPCSTR src
, INT slen
)
85 if (!src
) return NULL
;
86 len
= MultiByteToWideChar(CP_ACP
, 0, src
, slen
, NULL
, 0);
87 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
88 MultiByteToWideChar(CP_ACP
, 0, src
, slen
, s
, len
);
92 LPWSTR
RPCRT4_strndupW(LPCWSTR src
, INT slen
)
96 if (!src
) return NULL
;
97 if (slen
== -1) slen
= strlenW(src
);
99 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
100 memcpy(s
, src
, len
*sizeof(WCHAR
));
105 void RPCRT4_strfree(LPSTR src
)
107 HeapFree(GetProcessHeap(), 0, src
);
110 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
112 RpcBinding
* NewBinding
;
114 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
115 NewBinding
->refs
= 1;
116 NewBinding
->server
= server
;
118 *Binding
= NewBinding
;
123 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
125 RpcBinding
* NewBinding
;
127 RPCRT4_AllocBinding(&NewBinding
, server
);
128 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
130 TRACE("binding: %p\n", NewBinding
);
131 *Binding
= NewBinding
;
136 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
138 RpcBinding
* NewBinding
;
140 RPCRT4_AllocBinding(&NewBinding
, server
);
141 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
143 TRACE("binding: %p\n", NewBinding
);
144 *Binding
= NewBinding
;
149 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
150 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
154 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
155 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
157 RPCRT4_strfree(Binding
->NetworkAddr
);
158 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
159 RPCRT4_strfree(Binding
->Endpoint
);
160 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
161 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
162 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
164 /* only attempt to get an association if the binding is complete */
165 if (Endpoint
&& Endpoint
[0] != '\0')
167 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
168 Binding
->Endpoint
, Binding
->NetworkOptions
,
170 if (status
!= RPC_S_OK
)
177 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
178 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
182 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
183 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
185 RPCRT4_strfree(Binding
->NetworkAddr
);
186 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
187 RPCRT4_strfree(Binding
->Endpoint
);
188 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
189 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
190 Binding
->NetworkOptions
= RPCRT4_strdupW(NetworkOptions
);
192 /* only attempt to get an association if the binding is complete */
193 if (Endpoint
&& Endpoint
[0] != '\0')
195 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
196 Binding
->Endpoint
, Binding
->NetworkOptions
,
198 if (status
!= RPC_S_OK
)
205 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
209 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
211 RPCRT4_strfree(Binding
->Endpoint
);
212 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
214 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
215 Binding
->Assoc
= NULL
;
216 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
217 Binding
->Endpoint
, Binding
->NetworkOptions
,
219 if (status
!= RPC_S_OK
)
225 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
227 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
228 if (ObjectUuid
) Binding
->ObjectUuid
= *ObjectUuid
;
229 else UuidCreateNil(&Binding
->ObjectUuid
);
233 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
235 RpcBinding
* NewBinding
;
236 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
238 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
239 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
240 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
241 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
242 NewBinding
->FromConn
= Connection
;
244 TRACE("binding: %p\n", NewBinding
);
245 *Binding
= NewBinding
;
250 void RPCRT4_AddRefBinding(RpcBinding
* Binding
)
252 InterlockedIncrement(&Binding
->refs
);
255 RPC_STATUS
RPCRT4_ReleaseBinding(RpcBinding
* Binding
)
257 if (InterlockedDecrement(&Binding
->refs
))
260 TRACE("binding: %p\n", Binding
);
261 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
262 RPCRT4_strfree(Binding
->Endpoint
);
263 RPCRT4_strfree(Binding
->NetworkAddr
);
264 RPCRT4_strfree(Binding
->Protseq
);
265 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
266 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
267 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
268 HeapFree(GetProcessHeap(), 0, Binding
);
272 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
273 const RPC_SYNTAX_IDENTIFIER
*TransferSyntax
,
274 const RPC_SYNTAX_IDENTIFIER
*InterfaceId
)
276 TRACE("(Binding == ^%p)\n", Binding
);
278 if (!Binding
->server
) {
279 return RpcAssoc_GetClientConnection(Binding
->Assoc
, InterfaceId
,
280 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
, Connection
);
282 /* we already have a connection with acceptable binding, so use it */
283 if (Binding
->FromConn
) {
284 *Connection
= Binding
->FromConn
;
287 ERR("no connection in binding\n");
288 return RPC_S_INTERNAL_ERROR
;
293 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
295 TRACE("(Binding == ^%p)\n", Binding
);
296 if (!Connection
) return RPC_S_OK
;
297 if (Binding
->server
) {
298 /* don't destroy a connection that is cached in the binding */
299 if (Binding
->FromConn
== Connection
)
301 return RPCRT4_DestroyConnection(Connection
);
304 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
309 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
311 DWORD len
= strlen(dst
), slen
= strlen(src
);
312 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
315 HeapFree(GetProcessHeap(), 0, dst
);
319 memcpy(ndst
+len
+1, src
, slen
+1);
323 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
325 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
326 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
329 HeapFree(GetProcessHeap(), 0, dst
);
333 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
337 /* Copies the escaped version of a component into a string binding.
338 * Note: doesn't nul-terminate the string */
339 static RPC_CSTR
escape_string_binding_component(RPC_CSTR string_binding
,
340 const unsigned char *component
)
342 for (; *component
; component
++) {
343 switch (*component
) {
349 *string_binding
++ = '\\';
350 *string_binding
++ = *component
;
353 *string_binding
++ = *component
;
357 return string_binding
;
360 static RPC_WSTR
escape_string_binding_componentW(RPC_WSTR string_binding
,
361 const WCHAR
*component
)
363 for (; *component
; component
++) {
364 switch (*component
) {
370 *string_binding
++ = '\\';
371 *string_binding
++ = *component
;
374 *string_binding
++ = *component
;
378 return string_binding
;
381 static const unsigned char *string_binding_find_delimiter(
382 const unsigned char *string_binding
, unsigned char delim
)
384 const unsigned char *next
;
385 for (next
= string_binding
; *next
; next
++) {
396 static const WCHAR
*string_binding_find_delimiterW(
397 const WCHAR
*string_binding
, WCHAR delim
)
400 for (next
= string_binding
; *next
; next
++) {
411 static RPC_CSTR
unescape_string_binding_component(
412 const unsigned char *string_binding
, int len
)
414 RPC_CSTR component
, p
;
416 if (len
== -1) len
= strlen((const char *)string_binding
);
418 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
419 if (!component
) return NULL
;
420 for (p
= component
; len
> 0; string_binding
++, len
--) {
421 if (*string_binding
== '\\') {
424 *p
++ = *string_binding
;
426 *p
++ = *string_binding
;
433 static RPC_WSTR
unescape_string_binding_componentW(
434 const WCHAR
*string_binding
, int len
)
436 RPC_WSTR component
, p
;
438 if (len
== -1) len
= strlenW(string_binding
);
440 component
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(*component
));
441 if (!component
) return NULL
;
442 for (p
= component
; len
> 0; string_binding
++, len
--) {
443 if (*string_binding
== '\\') {
446 *p
++ = *string_binding
;
448 *p
++ = *string_binding
;
455 /***********************************************************************
456 * RpcStringBindingComposeA (RPCRT4.@)
458 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
459 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
460 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
465 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
466 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
467 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
468 debugstr_a( (char*)Options
), StringBinding
);
470 /* overestimate for each component for escaping of delimiters */
471 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) * 2 + 1;
472 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) * 2 + 1;
473 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
) * 2;
474 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) * 2 + 2;
475 if (Options
&& *Options
) len
+= strlen((char*)Options
) * 2 + 2;
477 data
= HeapAlloc(GetProcessHeap(), 0, len
);
478 *StringBinding
= data
;
480 if (ObjUuid
&& *ObjUuid
) {
481 data
= escape_string_binding_component(data
, ObjUuid
);
484 if (Protseq
&& *Protseq
) {
485 data
= escape_string_binding_component(data
, Protseq
);
488 if (NetworkAddr
&& *NetworkAddr
)
489 data
= escape_string_binding_component(data
, NetworkAddr
);
491 if ((Endpoint
&& *Endpoint
) ||
492 (Options
&& *Options
)) {
494 if (Endpoint
&& *Endpoint
) {
495 data
= escape_string_binding_component(data
, Endpoint
);
496 if (Options
&& *Options
) *data
++ = ',';
498 if (Options
&& *Options
) {
499 data
= escape_string_binding_component(data
, Options
);
508 /***********************************************************************
509 * RpcStringBindingComposeW (RPCRT4.@)
511 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
512 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
513 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
518 TRACE("(%s,%s,%s,%s,%s,%p)\n",
519 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
520 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
521 debugstr_w( Options
), StringBinding
);
523 /* overestimate for each component for escaping of delimiters */
524 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) * 2 + 1;
525 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) * 2 + 1;
526 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
) * 2;
527 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) * 2 + 2;
528 if (Options
&& *Options
) len
+= strlenW(Options
) * 2 + 2;
530 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
531 *StringBinding
= data
;
533 if (ObjUuid
&& *ObjUuid
) {
534 data
= escape_string_binding_componentW(data
, ObjUuid
);
537 if (Protseq
&& *Protseq
) {
538 data
= escape_string_binding_componentW(data
, Protseq
);
541 if (NetworkAddr
&& *NetworkAddr
) {
542 data
= escape_string_binding_componentW(data
, NetworkAddr
);
544 if ((Endpoint
&& *Endpoint
) ||
545 (Options
&& *Options
)) {
547 if (Endpoint
&& *Endpoint
) {
548 data
= escape_string_binding_componentW(data
, Endpoint
);
549 if (Options
&& *Options
) *data
++ = ',';
551 if (Options
&& *Options
) {
552 data
= escape_string_binding_componentW(data
, Options
);
562 /***********************************************************************
563 * RpcStringBindingParseA (RPCRT4.@)
565 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
566 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
567 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
569 const unsigned char *data
, *next
;
570 static const char ep_opt
[] = "endpoint=";
571 BOOL endpoint_already_found
= FALSE
;
573 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
574 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
576 if (ObjUuid
) *ObjUuid
= NULL
;
577 if (Protseq
) *Protseq
= NULL
;
578 if (NetworkAddr
) *NetworkAddr
= NULL
;
579 if (Endpoint
) *Endpoint
= NULL
;
580 if (Options
) *Options
= NULL
;
582 data
= StringBinding
;
584 next
= string_binding_find_delimiter(data
, '@');
588 RPC_CSTR str_uuid
= unescape_string_binding_component(data
, next
- data
);
589 status
= UuidFromStringA(str_uuid
, &uuid
);
590 if (status
!= RPC_S_OK
) {
591 HeapFree(GetProcessHeap(), 0, str_uuid
);
597 HeapFree(GetProcessHeap(), 0, str_uuid
);
601 next
= string_binding_find_delimiter(data
, ':');
603 if (Protseq
) *Protseq
= unescape_string_binding_component(data
, next
- data
);
607 next
= string_binding_find_delimiter(data
, '[');
609 const unsigned char *close
;
612 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_component(data
, next
- data
);
614 close
= string_binding_find_delimiter(data
, ']');
615 if (!close
) goto fail
;
617 /* tokenize options */
618 while (data
< close
) {
619 next
= string_binding_find_delimiter(data
, ',');
620 if (!next
|| next
> close
) next
= close
;
621 /* FIXME: this is kind of inefficient */
622 opt
= unescape_string_binding_component(data
, next
- data
);
626 next
= string_binding_find_delimiter(opt
, '=');
628 /* not an option, must be an endpoint */
629 if (endpoint_already_found
) goto fail
;
630 if (Endpoint
) *Endpoint
= opt
;
631 else HeapFree(GetProcessHeap(), 0, opt
);
632 endpoint_already_found
= TRUE
;
634 if (strncmp((const char *)opt
, ep_opt
, strlen(ep_opt
)) == 0) {
635 /* endpoint option */
636 if (endpoint_already_found
) goto fail
;
637 if (Endpoint
) *Endpoint
= unescape_string_binding_component(next
+1, -1);
638 HeapFree(GetProcessHeap(), 0, opt
);
639 endpoint_already_found
= TRUE
;
644 /* FIXME: this is kind of inefficient */
645 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, (char *)opt
);
646 HeapFree(GetProcessHeap(), 0, opt
);
650 HeapFree(GetProcessHeap(), 0, opt
);
656 if (*data
) goto fail
;
658 else if (NetworkAddr
)
659 *NetworkAddr
= unescape_string_binding_component(data
, -1);
664 if (ObjUuid
) RpcStringFreeA(ObjUuid
);
665 if (Protseq
) RpcStringFreeA(Protseq
);
666 if (NetworkAddr
) RpcStringFreeA(NetworkAddr
);
667 if (Endpoint
) RpcStringFreeA(Endpoint
);
668 if (Options
) RpcStringFreeA(Options
);
669 return RPC_S_INVALID_STRING_BINDING
;
672 /***********************************************************************
673 * RpcStringBindingParseW (RPCRT4.@)
675 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
676 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
677 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
679 const WCHAR
*data
, *next
;
680 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
681 BOOL endpoint_already_found
= FALSE
;
683 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
684 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
686 if (ObjUuid
) *ObjUuid
= NULL
;
687 if (Protseq
) *Protseq
= NULL
;
688 if (NetworkAddr
) *NetworkAddr
= NULL
;
689 if (Endpoint
) *Endpoint
= NULL
;
690 if (Options
) *Options
= NULL
;
692 data
= StringBinding
;
694 next
= string_binding_find_delimiterW(data
, '@');
698 RPC_WSTR str_uuid
= unescape_string_binding_componentW(data
, next
- data
);
699 status
= UuidFromStringW(str_uuid
, &uuid
);
700 if (status
!= RPC_S_OK
) {
701 HeapFree(GetProcessHeap(), 0, str_uuid
);
707 HeapFree(GetProcessHeap(), 0, str_uuid
);
711 next
= string_binding_find_delimiterW(data
, ':');
713 if (Protseq
) *Protseq
= unescape_string_binding_componentW(data
, next
- data
);
717 next
= string_binding_find_delimiterW(data
, '[');
722 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_componentW(data
, next
- data
);
724 close
= string_binding_find_delimiterW(data
, ']');
725 if (!close
) goto fail
;
727 /* tokenize options */
728 while (data
< close
) {
729 next
= string_binding_find_delimiterW(data
, ',');
730 if (!next
|| next
> close
) next
= close
;
731 /* FIXME: this is kind of inefficient */
732 opt
= unescape_string_binding_componentW(data
, next
- data
);
736 next
= string_binding_find_delimiterW(opt
, '=');
738 /* not an option, must be an endpoint */
739 if (endpoint_already_found
) goto fail
;
740 if (Endpoint
) *Endpoint
= opt
;
741 else HeapFree(GetProcessHeap(), 0, opt
);
742 endpoint_already_found
= TRUE
;
744 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
745 /* endpoint option */
746 if (endpoint_already_found
) goto fail
;
747 if (Endpoint
) *Endpoint
= unescape_string_binding_componentW(next
+1, -1);
748 HeapFree(GetProcessHeap(), 0, opt
);
749 endpoint_already_found
= TRUE
;
754 /* FIXME: this is kind of inefficient */
755 *Options
= RPCRT4_strconcatW(*Options
, opt
);
756 HeapFree(GetProcessHeap(), 0, opt
);
760 HeapFree(GetProcessHeap(), 0, opt
);
766 if (*data
) goto fail
;
767 } else if (NetworkAddr
)
768 *NetworkAddr
= unescape_string_binding_componentW(data
, -1);
773 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
774 if (Protseq
) RpcStringFreeW(Protseq
);
775 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
776 if (Endpoint
) RpcStringFreeW(Endpoint
);
777 if (Options
) RpcStringFreeW(Options
);
778 return RPC_S_INVALID_STRING_BINDING
;
781 /***********************************************************************
782 * RpcBindingFree (RPCRT4.@)
784 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
787 TRACE("(%p) = %p\n", Binding
, *Binding
);
789 status
= RPCRT4_ReleaseBinding(*Binding
);
791 status
= RPC_S_INVALID_BINDING
;
792 if (status
== RPC_S_OK
) *Binding
= NULL
;
796 /***********************************************************************
797 * RpcBindingVectorFree (RPCRT4.@)
799 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
803 TRACE("(%p)\n", BindingVector
);
804 for (c
=0; c
<(*BindingVector
)->Count
; c
++) RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
805 HeapFree(GetProcessHeap(), 0, *BindingVector
);
806 *BindingVector
= NULL
;
810 /***********************************************************************
811 * RpcBindingInqObject (RPCRT4.@)
813 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
815 RpcBinding
* bind
= Binding
;
817 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
818 *ObjectUuid
= bind
->ObjectUuid
;
822 /***********************************************************************
823 * RpcBindingSetObject (RPCRT4.@)
825 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
827 RpcBinding
* bind
= Binding
;
829 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
830 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
831 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
834 /***********************************************************************
835 * RpcBindingFromStringBindingA (RPCRT4.@)
837 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
840 RpcBinding
* bind
= NULL
;
841 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
844 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
846 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
847 &NetworkAddr
, &Endpoint
, &Options
);
848 if (ret
!= RPC_S_OK
) return ret
;
850 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
853 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
854 if (ret
!= RPC_S_OK
) return ret
;
855 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
857 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
859 RpcStringFreeA(&Options
);
860 RpcStringFreeA(&Endpoint
);
861 RpcStringFreeA(&NetworkAddr
);
862 RpcStringFreeA(&Protseq
);
863 RpcStringFreeA(&ObjectUuid
);
866 *Binding
= (RPC_BINDING_HANDLE
)bind
;
868 RPCRT4_ReleaseBinding(bind
);
873 /***********************************************************************
874 * RpcBindingFromStringBindingW (RPCRT4.@)
876 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
879 RpcBinding
* bind
= NULL
;
880 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
883 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
885 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
886 &NetworkAddr
, &Endpoint
, &Options
);
887 if (ret
!= RPC_S_OK
) return ret
;
889 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
892 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
893 if (ret
!= RPC_S_OK
) return ret
;
894 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
896 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
898 RpcStringFreeW(&Options
);
899 RpcStringFreeW(&Endpoint
);
900 RpcStringFreeW(&NetworkAddr
);
901 RpcStringFreeW(&Protseq
);
902 RpcStringFreeW(&ObjectUuid
);
905 *Binding
= (RPC_BINDING_HANDLE
)bind
;
907 RPCRT4_ReleaseBinding(bind
);
912 /***********************************************************************
913 * RpcBindingToStringBindingA (RPCRT4.@)
915 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
918 RpcBinding
* bind
= Binding
;
921 TRACE("(%p,%p)\n", Binding
, StringBinding
);
923 if (UuidIsNil(&bind
->ObjectUuid
, &ret
))
927 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
928 if (ret
!= RPC_S_OK
) return ret
;
931 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
932 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
934 RpcStringFreeA(&ObjectUuid
);
939 /***********************************************************************
940 * RpcBindingToStringBindingW (RPCRT4.@)
942 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
945 unsigned char *str
= NULL
;
946 TRACE("(%p,%p)\n", Binding
, StringBinding
);
947 ret
= RpcBindingToStringBindingA(Binding
, &str
);
948 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
949 RpcStringFreeA(&str
);
953 /***********************************************************************
954 * I_RpcBindingInqTransportType (RPCRT4.@)
956 RPC_STATUS WINAPI
I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding
, unsigned int * Type
)
959 FIXME( "(%p,%p): stub\n", Binding
, Type
);
960 *Type
= TRANSPORT_TYPE_LPC
;
964 /***********************************************************************
965 * I_RpcBindingSetAsync (RPCRT4.@)
967 * Exists in win9x and winNT, but with different number of arguments
968 * (9x version has 3 arguments, NT has 2).
970 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
972 RpcBinding
* bind
= Binding
;
974 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
976 bind
->BlockingFn
= BlockingFn
;
981 /***********************************************************************
982 * RpcBindingCopy (RPCRT4.@)
984 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
985 RPC_BINDING_HANDLE SourceBinding
,
986 RPC_BINDING_HANDLE
* DestinationBinding
)
988 RpcBinding
*DestBinding
;
989 RpcBinding
*SrcBinding
= SourceBinding
;
992 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
994 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
995 if (status
!= RPC_S_OK
) return status
;
997 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
998 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
999 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
1000 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
1001 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
1002 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
1003 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
1004 DestBinding
->Assoc
= SrcBinding
->Assoc
;
1006 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
1007 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
1008 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
1009 DestBinding
->QOS
= SrcBinding
->QOS
;
1011 *DestinationBinding
= DestBinding
;
1015 /***********************************************************************
1016 * RpcBindingReset (RPCRT4.@)
1018 RPC_STATUS RPC_ENTRY
RpcBindingReset(RPC_BINDING_HANDLE Binding
)
1020 RpcBinding
*bind
= Binding
;
1022 TRACE("(%p)\n", Binding
);
1024 RPCRT4_strfree(bind
->Endpoint
);
1025 bind
->Endpoint
= NULL
;
1026 if (bind
->Assoc
) RpcAssoc_Release(bind
->Assoc
);
1032 /***********************************************************************
1033 * RpcImpersonateClient (RPCRT4.@)
1035 * Impersonates the client connected via a binding handle so that security
1036 * checks are done in the context of the client.
1039 * BindingHandle [I] Handle to the binding to the client.
1042 * Success: RPS_S_OK.
1043 * Failure: RPC_STATUS value.
1047 * If BindingHandle is NULL then the function impersonates the client
1048 * connected to the binding handle of the current thread.
1050 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
1054 TRACE("(%p)\n", BindingHandle
);
1056 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1057 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1059 bind
= BindingHandle
;
1061 return rpcrt4_conn_impersonate_client(bind
->FromConn
);
1062 return RPC_S_WRONG_KIND_OF_BINDING
;
1065 /***********************************************************************
1066 * RpcRevertToSelfEx (RPCRT4.@)
1068 * Stops impersonating the client connected to the binding handle so that security
1069 * checks are no longer done in the context of the client.
1072 * BindingHandle [I] Handle to the binding to the client.
1075 * Success: RPS_S_OK.
1076 * Failure: RPC_STATUS value.
1080 * If BindingHandle is NULL then the function stops impersonating the client
1081 * connected to the binding handle of the current thread.
1083 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
1087 TRACE("(%p)\n", BindingHandle
);
1089 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1090 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1092 bind
= BindingHandle
;
1094 return rpcrt4_conn_revert_to_self(bind
->FromConn
);
1095 return RPC_S_WRONG_KIND_OF_BINDING
;
1098 static inline BOOL
has_nt_auth_identity(ULONG AuthnLevel
)
1102 case RPC_C_AUTHN_GSS_NEGOTIATE
:
1103 case RPC_C_AUTHN_WINNT
:
1104 case RPC_C_AUTHN_GSS_KERBEROS
:
1111 RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
1112 CredHandle cred
, TimeStamp exp
,
1114 RPC_AUTH_IDENTITY_HANDLE identity
,
1117 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
1119 return ERROR_OUTOFMEMORY
;
1122 AuthInfo
->AuthnLevel
= AuthnLevel
;
1123 AuthInfo
->AuthnSvc
= AuthnSvc
;
1124 AuthInfo
->cred
= cred
;
1125 AuthInfo
->exp
= exp
;
1126 AuthInfo
->cbMaxToken
= cbMaxToken
;
1127 AuthInfo
->identity
= identity
;
1128 AuthInfo
->server_principal_name
= NULL
;
1130 /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to
1131 * enable better matching in RpcAuthInfo_IsEqual */
1132 if (identity
&& has_nt_auth_identity(AuthnSvc
))
1134 const SEC_WINNT_AUTH_IDENTITY_W
*nt_identity
= identity
;
1135 AuthInfo
->nt_identity
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
->nt_identity
));
1136 if (!AuthInfo
->nt_identity
)
1138 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1139 return ERROR_OUTOFMEMORY
;
1142 AuthInfo
->nt_identity
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1143 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1144 AuthInfo
->nt_identity
->User
= RPCRT4_strndupW(nt_identity
->User
, nt_identity
->UserLength
);
1146 AuthInfo
->nt_identity
->User
= RPCRT4_strndupAtoW((const char *)nt_identity
->User
, nt_identity
->UserLength
);
1147 AuthInfo
->nt_identity
->UserLength
= nt_identity
->UserLength
;
1148 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1149 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupW(nt_identity
->Domain
, nt_identity
->DomainLength
);
1151 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupAtoW((const char *)nt_identity
->Domain
, nt_identity
->DomainLength
);
1152 AuthInfo
->nt_identity
->DomainLength
= nt_identity
->DomainLength
;
1153 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1154 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupW(nt_identity
->Password
, nt_identity
->PasswordLength
);
1156 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupAtoW((const char *)nt_identity
->Password
, nt_identity
->PasswordLength
);
1157 AuthInfo
->nt_identity
->PasswordLength
= nt_identity
->PasswordLength
;
1159 if ((nt_identity
->User
&& !AuthInfo
->nt_identity
->User
) ||
1160 (nt_identity
->Domain
&& !AuthInfo
->nt_identity
->Domain
) ||
1161 (nt_identity
->Password
&& !AuthInfo
->nt_identity
->Password
))
1163 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1164 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1165 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1166 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1167 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1168 return ERROR_OUTOFMEMORY
;
1172 AuthInfo
->nt_identity
= NULL
;
1177 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
1179 return InterlockedIncrement(&AuthInfo
->refs
);
1182 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
1184 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
1188 FreeCredentialsHandle(&AuthInfo
->cred
);
1189 if (AuthInfo
->nt_identity
)
1191 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->User
);
1192 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Domain
);
1193 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
->Password
);
1194 HeapFree(GetProcessHeap(), 0, AuthInfo
->nt_identity
);
1196 HeapFree(GetProcessHeap(), 0, AuthInfo
->server_principal_name
);
1197 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1203 BOOL
RpcAuthInfo_IsEqual(const RpcAuthInfo
*AuthInfo1
, const RpcAuthInfo
*AuthInfo2
)
1205 if (AuthInfo1
== AuthInfo2
)
1208 if (!AuthInfo1
|| !AuthInfo2
)
1211 if ((AuthInfo1
->AuthnLevel
!= AuthInfo2
->AuthnLevel
) ||
1212 (AuthInfo1
->AuthnSvc
!= AuthInfo2
->AuthnSvc
))
1215 if (AuthInfo1
->identity
== AuthInfo2
->identity
)
1218 if (!AuthInfo1
->identity
|| !AuthInfo2
->identity
)
1221 if (has_nt_auth_identity(AuthInfo1
->AuthnSvc
))
1223 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= AuthInfo1
->nt_identity
;
1224 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= AuthInfo2
->nt_identity
;
1225 /* compare user names */
1226 if (identity1
->UserLength
!= identity2
->UserLength
||
1227 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1229 /* compare domain names */
1230 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1231 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1233 /* compare passwords */
1234 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1235 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1244 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1246 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1249 return RPC_S_OUT_OF_RESOURCES
;
1252 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1253 if (!qos
->qos
) goto error
;
1254 qos
->qos
->Version
= qos_src
->Version
;
1255 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1256 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1257 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1258 qos
->qos
->AdditionalSecurityInfoType
= 0;
1260 if (qos_src
->Version
>= 2)
1262 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1263 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1264 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1266 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1267 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1269 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1270 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1271 if (!http_credentials_dst
) goto error
;
1272 http_credentials_dst
->TransportCredentials
= NULL
;
1273 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1274 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1275 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1276 http_credentials_dst
->AuthnSchemes
= NULL
;
1277 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1278 if (http_credentials_src
->TransportCredentials
)
1280 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1281 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1282 if (!cred_dst
) goto error
;
1283 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1286 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1287 cred_dst
->UserLength
= cred_src
->UserLength
;
1288 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1289 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1290 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1291 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1292 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1296 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1297 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1298 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1299 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1300 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1301 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1302 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1303 if (!cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1304 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1305 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1306 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1309 if (http_credentials_src
->NumberOfAuthnSchemes
)
1311 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1312 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1313 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1315 if (http_credentials_src
->ServerCertificateSubject
)
1318 http_credentials_dst
->ServerCertificateSubject
=
1319 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1320 strlenW(http_credentials_src
->ServerCertificateSubject
));
1322 http_credentials_dst
->ServerCertificateSubject
=
1323 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1324 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1334 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1335 qos
->qos
->u
.HttpCredentials
)
1337 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1339 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1340 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1341 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1342 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1344 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1345 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1346 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1348 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1350 HeapFree(GetProcessHeap(), 0, qos
);
1351 return RPC_S_OUT_OF_RESOURCES
;
1354 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1356 return InterlockedIncrement(&qos
->refs
);
1359 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1361 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1365 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1367 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1369 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1370 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1371 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1372 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1374 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1375 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1376 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1378 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1379 HeapFree(GetProcessHeap(), 0, qos
);
1384 BOOL
RpcQualityOfService_IsEqual(const RpcQualityOfService
*qos1
, const RpcQualityOfService
*qos2
)
1392 TRACE("qos1 = { %d %d %d %d }, qos2 = { %d %d %d %d }\n",
1393 qos1
->qos
->Capabilities
, qos1
->qos
->IdentityTracking
,
1394 qos1
->qos
->ImpersonationType
, qos1
->qos
->AdditionalSecurityInfoType
,
1395 qos2
->qos
->Capabilities
, qos2
->qos
->IdentityTracking
,
1396 qos2
->qos
->ImpersonationType
, qos2
->qos
->AdditionalSecurityInfoType
);
1398 if ((qos1
->qos
->Capabilities
!= qos2
->qos
->Capabilities
) ||
1399 (qos1
->qos
->IdentityTracking
!= qos2
->qos
->IdentityTracking
) ||
1400 (qos1
->qos
->ImpersonationType
!= qos2
->qos
->ImpersonationType
) ||
1401 (qos1
->qos
->AdditionalSecurityInfoType
!= qos2
->qos
->AdditionalSecurityInfoType
))
1404 if (qos1
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1406 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials1
= qos1
->qos
->u
.HttpCredentials
;
1407 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials2
= qos2
->qos
->u
.HttpCredentials
;
1409 if (http_credentials1
->Flags
!= http_credentials2
->Flags
)
1412 if (http_credentials1
->AuthenticationTarget
!= http_credentials2
->AuthenticationTarget
)
1415 /* authentication schemes and server certificate subject not currently used */
1417 if (http_credentials1
->TransportCredentials
!= http_credentials2
->TransportCredentials
)
1419 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= http_credentials1
->TransportCredentials
;
1420 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= http_credentials2
->TransportCredentials
;
1422 if (!identity1
|| !identity2
)
1425 /* compare user names */
1426 if (identity1
->UserLength
!= identity2
->UserLength
||
1427 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1429 /* compare domain names */
1430 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1431 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1433 /* compare passwords */
1434 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1435 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1443 /***********************************************************************
1444 * RpcRevertToSelf (RPCRT4.@)
1446 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1449 return RpcRevertToSelfEx(NULL
);
1452 /***********************************************************************
1453 * RpcMgmtSetComTimeout (RPCRT4.@)
1455 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1457 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1461 /***********************************************************************
1462 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1464 RPCRTAPI RPC_STATUS RPC_ENTRY
1465 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1466 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1467 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1472 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1473 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1475 status
= RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
? &principal
: NULL
, AuthnLevel
,
1476 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1477 if (status
== RPC_S_OK
&& ServerPrincName
)
1479 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1480 RpcStringFreeW(&principal
);
1481 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1487 /***********************************************************************
1488 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1490 RPCRTAPI RPC_STATUS RPC_ENTRY
1491 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1492 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1493 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1495 RpcBinding
*bind
= Binding
;
1497 TRACE("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1498 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1500 if (!bind
->AuthInfo
) return RPC_S_BINDING_HAS_NO_AUTH
;
1504 FIXME("QOS not implemented\n");
1505 return RPC_S_INVALID_BINDING
;
1508 if (ServerPrincName
)
1510 if (bind
->AuthInfo
->server_principal_name
)
1512 *ServerPrincName
= RPCRT4_strdupW(bind
->AuthInfo
->server_principal_name
);
1513 if (!*ServerPrincName
) return ERROR_OUTOFMEMORY
;
1515 else *ServerPrincName
= NULL
;
1517 if (AuthnLevel
) *AuthnLevel
= bind
->AuthInfo
->AuthnLevel
;
1518 if (AuthnSvc
) *AuthnSvc
= bind
->AuthInfo
->AuthnSvc
;
1519 if (AuthIdentity
) *AuthIdentity
= bind
->AuthInfo
->identity
;
1522 FIXME("authorization service not implemented\n");
1523 *AuthzSvc
= RPC_C_AUTHZ_NONE
;
1529 /***********************************************************************
1530 * RpcBindingInqAuthInfoA (RPCRT4.@)
1532 RPCRTAPI RPC_STATUS RPC_ENTRY
1533 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1534 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1536 return RpcBindingInqAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1540 /***********************************************************************
1541 * RpcBindingInqAuthInfoW (RPCRT4.@)
1543 RPCRTAPI RPC_STATUS RPC_ENTRY
1544 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1545 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1547 return RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1551 /***********************************************************************
1552 * RpcBindingInqAuthClientA (RPCRT4.@)
1554 RPCRTAPI RPC_STATUS RPC_ENTRY
1555 RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1556 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1559 return RpcBindingInqAuthClientExA(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1560 AuthnSvc
, AuthzSvc
, 0);
1563 /***********************************************************************
1564 * RpcBindingInqAuthClientW (RPCRT4.@)
1566 RPCRTAPI RPC_STATUS RPC_ENTRY
1567 RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1568 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1571 return RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1572 AuthnSvc
, AuthzSvc
, 0);
1575 /***********************************************************************
1576 * RpcBindingInqAuthClientExA (RPCRT4.@)
1578 RPCRTAPI RPC_STATUS RPC_ENTRY
1579 RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1580 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1581 ULONG
*AuthzSvc
, ULONG Flags
)
1586 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1587 AuthnSvc
, AuthzSvc
, Flags
);
1589 status
= RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
? &principal
: NULL
,
1590 AuthnLevel
, AuthnSvc
, AuthzSvc
, Flags
);
1591 if (status
== RPC_S_OK
&& ServerPrincName
)
1593 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1594 if (!*ServerPrincName
&& principal
) status
= ERROR_OUTOFMEMORY
;
1595 RpcStringFreeW(&principal
);
1601 /***********************************************************************
1602 * RpcBindingInqAuthClientExW (RPCRT4.@)
1604 RPCRTAPI RPC_STATUS RPC_ENTRY
1605 RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1606 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1607 ULONG
*AuthzSvc
, ULONG Flags
)
1609 RpcBinding
*bind
= ClientBinding
;
1611 TRACE("%p %p %p %p %p %p 0x%x\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1612 AuthnSvc
, AuthzSvc
, Flags
);
1614 if (!bind
->FromConn
) return RPC_S_INVALID_BINDING
;
1616 return rpcrt4_conn_inquire_auth_client(bind
->FromConn
, Privs
,
1617 ServerPrincName
, AuthnLevel
,
1618 AuthnSvc
, AuthzSvc
, Flags
);
1621 /***********************************************************************
1622 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1624 RPCRTAPI RPC_STATUS RPC_ENTRY
1625 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1626 ULONG AuthnLevel
, ULONG AuthnSvc
,
1627 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1628 RPC_SECURITY_QOS
*SecurityQos
)
1630 RpcBinding
* bind
= Binding
;
1634 ULONG package_count
;
1636 PSecPkgInfoA packages
;
1639 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1640 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1646 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1647 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1648 if (SecurityQos
->Version
>= 2)
1650 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1651 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1652 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1653 TRACE(", { %p, 0x%x, %d, %d, %p, %s }",
1654 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1655 SecurityQos2
->u
.HttpCredentials
->Flags
,
1656 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1657 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1658 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1659 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1662 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1663 if (status
!= RPC_S_OK
)
1668 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1672 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1673 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1675 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1676 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1677 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1679 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1681 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1682 bind
->AuthInfo
= NULL
;
1686 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1688 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1689 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1692 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1693 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1695 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1696 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1699 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1702 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1703 return RPC_S_SEC_PKG_ERROR
;
1706 for (i
= 0; i
< package_count
; i
++)
1707 if (packages
[i
].wRPCID
== AuthnSvc
)
1710 if (i
== package_count
)
1712 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1713 FreeContextBuffer(packages
);
1714 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1717 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1718 r
= AcquireCredentialsHandleA(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1719 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1720 cbMaxToken
= packages
[i
].cbMaxToken
;
1721 FreeContextBuffer(packages
);
1722 if (r
== ERROR_SUCCESS
)
1724 RpcAuthInfo
*new_auth_info
;
1725 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1726 AuthIdentity
, &new_auth_info
);
1729 new_auth_info
->server_principal_name
= RPCRT4_strdupAtoW((char *)ServerPrincName
);
1730 if (new_auth_info
->server_principal_name
)
1732 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1733 bind
->AuthInfo
= new_auth_info
;
1737 RpcAuthInfo_Release(new_auth_info
);
1738 r
= ERROR_OUTOFMEMORY
;
1742 FreeCredentialsHandle(&cred
);
1747 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1748 return RPC_S_SEC_PKG_ERROR
;
1752 /***********************************************************************
1753 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1755 RPCRTAPI RPC_STATUS RPC_ENTRY
1756 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1757 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1758 RPC_SECURITY_QOS
*SecurityQos
)
1760 RpcBinding
* bind
= Binding
;
1764 ULONG package_count
;
1766 PSecPkgInfoW packages
;
1769 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w(ServerPrincName
),
1770 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1776 TRACE("SecurityQos { Version=%d, Capabilities=0x%x, IdentityTracking=%d, ImpersonationLevel=%d",
1777 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1778 if (SecurityQos
->Version
>= 2)
1780 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1781 TRACE(", AdditionalSecurityInfoType=%d", SecurityQos2
->AdditionalSecurityInfoType
);
1782 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1783 TRACE(", { %p, 0x%x, %d, %d, %p, %s }",
1784 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1785 SecurityQos2
->u
.HttpCredentials
->Flags
,
1786 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1787 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1788 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1789 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1792 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1793 if (status
!= RPC_S_OK
)
1798 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1802 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1803 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1805 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1806 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1807 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1809 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1811 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1812 bind
->AuthInfo
= NULL
;
1816 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1818 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1819 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1822 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1823 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1825 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1826 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1829 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1832 ERR("EnumerateSecurityPackagesW failed with error 0x%08x\n", r
);
1833 return RPC_S_SEC_PKG_ERROR
;
1836 for (i
= 0; i
< package_count
; i
++)
1837 if (packages
[i
].wRPCID
== AuthnSvc
)
1840 if (i
== package_count
)
1842 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1843 FreeContextBuffer(packages
);
1844 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1847 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1848 r
= AcquireCredentialsHandleW(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1849 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1850 cbMaxToken
= packages
[i
].cbMaxToken
;
1851 FreeContextBuffer(packages
);
1852 if (r
== ERROR_SUCCESS
)
1854 RpcAuthInfo
*new_auth_info
;
1855 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1856 AuthIdentity
, &new_auth_info
);
1859 new_auth_info
->server_principal_name
= RPCRT4_strdupW(ServerPrincName
);
1860 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1862 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1863 bind
->AuthInfo
= new_auth_info
;
1867 RpcAuthInfo_Release(new_auth_info
);
1868 r
= ERROR_OUTOFMEMORY
;
1872 FreeCredentialsHandle(&cred
);
1877 ERR("AcquireCredentialsHandleW failed with error 0x%08x\n", r
);
1878 return RPC_S_SEC_PKG_ERROR
;
1882 /***********************************************************************
1883 * RpcBindingSetAuthInfoA (RPCRT4.@)
1885 RPCRTAPI RPC_STATUS RPC_ENTRY
1886 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1887 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1889 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1890 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1891 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1894 /***********************************************************************
1895 * RpcBindingSetAuthInfoW (RPCRT4.@)
1897 RPCRTAPI RPC_STATUS RPC_ENTRY
1898 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1899 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1901 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w(ServerPrincName
),
1902 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1903 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1906 /***********************************************************************
1907 * RpcBindingSetOption (RPCRT4.@)
1909 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG_PTR OptionValue
)
1911 FIXME("(%p, %d, %ld): stub\n", BindingHandle
, Option
, OptionValue
);