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
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
);
59 LPSTR
RPCRT4_strdupWtoA(LPCWSTR src
)
63 if (!src
) return NULL
;
64 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
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
= malloc(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
= malloc(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
= lstrlenW(src
);
99 s
= malloc((len
+ 1) * sizeof(WCHAR
));
100 memcpy(s
, src
, len
*sizeof(WCHAR
));
105 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
107 RpcBinding
* NewBinding
;
109 NewBinding
= calloc(1, sizeof(RpcBinding
));
110 NewBinding
->refs
= 1;
111 NewBinding
->server
= server
;
113 *Binding
= NewBinding
;
118 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
120 RpcBinding
* NewBinding
;
122 RPCRT4_AllocBinding(&NewBinding
, server
);
123 NewBinding
->Protseq
= strdup(Protseq
);
125 TRACE("binding: %p\n", NewBinding
);
126 *Binding
= NewBinding
;
131 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
133 RpcBinding
* NewBinding
;
135 RPCRT4_AllocBinding(&NewBinding
, server
);
136 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
138 TRACE("binding: %p\n", NewBinding
);
139 *Binding
= NewBinding
;
144 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
145 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
149 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
150 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
152 free(Binding
->NetworkAddr
);
153 Binding
->NetworkAddr
= strdup(NetworkAddr
);
154 free(Binding
->Endpoint
);
155 Binding
->Endpoint
= strdup(Endpoint
);
156 free(Binding
->NetworkOptions
);
157 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
159 /* only attempt to get an association if the binding is complete */
160 if (Endpoint
&& Endpoint
[0] != '\0')
162 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
163 Binding
->Endpoint
, Binding
->NetworkOptions
,
165 if (status
!= RPC_S_OK
)
172 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
173 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
177 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
178 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
180 free(Binding
->NetworkAddr
);
181 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
182 free(Binding
->Endpoint
);
183 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
184 free(Binding
->NetworkOptions
);
185 Binding
->NetworkOptions
= wcsdup(NetworkOptions
);
187 /* only attempt to get an association if the binding is complete */
188 if (Endpoint
&& Endpoint
[0] != '\0')
190 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
191 Binding
->Endpoint
, Binding
->NetworkOptions
,
193 if (status
!= RPC_S_OK
)
200 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
204 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
206 free(Binding
->Endpoint
);
207 Binding
->Endpoint
= strdup(Endpoint
);
209 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
210 Binding
->Assoc
= NULL
;
211 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
212 Binding
->Endpoint
, Binding
->NetworkOptions
,
214 if (status
!= RPC_S_OK
)
220 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
222 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
223 if (ObjectUuid
) Binding
->ObjectUuid
= *ObjectUuid
;
224 else UuidCreateNil(&Binding
->ObjectUuid
);
228 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
230 RpcBinding
* NewBinding
;
231 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
233 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
234 NewBinding
->Protseq
= strdup(rpcrt4_conn_get_name(Connection
));
235 NewBinding
->NetworkAddr
= strdup(Connection
->NetworkAddr
);
236 NewBinding
->Endpoint
= strdup(Connection
->Endpoint
);
237 NewBinding
->FromConn
= Connection
;
239 TRACE("binding: %p\n", NewBinding
);
240 *Binding
= NewBinding
;
245 void RPCRT4_AddRefBinding(RpcBinding
* Binding
)
247 InterlockedIncrement(&Binding
->refs
);
250 RPC_STATUS
RPCRT4_ReleaseBinding(RpcBinding
* Binding
)
252 if (InterlockedDecrement(&Binding
->refs
))
255 TRACE("binding: %p\n", Binding
);
256 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
257 free(Binding
->Endpoint
);
258 free(Binding
->NetworkAddr
);
259 free(Binding
->Protseq
);
260 free(Binding
->NetworkOptions
);
261 free(Binding
->CookieAuth
);
262 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
263 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
268 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
269 const RPC_SYNTAX_IDENTIFIER
*TransferSyntax
,
270 const RPC_SYNTAX_IDENTIFIER
*InterfaceId
, BOOL
*from_cache
)
272 TRACE("(Binding == ^%p)\n", Binding
);
274 if (!Binding
->server
) {
275 return RpcAssoc_GetClientConnection(Binding
->Assoc
, InterfaceId
,
276 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
, Binding
->CookieAuth
, Connection
, from_cache
);
278 /* we already have a connection with acceptable binding, so use it */
279 if (Binding
->FromConn
) {
280 *Connection
= Binding
->FromConn
;
283 ERR("no connection in binding\n");
284 return RPC_S_INTERNAL_ERROR
;
289 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
291 TRACE("(Binding == ^%p)\n", Binding
);
292 if (!Connection
) return RPC_S_OK
;
293 if (Binding
->server
) {
294 /* don't destroy a connection that is cached in the binding */
295 if (Binding
->FromConn
!= Connection
)
296 RPCRT4_ReleaseConnection(Connection
);
299 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
304 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
306 DWORD len
= strlen(dst
), slen
= strlen(src
);
307 char *ndst
= realloc(dst
, len
+ slen
+ 2);
314 memcpy(ndst
+len
+1, src
, slen
+1);
318 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
320 DWORD len
= lstrlenW(dst
), slen
= lstrlenW(src
);
321 WCHAR
*ndst
= realloc(dst
, (len
+ slen
+ 2) * sizeof(WCHAR
));
328 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
332 /* Copies the escaped version of a component into a string binding.
333 * Note: doesn't nul-terminate the string */
334 static RPC_CSTR
escape_string_binding_component(RPC_CSTR string_binding
,
335 const unsigned char *component
)
337 for (; *component
; component
++) {
338 switch (*component
) {
344 *string_binding
++ = '\\';
345 *string_binding
++ = *component
;
348 *string_binding
++ = *component
;
352 return string_binding
;
355 static RPC_WSTR
escape_string_binding_componentW(RPC_WSTR string_binding
,
356 const WCHAR
*component
)
358 for (; *component
; component
++) {
359 switch (*component
) {
365 *string_binding
++ = '\\';
366 *string_binding
++ = *component
;
369 *string_binding
++ = *component
;
373 return string_binding
;
376 static const unsigned char *string_binding_find_delimiter(
377 const unsigned char *string_binding
, unsigned char delim
)
379 const unsigned char *next
;
380 for (next
= string_binding
; *next
; next
++) {
391 static const WCHAR
*string_binding_find_delimiterW(
392 const WCHAR
*string_binding
, WCHAR delim
)
395 for (next
= string_binding
; *next
; next
++) {
406 static RPC_CSTR
unescape_string_binding_component(
407 const unsigned char *string_binding
, int len
)
409 RPC_CSTR component
, p
;
411 if (len
== -1) len
= strlen((const char *)string_binding
);
413 component
= malloc((len
+ 1) * sizeof(*component
));
414 if (!component
) return NULL
;
415 for (p
= component
; len
> 0; string_binding
++, len
--) {
416 if (*string_binding
== '\\') {
419 *p
++ = *string_binding
;
421 *p
++ = *string_binding
;
428 static RPC_WSTR
unescape_string_binding_componentW(
429 const WCHAR
*string_binding
, int len
)
431 RPC_WSTR component
, p
;
433 if (len
== -1) len
= lstrlenW(string_binding
);
435 component
= malloc((len
+ 1) * sizeof(*component
));
436 if (!component
) return NULL
;
437 for (p
= component
; len
> 0; string_binding
++, len
--) {
438 if (*string_binding
== '\\') {
441 *p
++ = *string_binding
;
443 *p
++ = *string_binding
;
450 /***********************************************************************
451 * RpcStringBindingComposeA (RPCRT4.@)
453 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
454 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
455 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
460 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
461 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
462 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
463 debugstr_a( (char*)Options
), StringBinding
);
465 /* overestimate for each component for escaping of delimiters */
466 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) * 2 + 1;
467 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) * 2 + 1;
468 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
) * 2;
469 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) * 2 + 2;
470 if (Options
&& *Options
) len
+= strlen((char*)Options
) * 2 + 2;
473 *StringBinding
= data
;
475 if (ObjUuid
&& *ObjUuid
) {
476 data
= escape_string_binding_component(data
, ObjUuid
);
479 if (Protseq
&& *Protseq
) {
480 data
= escape_string_binding_component(data
, Protseq
);
483 if (NetworkAddr
&& *NetworkAddr
)
484 data
= escape_string_binding_component(data
, NetworkAddr
);
486 if ((Endpoint
&& *Endpoint
) ||
487 (Options
&& *Options
)) {
489 if (Endpoint
&& *Endpoint
) {
490 data
= escape_string_binding_component(data
, Endpoint
);
491 if (Options
&& *Options
) *data
++ = ',';
493 if (Options
&& *Options
) {
494 data
= escape_string_binding_component(data
, Options
);
503 /***********************************************************************
504 * RpcStringBindingComposeW (RPCRT4.@)
506 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
507 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
508 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
513 TRACE("(%s,%s,%s,%s,%s,%p)\n",
514 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
515 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
516 debugstr_w( Options
), StringBinding
);
518 /* overestimate for each component for escaping of delimiters */
519 if (ObjUuid
&& *ObjUuid
) len
+= lstrlenW(ObjUuid
) * 2 + 1;
520 if (Protseq
&& *Protseq
) len
+= lstrlenW(Protseq
) * 2 + 1;
521 if (NetworkAddr
&& *NetworkAddr
) len
+= lstrlenW(NetworkAddr
) * 2;
522 if (Endpoint
&& *Endpoint
) len
+= lstrlenW(Endpoint
) * 2 + 2;
523 if (Options
&& *Options
) len
+= lstrlenW(Options
) * 2 + 2;
525 data
= malloc(len
* sizeof(WCHAR
));
526 *StringBinding
= data
;
528 if (ObjUuid
&& *ObjUuid
) {
529 data
= escape_string_binding_componentW(data
, ObjUuid
);
532 if (Protseq
&& *Protseq
) {
533 data
= escape_string_binding_componentW(data
, Protseq
);
536 if (NetworkAddr
&& *NetworkAddr
) {
537 data
= escape_string_binding_componentW(data
, NetworkAddr
);
539 if ((Endpoint
&& *Endpoint
) ||
540 (Options
&& *Options
)) {
542 if (Endpoint
&& *Endpoint
) {
543 data
= escape_string_binding_componentW(data
, Endpoint
);
544 if (Options
&& *Options
) *data
++ = ',';
546 if (Options
&& *Options
) {
547 data
= escape_string_binding_componentW(data
, Options
);
557 /***********************************************************************
558 * RpcStringBindingParseA (RPCRT4.@)
560 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
561 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
562 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
564 const unsigned char *data
, *next
;
565 static const char ep_opt
[] = "endpoint=";
566 BOOL endpoint_already_found
= FALSE
;
568 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
569 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
571 if (ObjUuid
) *ObjUuid
= NULL
;
572 if (Protseq
) *Protseq
= NULL
;
573 if (NetworkAddr
) *NetworkAddr
= NULL
;
574 if (Endpoint
) *Endpoint
= NULL
;
575 if (Options
) *Options
= NULL
;
577 data
= StringBinding
;
579 next
= string_binding_find_delimiter(data
, '@');
583 RPC_CSTR str_uuid
= unescape_string_binding_component(data
, next
- data
);
584 status
= UuidFromStringA(str_uuid
, &uuid
);
585 if (status
!= RPC_S_OK
) {
596 next
= string_binding_find_delimiter(data
, ':');
598 if (Protseq
) *Protseq
= unescape_string_binding_component(data
, next
- data
);
602 next
= string_binding_find_delimiter(data
, '[');
604 const unsigned char *close
;
607 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_component(data
, next
- data
);
609 close
= string_binding_find_delimiter(data
, ']');
610 if (!close
) goto fail
;
612 /* tokenize options */
613 while (data
< close
) {
614 next
= string_binding_find_delimiter(data
, ',');
615 if (!next
|| next
> close
) next
= close
;
616 /* FIXME: this is kind of inefficient */
617 opt
= unescape_string_binding_component(data
, next
- data
);
621 next
= string_binding_find_delimiter(opt
, '=');
623 /* not an option, must be an endpoint */
624 if (endpoint_already_found
) goto fail
;
625 if (Endpoint
) *Endpoint
= opt
;
627 endpoint_already_found
= TRUE
;
629 if (strncmp((const char *)opt
, ep_opt
, strlen(ep_opt
)) == 0) {
630 /* endpoint option */
631 if (endpoint_already_found
) goto fail
;
632 if (Endpoint
) *Endpoint
= unescape_string_binding_component(next
+1, -1);
634 endpoint_already_found
= TRUE
;
639 /* FIXME: this is kind of inefficient */
640 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, (char *)opt
);
651 if (*data
) goto fail
;
653 else if (NetworkAddr
)
654 *NetworkAddr
= unescape_string_binding_component(data
, -1);
659 if (ObjUuid
) RpcStringFreeA(ObjUuid
);
660 if (Protseq
) RpcStringFreeA(Protseq
);
661 if (NetworkAddr
) RpcStringFreeA(NetworkAddr
);
662 if (Endpoint
) RpcStringFreeA(Endpoint
);
663 if (Options
) RpcStringFreeA(Options
);
664 return RPC_S_INVALID_STRING_BINDING
;
667 /***********************************************************************
668 * RpcStringBindingParseW (RPCRT4.@)
670 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
671 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
672 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
674 const WCHAR
*data
, *next
;
675 BOOL endpoint_already_found
= FALSE
;
677 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
678 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
680 if (ObjUuid
) *ObjUuid
= NULL
;
681 if (Protseq
) *Protseq
= NULL
;
682 if (NetworkAddr
) *NetworkAddr
= NULL
;
683 if (Endpoint
) *Endpoint
= NULL
;
684 if (Options
) *Options
= NULL
;
686 data
= StringBinding
;
688 next
= string_binding_find_delimiterW(data
, '@');
692 RPC_WSTR str_uuid
= unescape_string_binding_componentW(data
, next
- data
);
693 status
= UuidFromStringW(str_uuid
, &uuid
);
694 if (status
!= RPC_S_OK
) {
705 next
= string_binding_find_delimiterW(data
, ':');
707 if (Protseq
) *Protseq
= unescape_string_binding_componentW(data
, next
- data
);
711 next
= string_binding_find_delimiterW(data
, '[');
716 if (NetworkAddr
) *NetworkAddr
= unescape_string_binding_componentW(data
, next
- data
);
718 close
= string_binding_find_delimiterW(data
, ']');
719 if (!close
) goto fail
;
721 /* tokenize options */
722 while (data
< close
) {
723 next
= string_binding_find_delimiterW(data
, ',');
724 if (!next
|| next
> close
) next
= close
;
725 /* FIXME: this is kind of inefficient */
726 opt
= unescape_string_binding_componentW(data
, next
- data
);
730 next
= string_binding_find_delimiterW(opt
, '=');
732 /* not an option, must be an endpoint */
733 if (endpoint_already_found
) goto fail
;
734 if (Endpoint
) *Endpoint
= opt
;
736 endpoint_already_found
= TRUE
;
738 if (wcsncmp(opt
, L
"endpoint=", lstrlenW(L
"endpoint=")) == 0) {
739 /* endpoint option */
740 if (endpoint_already_found
) goto fail
;
741 if (Endpoint
) *Endpoint
= unescape_string_binding_componentW(next
+1, -1);
743 endpoint_already_found
= TRUE
;
748 /* FIXME: this is kind of inefficient */
749 *Options
= RPCRT4_strconcatW(*Options
, opt
);
760 if (*data
) goto fail
;
761 } else if (NetworkAddr
)
762 *NetworkAddr
= unescape_string_binding_componentW(data
, -1);
767 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
768 if (Protseq
) RpcStringFreeW(Protseq
);
769 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
770 if (Endpoint
) RpcStringFreeW(Endpoint
);
771 if (Options
) RpcStringFreeW(Options
);
772 return RPC_S_INVALID_STRING_BINDING
;
775 /***********************************************************************
776 * RpcBindingFree (RPCRT4.@)
778 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
781 TRACE("(%p) = %p\n", Binding
, *Binding
);
783 status
= RPCRT4_ReleaseBinding(*Binding
);
785 status
= RPC_S_INVALID_BINDING
;
786 if (status
== RPC_S_OK
) *Binding
= NULL
;
790 /***********************************************************************
791 * RpcBindingVectorFree (RPCRT4.@)
793 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
797 TRACE("(%p)\n", BindingVector
);
798 for (c
=0; c
<(*BindingVector
)->Count
; c
++) RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
799 free(*BindingVector
);
800 *BindingVector
= NULL
;
804 /***********************************************************************
805 * RpcBindingInqObject (RPCRT4.@)
807 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
809 RpcBinding
* bind
= Binding
;
811 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
812 *ObjectUuid
= bind
->ObjectUuid
;
816 /***********************************************************************
817 * RpcBindingSetObject (RPCRT4.@)
819 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
821 RpcBinding
* bind
= Binding
;
823 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
824 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
825 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
828 /***********************************************************************
829 * RpcBindingFromStringBindingA (RPCRT4.@)
831 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
834 RpcBinding
* bind
= NULL
;
835 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
838 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
840 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
841 &NetworkAddr
, &Endpoint
, &Options
);
842 if (ret
!= RPC_S_OK
) return ret
;
844 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
847 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
848 if (ret
== RPC_S_OK
) {
849 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
851 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
854 *Binding
= (RPC_BINDING_HANDLE
)bind
;
856 RPCRT4_ReleaseBinding(bind
);
859 RpcStringFreeA(&Options
);
860 RpcStringFreeA(&Endpoint
);
861 RpcStringFreeA(&NetworkAddr
);
862 RpcStringFreeA(&Protseq
);
863 RpcStringFreeA(&ObjectUuid
);
868 /***********************************************************************
869 * RpcBindingFromStringBindingW (RPCRT4.@)
871 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
874 RpcBinding
* bind
= NULL
;
875 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
878 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
880 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
881 &NetworkAddr
, &Endpoint
, &Options
);
882 if (ret
!= RPC_S_OK
) return ret
;
884 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
887 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
888 if (ret
== RPC_S_OK
) {
889 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
891 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
894 *Binding
= (RPC_BINDING_HANDLE
)bind
;
896 RPCRT4_ReleaseBinding(bind
);
899 RpcStringFreeW(&Options
);
900 RpcStringFreeW(&Endpoint
);
901 RpcStringFreeW(&NetworkAddr
);
902 RpcStringFreeW(&Protseq
);
903 RpcStringFreeW(&ObjectUuid
);
908 /***********************************************************************
909 * RpcBindingToStringBindingA (RPCRT4.@)
911 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
914 RpcBinding
* bind
= Binding
;
917 TRACE("(%p,%p)\n", Binding
, StringBinding
);
919 if (UuidIsNil(&bind
->ObjectUuid
, &ret
))
923 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
924 if (ret
!= RPC_S_OK
) return ret
;
927 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
928 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
930 RpcStringFreeA(&ObjectUuid
);
935 /***********************************************************************
936 * RpcBindingToStringBindingW (RPCRT4.@)
938 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
941 unsigned char *str
= NULL
;
942 TRACE("(%p,%p)\n", Binding
, StringBinding
);
943 ret
= RpcBindingToStringBindingA(Binding
, &str
);
944 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
945 RpcStringFreeA(&str
);
949 /***********************************************************************
950 * I_RpcBindingInqTransportType (RPCRT4.@)
952 RPC_STATUS WINAPI
I_RpcBindingInqTransportType( RPC_BINDING_HANDLE Binding
, unsigned int * Type
)
955 FIXME( "(%p,%p): stub\n", Binding
, Type
);
956 *Type
= TRANSPORT_TYPE_LPC
;
960 /***********************************************************************
961 * I_RpcBindingSetAsync (RPCRT4.@)
963 * Exists in win9x and winNT, but with different number of arguments
964 * (9x version has 3 arguments, NT has 2).
966 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
968 RpcBinding
* bind
= Binding
;
970 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
972 bind
->BlockingFn
= BlockingFn
;
977 /***********************************************************************
978 * RpcBindingCopy (RPCRT4.@)
980 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
981 RPC_BINDING_HANDLE SourceBinding
,
982 RPC_BINDING_HANDLE
* DestinationBinding
)
984 RpcBinding
*DestBinding
;
985 RpcBinding
*SrcBinding
= SourceBinding
;
988 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
990 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
991 if (status
!= RPC_S_OK
) return status
;
993 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
994 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
995 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
996 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
997 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
998 DestBinding
->NetworkOptions
= wcsdup(SrcBinding
->NetworkOptions
);
999 DestBinding
->CookieAuth
= wcsdup(SrcBinding
->CookieAuth
);
1000 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
1001 DestBinding
->Assoc
= SrcBinding
->Assoc
;
1003 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
1004 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
1005 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
1006 DestBinding
->QOS
= SrcBinding
->QOS
;
1008 *DestinationBinding
= DestBinding
;
1012 /***********************************************************************
1013 * RpcBindingReset (RPCRT4.@)
1015 RPC_STATUS RPC_ENTRY
RpcBindingReset(RPC_BINDING_HANDLE Binding
)
1017 RpcBinding
*bind
= Binding
;
1019 TRACE("(%p)\n", Binding
);
1021 free(bind
->Endpoint
);
1022 bind
->Endpoint
= NULL
;
1023 if (bind
->Assoc
) RpcAssoc_Release(bind
->Assoc
);
1029 /***********************************************************************
1030 * RpcImpersonateClient (RPCRT4.@)
1032 * Impersonates the client connected via a binding handle so that security
1033 * checks are done in the context of the client.
1036 * BindingHandle [I] Handle to the binding to the client.
1039 * Success: RPS_S_OK.
1040 * Failure: RPC_STATUS value.
1044 * If BindingHandle is NULL then the function impersonates the client
1045 * connected to the binding handle of the current thread.
1047 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
1051 TRACE("(%p)\n", BindingHandle
);
1053 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1054 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1056 bind
= BindingHandle
;
1058 return rpcrt4_conn_impersonate_client(bind
->FromConn
);
1059 return RPC_S_WRONG_KIND_OF_BINDING
;
1062 /***********************************************************************
1063 * RpcRevertToSelfEx (RPCRT4.@)
1065 * Stops impersonating the client connected to the binding handle so that security
1066 * checks are no longer done in the context of the client.
1069 * BindingHandle [I] Handle to the binding to the client.
1072 * Success: RPS_S_OK.
1073 * Failure: RPC_STATUS value.
1077 * If BindingHandle is NULL then the function stops impersonating the client
1078 * connected to the binding handle of the current thread.
1080 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
1084 TRACE("(%p)\n", BindingHandle
);
1086 if (!BindingHandle
) BindingHandle
= I_RpcGetCurrentCallHandle();
1087 if (!BindingHandle
) return RPC_S_INVALID_BINDING
;
1089 bind
= BindingHandle
;
1091 return rpcrt4_conn_revert_to_self(bind
->FromConn
);
1092 return RPC_S_WRONG_KIND_OF_BINDING
;
1095 static inline BOOL
has_nt_auth_identity(ULONG AuthnLevel
)
1099 case RPC_C_AUTHN_GSS_NEGOTIATE
:
1100 case RPC_C_AUTHN_WINNT
:
1101 case RPC_C_AUTHN_GSS_KERBEROS
:
1108 RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
1109 CredHandle cred
, TimeStamp exp
,
1111 RPC_AUTH_IDENTITY_HANDLE identity
,
1114 RpcAuthInfo
*AuthInfo
= malloc(sizeof(*AuthInfo
));
1116 return RPC_S_OUT_OF_MEMORY
;
1119 AuthInfo
->AuthnLevel
= AuthnLevel
;
1120 AuthInfo
->AuthnSvc
= AuthnSvc
;
1121 AuthInfo
->cred
= cred
;
1122 AuthInfo
->exp
= exp
;
1123 AuthInfo
->cbMaxToken
= cbMaxToken
;
1124 AuthInfo
->identity
= identity
;
1125 AuthInfo
->server_principal_name
= NULL
;
1127 /* duplicate the SEC_WINNT_AUTH_IDENTITY structure, if applicable, to
1128 * enable better matching in RpcAuthInfo_IsEqual */
1129 if (identity
&& has_nt_auth_identity(AuthnSvc
))
1131 const SEC_WINNT_AUTH_IDENTITY_W
*nt_identity
= identity
;
1132 AuthInfo
->nt_identity
= malloc(sizeof(*AuthInfo
->nt_identity
));
1133 if (!AuthInfo
->nt_identity
)
1136 return RPC_S_OUT_OF_MEMORY
;
1139 AuthInfo
->nt_identity
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1140 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1141 AuthInfo
->nt_identity
->User
= RPCRT4_strndupW(nt_identity
->User
, nt_identity
->UserLength
);
1143 AuthInfo
->nt_identity
->User
= RPCRT4_strndupAtoW((const char *)nt_identity
->User
, nt_identity
->UserLength
);
1144 AuthInfo
->nt_identity
->UserLength
= nt_identity
->UserLength
;
1145 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1146 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupW(nt_identity
->Domain
, nt_identity
->DomainLength
);
1148 AuthInfo
->nt_identity
->Domain
= RPCRT4_strndupAtoW((const char *)nt_identity
->Domain
, nt_identity
->DomainLength
);
1149 AuthInfo
->nt_identity
->DomainLength
= nt_identity
->DomainLength
;
1150 if (nt_identity
->Flags
& SEC_WINNT_AUTH_IDENTITY_UNICODE
)
1151 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupW(nt_identity
->Password
, nt_identity
->PasswordLength
);
1153 AuthInfo
->nt_identity
->Password
= RPCRT4_strndupAtoW((const char *)nt_identity
->Password
, nt_identity
->PasswordLength
);
1154 AuthInfo
->nt_identity
->PasswordLength
= nt_identity
->PasswordLength
;
1156 if ((nt_identity
->User
&& !AuthInfo
->nt_identity
->User
) ||
1157 (nt_identity
->Domain
&& !AuthInfo
->nt_identity
->Domain
) ||
1158 (nt_identity
->Password
&& !AuthInfo
->nt_identity
->Password
))
1160 free(AuthInfo
->nt_identity
->User
);
1161 free(AuthInfo
->nt_identity
->Domain
);
1162 free(AuthInfo
->nt_identity
->Password
);
1163 free(AuthInfo
->nt_identity
);
1165 return RPC_S_OUT_OF_MEMORY
;
1169 AuthInfo
->nt_identity
= NULL
;
1174 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
1176 return InterlockedIncrement(&AuthInfo
->refs
);
1179 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
1181 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
1185 FreeCredentialsHandle(&AuthInfo
->cred
);
1186 if (AuthInfo
->nt_identity
)
1188 free(AuthInfo
->nt_identity
->User
);
1189 free(AuthInfo
->nt_identity
->Domain
);
1190 free(AuthInfo
->nt_identity
->Password
);
1191 free(AuthInfo
->nt_identity
);
1193 free(AuthInfo
->server_principal_name
);
1200 BOOL
RpcAuthInfo_IsEqual(const RpcAuthInfo
*AuthInfo1
, const RpcAuthInfo
*AuthInfo2
)
1202 if (AuthInfo1
== AuthInfo2
)
1205 if (!AuthInfo1
|| !AuthInfo2
)
1208 if ((AuthInfo1
->AuthnLevel
!= AuthInfo2
->AuthnLevel
) ||
1209 (AuthInfo1
->AuthnSvc
!= AuthInfo2
->AuthnSvc
))
1212 if (AuthInfo1
->identity
== AuthInfo2
->identity
)
1215 if (!AuthInfo1
->identity
|| !AuthInfo2
->identity
)
1218 if (has_nt_auth_identity(AuthInfo1
->AuthnSvc
))
1220 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= AuthInfo1
->nt_identity
;
1221 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= AuthInfo2
->nt_identity
;
1222 /* compare user names */
1223 if (identity1
->UserLength
!= identity2
->UserLength
||
1224 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1226 /* compare domain names */
1227 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1228 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1230 /* compare passwords */
1231 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1232 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1241 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1243 RpcQualityOfService
*qos
= malloc(sizeof(*qos
));
1246 return RPC_S_OUT_OF_RESOURCES
;
1249 qos
->qos
= malloc(sizeof(*qos
->qos
));
1250 if (!qos
->qos
) goto error
;
1251 qos
->qos
->Version
= qos_src
->Version
;
1252 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1253 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1254 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1255 qos
->qos
->AdditionalSecurityInfoType
= 0;
1257 if (qos_src
->Version
>= 2)
1259 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1260 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1261 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1263 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1264 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1266 http_credentials_dst
= malloc(sizeof(*http_credentials_dst
));
1267 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1268 if (!http_credentials_dst
) goto error
;
1269 http_credentials_dst
->TransportCredentials
= NULL
;
1270 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1271 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1272 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1273 http_credentials_dst
->AuthnSchemes
= NULL
;
1274 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1275 if (http_credentials_src
->TransportCredentials
)
1277 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1278 cred_dst
= http_credentials_dst
->TransportCredentials
= calloc(1, sizeof(*cred_dst
));
1279 if (!cred_dst
) goto error
;
1280 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1283 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1284 cred_dst
->UserLength
= cred_src
->UserLength
;
1285 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1286 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1287 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1288 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1289 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1293 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1294 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1295 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1296 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1297 cred_dst
->User
= malloc(cred_dst
->UserLength
* sizeof(WCHAR
));
1298 cred_dst
->Password
= malloc(cred_dst
->PasswordLength
* sizeof(WCHAR
));
1299 cred_dst
->Domain
= malloc(cred_dst
->DomainLength
* sizeof(WCHAR
));
1300 if (!cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1301 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1302 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1303 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1306 if (http_credentials_src
->NumberOfAuthnSchemes
)
1308 http_credentials_dst
->AuthnSchemes
= malloc(http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1309 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1310 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1312 if (http_credentials_src
->ServerCertificateSubject
)
1315 http_credentials_dst
->ServerCertificateSubject
=
1316 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1317 lstrlenW(http_credentials_src
->ServerCertificateSubject
));
1319 http_credentials_dst
->ServerCertificateSubject
=
1320 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1321 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1331 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1332 qos
->qos
->u
.HttpCredentials
)
1334 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1336 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1337 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1338 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1339 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1341 free(qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1342 free(qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1343 free(qos
->qos
->u
.HttpCredentials
);
1348 return RPC_S_OUT_OF_RESOURCES
;
1351 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1353 return InterlockedIncrement(&qos
->refs
);
1356 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1358 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1362 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1364 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1366 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1367 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1368 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1369 free(qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1371 free(qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1372 free(qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1373 free(qos
->qos
->u
.HttpCredentials
);
1381 BOOL
RpcQualityOfService_IsEqual(const RpcQualityOfService
*qos1
, const RpcQualityOfService
*qos2
)
1389 TRACE("qos1 = { %ld %ld %ld %ld }, qos2 = { %ld %ld %ld %ld }\n",
1390 qos1
->qos
->Capabilities
, qos1
->qos
->IdentityTracking
,
1391 qos1
->qos
->ImpersonationType
, qos1
->qos
->AdditionalSecurityInfoType
,
1392 qos2
->qos
->Capabilities
, qos2
->qos
->IdentityTracking
,
1393 qos2
->qos
->ImpersonationType
, qos2
->qos
->AdditionalSecurityInfoType
);
1395 if ((qos1
->qos
->Capabilities
!= qos2
->qos
->Capabilities
) ||
1396 (qos1
->qos
->IdentityTracking
!= qos2
->qos
->IdentityTracking
) ||
1397 (qos1
->qos
->ImpersonationType
!= qos2
->qos
->ImpersonationType
) ||
1398 (qos1
->qos
->AdditionalSecurityInfoType
!= qos2
->qos
->AdditionalSecurityInfoType
))
1401 if (qos1
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1403 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials1
= qos1
->qos
->u
.HttpCredentials
;
1404 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials2
= qos2
->qos
->u
.HttpCredentials
;
1406 if (http_credentials1
->Flags
!= http_credentials2
->Flags
)
1409 if (http_credentials1
->AuthenticationTarget
!= http_credentials2
->AuthenticationTarget
)
1412 if (http_credentials1
->NumberOfAuthnSchemes
!= http_credentials2
->NumberOfAuthnSchemes
)
1415 if ((!http_credentials1
->AuthnSchemes
&& http_credentials2
->AuthnSchemes
) ||
1416 (http_credentials1
->AuthnSchemes
&& !http_credentials2
->AuthnSchemes
))
1419 if (memcmp(http_credentials1
->AuthnSchemes
, http_credentials2
->AuthnSchemes
,
1420 http_credentials1
->NumberOfAuthnSchemes
* sizeof(http_credentials1
->AuthnSchemes
[0])))
1423 /* server certificate subject not currently used */
1425 if (http_credentials1
->TransportCredentials
!= http_credentials2
->TransportCredentials
)
1427 const SEC_WINNT_AUTH_IDENTITY_W
*identity1
= http_credentials1
->TransportCredentials
;
1428 const SEC_WINNT_AUTH_IDENTITY_W
*identity2
= http_credentials2
->TransportCredentials
;
1430 if (!identity1
|| !identity2
)
1433 /* compare user names */
1434 if (identity1
->UserLength
!= identity2
->UserLength
||
1435 memcmp(identity1
->User
, identity2
->User
, identity1
->UserLength
))
1437 /* compare domain names */
1438 if (identity1
->DomainLength
!= identity2
->DomainLength
||
1439 memcmp(identity1
->Domain
, identity2
->Domain
, identity1
->DomainLength
))
1441 /* compare passwords */
1442 if (identity1
->PasswordLength
!= identity2
->PasswordLength
||
1443 memcmp(identity1
->Password
, identity2
->Password
, identity1
->PasswordLength
))
1451 /***********************************************************************
1452 * RpcRevertToSelf (RPCRT4.@)
1454 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1457 return RpcRevertToSelfEx(NULL
);
1460 /***********************************************************************
1461 * RpcMgmtSetComTimeout (RPCRT4.@)
1463 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1465 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1469 /***********************************************************************
1470 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1472 RPCRTAPI RPC_STATUS RPC_ENTRY
1473 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1474 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1475 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1480 TRACE("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1481 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1483 status
= RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
? &principal
: NULL
, AuthnLevel
,
1484 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1485 if (status
== RPC_S_OK
&& ServerPrincName
)
1487 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1488 RpcStringFreeW(&principal
);
1489 if (!*ServerPrincName
) return RPC_S_OUT_OF_MEMORY
;
1495 /***********************************************************************
1496 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1498 RPCRTAPI RPC_STATUS RPC_ENTRY
1499 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1500 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1501 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1503 RpcBinding
*bind
= Binding
;
1505 TRACE("%p %p %p %p %p %p %lu %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1506 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1508 if (!bind
->AuthInfo
) return RPC_S_BINDING_HAS_NO_AUTH
;
1512 FIXME("QOS not implemented\n");
1513 return RPC_S_INVALID_BINDING
;
1516 if (ServerPrincName
)
1518 if (bind
->AuthInfo
->server_principal_name
)
1520 *ServerPrincName
= wcsdup(bind
->AuthInfo
->server_principal_name
);
1521 if (!*ServerPrincName
) return RPC_S_OUT_OF_MEMORY
;
1523 else *ServerPrincName
= NULL
;
1525 if (AuthnLevel
) *AuthnLevel
= bind
->AuthInfo
->AuthnLevel
;
1526 if (AuthnSvc
) *AuthnSvc
= bind
->AuthInfo
->AuthnSvc
;
1527 if (AuthIdentity
) *AuthIdentity
= bind
->AuthInfo
->identity
;
1530 FIXME("authorization service not implemented\n");
1531 *AuthzSvc
= RPC_C_AUTHZ_NONE
;
1537 /***********************************************************************
1538 * RpcBindingInqAuthInfoA (RPCRT4.@)
1540 RPCRTAPI RPC_STATUS RPC_ENTRY
1541 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1542 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1544 return RpcBindingInqAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1548 /***********************************************************************
1549 * RpcBindingInqAuthInfoW (RPCRT4.@)
1551 RPCRTAPI RPC_STATUS RPC_ENTRY
1552 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1553 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1555 return RpcBindingInqAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
,
1559 /***********************************************************************
1560 * RpcBindingInqAuthClientA (RPCRT4.@)
1562 RPCRTAPI RPC_STATUS RPC_ENTRY
1563 RpcBindingInqAuthClientA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1564 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1567 return RpcBindingInqAuthClientExA(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1568 AuthnSvc
, AuthzSvc
, 0);
1571 /***********************************************************************
1572 * RpcBindingInqAuthClientW (RPCRT4.@)
1574 RPCRTAPI RPC_STATUS RPC_ENTRY
1575 RpcBindingInqAuthClientW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1576 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1579 return RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1580 AuthnSvc
, AuthzSvc
, 0);
1583 /***********************************************************************
1584 * RpcBindingInqAuthClientExA (RPCRT4.@)
1586 RPCRTAPI RPC_STATUS RPC_ENTRY
1587 RpcBindingInqAuthClientExA( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1588 RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1589 ULONG
*AuthzSvc
, ULONG Flags
)
1594 TRACE("%p %p %p %p %p %p 0x%lx\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1595 AuthnSvc
, AuthzSvc
, Flags
);
1597 status
= RpcBindingInqAuthClientExW(ClientBinding
, Privs
, ServerPrincName
? &principal
: NULL
,
1598 AuthnLevel
, AuthnSvc
, AuthzSvc
, Flags
);
1599 if (status
== RPC_S_OK
&& ServerPrincName
)
1601 *ServerPrincName
= (RPC_CSTR
)RPCRT4_strdupWtoA(principal
);
1602 if (!*ServerPrincName
&& principal
) status
= RPC_S_OUT_OF_MEMORY
;
1603 RpcStringFreeW(&principal
);
1609 /***********************************************************************
1610 * RpcBindingInqAuthClientExW (RPCRT4.@)
1612 RPCRTAPI RPC_STATUS RPC_ENTRY
1613 RpcBindingInqAuthClientExW( RPC_BINDING_HANDLE ClientBinding
, RPC_AUTHZ_HANDLE
*Privs
,
1614 RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
, ULONG
*AuthnSvc
,
1615 ULONG
*AuthzSvc
, ULONG Flags
)
1619 TRACE("%p %p %p %p %p %p 0x%lx\n", ClientBinding
, Privs
, ServerPrincName
, AuthnLevel
,
1620 AuthnSvc
, AuthzSvc
, Flags
);
1622 if (!ClientBinding
) ClientBinding
= I_RpcGetCurrentCallHandle();
1623 if (!ClientBinding
) return RPC_S_INVALID_BINDING
;
1625 bind
= ClientBinding
;
1626 if (!bind
->FromConn
) return RPC_S_INVALID_BINDING
;
1628 return rpcrt4_conn_inquire_auth_client(bind
->FromConn
, Privs
,
1629 ServerPrincName
, AuthnLevel
,
1630 AuthnSvc
, AuthzSvc
, Flags
);
1633 /***********************************************************************
1634 * RpcBindingServerFromClient (RPCRT4.@)
1636 RPCRTAPI RPC_STATUS RPC_ENTRY
1637 RpcBindingServerFromClient(RPC_BINDING_HANDLE ClientBinding
, RPC_BINDING_HANDLE
* ServerBinding
)
1639 RpcBinding
* bind
= ClientBinding
;
1640 RpcBinding
* NewBinding
;
1643 bind
= I_RpcGetCurrentCallHandle();
1646 return RPC_S_INVALID_BINDING
;
1648 RPCRT4_AllocBinding(&NewBinding
, TRUE
);
1649 NewBinding
->Protseq
= strdup(bind
->Protseq
);
1650 NewBinding
->NetworkAddr
= strdup(bind
->NetworkAddr
);
1652 *ServerBinding
= NewBinding
;
1657 /***********************************************************************
1658 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1660 RPCRTAPI RPC_STATUS RPC_ENTRY
1661 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1662 ULONG AuthnLevel
, ULONG AuthnSvc
,
1663 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1664 RPC_SECURITY_QOS
*SecurityQos
)
1666 RpcBinding
* bind
= Binding
;
1670 ULONG package_count
;
1672 PSecPkgInfoA packages
;
1675 TRACE("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1676 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1682 TRACE("SecurityQos { Version=%ld, Capabilities=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1683 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1684 if (SecurityQos
->Version
>= 2)
1686 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1687 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1688 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1689 TRACE(", { %p, 0x%lx, %ld, %ld, %p(%lu), %s }",
1690 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1691 SecurityQos2
->u
.HttpCredentials
->Flags
,
1692 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1693 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1694 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1695 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1696 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1699 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1700 if (status
!= RPC_S_OK
)
1705 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1709 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1710 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1712 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1713 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1714 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1716 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1718 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1719 bind
->AuthInfo
= NULL
;
1723 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1725 FIXME("unknown AuthnLevel %lu\n", AuthnLevel
);
1726 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1729 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1730 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1732 FIXME("unsupported AuthzSvr %lu\n", AuthzSvr
);
1733 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1736 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1739 ERR("EnumerateSecurityPackagesA failed with error 0x%08lx\n", r
);
1740 return RPC_S_SEC_PKG_ERROR
;
1743 for (i
= 0; i
< package_count
; i
++)
1744 if (packages
[i
].wRPCID
== AuthnSvc
)
1747 if (i
== package_count
)
1749 FIXME("unsupported AuthnSvc %lu\n", AuthnSvc
);
1750 FreeContextBuffer(packages
);
1751 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1754 TRACE("found package %s for service %lu\n", packages
[i
].Name
, AuthnSvc
);
1755 r
= AcquireCredentialsHandleA(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1756 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1757 cbMaxToken
= packages
[i
].cbMaxToken
;
1758 FreeContextBuffer(packages
);
1759 if (r
== ERROR_SUCCESS
)
1761 RpcAuthInfo
*new_auth_info
;
1762 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1763 AuthIdentity
, &new_auth_info
);
1766 new_auth_info
->server_principal_name
= RPCRT4_strdupAtoW((char *)ServerPrincName
);
1767 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1769 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1770 bind
->AuthInfo
= new_auth_info
;
1774 RpcAuthInfo_Release(new_auth_info
);
1775 r
= RPC_S_OUT_OF_MEMORY
;
1779 FreeCredentialsHandle(&cred
);
1784 ERR("AcquireCredentialsHandleA failed with error 0x%08lx\n", r
);
1785 return RPC_S_SEC_PKG_ERROR
;
1789 /***********************************************************************
1790 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1792 RPCRTAPI RPC_STATUS RPC_ENTRY
1793 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1794 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1795 RPC_SECURITY_QOS
*SecurityQos
)
1797 RpcBinding
* bind
= Binding
;
1801 ULONG package_count
;
1803 PSecPkgInfoW packages
;
1806 TRACE("%p %s %lu %lu %p %lu %p\n", Binding
, debugstr_w(ServerPrincName
),
1807 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1813 TRACE("SecurityQos { Version=%ld, Capabilities=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1814 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1815 if (SecurityQos
->Version
>= 2)
1817 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1818 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1819 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1820 TRACE(", { %p, 0x%lx, %ld, %ld, %p(%lu), %s }",
1821 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1822 SecurityQos2
->u
.HttpCredentials
->Flags
,
1823 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1824 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1825 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1826 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
? *SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
: 0,
1827 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1830 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1831 if (status
!= RPC_S_OK
)
1836 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1840 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1841 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1843 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1844 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1845 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1847 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1849 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1850 bind
->AuthInfo
= NULL
;
1854 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1856 FIXME("unknown AuthnLevel %lu\n", AuthnLevel
);
1857 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1860 /* RPC_C_AUTHN_WINNT ignores the AuthzSvr parameter */
1861 if (AuthzSvr
&& AuthnSvc
!= RPC_C_AUTHN_WINNT
)
1863 FIXME("unsupported AuthzSvr %lu\n", AuthzSvr
);
1864 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1867 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1870 ERR("EnumerateSecurityPackagesW failed with error 0x%08lx\n", r
);
1871 return RPC_S_SEC_PKG_ERROR
;
1874 for (i
= 0; i
< package_count
; i
++)
1875 if (packages
[i
].wRPCID
== AuthnSvc
)
1878 if (i
== package_count
)
1880 FIXME("unsupported AuthnSvc %lu\n", AuthnSvc
);
1881 FreeContextBuffer(packages
);
1882 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1885 TRACE("found package %s for service %lu\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1886 r
= AcquireCredentialsHandleW(NULL
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1887 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1888 cbMaxToken
= packages
[i
].cbMaxToken
;
1889 FreeContextBuffer(packages
);
1890 if (r
== ERROR_SUCCESS
)
1892 RpcAuthInfo
*new_auth_info
;
1893 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1894 AuthIdentity
, &new_auth_info
);
1897 new_auth_info
->server_principal_name
= wcsdup(ServerPrincName
);
1898 if (!ServerPrincName
|| new_auth_info
->server_principal_name
)
1900 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1901 bind
->AuthInfo
= new_auth_info
;
1905 RpcAuthInfo_Release(new_auth_info
);
1906 r
= RPC_S_OUT_OF_MEMORY
;
1910 FreeCredentialsHandle(&cred
);
1915 ERR("AcquireCredentialsHandleW failed with error 0x%08lx\n", r
);
1916 return RPC_S_SEC_PKG_ERROR
;
1920 /***********************************************************************
1921 * RpcBindingSetAuthInfoA (RPCRT4.@)
1923 RPCRTAPI RPC_STATUS RPC_ENTRY
1924 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1925 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1927 TRACE("%p %s %lu %lu %p %lu\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1928 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1929 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1932 /***********************************************************************
1933 * RpcBindingSetAuthInfoW (RPCRT4.@)
1935 RPCRTAPI RPC_STATUS RPC_ENTRY
1936 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1937 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1939 TRACE("%p %s %lu %lu %p %lu\n", Binding
, debugstr_w(ServerPrincName
),
1940 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1941 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1944 /***********************************************************************
1945 * RpcBindingSetOption (RPCRT4.@)
1947 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG_PTR OptionValue
)
1949 TRACE("(%p, %ld, %Id)\n", BindingHandle
, Option
, OptionValue
);
1953 case RPC_C_OPT_COOKIE_AUTH
:
1955 RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*cookie
= (RPC_C_OPT_COOKIE_AUTH_DESCRIPTOR
*)OptionValue
;
1956 RpcBinding
*binding
= BindingHandle
;
1957 int len
= MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, NULL
, 0);
1960 if (!(str
= malloc((len
+ 1) * sizeof(WCHAR
)))) return RPC_S_OUT_OF_MEMORY
;
1961 MultiByteToWideChar(CP_ACP
, 0, cookie
->Buffer
, cookie
->BufferSize
, str
, len
);
1963 free(binding
->CookieAuth
);
1964 binding
->CookieAuth
= str
;
1968 FIXME("option %lu not supported\n", Option
);
1974 /***********************************************************************
1975 * I_RpcBindingInqLocalClientPID (RPCRT4.@)
1978 RPC_STATUS WINAPI
I_RpcBindingInqLocalClientPID(RPC_BINDING_HANDLE ClientBinding
, ULONG
*ClientPID
)
1980 RpcConnection
*connection
= NULL
;
1981 RpcBinding
*binding
;
1983 TRACE("%p %p\n", ClientBinding
, ClientPID
);
1985 binding
= ClientBinding
? ClientBinding
: RPCRT4_GetThreadCurrentCallHandle();
1987 return RPC_S_NO_CALL_ACTIVE
;
1989 connection
= binding
->FromConn
;
1990 if (!connection
->ops
->inquire_client_pid
)
1991 return RPC_S_INVALID_BINDING
;
1993 return connection
->ops
->inquire_client_pid(connection
, ClientPID
);