1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** ctxerrtl.c 82** 83** FACILITY: 84** 85** IDL Stub Runtime Support 86** 87** ABSTRACT: 88** 89** Runtime support for caller context 90** 91** 92*/ 93#if HAVE_CONFIG_H 94#include <config.h> 95#endif 96 97/* The ordering of the following 3 includes should NOT be changed! */ 98#include <dce/rpc.h> 99#include <dce/stubbase.h> 100#include <lsysdep.h> 101 102#ifdef DEBUGCTX 103# include <stdio.h> 104#endif 105 106#ifdef PERFMON 107#include <dce/idl_log.h> 108#endif 109 110/* On the caller side a context handle is a pointer into the stub's data space. 111 The object pointed to contains a 0 attributes word, a UUID and a handle_t */ 112 113/*****************************************************************************/ 114/* */ 115/* Uses malloc to create a context_element_t containing the */ 116/* wire rep of the context handle and the binding handle */ 117/* of the association. Makes the caller's context handle point at */ 118/* the created object. Starts liveness maintenance */ 119/* */ 120/*****************************************************************************/ 121static void rpc_ss_create_caller_context 122( 123 ndr_context_handle *p_wire_context, 124 /* Pointer to the wire representation of the context_handle */ 125 handle_t caller_handle, /* Binding handle */ 126 rpc_ss_context_t *p_caller_context, /* Pointer to caller's context handle */ 127 error_status_t *p_st 128) 129{ 130 rpc_ss_caller_context_element_t *p_created_context; 131 132#ifdef PERFMON 133 RPC_SS_CREATE_CALLER_CONTEXT_N; 134#endif 135 136 p_created_context = (rpc_ss_caller_context_element_t *) 137 malloc(sizeof(rpc_ss_caller_context_element_t)); 138 if (p_created_context == NULL) 139 { 140 141#ifdef PERFMON 142 RPC_SS_CREATE_CALLER_CONTEXT_X; 143#endif 144 145 DCETHREAD_RAISE( rpc_x_no_memory ); 146 return; 147 } 148 149 p_created_context->context_on_wire.context_handle_attributes 150 = p_wire_context->context_handle_attributes; 151 memcpy( 152 (char *)&p_created_context->context_on_wire.context_handle_uuid, 153 (char *)&p_wire_context->context_handle_uuid, 154 sizeof(idl_uuid_t)); 155 156 rpc_binding_copy(caller_handle, &p_created_context->using_handle, p_st); 157 if (*p_st != error_status_ok) return; 158 *p_caller_context = (rpc_ss_context_t)p_created_context; 159 rpc_network_maintain_liveness(p_created_context->using_handle, p_st); 160#ifdef PERFMON 161 RPC_SS_CREATE_CALLER_CONTEXT_X; 162#endif 163 164} 165 166/******************************************************************************/ 167/* */ 168/* Convert wire form of context handle to local form and update the stub's */ 169/* internal tables */ 170/* */ 171/******************************************************************************/ 172void rpc_ss_er_ctx_from_wire 173( 174 ndr_context_handle *p_wire_context, 175 rpc_ss_context_t *p_caller_context, /* Pointer to application context */ 176 handle_t caller_handle, /* Binding handle */ 177 ndr_boolean in_out, /* TRUE for [in,out], FALSE for [out] */ 178 volatile error_status_t *p_st 179) 180{ 181#ifdef DEBUGCTX 182 debug_context_uuid(&p_wire_context->context_handle_uuid, "N"); 183#endif 184 185#ifdef PERFMON 186 RPC_SS_ER_CTX_FROM_WIRE_N; 187#endif 188 189 if (in_out) { 190 if ( 191 uuid_is_nil( 192 &p_wire_context->context_handle_uuid, (error_status_t *)p_st 193 ) 194 ) { 195 /* Context is now NIL */ 196 if (*p_caller_context != NULL) { 197 /* If it wasn't NIL previously, stop monitoring it */ 198 rpc_network_stop_maintaining( 199 caller_handle, (error_status_t *)p_st 200 ); 201 rpc_binding_free( 202 &((rpc_ss_caller_context_element_t *)*p_caller_context) 203 ->using_handle, (error_status_t *)p_st 204 ); 205 /* Now release it */ 206 free((byte_p_t)*p_caller_context); 207 *p_caller_context = NULL; 208 209#ifdef PERFMON 210 RPC_SS_ER_CTX_FROM_WIRE_X; 211#endif 212 213 return; 214 } 215 } 216 else { /* Returned context is not NIL */ 217 if (*p_caller_context != NULL) { 218 /* And it wasn't NIL before the call */ 219 if ( 220 ! uuid_equal( 221 &p_wire_context->context_handle_uuid, 222 &((rpc_ss_caller_context_element_t *)*p_caller_context) 223 ->context_on_wire.context_handle_uuid, 224 (error_status_t *)p_st 225 ) 226 ) 227 DCETHREAD_RAISE( rpc_x_ss_context_damaged ); 228 } 229 else { 230 /* This is a new context */ 231 rpc_ss_create_caller_context( 232 p_wire_context, caller_handle, 233 p_caller_context, (error_status_t *)p_st 234 ); 235 } 236 } 237 } 238 else { /* Handling an OUT parameter */ 239 if ( 240 uuid_is_nil( 241 &p_wire_context->context_handle_uuid, (error_status_t *)p_st 242 ) 243 ) 244 *p_caller_context = NULL; /* A NIL context was returned */ 245 else 246 rpc_ss_create_caller_context( 247 p_wire_context, caller_handle, 248 p_caller_context, (error_status_t *)p_st 249 ); 250 } 251/* 252 closedown: 253*/ 254#ifdef PERFMON 255 RPC_SS_ER_CTX_FROM_WIRE_X; 256#endif 257 258 return; 259} 260 261/******************************************************************************/ 262/* */ 263/* This routine converts a caller's context handle to wire format */ 264/* This routine is only called for an IN or IN OUT context_t parameter */ 265/* */ 266/******************************************************************************/ 267void rpc_ss_er_ctx_to_wire 268( 269 rpc_ss_context_t caller_context, /* The context handle the caller is using */ 270 ndr_context_handle *p_wire_context, /* Where to put data to be marshalled */ 271 handle_t assoc_handle ATTRIBUTE_UNUSED, /* Handle on which the call will be made */ 272 ndr_boolean in_out, /* TRUE for [in,out] param, FALSE for [in] */ 273 volatile error_status_t *p_st 274) 275{ 276 277#ifdef PERFMON 278 RPC_SS_ER_CTX_TO_WIRE_N; 279#endif 280 281 *p_st = error_status_ok; 282 if (caller_context != NULL) 283 { 284 memcpy( 285 (char *)p_wire_context, 286 (char *) 287 &((rpc_ss_caller_context_element_t *)caller_context)->context_on_wire, 288 sizeof(ndr_context_handle) ); 289 } 290 else 291 { 292 if ( in_out ) 293 { 294 /* No active context. Send callee a NIL UUID */ 295 p_wire_context->context_handle_attributes = 0; 296 uuid_create_nil(&p_wire_context->context_handle_uuid,(unsigned32*)p_st); 297 } 298 else 299 { 300 DCETHREAD_RAISE( rpc_x_ss_in_null_context ); 301 } 302 } 303 304#ifdef DEBUGCTX 305 debug_context_uuid(&p_wire_context->context_handle_uuid, "L"); 306#endif 307 308#ifdef PERFMON 309 RPC_SS_ER_CTX_TO_WIRE_X; 310#endif 311 312} 313 314#ifdef DEBUGCTX 315static ndr_boolean debug_file_open = ndr_false; 316static char *debug_file = "ctxer.dmp"; 317static FILE *debug_fid; 318 319static int debug_context_uuid(uuid_p, prefix) 320 unsigned char *uuid_p; 321 char *prefix; 322{ 323 int j; 324 unsigned long k; 325 326 if (!debug_file_open) 327 { 328 debug_fid = fopen(debug_file, "w"); 329 debug_file_open = ndr_true; 330 } 331 332 fprintf(debug_fid, prefix); 333 for (j=0; j<sizeof(idl_uuid_t); j++) 334 { 335 k = *uuid_p++; 336 fprintf(debug_fid, " %02x", k); 337 } 338 fprintf(debug_fid, "\n"); 339} 340#endif 341 342/******************************************************************************/ 343/* */ 344/* Function to be called by user to release unusable context_handle */ 345/* */ 346/******************************************************************************/ 347void rpc_ss_destroy_client_context 348( 349 rpc_ss_context_t *p_unusable_context_handle 350) 351{ 352 353#ifdef PERFMON 354 RPC_SS_DESTROY_CLIENT_CONTEXT_N; 355#endif 356 357 free( *p_unusable_context_handle ); 358 *p_unusable_context_handle = NULL; 359 360#ifdef PERFMON 361 RPC_SS_DESTROY_CLIENT_CONTEXT_X; 362#endif 363 364} 365