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_message.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 LPWSTR
RPCRT4_strndupW(LPCWSTR src
, INT slen
)
85 if (!src
) return NULL
;
86 if (slen
== -1) slen
= strlenW(src
);
88 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
89 memcpy(s
, src
, len
*sizeof(WCHAR
));
94 void RPCRT4_strfree(LPSTR src
)
96 HeapFree(GetProcessHeap(), 0, src
);
99 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
101 RpcBinding
* NewBinding
;
103 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
104 NewBinding
->refs
= 1;
105 NewBinding
->server
= server
;
107 *Binding
= NewBinding
;
112 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
114 RpcBinding
* NewBinding
;
116 RPCRT4_AllocBinding(&NewBinding
, server
);
117 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
119 TRACE("binding: %p\n", NewBinding
);
120 *Binding
= NewBinding
;
125 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
127 RpcBinding
* NewBinding
;
129 RPCRT4_AllocBinding(&NewBinding
, server
);
130 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
132 TRACE("binding: %p\n", NewBinding
);
133 *Binding
= NewBinding
;
138 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
139 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
143 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
144 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
146 RPCRT4_strfree(Binding
->NetworkAddr
);
147 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
148 RPCRT4_strfree(Binding
->Endpoint
);
150 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
152 Binding
->Endpoint
= RPCRT4_strdupA("");
154 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
155 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
156 if (!Binding
->Endpoint
) ERR("out of memory?\n");
158 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
159 Binding
->Endpoint
, Binding
->NetworkOptions
,
161 if (status
!= RPC_S_OK
)
167 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
168 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
172 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
173 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
175 RPCRT4_strfree(Binding
->NetworkAddr
);
176 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
177 RPCRT4_strfree(Binding
->Endpoint
);
179 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
181 Binding
->Endpoint
= RPCRT4_strdupA("");
183 if (!Binding
->Endpoint
) ERR("out of memory?\n");
184 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
185 Binding
->NetworkOptions
= RPCRT4_strdupW(NetworkOptions
);
187 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
188 Binding
->Endpoint
, Binding
->NetworkOptions
,
190 if (status
!= RPC_S_OK
)
196 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
200 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
202 RPCRT4_strfree(Binding
->Endpoint
);
203 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
205 RpcAssoc_Release(Binding
->Assoc
);
206 Binding
->Assoc
= NULL
;
207 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
208 Binding
->Endpoint
, Binding
->NetworkOptions
,
210 if (status
!= RPC_S_OK
)
216 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
218 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
219 if (ObjectUuid
) memcpy(&Binding
->ObjectUuid
, ObjectUuid
, sizeof(UUID
));
220 else UuidCreateNil(&Binding
->ObjectUuid
);
224 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
226 RpcBinding
* NewBinding
;
227 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
229 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
230 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
231 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
232 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
233 NewBinding
->FromConn
= Connection
;
235 TRACE("binding: %p\n", NewBinding
);
236 *Binding
= NewBinding
;
241 RPC_STATUS
RPCRT4_ExportBinding(RpcBinding
** Binding
, RpcBinding
* OldBinding
)
243 InterlockedIncrement(&OldBinding
->refs
);
244 *Binding
= OldBinding
;
248 RPC_STATUS
RPCRT4_DestroyBinding(RpcBinding
* Binding
)
250 if (InterlockedDecrement(&Binding
->refs
))
253 TRACE("binding: %p\n", Binding
);
254 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
255 RPCRT4_strfree(Binding
->Endpoint
);
256 RPCRT4_strfree(Binding
->NetworkAddr
);
257 RPCRT4_strfree(Binding
->Protseq
);
258 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
259 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
260 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
261 HeapFree(GetProcessHeap(), 0, Binding
);
265 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
266 PRPC_SYNTAX_IDENTIFIER TransferSyntax
,
267 PRPC_SYNTAX_IDENTIFIER InterfaceId
)
269 RpcConnection
* NewConnection
;
272 TRACE("(Binding == ^%p)\n", Binding
);
274 if (!Binding
->server
) {
275 /* try to find a compatible connection from the connection pool */
276 NewConnection
= RpcAssoc_GetIdleConnection(Binding
->Assoc
, InterfaceId
,
277 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
);
279 *Connection
= NewConnection
;
283 /* we already have a connection with acceptable binding, so use it */
284 if (Binding
->FromConn
) {
285 *Connection
= Binding
->FromConn
;
290 /* create a new connection */
291 status
= RPCRT4_CreateConnection(&NewConnection
, Binding
->server
,
292 Binding
->Protseq
, Binding
->NetworkAddr
,
293 Binding
->Endpoint
, Binding
->NetworkOptions
,
294 Binding
->AuthInfo
, Binding
->QOS
, Binding
);
295 if (status
!= RPC_S_OK
)
298 status
= RPCRT4_OpenClientConnection(NewConnection
);
299 if (status
!= RPC_S_OK
)
301 RPCRT4_DestroyConnection(NewConnection
);
305 /* we need to send a binding packet if we are client. */
306 if (!NewConnection
->server
) {
308 RpcPktHdr
*response_hdr
;
311 TRACE("sending bind request to server\n");
313 hdr
= RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION
,
314 RPC_MAX_PACKET_SIZE
, RPC_MAX_PACKET_SIZE
,
315 InterfaceId
, TransferSyntax
);
317 status
= RPCRT4_Send(NewConnection
, hdr
, NULL
, 0);
318 RPCRT4_FreeHeader(hdr
);
319 if (status
!= RPC_S_OK
) {
320 RPCRT4_DestroyConnection(NewConnection
);
324 status
= RPCRT4_Receive(NewConnection
, &response_hdr
, &msg
);
325 if (status
!= RPC_S_OK
) {
326 ERR("receive failed\n");
327 RPCRT4_DestroyConnection(NewConnection
);
331 if (response_hdr
->common
.ptype
!= PKT_BIND_ACK
||
332 response_hdr
->bind_ack
.max_tsize
< RPC_MIN_PACKET_SIZE
) {
333 ERR("failed to bind for interface %s, %d.%d\n",
334 debugstr_guid(&InterfaceId
->SyntaxGUID
),
335 InterfaceId
->SyntaxVersion
.MajorVersion
,
336 InterfaceId
->SyntaxVersion
.MinorVersion
);
337 RPCRT4_FreeHeader(response_hdr
);
338 RPCRT4_DestroyConnection(NewConnection
);
339 return RPC_S_PROTOCOL_ERROR
;
342 /* FIXME: do more checks? */
344 NewConnection
->MaxTransmissionSize
= response_hdr
->bind_ack
.max_tsize
;
345 NewConnection
->ActiveInterface
= *InterfaceId
;
346 RPCRT4_FreeHeader(response_hdr
);
350 Binding
->FromConn
= NewConnection
;
351 *Connection
= NewConnection
;
356 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
358 TRACE("(Binding == ^%p)\n", Binding
);
359 if (!Connection
) return RPC_S_OK
;
360 if (Binding
->server
) {
361 /* don't destroy a connection that is cached in the binding */
362 if (Binding
->FromConn
== Connection
)
364 return RPCRT4_DestroyConnection(Connection
);
367 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
372 /* utility functions for string composing and parsing */
373 static unsigned RPCRT4_strcopyA(LPSTR data
, LPCSTR src
)
375 unsigned len
= strlen(src
);
376 memcpy(data
, src
, len
*sizeof(CHAR
));
380 static unsigned RPCRT4_strcopyW(LPWSTR data
, LPCWSTR src
)
382 unsigned len
= strlenW(src
);
383 memcpy(data
, src
, len
*sizeof(WCHAR
));
387 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
389 DWORD len
= strlen(dst
), slen
= strlen(src
);
390 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
393 HeapFree(GetProcessHeap(), 0, dst
);
397 memcpy(ndst
+len
+1, src
, slen
+1);
401 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
403 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
404 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
407 HeapFree(GetProcessHeap(), 0, dst
);
411 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
416 /***********************************************************************
417 * RpcStringBindingComposeA (RPCRT4.@)
419 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
420 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
421 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
426 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
427 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
428 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
429 debugstr_a( (char*)Options
), StringBinding
);
431 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) + 1;
432 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) + 1;
433 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
);
434 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) + 2;
435 if (Options
&& *Options
) len
+= strlen((char*)Options
) + 2;
437 data
= HeapAlloc(GetProcessHeap(), 0, len
);
438 *StringBinding
= (unsigned char*)data
;
440 if (ObjUuid
&& *ObjUuid
) {
441 data
+= RPCRT4_strcopyA(data
, (char*)ObjUuid
);
444 if (Protseq
&& *Protseq
) {
445 data
+= RPCRT4_strcopyA(data
, (char*)Protseq
);
448 if (NetworkAddr
&& *NetworkAddr
)
449 data
+= RPCRT4_strcopyA(data
, (char*)NetworkAddr
);
451 if ((Endpoint
&& *Endpoint
) ||
452 (Options
&& *Options
)) {
454 if (Endpoint
&& *Endpoint
) {
455 data
+= RPCRT4_strcopyA(data
, (char*)Endpoint
);
456 if (Options
&& *Options
) *data
++ = ',';
458 if (Options
&& *Options
) {
459 data
+= RPCRT4_strcopyA(data
, (char*)Options
);
468 /***********************************************************************
469 * RpcStringBindingComposeW (RPCRT4.@)
471 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
472 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
473 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
478 TRACE("(%s,%s,%s,%s,%s,%p)\n",
479 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
480 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
481 debugstr_w( Options
), StringBinding
);
483 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) + 1;
484 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) + 1;
485 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
);
486 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) + 2;
487 if (Options
&& *Options
) len
+= strlenW(Options
) + 2;
489 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
490 *StringBinding
= data
;
492 if (ObjUuid
&& *ObjUuid
) {
493 data
+= RPCRT4_strcopyW(data
, ObjUuid
);
496 if (Protseq
&& *Protseq
) {
497 data
+= RPCRT4_strcopyW(data
, Protseq
);
500 if (NetworkAddr
&& *NetworkAddr
) {
501 data
+= RPCRT4_strcopyW(data
, NetworkAddr
);
503 if ((Endpoint
&& *Endpoint
) ||
504 (Options
&& *Options
)) {
506 if (Endpoint
&& *Endpoint
) {
507 data
+= RPCRT4_strcopyW(data
, Endpoint
);
508 if (Options
&& *Options
) *data
++ = ',';
510 if (Options
&& *Options
) {
511 data
+= RPCRT4_strcopyW(data
, Options
);
521 /***********************************************************************
522 * RpcStringBindingParseA (RPCRT4.@)
524 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
525 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
526 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
529 static const char ep_opt
[] = "endpoint=";
531 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
532 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
534 if (ObjUuid
) *ObjUuid
= NULL
;
535 if (Protseq
) *Protseq
= NULL
;
536 if (NetworkAddr
) *NetworkAddr
= NULL
;
537 if (Endpoint
) *Endpoint
= NULL
;
538 if (Options
) *Options
= NULL
;
540 data
= (char*) StringBinding
;
542 next
= strchr(data
, '@');
544 if (ObjUuid
) *ObjUuid
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
548 next
= strchr(data
, ':');
550 if (Protseq
) *Protseq
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
554 next
= strchr(data
, '[');
558 if (NetworkAddr
) *NetworkAddr
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
560 close
= strchr(data
, ']');
561 if (!close
) goto fail
;
563 /* tokenize options */
564 while (data
< close
) {
565 next
= strchr(data
, ',');
566 if (!next
|| next
> close
) next
= close
;
567 /* FIXME: this is kind of inefficient */
568 opt
= RPCRT4_strndupA(data
, next
- data
);
572 next
= strchr(opt
, '=');
574 /* not an option, must be an endpoint */
575 if (*Endpoint
) goto fail
;
576 *Endpoint
= (unsigned char*) opt
;
578 if (strncmp(opt
, ep_opt
, strlen(ep_opt
)) == 0) {
579 /* endpoint option */
580 if (*Endpoint
) goto fail
;
581 *Endpoint
= (unsigned char*) RPCRT4_strdupA(next
+1);
582 HeapFree(GetProcessHeap(), 0, opt
);
586 /* FIXME: this is kind of inefficient */
587 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, opt
);
588 HeapFree(GetProcessHeap(), 0, opt
);
590 *Options
= (unsigned char*) opt
;
596 if (*data
) goto fail
;
598 else if (NetworkAddr
)
599 *NetworkAddr
= (unsigned char*)RPCRT4_strdupA(data
);
604 if (ObjUuid
) RpcStringFreeA((unsigned char**)ObjUuid
);
605 if (Protseq
) RpcStringFreeA((unsigned char**)Protseq
);
606 if (NetworkAddr
) RpcStringFreeA((unsigned char**)NetworkAddr
);
607 if (Endpoint
) RpcStringFreeA((unsigned char**)Endpoint
);
608 if (Options
) RpcStringFreeA((unsigned char**)Options
);
609 return RPC_S_INVALID_STRING_BINDING
;
612 /***********************************************************************
613 * RpcStringBindingParseW (RPCRT4.@)
615 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
616 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
617 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
620 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
622 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
623 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
625 if (ObjUuid
) *ObjUuid
= NULL
;
626 if (Protseq
) *Protseq
= NULL
;
627 if (NetworkAddr
) *NetworkAddr
= NULL
;
628 if (Endpoint
) *Endpoint
= NULL
;
629 if (Options
) *Options
= NULL
;
631 data
= StringBinding
;
633 next
= strchrW(data
, '@');
635 if (ObjUuid
) *ObjUuid
= RPCRT4_strndupW(data
, next
- data
);
639 next
= strchrW(data
, ':');
641 if (Protseq
) *Protseq
= RPCRT4_strndupW(data
, next
- data
);
645 next
= strchrW(data
, '[');
649 if (NetworkAddr
) *NetworkAddr
= RPCRT4_strndupW(data
, next
- data
);
651 close
= strchrW(data
, ']');
652 if (!close
) goto fail
;
654 /* tokenize options */
655 while (data
< close
) {
656 next
= strchrW(data
, ',');
657 if (!next
|| next
> close
) next
= close
;
658 /* FIXME: this is kind of inefficient */
659 opt
= RPCRT4_strndupW(data
, next
- data
);
663 next
= strchrW(opt
, '=');
665 /* not an option, must be an endpoint */
666 if (*Endpoint
) goto fail
;
669 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
670 /* endpoint option */
671 if (*Endpoint
) goto fail
;
672 *Endpoint
= RPCRT4_strdupW(next
+1);
673 HeapFree(GetProcessHeap(), 0, opt
);
677 /* FIXME: this is kind of inefficient */
678 *Options
= RPCRT4_strconcatW(*Options
, opt
);
679 HeapFree(GetProcessHeap(), 0, opt
);
687 if (*data
) goto fail
;
688 } else if (NetworkAddr
)
689 *NetworkAddr
= RPCRT4_strdupW(data
);
694 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
695 if (Protseq
) RpcStringFreeW(Protseq
);
696 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
697 if (Endpoint
) RpcStringFreeW(Endpoint
);
698 if (Options
) RpcStringFreeW(Options
);
699 return RPC_S_INVALID_STRING_BINDING
;
702 /***********************************************************************
703 * RpcBindingFree (RPCRT4.@)
705 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
708 TRACE("(%p) = %p\n", Binding
, *Binding
);
709 status
= RPCRT4_DestroyBinding(*Binding
);
710 if (status
== RPC_S_OK
) *Binding
= 0;
714 /***********************************************************************
715 * RpcBindingVectorFree (RPCRT4.@)
717 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
722 TRACE("(%p)\n", BindingVector
);
723 for (c
=0; c
<(*BindingVector
)->Count
; c
++) {
724 status
= RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
726 HeapFree(GetProcessHeap(), 0, *BindingVector
);
727 *BindingVector
= NULL
;
731 /***********************************************************************
732 * RpcBindingInqObject (RPCRT4.@)
734 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
736 RpcBinding
* bind
= (RpcBinding
*)Binding
;
738 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
739 memcpy(ObjectUuid
, &bind
->ObjectUuid
, sizeof(UUID
));
743 /***********************************************************************
744 * RpcBindingSetObject (RPCRT4.@)
746 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
748 RpcBinding
* bind
= (RpcBinding
*)Binding
;
750 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
751 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
752 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
755 /***********************************************************************
756 * RpcBindingFromStringBindingA (RPCRT4.@)
758 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
761 RpcBinding
* bind
= NULL
;
762 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
765 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
767 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
768 &NetworkAddr
, &Endpoint
, &Options
);
769 if (ret
!= RPC_S_OK
) return ret
;
771 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
774 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
776 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
778 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
780 RpcStringFreeA((unsigned char**)&Options
);
781 RpcStringFreeA((unsigned char**)&Endpoint
);
782 RpcStringFreeA((unsigned char**)&NetworkAddr
);
783 RpcStringFreeA((unsigned char**)&Protseq
);
784 RpcStringFreeA((unsigned char**)&ObjectUuid
);
787 *Binding
= (RPC_BINDING_HANDLE
)bind
;
789 RPCRT4_DestroyBinding(bind
);
794 /***********************************************************************
795 * RpcBindingFromStringBindingW (RPCRT4.@)
797 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
800 RpcBinding
* bind
= NULL
;
801 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
804 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
806 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
807 &NetworkAddr
, &Endpoint
, &Options
);
808 if (ret
!= RPC_S_OK
) return ret
;
810 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
813 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
815 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
817 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
819 RpcStringFreeW(&Options
);
820 RpcStringFreeW(&Endpoint
);
821 RpcStringFreeW(&NetworkAddr
);
822 RpcStringFreeW(&Protseq
);
823 RpcStringFreeW(&ObjectUuid
);
826 *Binding
= (RPC_BINDING_HANDLE
)bind
;
828 RPCRT4_DestroyBinding(bind
);
833 /***********************************************************************
834 * RpcBindingToStringBindingA (RPCRT4.@)
836 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
839 RpcBinding
* bind
= (RpcBinding
*)Binding
;
842 TRACE("(%p,%p)\n", Binding
, StringBinding
);
844 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
845 if (ret
!= RPC_S_OK
) return ret
;
847 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
848 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
850 RpcStringFreeA(&ObjectUuid
);
855 /***********************************************************************
856 * RpcBindingToStringBindingW (RPCRT4.@)
858 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
861 unsigned char *str
= NULL
;
862 TRACE("(%p,%p)\n", Binding
, StringBinding
);
863 ret
= RpcBindingToStringBindingA(Binding
, &str
);
864 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
865 RpcStringFreeA((unsigned char**)&str
);
869 /***********************************************************************
870 * I_RpcBindingSetAsync (RPCRT4.@)
872 * Exists in win9x and winNT, but with different number of arguments
873 * (9x version has 3 arguments, NT has 2).
875 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
877 RpcBinding
* bind
= (RpcBinding
*)Binding
;
879 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
881 bind
->BlockingFn
= BlockingFn
;
886 /***********************************************************************
887 * RpcBindingCopy (RPCRT4.@)
889 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
890 RPC_BINDING_HANDLE SourceBinding
,
891 RPC_BINDING_HANDLE
* DestinationBinding
)
893 RpcBinding
*DestBinding
;
894 RpcBinding
*SrcBinding
= (RpcBinding
*)SourceBinding
;
897 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
899 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
900 if (status
!= RPC_S_OK
) return status
;
902 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
903 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
904 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
905 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
906 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
907 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
908 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
909 DestBinding
->Assoc
= SrcBinding
->Assoc
;
911 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
912 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
913 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
914 DestBinding
->QOS
= SrcBinding
->QOS
;
916 *DestinationBinding
= DestBinding
;
920 /***********************************************************************
921 * RpcImpersonateClient (RPCRT4.@)
923 * Impersonates the client connected via a binding handle so that security
924 * checks are done in the context of the client.
927 * BindingHandle [I] Handle to the binding to the client.
931 * Failure: RPC_STATUS value.
935 * If BindingHandle is NULL then the function impersonates the client
936 * connected to the binding handle of the current thread.
938 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
940 FIXME("(%p): stub\n", BindingHandle
);
941 ImpersonateSelf(SecurityImpersonation
);
945 /***********************************************************************
946 * RpcRevertToSelfEx (RPCRT4.@)
948 * Stops impersonating the client connected to the binding handle so that security
949 * checks are no longer done in the context of the client.
952 * BindingHandle [I] Handle to the binding to the client.
956 * Failure: RPC_STATUS value.
960 * If BindingHandle is NULL then the function stops impersonating the client
961 * connected to the binding handle of the current thread.
963 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
965 FIXME("(%p): stub\n", BindingHandle
);
969 static RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
970 CredHandle cred
, TimeStamp exp
,
971 ULONG cbMaxToken
, RpcAuthInfo
**ret
)
973 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
975 return ERROR_OUTOFMEMORY
;
978 AuthInfo
->AuthnLevel
= AuthnLevel
;
979 AuthInfo
->AuthnSvc
= AuthnSvc
;
980 AuthInfo
->cred
= cred
;
982 AuthInfo
->cbMaxToken
= cbMaxToken
;
987 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
989 return InterlockedIncrement(&AuthInfo
->refs
);
992 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
994 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
998 FreeCredentialsHandle(&AuthInfo
->cred
);
999 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1005 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1007 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1010 return RPC_S_OUT_OF_RESOURCES
;
1013 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1014 if (!qos
->qos
) goto error
;
1015 qos
->qos
->Version
= qos_src
->Version
;
1016 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1017 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1018 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1019 qos
->qos
->AdditionalSecurityInfoType
= 0;
1021 if (qos_src
->Version
>= 2)
1023 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1024 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1025 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1027 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1028 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1030 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1031 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1032 if (!http_credentials_dst
) goto error
;
1033 http_credentials_dst
->TransportCredentials
= NULL
;
1034 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1035 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1036 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1037 http_credentials_dst
->AuthnSchemes
= NULL
;
1038 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1039 if (http_credentials_src
->TransportCredentials
)
1041 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1042 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1043 if (!cred_dst
) goto error
;
1044 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1047 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1048 cred_dst
->UserLength
= cred_src
->UserLength
;
1049 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1050 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1051 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1052 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1053 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1057 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1058 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1059 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1060 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1061 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1062 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1063 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1064 if (!cred_dst
|| !cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1065 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1066 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1067 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1070 if (http_credentials_src
->NumberOfAuthnSchemes
)
1072 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1073 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1074 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1076 if (http_credentials_src
->ServerCertificateSubject
)
1079 http_credentials_dst
->ServerCertificateSubject
=
1080 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1081 strlenW(http_credentials_src
->ServerCertificateSubject
));
1083 http_credentials_dst
->ServerCertificateSubject
=
1084 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1085 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1095 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1096 qos
->qos
->u
.HttpCredentials
)
1098 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1100 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1101 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1102 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1103 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1105 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1106 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1107 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1109 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1111 HeapFree(GetProcessHeap(), 0, qos
);
1112 return RPC_S_OUT_OF_RESOURCES
;
1115 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1117 return InterlockedIncrement(&qos
->refs
);
1120 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1122 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1126 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1128 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1130 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1131 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1132 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1133 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1135 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1136 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1137 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1139 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1140 HeapFree(GetProcessHeap(), 0, qos
);
1145 /***********************************************************************
1146 * RpcRevertToSelf (RPCRT4.@)
1148 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1155 /***********************************************************************
1156 * RpcMgmtSetComTimeout (RPCRT4.@)
1158 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1160 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1164 /***********************************************************************
1165 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1167 RPCRTAPI RPC_STATUS RPC_ENTRY
1168 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1169 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1170 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1172 FIXME("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1173 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1174 return RPC_S_INVALID_BINDING
;
1177 /***********************************************************************
1178 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1180 RPCRTAPI RPC_STATUS RPC_ENTRY
1181 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1182 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1183 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1185 FIXME("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1186 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1187 return RPC_S_INVALID_BINDING
;
1190 /***********************************************************************
1191 * RpcBindingInqAuthInfoA (RPCRT4.@)
1193 RPCRTAPI RPC_STATUS RPC_ENTRY
1194 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1195 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1197 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1198 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1199 return RPC_S_INVALID_BINDING
;
1202 /***********************************************************************
1203 * RpcBindingInqAuthInfoW (RPCRT4.@)
1205 RPCRTAPI RPC_STATUS RPC_ENTRY
1206 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1207 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1209 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1210 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1211 return RPC_S_INVALID_BINDING
;
1214 /***********************************************************************
1215 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1217 RPCRTAPI RPC_STATUS RPC_ENTRY
1218 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1219 ULONG AuthnLevel
, ULONG AuthnSvc
,
1220 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1221 RPC_SECURITY_QOS
*SecurityQos
)
1223 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1227 ULONG package_count
;
1229 PSecPkgInfoA packages
;
1232 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1233 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1239 TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1240 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1241 if (SecurityQos
->Version
>= 2)
1243 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1244 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1245 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1246 TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }",
1247 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1248 SecurityQos2
->u
.HttpCredentials
->Flags
,
1249 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1250 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1251 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1252 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1255 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1256 if (status
!= RPC_S_OK
)
1261 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1265 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1266 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1268 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1269 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1270 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1272 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1274 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1275 bind
->AuthInfo
= NULL
;
1279 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1281 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1282 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1287 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1288 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1291 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1294 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1295 return RPC_S_SEC_PKG_ERROR
;
1298 for (i
= 0; i
< package_count
; i
++)
1299 if (packages
[i
].wRPCID
== AuthnSvc
)
1302 if (i
== package_count
)
1304 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1305 FreeContextBuffer(packages
);
1306 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1309 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1310 r
= AcquireCredentialsHandleA((SEC_CHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1311 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1312 cbMaxToken
= packages
[i
].cbMaxToken
;
1313 FreeContextBuffer(packages
);
1314 if (r
== ERROR_SUCCESS
)
1316 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1317 bind
->AuthInfo
= NULL
;
1318 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1321 FreeCredentialsHandle(&cred
);
1326 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1327 return RPC_S_SEC_PKG_ERROR
;
1331 /***********************************************************************
1332 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1334 RPCRTAPI RPC_STATUS RPC_ENTRY
1335 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1336 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1337 RPC_SECURITY_QOS
*SecurityQos
)
1339 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1343 ULONG package_count
;
1345 PSecPkgInfoW packages
;
1348 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1349 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1355 TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1356 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1357 if (SecurityQos
->Version
>= 2)
1359 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1360 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1361 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1362 TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }",
1363 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1364 SecurityQos2
->u
.HttpCredentials
->Flags
,
1365 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1366 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1367 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1368 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1371 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1372 if (status
!= RPC_S_OK
)
1377 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1381 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1382 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1384 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1385 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1386 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1388 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1390 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1391 bind
->AuthInfo
= NULL
;
1395 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1397 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1398 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1403 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1404 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1407 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1410 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1411 return RPC_S_SEC_PKG_ERROR
;
1414 for (i
= 0; i
< package_count
; i
++)
1415 if (packages
[i
].wRPCID
== AuthnSvc
)
1418 if (i
== package_count
)
1420 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1421 FreeContextBuffer(packages
);
1422 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1425 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1426 r
= AcquireCredentialsHandleW((SEC_WCHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1427 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1428 cbMaxToken
= packages
[i
].cbMaxToken
;
1429 FreeContextBuffer(packages
);
1430 if (r
== ERROR_SUCCESS
)
1432 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1433 bind
->AuthInfo
= NULL
;
1434 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1437 FreeCredentialsHandle(&cred
);
1442 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1443 return RPC_S_SEC_PKG_ERROR
;
1447 /***********************************************************************
1448 * RpcBindingSetAuthInfoA (RPCRT4.@)
1450 RPCRTAPI RPC_STATUS RPC_ENTRY
1451 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1452 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1454 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1455 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1456 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1459 /***********************************************************************
1460 * RpcBindingSetAuthInfoW (RPCRT4.@)
1462 RPCRTAPI RPC_STATUS RPC_ENTRY
1463 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1464 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1466 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1467 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1468 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1471 /***********************************************************************
1472 * RpcBindingSetOption (RPCRT4.@)
1474 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG OptionValue
)
1476 FIXME("(%p, %d, %d): stub\n", BindingHandle
, Option
, OptionValue
);