예제 #1
0
파일: dgslive.c 프로젝트: Brainiarc7/pbis
INTERNAL rpc_dg_client_rep_p_t find_client
(
    dce_uuid_p_t cas_uuid
)
{
    rpc_dg_client_rep_p_t client;
    unsigned16 probe;
    unsigned32 st;
                        
    probe = CLIENT_HASH_PROBE(cas_uuid, &st);
    client = client_table[probe];

    while (client != NULL) 
    {
        if (dce_uuid_equal(cas_uuid, &client->cas_uuid, &st))
            return(client);
        client = client->next;
    }
    return(NULL);
}
예제 #2
0
파일: ctxeectx.c 프로젝트: Brainiarc7/pbis
void rpc_ss_update_callee_context
(
    rpc_ss_context_t    callee_context, /* The user's local form of the context */
    dce_uuid_t              *p_uuid,        /* Pointer to the equivalent UUID */
    error_status_t      *result         /* Function result */
)
{
    callee_context_entry_t *this_link;

#ifdef PERFMON
    RPC_SS_UPDATE_CALLEE_CONTEXT_N;
#endif

    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    this_link = &context_table[dce_uuid_hash(p_uuid,result)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    while ( ! dce_uuid_equal(p_uuid,&this_link->uuid,result) )
    {
        this_link = this_link->next_context;
        if (this_link == NULL)
        {
            RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
            DPRINT(("Released context tables\n"));
            DCETHREAD_RAISE( rpc_x_ss_context_mismatch);
        }
    }
    this_link->user_context = callee_context;
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));
    *result = error_status_ok;

#ifdef PERFMON
    RPC_SS_UPDATE_CALLEE_CONTEXT_X;
#endif

}
예제 #3
0
/*
 * R P C _ _ S E R V E R _ F W D _ R E S O L V E _ D E A L Y E D
 *
 * Remove specified packet from the list of delayed packets
 * and do what we are told with it
 */
PRIVATE void rpc__server_fwd_resolve_delayed(
    dce_uuid_p_t             actuuid,
    rpc_addr_p_t	fwd_addr,
    rpc_fwd_action_t	*fwd_action,
    unsigned32		*status)

