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
35 #include "wine/unicode.h"
40 #include "wine/debug.h"
42 #include "rpc_binding.h"
43 #include "rpc_message.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(rpc
);
47 LPSTR
RPCRT4_strndupA(LPCSTR src
, INT slen
)
51 if (!src
) return NULL
;
52 if (slen
== -1) slen
= strlen(src
);
54 s
= HeapAlloc(GetProcessHeap(), 0, len
+1);
60 LPSTR
RPCRT4_strdupWtoA(LPCWSTR src
)
64 if (!src
) return NULL
;
65 len
= WideCharToMultiByte(CP_ACP
, 0, src
, -1, NULL
, 0, NULL
, NULL
);
66 s
= HeapAlloc(GetProcessHeap(), 0, len
);
67 WideCharToMultiByte(CP_ACP
, 0, src
, -1, s
, len
, NULL
, NULL
);
71 LPWSTR
RPCRT4_strdupAtoW(LPCSTR src
)
75 if (!src
) return NULL
;
76 len
= MultiByteToWideChar(CP_ACP
, 0, src
, -1, NULL
, 0);
77 s
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
78 MultiByteToWideChar(CP_ACP
, 0, src
, -1, s
, len
);
82 LPWSTR
RPCRT4_strndupW(LPCWSTR src
, INT slen
)
86 if (!src
) return NULL
;
87 if (slen
== -1) slen
= strlenW(src
);
89 s
= HeapAlloc(GetProcessHeap(), 0, (len
+1)*sizeof(WCHAR
));
90 memcpy(s
, src
, len
*sizeof(WCHAR
));
95 void RPCRT4_strfree(LPSTR src
)
97 HeapFree(GetProcessHeap(), 0, src
);
100 static RPC_STATUS
RPCRT4_AllocBinding(RpcBinding
** Binding
, BOOL server
)
102 RpcBinding
* NewBinding
;
104 NewBinding
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcBinding
));
105 NewBinding
->refs
= 1;
106 NewBinding
->server
= server
;
108 *Binding
= NewBinding
;
113 static RPC_STATUS
RPCRT4_CreateBindingA(RpcBinding
** Binding
, BOOL server
, LPCSTR Protseq
)
115 RpcBinding
* NewBinding
;
117 RPCRT4_AllocBinding(&NewBinding
, server
);
118 NewBinding
->Protseq
= RPCRT4_strdupA(Protseq
);
120 TRACE("binding: %p\n", NewBinding
);
121 *Binding
= NewBinding
;
126 static RPC_STATUS
RPCRT4_CreateBindingW(RpcBinding
** Binding
, BOOL server
, LPCWSTR Protseq
)
128 RpcBinding
* NewBinding
;
130 RPCRT4_AllocBinding(&NewBinding
, server
);
131 NewBinding
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
133 TRACE("binding: %p\n", NewBinding
);
134 *Binding
= NewBinding
;
139 static RPC_STATUS
RPCRT4_CompleteBindingA(RpcBinding
* Binding
, LPCSTR NetworkAddr
,
140 LPCSTR Endpoint
, LPCSTR NetworkOptions
)
144 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
145 debugstr_a(NetworkAddr
), debugstr_a(Endpoint
), debugstr_a(NetworkOptions
));
147 RPCRT4_strfree(Binding
->NetworkAddr
);
148 Binding
->NetworkAddr
= RPCRT4_strdupA(NetworkAddr
);
149 RPCRT4_strfree(Binding
->Endpoint
);
151 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
153 Binding
->Endpoint
= RPCRT4_strdupA("");
155 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
156 Binding
->NetworkOptions
= RPCRT4_strdupAtoW(NetworkOptions
);
157 if (!Binding
->Endpoint
) ERR("out of memory?\n");
159 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
160 Binding
->Endpoint
, Binding
->NetworkOptions
,
162 if (status
!= RPC_S_OK
)
168 static RPC_STATUS
RPCRT4_CompleteBindingW(RpcBinding
* Binding
, LPCWSTR NetworkAddr
,
169 LPCWSTR Endpoint
, LPCWSTR NetworkOptions
)
173 TRACE("(RpcBinding == ^%p, NetworkAddr == %s, EndPoint == %s, NetworkOptions == %s)\n", Binding
,
174 debugstr_w(NetworkAddr
), debugstr_w(Endpoint
), debugstr_w(NetworkOptions
));
176 RPCRT4_strfree(Binding
->NetworkAddr
);
177 Binding
->NetworkAddr
= RPCRT4_strdupWtoA(NetworkAddr
);
178 RPCRT4_strfree(Binding
->Endpoint
);
180 Binding
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
182 Binding
->Endpoint
= RPCRT4_strdupA("");
184 if (!Binding
->Endpoint
) ERR("out of memory?\n");
185 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
186 Binding
->NetworkOptions
= RPCRT4_strdupW(NetworkOptions
);
188 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
189 Binding
->Endpoint
, Binding
->NetworkOptions
,
191 if (status
!= RPC_S_OK
)
197 RPC_STATUS
RPCRT4_ResolveBinding(RpcBinding
* Binding
, LPCSTR Endpoint
)
201 TRACE("(RpcBinding == ^%p, EndPoint == \"%s\"\n", Binding
, Endpoint
);
203 RPCRT4_strfree(Binding
->Endpoint
);
204 Binding
->Endpoint
= RPCRT4_strdupA(Endpoint
);
206 RpcAssoc_Release(Binding
->Assoc
);
207 Binding
->Assoc
= NULL
;
208 status
= RPCRT4_GetAssociation(Binding
->Protseq
, Binding
->NetworkAddr
,
209 Binding
->Endpoint
, Binding
->NetworkOptions
,
211 if (status
!= RPC_S_OK
)
217 RPC_STATUS
RPCRT4_SetBindingObject(RpcBinding
* Binding
, const UUID
* ObjectUuid
)
219 TRACE("(*RpcBinding == ^%p, UUID == %s)\n", Binding
, debugstr_guid(ObjectUuid
));
220 if (ObjectUuid
) memcpy(&Binding
->ObjectUuid
, ObjectUuid
, sizeof(UUID
));
221 else UuidCreateNil(&Binding
->ObjectUuid
);
225 RPC_STATUS
RPCRT4_MakeBinding(RpcBinding
** Binding
, RpcConnection
* Connection
)
227 RpcBinding
* NewBinding
;
228 TRACE("(RpcBinding == ^%p, Connection == ^%p)\n", Binding
, Connection
);
230 RPCRT4_AllocBinding(&NewBinding
, Connection
->server
);
231 NewBinding
->Protseq
= RPCRT4_strdupA(rpcrt4_conn_get_name(Connection
));
232 NewBinding
->NetworkAddr
= RPCRT4_strdupA(Connection
->NetworkAddr
);
233 NewBinding
->Endpoint
= RPCRT4_strdupA(Connection
->Endpoint
);
234 NewBinding
->FromConn
= Connection
;
236 TRACE("binding: %p\n", NewBinding
);
237 *Binding
= NewBinding
;
242 RPC_STATUS
RPCRT4_ExportBinding(RpcBinding
** Binding
, RpcBinding
* OldBinding
)
244 InterlockedIncrement(&OldBinding
->refs
);
245 *Binding
= OldBinding
;
249 RPC_STATUS
RPCRT4_DestroyBinding(RpcBinding
* Binding
)
251 if (InterlockedDecrement(&Binding
->refs
))
254 TRACE("binding: %p\n", Binding
);
255 if (Binding
->Assoc
) RpcAssoc_Release(Binding
->Assoc
);
256 RPCRT4_strfree(Binding
->Endpoint
);
257 RPCRT4_strfree(Binding
->NetworkAddr
);
258 RPCRT4_strfree(Binding
->Protseq
);
259 HeapFree(GetProcessHeap(), 0, Binding
->NetworkOptions
);
260 if (Binding
->AuthInfo
) RpcAuthInfo_Release(Binding
->AuthInfo
);
261 if (Binding
->QOS
) RpcQualityOfService_Release(Binding
->QOS
);
262 HeapFree(GetProcessHeap(), 0, Binding
);
266 RPC_STATUS
RPCRT4_OpenBinding(RpcBinding
* Binding
, RpcConnection
** Connection
,
267 PRPC_SYNTAX_IDENTIFIER TransferSyntax
,
268 PRPC_SYNTAX_IDENTIFIER InterfaceId
)
270 RpcConnection
* NewConnection
;
273 TRACE("(Binding == ^%p)\n", Binding
);
275 if (!Binding
->server
) {
276 /* try to find a compatible connection from the connection pool */
277 NewConnection
= RpcAssoc_GetIdleConnection(Binding
->Assoc
, InterfaceId
,
278 TransferSyntax
, Binding
->AuthInfo
, Binding
->QOS
);
280 *Connection
= NewConnection
;
284 /* we already have a connection with acceptable binding, so use it */
285 if (Binding
->FromConn
) {
286 *Connection
= Binding
->FromConn
;
291 /* create a new connection */
292 status
= RPCRT4_CreateConnection(&NewConnection
, Binding
->server
,
293 Binding
->Protseq
, Binding
->NetworkAddr
,
294 Binding
->Endpoint
, Binding
->NetworkOptions
,
295 Binding
->AuthInfo
, Binding
->QOS
, Binding
);
296 if (status
!= RPC_S_OK
)
299 status
= RPCRT4_OpenClientConnection(NewConnection
);
300 if (status
!= RPC_S_OK
)
302 RPCRT4_DestroyConnection(NewConnection
);
306 /* we need to send a binding packet if we are client. */
307 if (!NewConnection
->server
) {
309 RpcPktHdr
*response_hdr
;
312 TRACE("sending bind request to server\n");
314 hdr
= RPCRT4_BuildBindHeader(NDR_LOCAL_DATA_REPRESENTATION
,
315 RPC_MAX_PACKET_SIZE
, RPC_MAX_PACKET_SIZE
,
316 InterfaceId
, TransferSyntax
);
318 status
= RPCRT4_Send(NewConnection
, hdr
, NULL
, 0);
319 RPCRT4_FreeHeader(hdr
);
320 if (status
!= RPC_S_OK
) {
321 RPCRT4_DestroyConnection(NewConnection
);
325 status
= RPCRT4_Receive(NewConnection
, &response_hdr
, &msg
);
326 if (status
!= RPC_S_OK
) {
327 ERR("receive failed\n");
328 RPCRT4_DestroyConnection(NewConnection
);
332 if (response_hdr
->common
.ptype
!= PKT_BIND_ACK
||
333 response_hdr
->bind_ack
.max_tsize
< RPC_MIN_PACKET_SIZE
) {
334 ERR("failed to bind for interface %s, %d.%d\n",
335 debugstr_guid(&InterfaceId
->SyntaxGUID
),
336 InterfaceId
->SyntaxVersion
.MajorVersion
,
337 InterfaceId
->SyntaxVersion
.MinorVersion
);
338 RPCRT4_FreeHeader(response_hdr
);
339 RPCRT4_DestroyConnection(NewConnection
);
340 return RPC_S_PROTOCOL_ERROR
;
343 /* FIXME: do more checks? */
345 NewConnection
->MaxTransmissionSize
= response_hdr
->bind_ack
.max_tsize
;
346 NewConnection
->ActiveInterface
= *InterfaceId
;
347 RPCRT4_FreeHeader(response_hdr
);
351 Binding
->FromConn
= NewConnection
;
352 *Connection
= NewConnection
;
357 RPC_STATUS
RPCRT4_CloseBinding(RpcBinding
* Binding
, RpcConnection
* Connection
)
359 TRACE("(Binding == ^%p)\n", Binding
);
360 if (!Connection
) return RPC_S_OK
;
361 if (Binding
->server
) {
362 /* don't destroy a connection that is cached in the binding */
363 if (Binding
->FromConn
== Connection
)
365 return RPCRT4_DestroyConnection(Connection
);
368 RpcAssoc_ReleaseIdleConnection(Binding
->Assoc
, Connection
);
373 /* utility functions for string composing and parsing */
374 static unsigned RPCRT4_strcopyA(LPSTR data
, LPCSTR src
)
376 unsigned len
= strlen(src
);
377 memcpy(data
, src
, len
*sizeof(CHAR
));
381 static unsigned RPCRT4_strcopyW(LPWSTR data
, LPCWSTR src
)
383 unsigned len
= strlenW(src
);
384 memcpy(data
, src
, len
*sizeof(WCHAR
));
388 static LPSTR
RPCRT4_strconcatA(LPSTR dst
, LPCSTR src
)
390 DWORD len
= strlen(dst
), slen
= strlen(src
);
391 LPSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(CHAR
));
394 HeapFree(GetProcessHeap(), 0, dst
);
398 memcpy(ndst
+len
+1, src
, slen
+1);
402 static LPWSTR
RPCRT4_strconcatW(LPWSTR dst
, LPCWSTR src
)
404 DWORD len
= strlenW(dst
), slen
= strlenW(src
);
405 LPWSTR ndst
= HeapReAlloc(GetProcessHeap(), 0, dst
, (len
+slen
+2)*sizeof(WCHAR
));
408 HeapFree(GetProcessHeap(), 0, dst
);
412 memcpy(ndst
+len
+1, src
, (slen
+1)*sizeof(WCHAR
));
417 /***********************************************************************
418 * RpcStringBindingComposeA (RPCRT4.@)
420 RPC_STATUS WINAPI
RpcStringBindingComposeA(RPC_CSTR ObjUuid
, RPC_CSTR Protseq
,
421 RPC_CSTR NetworkAddr
, RPC_CSTR Endpoint
,
422 RPC_CSTR Options
, RPC_CSTR
*StringBinding
)
427 TRACE( "(%s,%s,%s,%s,%s,%p)\n",
428 debugstr_a( (char*)ObjUuid
), debugstr_a( (char*)Protseq
),
429 debugstr_a( (char*)NetworkAddr
), debugstr_a( (char*)Endpoint
),
430 debugstr_a( (char*)Options
), StringBinding
);
432 if (ObjUuid
&& *ObjUuid
) len
+= strlen((char*)ObjUuid
) + 1;
433 if (Protseq
&& *Protseq
) len
+= strlen((char*)Protseq
) + 1;
434 if (NetworkAddr
&& *NetworkAddr
) len
+= strlen((char*)NetworkAddr
);
435 if (Endpoint
&& *Endpoint
) len
+= strlen((char*)Endpoint
) + 2;
436 if (Options
&& *Options
) len
+= strlen((char*)Options
) + 2;
438 data
= HeapAlloc(GetProcessHeap(), 0, len
);
439 *StringBinding
= (unsigned char*)data
;
441 if (ObjUuid
&& *ObjUuid
) {
442 data
+= RPCRT4_strcopyA(data
, (char*)ObjUuid
);
445 if (Protseq
&& *Protseq
) {
446 data
+= RPCRT4_strcopyA(data
, (char*)Protseq
);
449 if (NetworkAddr
&& *NetworkAddr
)
450 data
+= RPCRT4_strcopyA(data
, (char*)NetworkAddr
);
452 if ((Endpoint
&& *Endpoint
) ||
453 (Options
&& *Options
)) {
455 if (Endpoint
&& *Endpoint
) {
456 data
+= RPCRT4_strcopyA(data
, (char*)Endpoint
);
457 if (Options
&& *Options
) *data
++ = ',';
459 if (Options
&& *Options
) {
460 data
+= RPCRT4_strcopyA(data
, (char*)Options
);
469 /***********************************************************************
470 * RpcStringBindingComposeW (RPCRT4.@)
472 RPC_STATUS WINAPI
RpcStringBindingComposeW( RPC_WSTR ObjUuid
, RPC_WSTR Protseq
,
473 RPC_WSTR NetworkAddr
, RPC_WSTR Endpoint
,
474 RPC_WSTR Options
, RPC_WSTR
* StringBinding
)
479 TRACE("(%s,%s,%s,%s,%s,%p)\n",
480 debugstr_w( ObjUuid
), debugstr_w( Protseq
),
481 debugstr_w( NetworkAddr
), debugstr_w( Endpoint
),
482 debugstr_w( Options
), StringBinding
);
484 if (ObjUuid
&& *ObjUuid
) len
+= strlenW(ObjUuid
) + 1;
485 if (Protseq
&& *Protseq
) len
+= strlenW(Protseq
) + 1;
486 if (NetworkAddr
&& *NetworkAddr
) len
+= strlenW(NetworkAddr
);
487 if (Endpoint
&& *Endpoint
) len
+= strlenW(Endpoint
) + 2;
488 if (Options
&& *Options
) len
+= strlenW(Options
) + 2;
490 data
= HeapAlloc(GetProcessHeap(), 0, len
*sizeof(WCHAR
));
491 *StringBinding
= data
;
493 if (ObjUuid
&& *ObjUuid
) {
494 data
+= RPCRT4_strcopyW(data
, ObjUuid
);
497 if (Protseq
&& *Protseq
) {
498 data
+= RPCRT4_strcopyW(data
, Protseq
);
501 if (NetworkAddr
&& *NetworkAddr
) {
502 data
+= RPCRT4_strcopyW(data
, NetworkAddr
);
504 if ((Endpoint
&& *Endpoint
) ||
505 (Options
&& *Options
)) {
507 if (Endpoint
&& *Endpoint
) {
508 data
+= RPCRT4_strcopyW(data
, Endpoint
);
509 if (Options
&& *Options
) *data
++ = ',';
511 if (Options
&& *Options
) {
512 data
+= RPCRT4_strcopyW(data
, Options
);
522 /***********************************************************************
523 * RpcStringBindingParseA (RPCRT4.@)
525 RPC_STATUS WINAPI
RpcStringBindingParseA( RPC_CSTR StringBinding
, RPC_CSTR
*ObjUuid
,
526 RPC_CSTR
*Protseq
, RPC_CSTR
*NetworkAddr
,
527 RPC_CSTR
*Endpoint
, RPC_CSTR
*Options
)
530 static const char ep_opt
[] = "endpoint=";
532 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_a((char*)StringBinding
),
533 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
535 if (ObjUuid
) *ObjUuid
= NULL
;
536 if (Protseq
) *Protseq
= NULL
;
537 if (NetworkAddr
) *NetworkAddr
= NULL
;
538 if (Endpoint
) *Endpoint
= NULL
;
539 if (Options
) *Options
= NULL
;
541 data
= (char*) StringBinding
;
543 next
= strchr(data
, '@');
545 if (ObjUuid
) *ObjUuid
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
549 next
= strchr(data
, ':');
551 if (Protseq
) *Protseq
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
555 next
= strchr(data
, '[');
559 if (NetworkAddr
) *NetworkAddr
= (unsigned char*)RPCRT4_strndupA(data
, next
- data
);
561 close
= strchr(data
, ']');
562 if (!close
) goto fail
;
564 /* tokenize options */
565 while (data
< close
) {
566 next
= strchr(data
, ',');
567 if (!next
|| next
> close
) next
= close
;
568 /* FIXME: this is kind of inefficient */
569 opt
= RPCRT4_strndupA(data
, next
- data
);
573 next
= strchr(opt
, '=');
575 /* not an option, must be an endpoint */
576 if (*Endpoint
) goto fail
;
577 *Endpoint
= (unsigned char*) opt
;
579 if (strncmp(opt
, ep_opt
, strlen(ep_opt
)) == 0) {
580 /* endpoint option */
581 if (*Endpoint
) goto fail
;
582 *Endpoint
= (unsigned char*) RPCRT4_strdupA(next
+1);
583 HeapFree(GetProcessHeap(), 0, opt
);
587 /* FIXME: this is kind of inefficient */
588 *Options
= (unsigned char*) RPCRT4_strconcatA( (char*)*Options
, opt
);
589 HeapFree(GetProcessHeap(), 0, opt
);
591 *Options
= (unsigned char*) opt
;
597 if (*data
) goto fail
;
599 else if (NetworkAddr
)
600 *NetworkAddr
= (unsigned char*)RPCRT4_strdupA(data
);
605 if (ObjUuid
) RpcStringFreeA((unsigned char**)ObjUuid
);
606 if (Protseq
) RpcStringFreeA((unsigned char**)Protseq
);
607 if (NetworkAddr
) RpcStringFreeA((unsigned char**)NetworkAddr
);
608 if (Endpoint
) RpcStringFreeA((unsigned char**)Endpoint
);
609 if (Options
) RpcStringFreeA((unsigned char**)Options
);
610 return RPC_S_INVALID_STRING_BINDING
;
613 /***********************************************************************
614 * RpcStringBindingParseW (RPCRT4.@)
616 RPC_STATUS WINAPI
RpcStringBindingParseW( RPC_WSTR StringBinding
, RPC_WSTR
*ObjUuid
,
617 RPC_WSTR
*Protseq
, RPC_WSTR
*NetworkAddr
,
618 RPC_WSTR
*Endpoint
, RPC_WSTR
*Options
)
621 static const WCHAR ep_opt
[] = {'e','n','d','p','o','i','n','t','=',0};
623 TRACE("(%s,%p,%p,%p,%p,%p)\n", debugstr_w(StringBinding
),
624 ObjUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
);
626 if (ObjUuid
) *ObjUuid
= NULL
;
627 if (Protseq
) *Protseq
= NULL
;
628 if (NetworkAddr
) *NetworkAddr
= NULL
;
629 if (Endpoint
) *Endpoint
= NULL
;
630 if (Options
) *Options
= NULL
;
632 data
= StringBinding
;
634 next
= strchrW(data
, '@');
636 if (ObjUuid
) *ObjUuid
= RPCRT4_strndupW(data
, next
- data
);
640 next
= strchrW(data
, ':');
642 if (Protseq
) *Protseq
= RPCRT4_strndupW(data
, next
- data
);
646 next
= strchrW(data
, '[');
650 if (NetworkAddr
) *NetworkAddr
= RPCRT4_strndupW(data
, next
- data
);
652 close
= strchrW(data
, ']');
653 if (!close
) goto fail
;
655 /* tokenize options */
656 while (data
< close
) {
657 next
= strchrW(data
, ',');
658 if (!next
|| next
> close
) next
= close
;
659 /* FIXME: this is kind of inefficient */
660 opt
= RPCRT4_strndupW(data
, next
- data
);
664 next
= strchrW(opt
, '=');
666 /* not an option, must be an endpoint */
667 if (*Endpoint
) goto fail
;
670 if (strncmpW(opt
, ep_opt
, strlenW(ep_opt
)) == 0) {
671 /* endpoint option */
672 if (*Endpoint
) goto fail
;
673 *Endpoint
= RPCRT4_strdupW(next
+1);
674 HeapFree(GetProcessHeap(), 0, opt
);
678 /* FIXME: this is kind of inefficient */
679 *Options
= RPCRT4_strconcatW(*Options
, opt
);
680 HeapFree(GetProcessHeap(), 0, opt
);
688 if (*data
) goto fail
;
689 } else if (NetworkAddr
)
690 *NetworkAddr
= RPCRT4_strdupW(data
);
695 if (ObjUuid
) RpcStringFreeW(ObjUuid
);
696 if (Protseq
) RpcStringFreeW(Protseq
);
697 if (NetworkAddr
) RpcStringFreeW(NetworkAddr
);
698 if (Endpoint
) RpcStringFreeW(Endpoint
);
699 if (Options
) RpcStringFreeW(Options
);
700 return RPC_S_INVALID_STRING_BINDING
;
703 /***********************************************************************
704 * RpcBindingFree (RPCRT4.@)
706 RPC_STATUS WINAPI
RpcBindingFree( RPC_BINDING_HANDLE
* Binding
)
709 TRACE("(%p) = %p\n", Binding
, *Binding
);
710 status
= RPCRT4_DestroyBinding(*Binding
);
711 if (status
== RPC_S_OK
) *Binding
= 0;
715 /***********************************************************************
716 * RpcBindingVectorFree (RPCRT4.@)
718 RPC_STATUS WINAPI
RpcBindingVectorFree( RPC_BINDING_VECTOR
** BindingVector
)
723 TRACE("(%p)\n", BindingVector
);
724 for (c
=0; c
<(*BindingVector
)->Count
; c
++) {
725 status
= RpcBindingFree(&(*BindingVector
)->BindingH
[c
]);
727 HeapFree(GetProcessHeap(), 0, *BindingVector
);
728 *BindingVector
= NULL
;
732 /***********************************************************************
733 * RpcBindingInqObject (RPCRT4.@)
735 RPC_STATUS WINAPI
RpcBindingInqObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
737 RpcBinding
* bind
= (RpcBinding
*)Binding
;
739 TRACE("(%p,%p) = %s\n", Binding
, ObjectUuid
, debugstr_guid(&bind
->ObjectUuid
));
740 memcpy(ObjectUuid
, &bind
->ObjectUuid
, sizeof(UUID
));
744 /***********************************************************************
745 * RpcBindingSetObject (RPCRT4.@)
747 RPC_STATUS WINAPI
RpcBindingSetObject( RPC_BINDING_HANDLE Binding
, UUID
* ObjectUuid
)
749 RpcBinding
* bind
= (RpcBinding
*)Binding
;
751 TRACE("(%p,%s)\n", Binding
, debugstr_guid(ObjectUuid
));
752 if (bind
->server
) return RPC_S_WRONG_KIND_OF_BINDING
;
753 return RPCRT4_SetBindingObject(Binding
, ObjectUuid
);
756 /***********************************************************************
757 * RpcBindingFromStringBindingA (RPCRT4.@)
759 RPC_STATUS WINAPI
RpcBindingFromStringBindingA( RPC_CSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
762 RpcBinding
* bind
= NULL
;
763 RPC_CSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
766 TRACE("(%s,%p)\n", debugstr_a((char*)StringBinding
), Binding
);
768 ret
= RpcStringBindingParseA(StringBinding
, &ObjectUuid
, &Protseq
,
769 &NetworkAddr
, &Endpoint
, &Options
);
770 if (ret
!= RPC_S_OK
) return ret
;
772 ret
= UuidFromStringA(ObjectUuid
, &Uuid
);
775 ret
= RPCRT4_CreateBindingA(&bind
, FALSE
, (char*)Protseq
);
777 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
779 ret
= RPCRT4_CompleteBindingA(bind
, (char*)NetworkAddr
, (char*)Endpoint
, (char*)Options
);
781 RpcStringFreeA((unsigned char**)&Options
);
782 RpcStringFreeA((unsigned char**)&Endpoint
);
783 RpcStringFreeA((unsigned char**)&NetworkAddr
);
784 RpcStringFreeA((unsigned char**)&Protseq
);
785 RpcStringFreeA((unsigned char**)&ObjectUuid
);
788 *Binding
= (RPC_BINDING_HANDLE
)bind
;
790 RPCRT4_DestroyBinding(bind
);
795 /***********************************************************************
796 * RpcBindingFromStringBindingW (RPCRT4.@)
798 RPC_STATUS WINAPI
RpcBindingFromStringBindingW( RPC_WSTR StringBinding
, RPC_BINDING_HANDLE
* Binding
)
801 RpcBinding
* bind
= NULL
;
802 RPC_WSTR ObjectUuid
, Protseq
, NetworkAddr
, Endpoint
, Options
;
805 TRACE("(%s,%p)\n", debugstr_w(StringBinding
), Binding
);
807 ret
= RpcStringBindingParseW(StringBinding
, &ObjectUuid
, &Protseq
,
808 &NetworkAddr
, &Endpoint
, &Options
);
809 if (ret
!= RPC_S_OK
) return ret
;
811 ret
= UuidFromStringW(ObjectUuid
, &Uuid
);
814 ret
= RPCRT4_CreateBindingW(&bind
, FALSE
, Protseq
);
816 ret
= RPCRT4_SetBindingObject(bind
, &Uuid
);
818 ret
= RPCRT4_CompleteBindingW(bind
, NetworkAddr
, Endpoint
, Options
);
820 RpcStringFreeW(&Options
);
821 RpcStringFreeW(&Endpoint
);
822 RpcStringFreeW(&NetworkAddr
);
823 RpcStringFreeW(&Protseq
);
824 RpcStringFreeW(&ObjectUuid
);
827 *Binding
= (RPC_BINDING_HANDLE
)bind
;
829 RPCRT4_DestroyBinding(bind
);
834 /***********************************************************************
835 * RpcBindingToStringBindingA (RPCRT4.@)
837 RPC_STATUS WINAPI
RpcBindingToStringBindingA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*StringBinding
)
840 RpcBinding
* bind
= (RpcBinding
*)Binding
;
843 TRACE("(%p,%p)\n", Binding
, StringBinding
);
845 ret
= UuidToStringA(&bind
->ObjectUuid
, &ObjectUuid
);
846 if (ret
!= RPC_S_OK
) return ret
;
848 ret
= RpcStringBindingComposeA(ObjectUuid
, (unsigned char*)bind
->Protseq
, (unsigned char*) bind
->NetworkAddr
,
849 (unsigned char*) bind
->Endpoint
, NULL
, StringBinding
);
851 RpcStringFreeA(&ObjectUuid
);
856 /***********************************************************************
857 * RpcBindingToStringBindingW (RPCRT4.@)
859 RPC_STATUS WINAPI
RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*StringBinding
)
862 unsigned char *str
= NULL
;
863 TRACE("(%p,%p)\n", Binding
, StringBinding
);
864 ret
= RpcBindingToStringBindingA(Binding
, &str
);
865 *StringBinding
= RPCRT4_strdupAtoW((char*)str
);
866 RpcStringFreeA((unsigned char**)&str
);
870 /***********************************************************************
871 * I_RpcBindingSetAsync (RPCRT4.@)
873 * Exists in win9x and winNT, but with different number of arguments
874 * (9x version has 3 arguments, NT has 2).
876 RPC_STATUS WINAPI
I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding
, RPC_BLOCKING_FN BlockingFn
)
878 RpcBinding
* bind
= (RpcBinding
*)Binding
;
880 TRACE( "(%p,%p): stub\n", Binding
, BlockingFn
);
882 bind
->BlockingFn
= BlockingFn
;
887 /***********************************************************************
888 * RpcBindingCopy (RPCRT4.@)
890 RPC_STATUS RPC_ENTRY
RpcBindingCopy(
891 RPC_BINDING_HANDLE SourceBinding
,
892 RPC_BINDING_HANDLE
* DestinationBinding
)
894 RpcBinding
*DestBinding
;
895 RpcBinding
*SrcBinding
= (RpcBinding
*)SourceBinding
;
898 TRACE("(%p, %p)\n", SourceBinding
, DestinationBinding
);
900 status
= RPCRT4_AllocBinding(&DestBinding
, SrcBinding
->server
);
901 if (status
!= RPC_S_OK
) return status
;
903 DestBinding
->ObjectUuid
= SrcBinding
->ObjectUuid
;
904 DestBinding
->BlockingFn
= SrcBinding
->BlockingFn
;
905 DestBinding
->Protseq
= RPCRT4_strndupA(SrcBinding
->Protseq
, -1);
906 DestBinding
->NetworkAddr
= RPCRT4_strndupA(SrcBinding
->NetworkAddr
, -1);
907 DestBinding
->Endpoint
= RPCRT4_strndupA(SrcBinding
->Endpoint
, -1);
908 DestBinding
->NetworkOptions
= RPCRT4_strdupW(SrcBinding
->NetworkOptions
);
909 if (SrcBinding
->Assoc
) SrcBinding
->Assoc
->refs
++;
910 DestBinding
->Assoc
= SrcBinding
->Assoc
;
912 if (SrcBinding
->AuthInfo
) RpcAuthInfo_AddRef(SrcBinding
->AuthInfo
);
913 DestBinding
->AuthInfo
= SrcBinding
->AuthInfo
;
914 if (SrcBinding
->QOS
) RpcQualityOfService_AddRef(SrcBinding
->QOS
);
915 DestBinding
->QOS
= SrcBinding
->QOS
;
917 *DestinationBinding
= DestBinding
;
921 /***********************************************************************
922 * RpcImpersonateClient (RPCRT4.@)
924 * Impersonates the client connected via a binding handle so that security
925 * checks are done in the context of the client.
928 * BindingHandle [I] Handle to the binding to the client.
932 * Failure: RPC_STATUS value.
936 * If BindingHandle is NULL then the function impersonates the client
937 * connected to the binding handle of the current thread.
939 RPC_STATUS WINAPI
RpcImpersonateClient(RPC_BINDING_HANDLE BindingHandle
)
941 FIXME("(%p): stub\n", BindingHandle
);
942 ImpersonateSelf(SecurityImpersonation
);
946 /***********************************************************************
947 * RpcRevertToSelfEx (RPCRT4.@)
949 * Stops impersonating the client connected to the binding handle so that security
950 * checks are no longer done in the context of the client.
953 * BindingHandle [I] Handle to the binding to the client.
957 * Failure: RPC_STATUS value.
961 * If BindingHandle is NULL then the function stops impersonating the client
962 * connected to the binding handle of the current thread.
964 RPC_STATUS WINAPI
RpcRevertToSelfEx(RPC_BINDING_HANDLE BindingHandle
)
966 FIXME("(%p): stub\n", BindingHandle
);
970 static RPC_STATUS
RpcAuthInfo_Create(ULONG AuthnLevel
, ULONG AuthnSvc
,
971 CredHandle cred
, TimeStamp exp
,
972 ULONG cbMaxToken
, RpcAuthInfo
**ret
)
974 RpcAuthInfo
*AuthInfo
= HeapAlloc(GetProcessHeap(), 0, sizeof(*AuthInfo
));
976 return ERROR_OUTOFMEMORY
;
979 AuthInfo
->AuthnLevel
= AuthnLevel
;
980 AuthInfo
->AuthnSvc
= AuthnSvc
;
981 AuthInfo
->cred
= cred
;
983 AuthInfo
->cbMaxToken
= cbMaxToken
;
988 ULONG
RpcAuthInfo_AddRef(RpcAuthInfo
*AuthInfo
)
990 return InterlockedIncrement(&AuthInfo
->refs
);
993 ULONG
RpcAuthInfo_Release(RpcAuthInfo
*AuthInfo
)
995 ULONG refs
= InterlockedDecrement(&AuthInfo
->refs
);
999 FreeCredentialsHandle(&AuthInfo
->cred
);
1000 HeapFree(GetProcessHeap(), 0, AuthInfo
);
1006 static RPC_STATUS
RpcQualityOfService_Create(const RPC_SECURITY_QOS
*qos_src
, BOOL unicode
, RpcQualityOfService
**qos_dst
)
1008 RpcQualityOfService
*qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
));
1011 return RPC_S_OUT_OF_RESOURCES
;
1014 qos
->qos
= HeapAlloc(GetProcessHeap(), 0, sizeof(*qos
->qos
));
1015 if (!qos
->qos
) goto error
;
1016 qos
->qos
->Version
= qos_src
->Version
;
1017 qos
->qos
->Capabilities
= qos_src
->Capabilities
;
1018 qos
->qos
->IdentityTracking
= qos_src
->IdentityTracking
;
1019 qos
->qos
->ImpersonationType
= qos_src
->ImpersonationType
;
1020 qos
->qos
->AdditionalSecurityInfoType
= 0;
1022 if (qos_src
->Version
>= 2)
1024 const RPC_SECURITY_QOS_V2_W
*qos_src2
= (const RPC_SECURITY_QOS_V2_W
*)qos_src
;
1025 qos
->qos
->AdditionalSecurityInfoType
= qos_src2
->AdditionalSecurityInfoType
;
1026 if (qos_src2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1028 const RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_src
= qos_src2
->u
.HttpCredentials
;
1029 RPC_HTTP_TRANSPORT_CREDENTIALS_W
*http_credentials_dst
;
1031 http_credentials_dst
= HeapAlloc(GetProcessHeap(), 0, sizeof(*http_credentials_dst
));
1032 qos
->qos
->u
.HttpCredentials
= http_credentials_dst
;
1033 if (!http_credentials_dst
) goto error
;
1034 http_credentials_dst
->TransportCredentials
= NULL
;
1035 http_credentials_dst
->Flags
= http_credentials_src
->Flags
;
1036 http_credentials_dst
->AuthenticationTarget
= http_credentials_src
->AuthenticationTarget
;
1037 http_credentials_dst
->NumberOfAuthnSchemes
= http_credentials_src
->NumberOfAuthnSchemes
;
1038 http_credentials_dst
->AuthnSchemes
= NULL
;
1039 http_credentials_dst
->ServerCertificateSubject
= NULL
;
1040 if (http_credentials_src
->TransportCredentials
)
1042 SEC_WINNT_AUTH_IDENTITY_W
*cred_dst
;
1043 cred_dst
= http_credentials_dst
->TransportCredentials
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*cred_dst
));
1044 if (!cred_dst
) goto error
;
1045 cred_dst
->Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
1048 const SEC_WINNT_AUTH_IDENTITY_W
*cred_src
= http_credentials_src
->TransportCredentials
;
1049 cred_dst
->UserLength
= cred_src
->UserLength
;
1050 cred_dst
->PasswordLength
= cred_src
->PasswordLength
;
1051 cred_dst
->DomainLength
= cred_src
->DomainLength
;
1052 cred_dst
->User
= RPCRT4_strndupW(cred_src
->User
, cred_src
->UserLength
);
1053 cred_dst
->Password
= RPCRT4_strndupW(cred_src
->Password
, cred_src
->PasswordLength
);
1054 cred_dst
->Domain
= RPCRT4_strndupW(cred_src
->Domain
, cred_src
->DomainLength
);
1058 const SEC_WINNT_AUTH_IDENTITY_A
*cred_src
= (const SEC_WINNT_AUTH_IDENTITY_A
*)http_credentials_src
->TransportCredentials
;
1059 cred_dst
->UserLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, NULL
, 0);
1060 cred_dst
->DomainLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, NULL
, 0);
1061 cred_dst
->PasswordLength
= MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, NULL
, 0);
1062 cred_dst
->User
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->UserLength
* sizeof(WCHAR
));
1063 cred_dst
->Password
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->PasswordLength
* sizeof(WCHAR
));
1064 cred_dst
->Domain
= HeapAlloc(GetProcessHeap(), 0, cred_dst
->DomainLength
* sizeof(WCHAR
));
1065 if (!cred_dst
|| !cred_dst
->Password
|| !cred_dst
->Domain
) goto error
;
1066 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->User
, cred_src
->UserLength
, cred_dst
->User
, cred_dst
->UserLength
);
1067 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Domain
, cred_src
->DomainLength
, cred_dst
->Domain
, cred_dst
->DomainLength
);
1068 MultiByteToWideChar(CP_ACP
, 0, (char *)cred_src
->Password
, cred_src
->PasswordLength
, cred_dst
->Password
, cred_dst
->PasswordLength
);
1071 if (http_credentials_src
->NumberOfAuthnSchemes
)
1073 http_credentials_dst
->AuthnSchemes
= HeapAlloc(GetProcessHeap(), 0, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1074 if (!http_credentials_dst
->AuthnSchemes
) goto error
;
1075 memcpy(http_credentials_dst
->AuthnSchemes
, http_credentials_src
->AuthnSchemes
, http_credentials_src
->NumberOfAuthnSchemes
* sizeof(*http_credentials_dst
->AuthnSchemes
));
1077 if (http_credentials_src
->ServerCertificateSubject
)
1080 http_credentials_dst
->ServerCertificateSubject
=
1081 RPCRT4_strndupW(http_credentials_src
->ServerCertificateSubject
,
1082 strlenW(http_credentials_src
->ServerCertificateSubject
));
1084 http_credentials_dst
->ServerCertificateSubject
=
1085 RPCRT4_strdupAtoW((char *)http_credentials_src
->ServerCertificateSubject
);
1086 if (!http_credentials_dst
->ServerCertificateSubject
) goto error
;
1096 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
&&
1097 qos
->qos
->u
.HttpCredentials
)
1099 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1101 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1102 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1103 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1104 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1106 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1107 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1108 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1110 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1112 HeapFree(GetProcessHeap(), 0, qos
);
1113 return RPC_S_OUT_OF_RESOURCES
;
1116 ULONG
RpcQualityOfService_AddRef(RpcQualityOfService
*qos
)
1118 return InterlockedIncrement(&qos
->refs
);
1121 ULONG
RpcQualityOfService_Release(RpcQualityOfService
*qos
)
1123 ULONG refs
= InterlockedDecrement(&qos
->refs
);
1127 if (qos
->qos
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1129 if (qos
->qos
->u
.HttpCredentials
->TransportCredentials
)
1131 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->User
);
1132 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Domain
);
1133 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
->Password
);
1134 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->TransportCredentials
);
1136 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->AuthnSchemes
);
1137 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
->ServerCertificateSubject
);
1138 HeapFree(GetProcessHeap(), 0, qos
->qos
->u
.HttpCredentials
);
1140 HeapFree(GetProcessHeap(), 0, qos
->qos
);
1141 HeapFree(GetProcessHeap(), 0, qos
);
1146 /***********************************************************************
1147 * RpcRevertToSelf (RPCRT4.@)
1149 RPC_STATUS WINAPI
RpcRevertToSelf(void)
1156 /***********************************************************************
1157 * RpcMgmtSetComTimeout (RPCRT4.@)
1159 RPC_STATUS WINAPI
RpcMgmtSetComTimeout(RPC_BINDING_HANDLE BindingHandle
, unsigned int Timeout
)
1161 FIXME("(%p, %d): stub\n", BindingHandle
, Timeout
);
1165 /***********************************************************************
1166 * RpcBindingInqAuthInfoExA (RPCRT4.@)
1168 RPCRTAPI RPC_STATUS RPC_ENTRY
1169 RpcBindingInqAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1170 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1171 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1173 FIXME("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1174 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1175 return RPC_S_INVALID_BINDING
;
1178 /***********************************************************************
1179 * RpcBindingInqAuthInfoExW (RPCRT4.@)
1181 RPCRTAPI RPC_STATUS RPC_ENTRY
1182 RpcBindingInqAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1183 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
,
1184 ULONG RpcQosVersion
, RPC_SECURITY_QOS
*SecurityQOS
)
1186 FIXME("%p %p %p %p %p %p %u %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1187 AuthnSvc
, AuthIdentity
, AuthzSvc
, RpcQosVersion
, SecurityQOS
);
1188 return RPC_S_INVALID_BINDING
;
1191 /***********************************************************************
1192 * RpcBindingInqAuthInfoA (RPCRT4.@)
1194 RPCRTAPI RPC_STATUS RPC_ENTRY
1195 RpcBindingInqAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1196 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1198 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1199 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1200 return RPC_S_INVALID_BINDING
;
1203 /***********************************************************************
1204 * RpcBindingInqAuthInfoW (RPCRT4.@)
1206 RPCRTAPI RPC_STATUS RPC_ENTRY
1207 RpcBindingInqAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR
*ServerPrincName
, ULONG
*AuthnLevel
,
1208 ULONG
*AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE
*AuthIdentity
, ULONG
*AuthzSvc
)
1210 FIXME("%p %p %p %p %p %p\n", Binding
, ServerPrincName
, AuthnLevel
,
1211 AuthnSvc
, AuthIdentity
, AuthzSvc
);
1212 return RPC_S_INVALID_BINDING
;
1215 /***********************************************************************
1216 * RpcBindingSetAuthInfoExA (RPCRT4.@)
1218 RPCRTAPI RPC_STATUS RPC_ENTRY
1219 RpcBindingSetAuthInfoExA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
,
1220 ULONG AuthnLevel
, ULONG AuthnSvc
,
1221 RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1222 RPC_SECURITY_QOS
*SecurityQos
)
1224 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1228 ULONG package_count
;
1230 PSecPkgInfoA packages
;
1233 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1234 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1240 TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1241 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1242 if (SecurityQos
->Version
>= 2)
1244 const RPC_SECURITY_QOS_V2_A
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_A
*)SecurityQos
;
1245 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1246 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1247 TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }",
1248 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1249 SecurityQos2
->u
.HttpCredentials
->Flags
,
1250 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1251 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1252 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1253 SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
);
1256 status
= RpcQualityOfService_Create(SecurityQos
, FALSE
, &bind
->QOS
);
1257 if (status
!= RPC_S_OK
)
1262 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1266 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1267 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1269 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1270 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1271 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1273 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1275 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1276 bind
->AuthInfo
= NULL
;
1280 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1282 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1283 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1288 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1289 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1292 r
= EnumerateSecurityPackagesA(&package_count
, &packages
);
1295 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1296 return RPC_S_SEC_PKG_ERROR
;
1299 for (i
= 0; i
< package_count
; i
++)
1300 if (packages
[i
].wRPCID
== AuthnSvc
)
1303 if (i
== package_count
)
1305 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1306 FreeContextBuffer(packages
);
1307 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1310 TRACE("found package %s for service %u\n", packages
[i
].Name
, AuthnSvc
);
1311 r
= AcquireCredentialsHandleA((SEC_CHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1312 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1313 cbMaxToken
= packages
[i
].cbMaxToken
;
1314 FreeContextBuffer(packages
);
1315 if (r
== ERROR_SUCCESS
)
1317 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1318 bind
->AuthInfo
= NULL
;
1319 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1322 FreeCredentialsHandle(&cred
);
1327 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1328 return RPC_S_SEC_PKG_ERROR
;
1332 /***********************************************************************
1333 * RpcBindingSetAuthInfoExW (RPCRT4.@)
1335 RPCRTAPI RPC_STATUS RPC_ENTRY
1336 RpcBindingSetAuthInfoExW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1337 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
,
1338 RPC_SECURITY_QOS
*SecurityQos
)
1340 RpcBinding
* bind
= (RpcBinding
*)Binding
;
1344 ULONG package_count
;
1346 PSecPkgInfoW packages
;
1349 TRACE("%p %s %u %u %p %u %p\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1350 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, SecurityQos
);
1356 TRACE("SecurityQos { Version=%ld, Capabilties=0x%lx, IdentityTracking=%ld, ImpersonationLevel=%ld",
1357 SecurityQos
->Version
, SecurityQos
->Capabilities
, SecurityQos
->IdentityTracking
, SecurityQos
->ImpersonationType
);
1358 if (SecurityQos
->Version
>= 2)
1360 const RPC_SECURITY_QOS_V2_W
*SecurityQos2
= (const RPC_SECURITY_QOS_V2_W
*)SecurityQos
;
1361 TRACE(", AdditionalSecurityInfoType=%ld", SecurityQos2
->AdditionalSecurityInfoType
);
1362 if (SecurityQos2
->AdditionalSecurityInfoType
== RPC_C_AUTHN_INFO_TYPE_HTTP
)
1363 TRACE(", { %p, 0x%lx, %ld, %ld, %p, %s }",
1364 SecurityQos2
->u
.HttpCredentials
->TransportCredentials
,
1365 SecurityQos2
->u
.HttpCredentials
->Flags
,
1366 SecurityQos2
->u
.HttpCredentials
->AuthenticationTarget
,
1367 SecurityQos2
->u
.HttpCredentials
->NumberOfAuthnSchemes
,
1368 SecurityQos2
->u
.HttpCredentials
->AuthnSchemes
,
1369 debugstr_w(SecurityQos2
->u
.HttpCredentials
->ServerCertificateSubject
));
1372 status
= RpcQualityOfService_Create(SecurityQos
, TRUE
, &bind
->QOS
);
1373 if (status
!= RPC_S_OK
)
1378 if (bind
->QOS
) RpcQualityOfService_Release(bind
->QOS
);
1382 if (AuthnSvc
== RPC_C_AUTHN_DEFAULT
)
1383 AuthnSvc
= RPC_C_AUTHN_WINNT
;
1385 /* FIXME: the mapping should probably be retrieved using SSPI somehow */
1386 if (AuthnLevel
== RPC_C_AUTHN_LEVEL_DEFAULT
)
1387 AuthnLevel
= RPC_C_AUTHN_LEVEL_NONE
;
1389 if ((AuthnLevel
== RPC_C_AUTHN_LEVEL_NONE
) || (AuthnSvc
== RPC_C_AUTHN_NONE
))
1391 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1392 bind
->AuthInfo
= NULL
;
1396 if (AuthnLevel
> RPC_C_AUTHN_LEVEL_PKT_PRIVACY
)
1398 FIXME("unknown AuthnLevel %u\n", AuthnLevel
);
1399 return RPC_S_UNKNOWN_AUTHN_LEVEL
;
1404 FIXME("unsupported AuthzSvr %u\n", AuthzSvr
);
1405 return RPC_S_UNKNOWN_AUTHZ_SERVICE
;
1408 r
= EnumerateSecurityPackagesW(&package_count
, &packages
);
1411 ERR("EnumerateSecurityPackagesA failed with error 0x%08x\n", r
);
1412 return RPC_S_SEC_PKG_ERROR
;
1415 for (i
= 0; i
< package_count
; i
++)
1416 if (packages
[i
].wRPCID
== AuthnSvc
)
1419 if (i
== package_count
)
1421 FIXME("unsupported AuthnSvc %u\n", AuthnSvc
);
1422 FreeContextBuffer(packages
);
1423 return RPC_S_UNKNOWN_AUTHN_SERVICE
;
1426 TRACE("found package %s for service %u\n", debugstr_w(packages
[i
].Name
), AuthnSvc
);
1427 r
= AcquireCredentialsHandleW((SEC_WCHAR
*)ServerPrincName
, packages
[i
].Name
, SECPKG_CRED_OUTBOUND
, NULL
,
1428 AuthIdentity
, NULL
, NULL
, &cred
, &exp
);
1429 cbMaxToken
= packages
[i
].cbMaxToken
;
1430 FreeContextBuffer(packages
);
1431 if (r
== ERROR_SUCCESS
)
1433 if (bind
->AuthInfo
) RpcAuthInfo_Release(bind
->AuthInfo
);
1434 bind
->AuthInfo
= NULL
;
1435 r
= RpcAuthInfo_Create(AuthnLevel
, AuthnSvc
, cred
, exp
, cbMaxToken
,
1438 FreeCredentialsHandle(&cred
);
1443 ERR("AcquireCredentialsHandleA failed with error 0x%08x\n", r
);
1444 return RPC_S_SEC_PKG_ERROR
;
1448 /***********************************************************************
1449 * RpcBindingSetAuthInfoA (RPCRT4.@)
1451 RPCRTAPI RPC_STATUS RPC_ENTRY
1452 RpcBindingSetAuthInfoA( RPC_BINDING_HANDLE Binding
, RPC_CSTR ServerPrincName
, ULONG AuthnLevel
,
1453 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1455 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_a((const char*)ServerPrincName
),
1456 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1457 return RpcBindingSetAuthInfoExA(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1460 /***********************************************************************
1461 * RpcBindingSetAuthInfoW (RPCRT4.@)
1463 RPCRTAPI RPC_STATUS RPC_ENTRY
1464 RpcBindingSetAuthInfoW( RPC_BINDING_HANDLE Binding
, RPC_WSTR ServerPrincName
, ULONG AuthnLevel
,
1465 ULONG AuthnSvc
, RPC_AUTH_IDENTITY_HANDLE AuthIdentity
, ULONG AuthzSvr
)
1467 TRACE("%p %s %u %u %p %u\n", Binding
, debugstr_w((const WCHAR
*)ServerPrincName
),
1468 AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
);
1469 return RpcBindingSetAuthInfoExW(Binding
, ServerPrincName
, AuthnLevel
, AuthnSvc
, AuthIdentity
, AuthzSvr
, NULL
);
1472 /***********************************************************************
1473 * RpcBindingSetOption (RPCRT4.@)
1475 RPC_STATUS WINAPI
RpcBindingSetOption(RPC_BINDING_HANDLE BindingHandle
, ULONG Option
, ULONG OptionValue
)
1477 FIXME("(%p, %d, %d): stub\n", BindingHandle
, Option
, OptionValue
);