{
    rpc_dg_sock_pool_elt_p_t 	sp;
    rpc_dg_recvq_elt_p_t 	rqe = (rpc_dg_recvq_elt_p_t)-1;
    rpc_dg_pkt_hdr_p_t  	hdrp;
    pkt_list_element_t          *ep, *last_ep = NULL;
    unsigned32 			st;

    /* get the requsted packet from the list */
    *status = rpc_s_not_found;

    RPC_MUTEX_LOCK(fwd_list_mutex);

    ep = delayed_pkt_head;
    while (ep != NULL)
    {
        hdrp = ep->rqe->hdrp;
        if (dce_uuid_equal(&(hdrp->actuid), actuuid, &st) && (st == rpc_s_ok))
        {
            /* found - remove it from the list */
            rqe = ep->rqe;
            sp = ep->sp;
            if (last_ep == NULL)
            {
                delayed_pkt_head  = ep->next;
            }
            else
            {
                last_ep->next  = ep->next;
            }
            RPC_MEM_FREE(ep, RPC_C_MEM_UTIL);
            *status = rpc_s_ok;
            break;
        }
        last_ep = ep;
        ep = ep->next;
    }
    RPC_MUTEX_UNLOCK(fwd_list_mutex);

    if (*status != rpc_s_ok)
    {
        return;
    }

    /*
     * Do what we're told to do with this packet.
     */
    switch (*fwd_action)
    {
        case rpc_e_fwd_drop:
            RPC_DBG_PRINTF(rpc_e_dbg_general, 10,
               ("(rpc__server_fwd_resolve_delayed) dropping (ptype=%s) [%s]\n",
                rpc__dg_pkt_name(RPC_DG_HDR_INQ_PTYPE(rqe->hdrp)),
                rpc__dg_act_seq_string(rqe->hdrp)));
            break;

        case rpc_e_fwd_reject:
            fwd_reject(sp, rqe);
            break;

        case rpc_e_fwd_forward:
            fwd_forward(sp, rqe, fwd_addr);
            break;

        default:
            *status = rpc_s_not_supported;
            break;
    }
    rpc__dg_network_sock_release(&sp);
	 if (rqe == (rpc_dg_recvq_elt_p_t)-1)	{
		 fprintf(stderr, "%s: bad rqe: aborting\n", __PRETTY_FUNCTION__);
		 abort();
	 }
    rpc__dg_pkt_free_rqe(rqe, NULL);
    return;
}
예제 #4
0
파일: ctxeectx.c 프로젝트: Brainiarc7/pbis
void rpc_ss_lkddest_callee_context
(
    dce_uuid_t *p_uuid,    /* Pointer to UUID of context to be destroyed */
    rpc_client_handle_t *p_close_client,
                                /* Ptr to NULL or client to stop monitoring */
    error_status_t *result /* Function result */
)    /* Returns error_status_ok unless the UUID is not in the lookup table */
{
    callee_context_entry_t *this_link, *next_link, *last_link;

#ifdef PERFMON
    RPC_SS_LKDDEST_CALLEE_CONTEXT_N;
#endif

    this_link = &context_table[dce_uuid_hash(p_uuid,(error_status_t *) result)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    next_link = this_link->next_context;
    if ( dce_uuid_equal(p_uuid,&this_link->uuid, (error_status_t *) result) )
    {
        /* Context to be destroyed is in home slot */
        rpc_ss_take_from_callee_client(this_link,p_close_client,result);
        if (next_link == NULL)
        {
            /* There is no chain from the home slot */
            dce_uuid_create_nil(&this_link->uuid, (error_status_t *) result);
        }
        else
        {
            /* Move the second item in the chain to the home slot */
            memcpy(
                (char *)&this_link->uuid,
                (char *)&next_link->uuid,
                sizeof(dce_uuid_t)
            );
            this_link->user_context = next_link->user_context;
            this_link->rundown = next_link->rundown;
            this_link->p_client_entry = next_link->p_client_entry;
            this_link->prev_in_client = next_link->prev_in_client;
            if (this_link->prev_in_client == NULL)
            {
                (this_link->p_client_entry)->first_context = this_link;
            }
            else
            {
                (this_link->prev_in_client)->next_in_client = this_link;
            }
            this_link->next_in_client = next_link->next_in_client;
            if (this_link->next_in_client == NULL)
            {
                (this_link->p_client_entry)->last_context = this_link;
            }
            else
            {
                (this_link->next_in_client)->prev_in_client = this_link;
            }
            this_link->next_context = next_link->next_context;
            /* And release the memory it was in */
            free((char_p_t)next_link);
        }

#ifdef PERFMON
        RPC_SS_LKDDEST_CALLEE_CONTEXT_X;
#endif

        return;
    }
    else    /* Context is further down chain */
    {
        while (next_link != NULL)
        {
            last_link = this_link;
            this_link = next_link;
            next_link = this_link->next_context;
            if ( dce_uuid_equal(p_uuid,&this_link->uuid,(error_status_t *)result) )
            {
                rpc_ss_take_from_callee_client(this_link,p_close_client,result);
                /* Relink chain to omit found entry */
                last_link->next_context = next_link;
                /* And free the memory it occupied */
                free((char_p_t)this_link);

#ifdef PERFMON
                RPC_SS_LKDDEST_CALLEE_CONTEXT_X;
#endif

                return;
            }
        }
        RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
        DPRINT(("Released context tables\n"));
        DCETHREAD_RAISE( rpc_x_ss_context_mismatch);
    }
}
예제 #5
0
파일: ctxeectx.c 프로젝트: Brainiarc7/pbis
void rpc_ss_ee_ctx_from_wire
(
    ndr_context_handle      *p_wire_context,
    rpc_ss_context_t        *p_context,         /* The application context */
    volatile error_status_t *p_st
)
{
    dce_uuid_t *p_uuid;    /* Pointer to the UUID that has come off the wire */
    callee_context_entry_t *this_link;

#ifdef PERFMON
    RPC_SS_EE_CTX_FROM_WIRE_N;
#endif

    p_uuid = &p_wire_context->context_handle_uuid;

#ifdef DEBUGCTX
    debug_context_lookup(p_uuid);
    debug_context_table();
#endif

    *p_st = error_status_ok;
    if ( dce_uuid_is_nil(p_uuid, (error_status_t *)p_st) )
    {
        *p_context = NULL;

#ifdef PERFMON
        RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

        return;
    }
    RPC_SS_THREADS_MUTEX_LOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Seized context tables\n"));
    this_link = &context_table[dce_uuid_hash(p_uuid, (error_status_t *)p_st)
                                               % CALLEE_CONTEXT_TABLE_SIZE];
    while ( ! dce_uuid_equal(p_uuid,&this_link->uuid, (error_status_t *)p_st) )
    {
        this_link = this_link->next_context;
        if (this_link == NULL)
        {
            RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
            DPRINT(("Released context tables\n"));

#ifdef PERFMON
            RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

            DCETHREAD_RAISE( rpc_x_ss_context_mismatch );
            return;
        }
    }
    *p_context = this_link->user_context;
    RPC_SS_THREADS_MUTEX_UNLOCK(&rpc_ss_context_table_mutex);
    DPRINT(("Released context tables\n"));

#ifdef PERFMON
    RPC_SS_EE_CTX_FROM_WIRE_X;
#endif

    return;
}
예제 #6
0
PRIVATE boolean rpc__tower_ref_is_compatible 
(
    rpc_if_rep_p_t          if_spec,
    rpc_tower_ref_p_t       tower_ref,
    unsigned32              *status
)
{
    boolean                 match;
    unsigned32              if_spec_syntax_count,
                            tower_vers_major,
                            tower_vers_minor,
                            version_major,
                            version_minor;
    rpc_if_id_t             if_id,
                            tower_if_id;
    rpc_syntax_id_t         *if_syntax_id,
                            tower_syntax_id;
    rpc_protseq_id_t        tower_protseq_id;
    rpc_protocol_id_t       tower_prot_id;
    unsigned8               temp_id;


    CODING_ERROR (status);


    /*
     * Obtain the protocol sequence from this tower.
     */
    rpc__tower_ref_inq_protseq_id (tower_ref, &tower_protseq_id, status);
    if (*status != rpc_s_ok)
    {
        *status = rpc_s_ok;	/* ignore towers we don't understand */
        return (false);
    }

    /*
     * Ensure the protocol sequence from the tower 
     * is supported by this client.  
     */
    if (!(RPC_PROTSEQ_INQ_SUPPORTED (tower_protseq_id)))
    {
        /*
         * Invalid protocol sequence, return status from call.
         */
        return (false);
    }

    /*
     * We have a valid protocol sequence.
     * Check the interface for compatibility if one is specified.
     */
    if (if_spec != NULL)
    {

        /*
         * Get the interface identifier.
         */
        rpc_if_inq_id ((rpc_if_handle_t) if_spec, &if_id, status);
        if (*status != rpc_s_ok)
        {
            return (false);
        }
        
        /*
         * Get the interface identifier from the tower
         */
        rpc__tower_flr_to_if_id (tower_ref->floor[0], &tower_if_id, status);
        if (*status != rpc_s_ok)
        {
            return (false);
        }

        /*
         * Compare the client's interface identifier to the
         * tower's interface id.  (Checks both the uuid and version.)
         */
        if (!(rpc__if_id_compare 
            (&if_id, &tower_if_id, rpc_c_vers_compatible, status)))
        {
            return (false);
        }

        /* 
         * See if any of the if_spec transfer syntaxes matches 
         * the tower transfer syntaxes. 
         *
         * Note an interface transfer syntax count of 0 is an internal error.
         */
         
         /*
          * Obtain the tower transfer syntax.
          */
        rpc__tower_flr_to_drep (tower_ref->floor[1], &tower_syntax_id, status);
        if (*status != rpc_s_ok)
        {
            return (false);
        }

        for (if_spec_syntax_count = 0, 
             match = false,
             if_syntax_id = if_spec->syntax_vector.syntax_id;
             ((match == false) && 
              (if_spec_syntax_count < if_spec->syntax_vector.count ));
             if_spec_syntax_count++,
             if_syntax_id++ )
        {
            /*
             * Check if a syntax id and version match.
             */
            match = dce_uuid_equal
                    (&(tower_syntax_id.id), &(if_syntax_id->id), status);

            if ((match == true) &&
                (tower_syntax_id.version != if_syntax_id->version))
            {
                match = false;
            }
        }

        /* 
         * if no match occurred, binding is not compatible - return false
         */
        if (match == false) 
        {
            *status = rpc_s_ok;
            return (false);
        }
    }

    /*
     * Obtain the RPC protocol id and version numbers of the tower.
     */
    rpc__tower_flr_to_rpc_prot_id (tower_ref->floor[2], &tower_prot_id,
        &tower_vers_major, &tower_vers_minor, status);
    if (*status != rpc_s_ok)
    {
        return (false);
    }

    /*
     * Obtain the clients' version numbers for the protocol sequence
     * specified in the tower.
     */
    rpc__network_inq_prot_version (
        tower_protseq_id, &temp_id, &version_major, 
        &version_minor, status);
    if (*status != rpc_s_ok)
    {
        return (false);
    }

    /*
     * Compare protocol versions, they are only 1 byte each.
     */
    if ((unsigned8) version_major != (unsigned8) tower_vers_major)
       /*
        * We don't do this so we can rev the minor protocol version.
        *  || ((unsigned8) version_minor >  (unsigned8) tower_vers_minor)
        */
    {
        return (false);
    }

    /*
     * Tower is compatible with the client's.
     */
    return (true);
}
예제 #7
0
PRIVATE void rpc__tower_ref_inq_protseq_id 
(
    rpc_tower_ref_p_t   tower_ref,
    rpc_protseq_id_t    *protseq_id,
    unsigned32          *status
)
{
    boolean             match;
    rpc_flr_prot_id_t   *tower_prot_ids,
                        master_prot_ids[RPC_C_MAX_NUM_NETWORK_FLOORS + 1];
    byte_p_t            tp;
    unsigned32          floors_to_search,
                        start_floor,
                        i, j, k;            
    rpc_protocol_id_t   rpc_protocol_id;
    unsigned32          version_major;
    unsigned32          version_minor;

    CODING_ERROR (status);

    /*  
     * Initialize return protseq in case of failure.
     */
    *protseq_id = RPC_C_INVALID_PROTSEQ_ID;

    /*
     * Let's find out if this is a tower without floors 1 & 2 (CDS
     * has been known to use towers like this). So long as the tower
     * contains an RPC protocol (floor 3) and recognized addressing
     * floors, we'll try to figure out its protseq id.
     */

    /*
     * Check to see if this is a full tower.
     */
    if (tower_ref->count >= RPC_C_FULL_TOWER_MIN_FLR_COUNT)
    {
        /*
         * Calculate the number of floors we are searching.
         * This is the number of lower tower floors plus one for floor 3.
         */
        floors_to_search = (tower_ref->count - RPC_C_NUM_RPC_FLOORS)+ 1;

        /*
         * For a full rpc tower, identifying the protseq begins at the
         * rpc protocol id floor.
         */
        start_floor = RPC_C_NUM_RPC_FLOORS - 1;
    }
    else
    {
        /*
         * Check to see if this is a minimal tower.
         */
        if (tower_ref->count >= RPC_C_MIN_TOWER_MIN_FLR_COUNT)
        {
            /*
             * We might have a minimal rpc tower. Let's make sure the 1st floor
             * in the tower contains a valid rpc protocol.
             */
            rpc__tower_flr_to_rpc_prot_id (tower_ref->floor[0],
                &rpc_protocol_id, &version_major, &version_minor, status);

            /*
             * If the floor contains a valid rpc protocol id, we have a minimal
             * rpc tower and need to process all of the floors.
             */
            if (*status == rpc_s_ok)
            {
                floors_to_search = tower_ref->count;
                start_floor = 0;
            }
            else
            {
                /*
                 * We don't have even a minimal rpc tower.
                 */
                *status = rpc_s_not_rpc_tower;
                return;
            }
        }
        else
        {
            *status = rpc_s_not_rpc_tower;
            return;
        }
    }

    /*
     * Allocate the array to hold the tower's protocol ids.
     * This is one element for each of the lower tower floors plus
     * an element for the the RPC protocol id floor (in a minimal tower 
     * floor 1; in a full tower floor 3).
     */
    RPC_MEM_ALLOC (
        tower_prot_ids, 
        rpc_flr_prot_id_p_t, 
        floors_to_search * sizeof (rpc_flr_prot_id_t),
        RPC_C_MEM_TOWER_PROT_IDS,
        RPC_C_MEM_WAITOK);

    /*
     * Copy the tower floors' protocol id, starting at the
     * RPC protocol id, into the tower_prot_ids array.
     */
    for (i= 0, j= start_floor; i < floors_to_search; i++)
    {
        
        /*
         * Copy the floor's protocol id prefix.
         */
        memcpy ((char *) &(tower_prot_ids[i].prefix),
                (char *) RPC_PROT_ID_START(tower_ref->floor[i+j]),
                RPC_C_TOWER_PROT_ID_SIZE);
        /*
         * If the floor's protocol id also has an uuid,
         * copy it.
         */
        if (tower_ref->floor[i+j]->prot_id_count > RPC_C_TOWER_PROT_ID_SIZE)
        { 
            tp = (byte_p_t) RPC_PROT_ID_START(tower_ref->floor[i+j]);

            memcpy ((char *) &(tower_prot_ids[i].uuid),
                    (char *) (tp + RPC_C_TOWER_PROT_ID_SIZE),
                    RPC_C_TOWER_UUID_SIZE);

            RPC_RESOLVE_ENDIAN_UUID (tower_prot_ids[i].uuid);
        }
        else
        {
            tower_prot_ids[i].uuid = uuid_g_nil_uuid;
        }
    }

    /*
     * For each protocol sequence supported by RPC,
     * see if the tower protocol ids match.
     *
     * Note, we use RPC_C_PROTSEQ_ID_MAX+1 since 
     * there are two entries in our table for 
     * RPC_C_PROTSEQ_ID_NCACN_OSI_DNA - one for nsp 
     * and the other for tp4.
     */
    for (i = 0; i < rpc_g_tower_prot_id_number; i++)
    {
        /*
         * If the number of floors to process does not
         * match the number of floors for this protocol
         * sequence, skip it.
         */
        if (floors_to_search != rpc_g_tower_prot_ids[i].num_floors)
        {
            continue;
        }

        /*
         * Copy the protocol id for the current
         * protocol sequence being matched into
         * a local array.  Do this for the number
         * of floors in this protocol sequence.
         */
        for (k = 0; k < rpc_g_tower_prot_ids[i].num_floors; k++)
        {
            master_prot_ids[k].prefix = 
                rpc_g_tower_prot_ids[i].floor_prot_ids[k].prefix;

            master_prot_ids[k].uuid = 
                rpc_g_tower_prot_ids[i].floor_prot_ids[k].uuid;
        }

        /*
         * For each protocol id in the master array,
         * see if a match is found with the tower floors' protocol ids.
         * We only compare to the number of significant floors.
         */

        /*
         * Assume success. This way we can check the status
         * of dce_uuid_equal when it is called.
         */
        *status = rpc_s_ok;

        for (k = 0; k < rpc_g_tower_prot_ids[i].num_floors; k++)
        {
            for (j = 0; j < floors_to_search; j++)
            {
                if ((master_prot_ids[k].prefix == tower_prot_ids[j].prefix) &&
                    (dce_uuid_equal (&(master_prot_ids[k].uuid),
                     &(tower_prot_ids[j].uuid), status)))
                {
                    master_prot_ids[k].prefix = 0;
                    break;
                }
                
                /*
                 * Check status from dce_uuid_equal.
                 * Return if failure.
                 */
                if (*status != rpc_s_ok)
                {
                    goto CLEANUP;
                }
            }
        }

        /*
         * See if a match was found
         */
        for (k = 0, match = true; k < rpc_g_tower_prot_ids[i].num_floors; k++)
        {
            if (master_prot_ids[k].prefix != 0)
            {
                match = false;
                break;
            }
        }

        if (match)
        {
            *protseq_id = rpc_g_tower_prot_ids[i].rpc_protseq_id;

            /*
             * Status is already set above.
             */
            goto CLEANUP;
        }

    }

    /*
     * If we get here, then we couldn't find a match and must
     * assume that the tower does not belong to RPC.
     */
    *status = rpc_s_not_rpc_tower;

CLEANUP:
    /*
     * Free the allocated array of the tower floors
     * protocol identifier.
     */
    RPC_MEM_FREE (tower_prot_ids, RPC_C_MEM_TOWER_PROT_IDS);

    /*
     * Return with the protocol id sequence and status.
     */
    return;

}