PRIVATE void rpc__tower_ref_copy ( rpc_tower_ref_p_t source_tower, rpc_tower_ref_p_t *dest_tower, unsigned32 *status ) { unsigned32 i, tower_ref_size; CODING_ERROR (status); tower_ref_size = sizeof (rpc_tower_ref_t) + (sizeof (rpc_tower_floor_p_t) * ((source_tower->count)-1)); /* * Allocate the destination tower structure and * copy the source tower into it. */ RPC_MEM_ALLOC ( *dest_tower, rpc_tower_ref_p_t, tower_ref_size, RPC_C_MEM_TOWER_REF, RPC_C_MEM_WAITOK); /* * Copy the floor count to the destination tower ref. */ (*dest_tower)->count = source_tower->count; /* * For each floor in the source tower ref, allocate a new floor * for the destination tower ref and copy the floor contents. * Set the destination free flag to false since the * floors' tower octet string will be freed when freeing * the source_tower. */ for (i=0; i < source_tower->count; i++) { RPC_MEM_ALLOC ( (*dest_tower)->floor[i], rpc_tower_floor_p_t, sizeof (rpc_tower_floor_t), RPC_C_MEM_TOWER_FLOOR, RPC_C_MEM_WAITOK); memcpy ((*dest_tower)->floor[i], source_tower->floor[i], sizeof (rpc_tower_floor_t)); (*dest_tower)->floor[i]->free_twr_octet_flag = false; } *status = rpc_s_ok; return; }
void rpc_ns_binding_lookup_next ( rpc_ns_handle_t lookup_context, rpc_binding_vector_p_t *binding_vector, unsigned32 *status ) { rpc_ns_handle_rep_t *rep = (rpc_ns_handle_rep_t *) lookup_context; if (rep->cursor == 0) { unsigned32 size, i; size = sizeof(rpc_binding_vector_t); size += (rep->count - 1) * sizeof(rpc_binding_handle_t); RPC_MEM_ALLOC(*binding_vector, rpc_binding_vector_p_t, size, RPC_C_MEM_BINDING_VEC, RPC_C_MEM_WAITOK); for (i = 0; i < rep->count; i++) { rpc_binding_from_string_binding(rep->bindings[i], &((*binding_vector)->binding_h[i]), status); } } else { *status = rpc_s_no_more_bindings; } }
INTERNAL void addr_inq_netaddr ( rpc_addr_p_t rpc_addr, unsigned_char_t **p_netaddr, unsigned32 *status ) { rpc_http_addr_p_t http_addr = (rpc_http_addr_p_t) rpc_addr; unsigned_char_p_t netaddr; size_t addr_length = 0; CODING_ERROR (status); addr_length = strlen(http_addr->server); RPC_MEM_ALLOC( *p_netaddr, unsigned_char_p_t, addr_length + 1, RPC_C_MEM_STRING, RPC_C_MEM_WAITOK); if (*p_netaddr == NULL) { *status = rpc_s_no_memory; return; } netaddr = *p_netaddr; memcpy(netaddr, http_addr->server, addr_length); netaddr[addr_length] = 0; *status = rpc_s_ok; }
PRIVATE void rpc__dg_plog_pkt ( rpc_dg_raw_pkt_hdr_p_t hdrp, rpc_dg_pkt_body_p_t bodyp, boolean32 recv, unsigned32 lossy_action /* (0)drop, (1)?, (2)rexmit, (3)normal */ ) { pktlog_elt_p_t pp; if (rpc_g_dg_pkt_log == NULL) { rpc_g_dg_pkt_log_bytes = RPC_C_DG_PKT_LOG_SIZE * sizeof(pktlog_elt_t); #ifdef STATIC_DG_PKTLOG rpc_g_dg_pkt_log = _pkt_log; #else RPC_MEM_ALLOC(rpc_g_dg_pkt_log, pktlog_elt_p_t, rpc_g_dg_pkt_log_bytes, RPC_C_MEM_DG_PKTLOG, RPC_C_MEM_NOWAIT); if (rpc_g_dg_pkt_log == NULL) return; /* b_z_e_r_o_(rpc_g_dg_pkt_log, rpc_g_dg_pkt_log_bytes);*/ memset(rpc_g_dg_pkt_log, 0, rpc_g_dg_pkt_log_bytes); #endif } pp = &rpc_g_dg_pkt_log[pkt_log_index]; pkt_log_index = (pkt_log_index + 1) % RPC_C_DG_PKT_LOG_SIZE; pp->timestamp = rpc__clock_stamp(); pp->lossy_action = lossy_action; /*b_c_o_p_y_(hdrp, &pp->hdr, sizeof(rpc_dg_raw_pkt_hdr_t));*/ memmove( &pp->hdr, hdrp, sizeof(rpc_dg_raw_pkt_hdr_t)); #ifndef MISPACKED_HDR /* b_c_o_p_y_ (bodyp, ((char *) pp->body), MIN(MAX_LOGGED_PKT_BODY_LEN, ((rpc_dg_pkt_hdr_p_t) hdrp)->len));*/ memmove( pp->body, bodyp, MIN(MAX_LOGGED_PKT_BODY_LEN, ((rpc_dg_pkt_hdr_p_t) hdrp)->len)) ; #else /* b_c_o_p_y(bodyp, ((char *) pp->body), MIN(MAX_LOGGED_PKT_BODY_LEN, ...extracted from raw hdr... hdrp->len));*/ memmove( pp->body, bodyp, MIN(MAX_LOGGED_PKT_BODY_LEN, ...extracted from raw hdr... hdrp->len)); #endif if (recv) #ifndef MISPACKED_HDR ((rpc_dg_pkt_hdr_p_t)(&pp->hdr))->_rpc_vers |= 0x80; #else set bit in raw hdr #endif }
INTERNAL void addr_alloc ( rpc_protseq_id_t rpc_protseq_id, rpc_naf_id_t naf_id, unsigned_char_p_t endpoint, unsigned_char_p_t netaddr, unsigned_char_p_t network_options ATTRIBUTE_UNUSED, rpc_addr_p_t *rpc_addr, unsigned32 *status ) { CODING_ERROR (status); /* * allocate memory for the new RPC address */ RPC_MEM_ALLOC ( *rpc_addr, rpc_addr_p_t, sizeof (rpc_http_addr_t), RPC_C_MEM_RPC_ADDR, RPC_C_MEM_WAITOK); if (*rpc_addr == NULL) { *status = rpc_s_no_memory; return; } /* * zero allocated memory */ memset( *rpc_addr, 0, sizeof (rpc_http_addr_t)); /* * insert id, length, family into rpc address */ (*rpc_addr)->rpc_protseq_id = rpc_protseq_id; (*rpc_addr)->len = sizeof (struct sockaddr); (*rpc_addr)->sa.family = naf_id; /* * set the endpoint in the RPC addr */ addr_set_endpoint (endpoint, rpc_addr, status); if (*status != rpc_s_ok) return; /* * set the network address in the RPC addr */ addr_set_netaddr (netaddr, rpc_addr, status); if (*status != rpc_s_ok) return; *status = rpc_s_ok; }
PRIVATE rpc_binding_rep_p_t rpc__dg_binding_alloc ( boolean32 is_server, unsigned32 *st ) { rpc_binding_rep_p_t h; *st = rpc_s_ok; if (is_server) { RPC_MEM_ALLOC(h, rpc_binding_rep_p_t, sizeof(rpc_dg_binding_server_t), RPC_C_MEM_DG_SHAND, RPC_C_MEM_NOWAIT); } else { RPC_MEM_ALLOC(h, rpc_binding_rep_p_t, sizeof(rpc_dg_binding_client_t), RPC_C_MEM_DG_CHAND, RPC_C_MEM_NOWAIT); } return(h); }
INTERNAL void addr_inq_endpoint ( rpc_addr_p_t rpc_addr, unsigned_char_t **endpoint, unsigned32 *status ) { rpc_http_addr_p_t http_addr = (rpc_http_addr_p_t) rpc_addr; static const unsigned int max_endpoint_len = 6; CODING_ERROR (status); if (http_addr->endpoint == 0) { RPC_MEM_ALLOC( *endpoint, unsigned_char_p_t, sizeof(unsigned32), /* can't stand to get just 1 byte */ RPC_C_MEM_STRING, RPC_C_MEM_WAITOK); (*endpoint)[0] = 0; } else { RPC_MEM_ALLOC( *endpoint, unsigned_char_p_t, max_endpoint_len, RPC_C_MEM_STRING, RPC_C_MEM_WAITOK); snprintf((char*) *endpoint, max_endpoint_len, "%u", http_addr->endpoint); } *status = rpc_s_ok; }
INTERNAL void addr_copy ( rpc_addr_p_t src_rpc_addr, rpc_addr_p_t *dst_rpc_addr, unsigned32 *status ) { CODING_ERROR (status); /* * if the source RPC address looks valid - IP family ok */ if (src_rpc_addr->sa.family == RPC_C_NAF_ID_HTTP) { /* * allocate memory for the new RPC address */ RPC_MEM_ALLOC ( *dst_rpc_addr, rpc_addr_p_t, sizeof (rpc_http_addr_t), RPC_C_MEM_RPC_ADDR, RPC_C_MEM_WAITOK); if (*dst_rpc_addr == NULL) { *status = rpc_s_no_memory; return; } /* * Copy source rpc address to destination rpc address */ /* b_c_o_p_y ((unsigned8 *) src_rpc_addr, (unsigned8 *) *dst_rpc_addr, sizeof (rpc_http_addr_t));*/ memmove( *dst_rpc_addr, src_rpc_addr, sizeof (rpc_http_addr_t)); *status = rpc_s_ok; return; } *status = rpc_s_invalid_naf_id; }
PRIVATE rpc_auth_info_p_t rpc__noauth_dg_create ( unsigned32 *stp ) { rpc_noauth_info_p_t noauth_info; RPC_MEM_ALLOC (noauth_info, rpc_noauth_info_p_t, sizeof (*noauth_info), RPC_C_MEM_UTIL, RPC_C_MEM_WAITOK); rpc_g_noauth_alloc_count++; RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, ("(rpc__noauth_dg_create) %x created (now %d active)\n", noauth_info, rpc_g_noauth_alloc_count - rpc_g_noauth_free_count)); memset (noauth_info, '\0', sizeof(*noauth_info)); RPC_MUTEX_INIT(noauth_info->lock); noauth_info->creds_valid = 0; noauth_info->level_valid = 0; noauth_info->client_valid = 0; /* * fill in the common auth_info stuff. */ noauth_info->auth_info.refcount = 1; noauth_info->auth_info.server_princ_name = 0; noauth_info->auth_info.authn_level = -1; noauth_info->auth_info.authn_protocol = rpc_c_authn_dce_dummy; noauth_info->auth_info.authz_protocol = rpc_c_authz_name; noauth_info->auth_info.is_server = 1; noauth_info->auth_info.u.s.privs = 0; { /* FAKE-EPAC */ noauth_info->auth_info.u.s.creds = 0; } /* XXX do other initialization here. */ *stp = 0; return (rpc_auth_info_p_t) noauth_info; }
/* * Create a new named server binding entry. */ static void rpc_ns__ldap_export_server_element(LDAP *ld, char *serverDN, rpc_if_handle_t if_spec, rpc_binding_vector_p_t vec, unsigned32 *status ) { unsigned_char_p_t dn = NULL, rdn = NULL; idl_uuid_t rdnUuid; /* Just create an arbitary UUID to name this entry. */ uuid_create(&rdnUuid, status); if (*status != rpc_s_ok) { goto out; } uuid_to_string(&rdnUuid, &rdn, status); if (*status != rpc_s_ok) { goto out; } RPC_MEM_ALLOC(dn, unsigned_char_p_t, strlen(serverDN) + strlen(rdn) + sizeof("CN=,"), RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(dn, "CN=%s,%s", rdn, serverDN); rpc_ns__ldap_export_server_element_ext(ld, dn, if_spec, vec, LDAP_MOD_ADD, status); out: if (dn != NULL) { RPC_MEM_FREE(dn, RPC_C_MEM_NSRESOLUTION); } if (rdn != NULL) { rpc_string_free(&rdn, status); } }
PRIVATE rpc_dg_scall_p_t rpc__dg_scall_alloc ( rpc_dg_sct_elt_p_t scte, rpc_dg_sock_pool_elt_p_t sp, rpc_dg_recvq_elt_p_t rqe ) { rpc_dg_scall_p_t scall; unsigned32 st ATTRIBUTE_UNUSED; static rpc_clock_t rpc_c_dg_scall_timer_freq_init = RPC_CLOCK_SEC(1); boolean maybe = RPC_DG_HDR_FLAG_IS_SET(rqe->hdrp, RPC_C_DG_PF_MAYBE); RPC_LOCK_ASSERT(0); RPC_MEM_ALLOC(scall, rpc_dg_scall_p_t, sizeof *scall, RPC_C_MEM_DG_SCALL, RPC_C_MEM_NOWAIT); /* * Initialize the common SCALL handle fields (and LOCK the SCALL) */ scall_init(scall, sp, rqe); /* * The rest is specific to normal (non-callback) SCALLs. */ scall->cbk_ccall = NULL; scall->c.actid_hash = rpc__dg_uuid_hash(&scte->actid); /* * Initialize the server specific call handle fields */ /* * Setup the SCTE / SCALL cross linkage. */ RPC_DG_SCT_REFERENCE(scte); scall->scte = scte; RPC_DG_CALL_REFERENCE(&scall->c); if (! maybe) scte->scall = scall; else { RPC_DBG_PRINTF(rpc_e_dbg_general, 3, ( "(rpc__dg_scall_alloc) putting call on maybe chain\n")); scall->c.next = (rpc_dg_call_p_t) scte->maybe_chain; scte->maybe_chain = scall; } /* * Initialize the fields of the common call handle header that * are really part of the prototype packet header. */ scall->c.call_actid = scte->actid; scall->c.call_ahint = scte->ahint; scall->c.is_cbk = false; /* * Copy over authentication/keying information. */ scall->c.auth_epv = scte->auth_epv; scall->c.key_info = scte->key_info; if (scall->c.key_info != NULL) RPC_DG_KEY_REFERENCE(scall->c.key_info); RPC_DG_CALL_SET_TIMER(&scall->c, rpc__dg_scall_timer, rpc_c_dg_scall_timer_freq_init); return(scall); }
PUBLIC void twr_dnet_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * make sure we have a pointer to some data structure */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, twr_c_tower_flr_count_size); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += twr_c_tower_flr_count_size; /* * Skip over the (application's) upper floors while we look for the * beginning of the dnet-specific lower floors. */ for (count = 0; count < floor_count; count++) { /* * Get the length of this floor's protocol id field (don't * advance the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), twr_c_tower_prot_id_size); /* * See if we support the protocol id. */ if ( (id_size == twr_c_tower_prot_id_size) && (id == TWR_C_FLR_PROT_ID_DNA) ) { /* * Indicate we found the beginning of the dnet floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's TWR_C_FLR_PROT_ID_DNA. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for a DECnet sockaddr */ length = sizeof(struct sockaddr_dn); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as a DECnet family socket */ ((struct sockaddr_dn *)(*sa))->sdn_family = RPC_C_NAF_ID_DNET; /* * Length of end user spec */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * End user spec */ memcpy (&((struct sockaddr_dn *)(*sa))->sdn_objnum, (char *)tower, addr_size); tower += addr_size; /* * Length of host transport */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Transport id * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); tower += id_size; if ((id_size != twr_c_tower_prot_id_size) || (id != TWR_C_FLR_PROT_ID_NSP)) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * Length of sdn_flags */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * this field is probably null */ if (addr_size) { memcpy ( &((struct sockaddr_dn *)(*sa))->sdn_flags, (char *)tower, addr_size); tower += addr_size; } /* * Length of routing id */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Protocol id * Expect one byte, so no need to convert. */ memcpy ((char *)&id, (char *)tower, twr_c_tower_prot_id_size); tower += id_size; if ( (id_size != twr_c_tower_prot_id_size) || (id != TWR_C_FLR_PROT_ID_ROUTING) ) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * the length of host address */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; memcpy (&((struct sockaddr_dn *)(*sa))->sdn_add, (char *)tower, addr_size); *status = twr_s_ok; }
PUBLIC void twr_dnet_lower_flrs_from_sa ( sockaddr_p_t sa, twr_p_t *lower_flrs, unsigned32 *status ) { unsigned8 protocol_id[TWR_C_NUM_DNA_LOWER_FLRS]; unsigned16 floor_count, id_size = twr_c_tower_prot_id_size, related_data_size[TWR_C_NUM_DNA_LOWER_FLRS], twr_rep_16; unsigned32 count, twr_t_length, *related_data_ptr[TWR_C_NUM_DNA_LOWER_FLRS]; byte_p_t tmp_tower; CODING_ERROR (status); RPC_VERIFY_INIT (); if (sa->family == RPC_C_NAF_ID_DNET) { protocol_id[0] = TWR_C_FLR_PROT_ID_DNA; protocol_id[1] = TWR_C_FLR_PROT_ID_NSP; protocol_id[2] = TWR_C_FLR_PROT_ID_ROUTING; /* * Since we now know the socket address we're dealing with, * collect the sizes of each field to allocate memory, and * remember the pointers to the fields so we can copy the * data once we have allocated the tower string. */ floor_count = TWR_C_NUM_DNA_LOWER_FLRS; related_data_size[0] = sizeof(((struct sockaddr_dn *)sa)->sdn_objnum) + sizeof(((struct sockaddr_dn *)sa)->sdn_objnamel) + ((struct sockaddr_dn *)sa)->sdn_objnamel; related_data_ptr[0] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_objnum); /* do we need to store flags ??? * related_data_size[1] = * sizeof(((struct sockaddr_dn *)sa)->sdn_flags); */ related_data_size[1] = 0; related_data_ptr[1] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_flags); related_data_size[2] = sizeof(((struct sockaddr_dn *)sa)->sdn_add.a_len) + ((struct sockaddr_dn *)sa)->sdn_add.a_len; related_data_ptr[2] = (unsigned32 *)(&((struct sockaddr_dn *)sa)->sdn_add); } else { *status = twr_s_unknown_sa; return; } /* * Allocate memory and copy the data into the proper * locations in each of up to three floors. */ /* * Calculate length of tower floor. */ twr_t_length = twr_c_tower_flr_count_size; /* to store floor count */ for ( count = 0; count < floor_count; count++ ) { twr_t_length += TWR_C_FLR_OVERHEAD; twr_t_length += related_data_size[count]; } /* * Next allocate space for the tower structure */ RPC_MEM_ALLOC ( *lower_flrs, twr_p_t, sizeof (twr_t) + (twr_t_length - 1), RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Copy the length of the tower octet string into the tower structure */ (*lower_flrs)->tower_length = twr_t_length; /* * Copy the floor information into the tower octet string */ /* * Use a temporary for the octet string since we need * to increment the pointer. */ tmp_tower = (*lower_flrs)->tower_octet_string; /* * Copy the number of floors into the tower octet string */ twr_rep_16 = floor_count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, twr_c_tower_flr_count_size); tmp_tower += twr_c_tower_flr_count_size; /* * Convert the protocol identifier size to its proper * representation for use in the following loop. */ RPC_RESOLVE_ENDIAN_INT16 (id_size); for (count = 0; count < floor_count; count++) { /* * Copy the length of the protocol identifier field into * tower octet string. (Converted before the loop.) */ memcpy ((char *)tmp_tower, (char *)&id_size, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Copy the protocol identifier into tower octet string * (1 byte so no need to convert endian representation). */ memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), twr_c_tower_prot_id_size); tmp_tower += twr_c_tower_prot_id_size; /* * Copy the length of the address data field into * tower octet string. */ twr_rep_16 = related_data_size[count]; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_RHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; /* * If there is addressing data, copy the address data field into * tower octet string */ if (related_data_size[count]) { memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], related_data_size[count] ); /* * Set up for the next floor. */ tmp_tower += related_data_size[count]; } } *status = twr_s_ok; }
PUBLIC void rpc_ns_import_ctx_add_eval ( rpc_ns_handle_t *import_ctx, unsigned32 func_type, void *args, void (*eval_func)(handle_t binding_h, void *args, void **cntx), void (*cs_free_func)(void *cntx), error_status_t *status ) { rpc_cs_eval_func_p_t eval_func_rep; rpc_cs_eval_list_p_t eval_list_p; rpc_import_rep_p_t import_p; rpc_lkup_rep_p_t lookup_p; unsigned_char_p_t client_codesets_file_p; rpc_codeset_mgmt_p_t client_codeset_p; CODING_ERROR (status); RPC_NS_VERIFY_INIT(); import_p = (rpc_import_rep_p_t)*import_ctx; lookup_p = (rpc_lkup_rep_p_t)import_p->lookup_context; if (lookup_p == NULL) { *status = rpc_s_invalid_ns_handle; return; } switch (func_type) { case RPC_EVAL_TYPE_CODESETS: case RPC_CUSTOM_EVAL_TYPE_CODESETS: /* * Check if import func context is already allocated */ if (lookup_p->eval_routines == NULL) /* no list exists yet */ { /* * Allocate the new import func context. */ RPC_MEM_ALLOC ( eval_func_rep, rpc_cs_eval_func_p_t, sizeof (rpc_cs_eval_func_t), RPC_C_MEM_FUNC, RPC_C_MEM_WAITOK); /* * Allocate a list */ RPC_MEM_ALLOC ( eval_list_p, rpc_cs_eval_list_p_t, sizeof (rpc_cs_eval_list_t), RPC_C_MEM_LIST, RPC_C_MEM_WAITOK); /* * set up the contents of the stack */ eval_list_p->type = func_type; eval_list_p->eval_func = eval_func; eval_list_p->cs_free_func = cs_free_func; eval_list_p->cntx = NULL; eval_list_p->next = NULL; /* Get client's supported code sets */ rpc_rgy_get_codesets ( &client_codeset_p, status ); if (*status != rpc_s_ok) { RPC_MEM_FREE (eval_func_rep, RPC_C_MEM_FUNC); RPC_MEM_FREE (eval_list_p, RPC_C_MEM_LIST); return; } eval_list_p->args = (void *)client_codeset_p; /* * set the list to import func context */ eval_func_rep->list = eval_list_p; eval_func_rep->num = 1; /* * set the list into import context */ lookup_p->eval_routines = (rpc_ns_handle_t)eval_func_rep; } else { /* * Allocate a list */ RPC_MEM_ALLOC ( eval_list_p, rpc_cs_eval_list_p_t, sizeof (rpc_cs_eval_list_t), RPC_C_MEM_LIST, RPC_C_MEM_WAITOK); /* * set up the contents of the stack */ eval_list_p->type = func_type; eval_list_p->eval_func = eval_func; eval_list_p->cs_free_func = cs_free_func; eval_list_p->cntx = NULL; eval_list_p->next = NULL; /* Get client's supported code sets */ rpc_rgy_get_codesets ( &client_codeset_p, status ); if (*status != rpc_s_ok) { RPC_MEM_FREE (eval_func_rep, RPC_C_MEM_FUNC); RPC_MEM_FREE (eval_list_p, RPC_C_MEM_LIST); return; } eval_list_p->args = (rpc_ns_handle_t *)client_codeset_p; /* * set the stack pointer to newly allocated stack */ eval_func_rep = (rpc_cs_eval_func_p_t)lookup_p->eval_routines; eval_func_rep->list->next = eval_list_p; eval_func_rep->num += 1; } *status = rpc_s_ok; return; default: ; } }
PUBLIC void twr_np_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; char *p; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * Make sure we have a pointer to some data structure. */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } RPC_DBG_GPRINTF(("(twr_np_lower_flrs_to_sa) called\n")); /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, TWR_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Skip over the (application's) upper floors while we look for the * beginning of the np-specific lower floors. */ for ( count = 0; count < floor_count; count++ ) { /* * Get the length of this floor's protocol id field (don't advance * the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), TWR_C_TOWER_PROT_ID_SIZE); /* * See if we support the protocol id. */ if ( (id_size == TWR_C_TOWER_PROT_ID_SIZE) && (id == TWR_C_FLR_PROT_ID_NP)) { /* * Indicate we found the beginning of the np floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's * TWR_C_FLR_PROT_ID_NP. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for sockaddr */ length = sizeof(struct sockaddr_un); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as an internet family socket */ ((struct sockaddr_un *)(*sa))->sun_family = RPC_C_NAF_ID_UXD; /* * Get the length of pipe name */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the pipe name to the sockaddr */ tower[addr_size - 1] = '\0'; addr_size += RPC_C_NP_DIR_LEN + 1; if ((size_t)addr_size + 1 > sizeof(((struct sockaddr_un *)(*sa))->sun_path)) { *status = rpc_s_no_memory; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } snprintf(((struct sockaddr_un *)(*sa))->sun_path, length, "%s/%s", RPC_C_NP_DIR, tower); for (p = ((struct sockaddr_un *)(*sa))->sun_path; *p != '\0'; p++) { if (*p == '\\') *p = '/'; } *status = twr_s_ok; /* For now, disregard the NetBIOS address. */ }
/* * Create or update an LDAP server binding entry. */ static void rpc_ns__ldap_export_server_element_ext(LDAP *ld, char *dn, rpc_if_handle_t if_spec, rpc_binding_vector_p_t vec, int modop, unsigned32 *status ) { unsigned_char_p_t uuid = NULL; unsigned_char_p_t interfaceID = NULL; rpc_if_id_t if_id; LDAPMod *modV[4]; LDAPMod modRpcNsInterfaceID, modRpcNsBindings, modObjectClass; char **valueRpcNsBindings = NULL; char *valueRpcNsInterfaceID[2], *valueObjectClass[3]; int rc; unsigned i; rpc_if_inq_id(if_spec, &if_id, status); if (*status != rpc_s_ok) { goto out; } /* Get the interface ID */ uuid_to_string(&if_id.uuid, &uuid, status); if (*status != rpc_s_ok) { goto out; } RPC_MEM_ALLOC(interfaceID, unsigned_char_p_t, strlen(uuid) + sizeof(",65535.65535"), RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(interfaceID, "%s,%hu.%hu", uuid, if_id.vers_major, if_id.vers_minor); valueRpcNsInterfaceID[0] = interfaceID; valueRpcNsInterfaceID[1] = NULL; modRpcNsInterfaceID.mod_op = LDAP_MOD_ADD; modRpcNsInterfaceID.mod_type = "rpcNsInterfaceID"; modRpcNsInterfaceID.mod_values = valueRpcNsInterfaceID; RPC_MEM_ALLOC(valueRpcNsBindings, char **, (vec->count * sizeof(char *)), RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); memset(valueRpcNsBindings, 0, (vec->count * sizeof(unsigned_char_p_t))); for (i = 0; i < vec->count; i++) { rpc_binding_to_string_binding(vec->binding_h[i], (unsigned_char_p_t *)&valueRpcNsBindings[i], status); if (*status != rpc_s_ok) { goto out; } } valueRpcNsBindings[vec->count] = NULL; modRpcNsBindings.mod_op = modop; modRpcNsBindings.mod_type = "rpcNsBindings"; modRpcNsBindings.mod_values = valueRpcNsBindings; valueObjectClass[0] = "rpcServerElement"; valueObjectClass[1] = "rpcEntry"; valueObjectClass[2] = "top"; modObjectClass.mod_op = modop; modObjectClass.mod_type = "objectClass"; modObjectClass.mod_values = valueObjectClass; modV[0] = &modRpcNsInterfaceID; modV[1] = &modRpcNsBindings; modV[2] = &modObjectClass; modV[3] = NULL; if (modop == LDAP_MOD_ADD) { rc = ldap_add_s(ld, dn, modV); } else { rc = ldap_modify_s(ld, dn, modV); } *status = (rc == LDAP_SUCCESS) ? rpc_s_ok : rpc_s_update_failed; out: if (uuid != NULL) free(uuid); if (interfaceID != NULL) free(interfaceID); if (valueRpcNsBindings != NULL) { char **p; for (p = valueRpcNsBindings; *valueRpcNsBindings != NULL; p++) { unsigned_char_p_t tmp = (unsigned_char_p_t)*p; rpc_string_free(&tmp, status); } RPC_MEM_FREE(valueRpcNsBindings, RPC_C_MEM_NSRESOLUTION); } }
static void rpc_ns__ldap_lookup_server_element(LDAP *ld, unsigned_char_p_t serverDN, rpc_if_handle_t if_spec, unsigned_char_p_t *dn, unsigned32 *status) { unsigned_char_p_t filter = NULL; unsigned_char_p_t uuid = NULL; rpc_if_id_t if_id; LDAPMessage *msg = NULL, *e; char *_dn; size_t len; rpc_if_inq_id(if_spec, &if_id, status); if (*status != rpc_s_ok) { goto out; } /* Get the interface ID */ uuid_to_string(&if_id.uuid, &uuid, status); if (*status != rpc_s_ok) { goto out; } len = strlen(uuid); len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", uuid, if_id.vers_major, if_id.vers_minor); if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &msg) != LDAP_SUCCESS) { *status = rpc_s_not_found; goto out; } e = ldap_first_entry(ld, msg); if (e == NULL) { *status = rpc_s_not_found; goto out; } _dn = ldap_get_dn(ld, e); if (dn == NULL) { *status = rpc_s_not_found; goto out; } *dn = rpc_stralloc(_dn); ldap_memfree(_dn); out: if (filter != NULL) { RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); } if (msg != NULL) { ldap_msgfree(msg); } if (uuid != NULL) { rpc_string_free(&uuid, status); } }
PUBLIC void rpc_rgy_get_codesets ( rpc_codeset_mgmt_p_t *codesets_p, error_status_t *status ) { int i; entry_t **epp; char *current_codeset; unsigned32 current_rgy_codeset; CODING_ERROR (status); rpc__codesets_read_registry_file(status); if (*status != rpc_s_ok) { return; } epp = rpc_g_codesets_sort_by_priority; RPC_MEM_ALLOC ( *codesets_p, rpc_codeset_mgmt_p_t, sizeof(rpc_codeset_mgmt_t) + (sizeof(rpc_cs_c_set_t) * (rpc_g_codesets_effective_count - 1)), RPC_C_MEM_CDS_ATTR, RPC_C_MEM_WAITOK); (*codesets_p)->count = rpc_g_codesets_effective_count; current_codeset = nl_langinfo(CODESET); dce_cs_loc_to_rgy( (unsigned_char_p_t)current_codeset, ¤t_rgy_codeset, NULL, NULL, status); if (*status != dce_cs_c_ok) { /* codeset registry error */ *status = rpc_s_ok; return; } /* * The top of the list is current locale's code set */ (*codesets_p)->codesets[0].c_set = current_rgy_codeset; for (i = 1; i < rpc_g_codesets_effective_count; i++) { /* ** This logic assumes current locale's code set is one of ** the supported code set. It should be. */ if ((*epp)->code_set != (*codesets_p)->codesets[0].c_set) { (*codesets_p)->codesets[i].c_set = (*epp)->code_set; (*codesets_p)->codesets[i].c_max_bytes = (*epp)->max_bytes; } else { (*codesets_p)->codesets[0].c_max_bytes = (*epp)->max_bytes; i--; } epp++; } *status = rpc_s_ok; }
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; }
PRIVATE void rpc__tower_ref_alloc ( byte_p_t tower_octet_string, unsigned32 num_flrs, unsigned32 start_flr, rpc_tower_ref_p_t *tower_ref, unsigned32 *status ) { byte_p_t tower_floor; unsigned32 i; CODING_ERROR (status); /* * Allocate the tower reference structure allowing * for the number of tower floors desired. * * Note, the first floor is allocated via the "floor[1] * member of rpc_tower_ref_t. */ RPC_MEM_ALLOC ( *tower_ref, rpc_tower_ref_p_t, sizeof (rpc_tower_ref_t) + (sizeof (rpc_tower_floor_p_t) * (num_flrs-1)), RPC_C_MEM_TOWER_REF, RPC_C_MEM_WAITOK); /* * Initialize floor count to the number of floors and * floor pointers to NULL. */ (*tower_ref)->count = num_flrs; for (i=0; i < num_flrs; i++) { (*tower_ref)->floor[i] = NULL; } /* * Initialize local to point to beginning of * the canonical tower floor. */ tower_floor = tower_octet_string + RPC_C_TOWER_FLR_COUNT_SIZE; /* * For each tower floor, starting at the desired floor, * allocate the floor and initialize with the information * in the tower structure. */ for (i= start_flr-1; i < num_flrs; i++) { /* * Allocate the tower floor */ RPC_MEM_ALLOC ( (*tower_ref)->floor[i], rpc_tower_floor_p_t, sizeof (rpc_tower_floor_t), RPC_C_MEM_TOWER_FLOOR, RPC_C_MEM_WAITOK ); /* * Initialize the floor's tower octet free flag to not * free the tower floor octet string, since they will be * freed by the caller who created them. */ (*tower_ref)->floor[i]->free_twr_octet_flag = false; /* * Get the pointer to the octet string. */ (*tower_ref)->floor[i]->octet_string = tower_floor; /* * Get the protocol identifier count. */ memcpy ((char *) &((*tower_ref)->floor[i]->prot_id_count), (char *) tower_floor, RPC_C_TOWER_FLR_LHS_COUNT_SIZE); /* * Convert prot id count to host's endian representation. */ RPC_RESOLVE_ENDIAN_INT16 ((*tower_ref)->floor[i]->prot_id_count); /* * Get the additional information count. */ memcpy ((char *) &((*tower_ref)->floor[i]->address_count), (char *) tower_floor + RPC_C_TOWER_FLR_LHS_COUNT_SIZE + (*tower_ref)->floor[i]->prot_id_count, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); /* * Convert address count to host's endian representation. */ RPC_RESOLVE_ENDIAN_INT16 ((*tower_ref)->floor[i]->address_count); /* * Point to the next tower floor in the tower octet string. */ tower_floor += RPC_C_TOWER_FLR_LHS_COUNT_SIZE + (*tower_ref)->floor[i]->prot_id_count + RPC_C_TOWER_FLR_RHS_COUNT_SIZE + (*tower_ref)->floor[i]->address_count; } *status = rpc_s_ok; return; }
PRIVATE void rpc__tower_ref_vec_from_binding ( rpc_if_rep_p_t if_spec, rpc_binding_handle_t binding, rpc_tower_ref_vector_p_t *tower_vector, unsigned32 *status ) { unsigned16 lower_flr_count; unsigned32 i, temp_status; twr_p_t lower_floors; rpc_tower_ref_p_t tower_copy; rpc_tower_floor_p_t tower_floor; rpc_if_id_t if_id; rpc_binding_rep_p_t binding_rep; rpc_syntax_id_t *if_syntax_id; CODING_ERROR (status); /* * Create the tower vector. */ RPC_MEM_ALLOC ( *tower_vector, rpc_tower_ref_vector_p_t, sizeof (rpc_tower_ref_vector_t) + ((if_spec->syntax_vector.count -1) * (sizeof (rpc_tower_ref_p_t))) , RPC_C_MEM_TOWER_REF_VECTOR, RPC_C_MEM_WAITOK ); /* * Initialize tower count. */ (*tower_vector)->count = 0; /* * Create the tower for the first transfer syntax * in the interface specification. */ /* * Obtain the rpc address of this binding. */ binding_rep = (rpc_binding_rep_p_t) binding; /* * Create the lower tower floors. */ rpc__naf_tower_flrs_from_addr ( binding_rep->rpc_addr, &lower_floors, status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*tower_vector, RPC_C_MEM_TOWER_REF_VECTOR); return; } /* * Initialize the tower vector with the pointer * to the lower floors. */ (*tower_vector)->lower_flrs = lower_floors; /* * Get the number of lower tower floors returned and * convert to host's representation. */ memcpy ((char *)&lower_flr_count, (char *)lower_floors->tower_octet_string, RPC_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (lower_flr_count); /* * Allocate the tower reference structure to the first tower. * The number of floors is equal to the number of RPC (upper) floors * plus the number of network (lower) floors. */ rpc__tower_ref_alloc (lower_floors->tower_octet_string, RPC_C_NUM_RPC_FLOORS + lower_flr_count, RPC_C_NUM_RPC_FLOORS+1, &((*tower_vector)->tower[0]), status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Get the interface identifier and create tower floor 1. */ rpc_if_inq_id ((rpc_if_handle_t) if_spec, &if_id, status); if (*status != rpc_s_ok) { goto CLEANUP; } rpc__tower_flr_from_if_id (&if_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 1 to the tower. */ rpc__tower_ref_add_floor (1, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create tower floor 2 from the transfer syntax from the ifspec. */ if_syntax_id = if_spec->syntax_vector.syntax_id; rpc__tower_flr_from_drep (if_syntax_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 2 to the tower. */ rpc__tower_ref_add_floor (2, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create tower floor 3 from the RPC protocol id. */ rpc__tower_flr_from_rpc_prot_id (binding_rep->rpc_addr->rpc_protseq_id, binding_rep->protocol_version, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 3 to the tower. */ rpc__tower_ref_add_floor (3, tower_floor, (*tower_vector)->tower[0], status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Increment the number of towers in the vector. */ (*tower_vector)->count++; /* * Create the towers for the remaining transfer syntaxes * in the interface specification. */ if_syntax_id++; for (i=1; i < if_spec->syntax_vector.count; i++, if_syntax_id++, (*tower_vector)->count++) { /* * Copy the initial tower created. */ rpc__tower_ref_copy ((*tower_vector)->tower[0], &tower_copy, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Create floor 2 for this tower from the next transfer syntax. */ rpc__tower_flr_from_drep (if_syntax_id, &tower_floor, status); if (*status != rpc_s_ok) { goto CLEANUP; } /* * Add floor 2 to the tower. */ rpc__tower_ref_add_floor (2, tower_floor, tower_copy, status); if (*status != rpc_s_ok) { goto CLEANUP; } (*tower_vector)->tower[i] = tower_copy; } CLEANUP: /* * If status is anything other than successful, * free the tower vector. */ if (*status != rpc_s_ok) { rpc__tower_ref_vec_free (tower_vector, &temp_status); } return; }
PRIVATE rpc_dg_scall_p_t rpc__dg_scall_cbk_alloc ( rpc_dg_ccall_p_t ccall, rpc_dg_sock_pool_elt_p_t sp, rpc_dg_recvq_elt_p_t rqe ) { rpc_dg_scall_p_t scall; static rpc_clock_t rpc_c_dg_scall_timer_freq_init = RPC_CLOCK_SEC(1); RPC_LOCK_ASSERT(0); RPC_MEM_ALLOC(scall, rpc_dg_scall_p_t, sizeof *scall, RPC_C_MEM_DG_SCALL, RPC_C_MEM_NOWAIT); /* * Initialize the common SCALL handle fields (and LOCK the SCALL) */ scall_init(scall, sp, rqe); /* * The rest is specific to callback SCALLs. */ scall->c.actid_hash = ccall->c.actid_hash; /* * Setup the CCALL (Logical SCTE) / SCALL cross linkage. */ scall->cbk_ccall = ccall; RPC_DG_CALL_REFERENCE(&ccall->c); ccall->cbk_scall = scall; RPC_DG_CALL_REFERENCE(&scall->c); /* * Initialize the fields of the common call handle header that * are really part of the prototype packet header. */ scall->c.call_actid = ccall->c.call_actid; scall->c.call_ahint = RPC_C_DG_NO_HINT; scall->c.is_cbk = true; { unsigned32 our_min ATTRIBUTE_UNUSED; /* * This is essentially a turnaround. The client, which is waiting * for a response, becomes the receiver. * * We inherit high_rcv_frag_size and snd_frag_size from the original * scall. */ scall->c.rq.high_rcv_frag_size = ccall->c.rq.high_rcv_frag_size; scall->c.xq.snd_frag_size = ccall->c.xq.snd_frag_size; /* * Also we inherit the reservation from the original ccall, which * gives us enough packets for receiving fragments. */ scall->c.n_resvs = ccall->c.n_resvs; } RPC_DG_CALL_SET_TIMER(&scall->c, rpc__dg_scall_timer, rpc_c_dg_scall_timer_freq_init); return(scall); }
PRIVATE void rpc__http_desc_inq_addr ( rpc_protseq_id_t protseq_id, rpc_socket_t sock, rpc_addr_vector_p_t *rpc_addr_vec, unsigned32 *status ) { rpc_http_addr_p_t http_addr; rpc_http_addr_t loc_http_addr; #ifdef HTTP_NETADDR char *p; #endif int err = 0; CODING_ERROR (status); memset (&loc_http_addr, 0, sizeof(rpc_http_addr_t)); loc_http_addr.len = sizeof(loc_http_addr) - offsetof(rpc_http_addr_t, sa); /* * Do a "getsockname" into a local IP RPC address. If the network * address part of the result is non-zero, then the socket must be * bound to a particular IP address and we can just return a RPC * address vector with that one address (and endpoint) in it. * Otherwise, we have to enumerate over all the local network * interfaces the local host has and construct an RPC address for * each one of them. */ err = rpc__socket_inq_endpoint(sock, (rpc_addr_p_t) &loc_http_addr); if (err) { *status = -1; return; } RPC_MEM_ALLOC ( http_addr, rpc_http_addr_p_t, sizeof (rpc_http_addr_t), RPC_C_MEM_RPC_ADDR, RPC_C_MEM_WAITOK); if (http_addr == NULL) { *status = rpc_s_no_memory; return; } RPC_MEM_ALLOC ( *rpc_addr_vec, rpc_addr_vector_p_t, sizeof **rpc_addr_vec, RPC_C_MEM_RPC_ADDR_VEC, RPC_C_MEM_WAITOK); if (*rpc_addr_vec == NULL) { RPC_MEM_FREE (http_addr, RPC_C_MEM_RPC_ADDR); *status = rpc_s_no_memory; return; } *http_addr = loc_http_addr; (*rpc_addr_vec)->len = 1; (*rpc_addr_vec)->addrs[0] = (rpc_addr_p_t) http_addr; *status = rpc_s_ok; return; }
PRIVATE void rpc__ntlmauth_bnd_set_auth ( unsigned_char_p_t server_name, rpc_authn_level_t level, rpc_auth_identity_handle_t auth_ident, rpc_authz_protocol_id_t authz_prot, rpc_binding_handle_t binding_h, rpc_auth_info_p_t *infop, unsigned32 *stp ) { int st; rpc_ntlmauth_info_p_t ntlmauth_info; rpc_g_ntlmauth_alloc_count++; RPC_MEM_ALLOC (ntlmauth_info, rpc_ntlmauth_info_p_t, sizeof (*ntlmauth_info), RPC_C_MEM_UTIL, RPC_C_MEM_WAITOK); if (authz_prot != rpc_c_authz_none) { st = rpc_s_authn_authz_mismatch; goto poison; } if (level != rpc_c_authn_level_none) { st = rpc_s_unsupported_authn_level; goto poison; } /* * If no server principal name was specified, go ask for it. */ if (server_name == NULL) { rpc_mgmt_inq_server_princ_name (binding_h, dce_c_rpc_authn_protocol_krb5, &server_name, stp); if (*stp != rpc_s_ok) return; } else { server_name = rpc_stralloc(server_name); } RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, ( "(rpc__ntlmauth_bnd_set_auth) %x created (now %d active)\n", ntlmauth_info, rpc_g_ntlmauth_alloc_count - rpc_g_ntlmauth_free_count)); memset (ntlmauth_info, 0, sizeof(*ntlmauth_info)); RPC_MUTEX_INIT(ntlmauth_info->lock); ntlmauth_info->auth_info.server_princ_name = server_name; ntlmauth_info->auth_info.authn_level = level; ntlmauth_info->auth_info.authn_protocol = rpc_c_authn_dce_dummy; ntlmauth_info->auth_info.authz_protocol = authz_prot; ntlmauth_info->auth_info.is_server = 0; ntlmauth_info->auth_info.u.auth_identity = auth_ident; ntlmauth_info->auth_info.refcount = 1; *infop = &ntlmauth_info->auth_info; ntlmauth_info->status = rpc_s_ok; *stp = rpc_s_ok; return; poison: *infop = (rpc_auth_info_p_t) &ntlmauth_info->auth_info; ntlmauth_info->status = st; *stp = st; return; }
PRIVATE void rpc__ip_desc_inq_addr ( rpc_protseq_id_t protseq_id, rpc_socket_t sock, rpc_addr_vector_p_t *rpc_addr_vec, unsigned32 *status ) { rpc_ip_addr_p_t ip_addr; rpc_ip_addr_t loc_ip_addr; unsigned16 i; int err = 0; CODING_ERROR (status); /* * Do a "getsockname" into a local IP RPC address. If the network * address part of the result is non-zero, then the socket must be * bound to a particular IP address and we can just return a RPC * address vector with that one address (and endpoint) in it. * Otherwise, we have to enumerate over all the local network * interfaces the local host has and construct an RPC address for * each one of them. */ loc_ip_addr.len = sizeof(loc_ip_addr.sa); err = rpc__socket_inq_endpoint (sock, (rpc_addr_p_t) &loc_ip_addr); if (err) { *status = -1; /* !!! */ return; } if (loc_ip_addr.sa.sin_addr.s_addr == 0) { err = rpc__socket_enum_ifaces(sock, get_addr_noloop, rpc_addr_vec, NULL, NULL); if (err != RPC_C_SOCKET_OK) { *status = -1; return; } for (i = 0; i < (*rpc_addr_vec)->len; i++) { ((rpc_ip_addr_p_t) (*rpc_addr_vec)->addrs[i])->sa.sin_port = loc_ip_addr.sa.sin_port; } *status = rpc_s_ok; return; } else { RPC_MEM_ALLOC ( ip_addr, rpc_ip_addr_p_t, sizeof (rpc_ip_addr_t), RPC_C_MEM_RPC_ADDR, RPC_C_MEM_WAITOK); if (ip_addr == NULL) { *status = rpc_s_no_memory; return; } RPC_MEM_ALLOC ( *rpc_addr_vec, rpc_addr_vector_p_t, sizeof **rpc_addr_vec, RPC_C_MEM_RPC_ADDR_VEC, RPC_C_MEM_WAITOK); if (*rpc_addr_vec == NULL) { RPC_MEM_FREE (ip_addr, RPC_C_MEM_RPC_ADDR); *status = rpc_s_no_memory; return; } ip_addr->rpc_protseq_id = protseq_id; ip_addr->len = sizeof (struct sockaddr_in); ip_addr->sa = loc_ip_addr.sa; (*rpc_addr_vec)->len = 1; (*rpc_addr_vec)->addrs[0] = (rpc_addr_p_t) ip_addr; *status = rpc_s_ok; return; } }
PUBLIC void twr_np_lower_flrs_from_sa ( sockaddr_p_t sa, twr_p_t *lower_flrs, unsigned32 *status ) { unsigned8 protocol_id[TWR_C_NUM_NP_LOWER_FLRS]; unsigned16 id_size = TWR_C_TOWER_PROT_ID_SIZE, floor_count, related_data_size[TWR_C_NUM_NP_LOWER_FLRS], twr_rep_16; unsigned32 count, twr_t_length; byte_p_t related_data_ptr[TWR_C_NUM_NP_LOWER_FLRS], tmp_tower; char hostname[MAXHOSTNAMELEN], *p; CODING_ERROR (status); RPC_VERIFY_INIT (); RPC_DBG_GPRINTF(("(twr_np_lower_flrs_from_sa) called\n")); if (sa->family == RPC_C_NAF_ID_UXD) { protocol_id[0] = TWR_C_FLR_PROT_ID_NP; protocol_id[1] = TWR_C_FLR_PROT_ID_NB; } else { *status = twr_s_unknown_sa; return; } /* * Since we now know the socket address we're dealing with, * collect the sizes of each field to allocate memory, and * remember the pointers to the fields so we can copy the * data once we have allocated the tower string. */ floor_count = TWR_C_NUM_NP_LOWER_FLRS; /* * related_data[0] contains the pipe name (eg. \PIPE\lsass) */ related_data_ptr[0] = (unsigned char*) ((struct sockaddr_un *)sa)->sun_path; if (strncmp((char*) related_data_ptr[0], (char*) RPC_C_NP_DIR"/", RPC_C_NP_DIR_LEN + 1) == 0) { /* Path is relative, but do not chop off first /. */ related_data_ptr[0] += RPC_C_NP_DIR_LEN; } related_data_size[0] = strlen((char*) related_data_ptr[0]) + 1; /* * related_data[1] contains the NetBIOS name (eg. \\MYSERVER) */ hostname[0] = '\\'; hostname[1] = '\\'; gethostname(&hostname[2], MAXHOSTNAMELEN - 3); hostname[MAXHOSTNAMELEN - 1] = '\0'; for (p = &hostname[2]; *p != '\0'; p++) *p = toupper((int)*p); related_data_size[1] = strlen(hostname) + 1; related_data_ptr[1] = (unsigned char*) hostname; /* * Calculate the length of the tower floors. */ twr_t_length = TWR_C_TOWER_FLR_COUNT_SIZE; /* to store floor count */ for ( count = 0; count < floor_count; count++ ) { twr_t_length += TWR_C_FLR_OVERHEAD; twr_t_length += related_data_size[count]; } /* * Next allocate space for the tower structure */ RPC_MEM_ALLOC ( *lower_flrs, twr_p_t, sizeof (twr_t) + (twr_t_length - 1), RPC_C_MEM_TOWER, RPC_C_MEM_WAITOK ); /* * Copy the length of the tower octet string into the tower structure */ (*lower_flrs)->tower_length = twr_t_length; /* * Copy the floor information into the tower octet string */ /* * Use a temporary for the octet string since we need * to increment the pointer. */ tmp_tower = (*lower_flrs)->tower_octet_string; /* * Copy the number of floors into the tower octet string */ twr_rep_16 = floor_count; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Convert the protocol identifier size to its proper * representation for use in the following loop. */ RPC_RESOLVE_ENDIAN_INT16 (id_size); for ( count = 0; count < floor_count; count++ ) { /* * Copy the length of the protocol identifier field into * tower octet string. (Converted before the loop.) */ memcpy ((char *)tmp_tower, (char *)&id_size, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Copy the protocol identifier into tower octet string * (1 byte so no need to convert endian representation). */ memcpy ((char *)tmp_tower, (char *)&(protocol_id[count]), TWR_C_TOWER_PROT_ID_SIZE); tmp_tower += TWR_C_TOWER_PROT_ID_SIZE; /* * Copy the length of the address data field into * tower octet string. */ twr_rep_16 = related_data_size[count]; RPC_RESOLVE_ENDIAN_INT16 (twr_rep_16); memcpy ((char *)tmp_tower, (char *)&twr_rep_16, TWR_C_TOWER_FLR_RHS_COUNT_SIZE); tmp_tower += TWR_C_TOWER_FLR_RHS_COUNT_SIZE; /* * If there is addressing data, copy the address data field into * tower octet string */ if (related_data_size[count]) { memcpy ((char *)tmp_tower, (char *)related_data_ptr[count], related_data_size[count]); /* Convert slashes */ for (p = (char*) tmp_tower; *p != '\0'; p++) { if (*p == '/') *p = '\\'; } /* * Set up for the next floor. */ tmp_tower += related_data_size[count]; } } *status = twr_s_ok; }
static void rpc_ns__ldap_import_server_element(LDAP *ld, unsigned_char_p_t serverDN, rpc_if_handle_t if_spec, rpc_ns_handle_t *ctx, unsigned32 *status ) { unsigned_char_p_t filter = NULL; unsigned_char_p_t uuid = NULL; rpc_if_id_t if_id; LDAPMessage *msg = NULL, *e; rpc_ns_handle_rep_t *rep; unsigned_char_p_t *bindings; size_t len; rpc_if_inq_id(if_spec, &if_id, status); if (*status != rpc_s_ok) { goto out; } /* Get the interface ID */ uuid_to_string(&if_id.uuid, &uuid, status); if (*status != rpc_s_ok) { goto out; } len = strlen(uuid); len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", uuid, if_id.vers_major, if_id.vers_minor); if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &msg) != LDAP_SUCCESS) { *status = rpc_s_not_found; goto out; } e = ldap_first_entry(ld, msg); if (e == NULL) { *status = rpc_s_not_found; goto out; } bindings = (unsigned_char_p_t *)ldap_get_values(ld, e, "rpcNsBindings"); if (bindings == NULL) { *status = rpc_s_not_found; goto out; } RPC_MEM_ALLOC(rep, rpc_ns_handle_rep_p_t, sizeof(*rep), RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); rep->count = ldap_count_values((char **)bindings); rep->bindings = bindings; rep->cursor = 0; *ctx = (rpc_ns_handle_t)rep; *status = rpc_s_ok; out: if (filter != NULL) { RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); } if (msg != NULL) { ldap_msgfree(msg); } }
INTERNAL void rpc__ntlmauth_bnd_set_auth ( unsigned_char_p_t server_name, rpc_authn_level_t level, rpc_auth_identity_handle_t auth_ident, rpc_authz_protocol_id_t authz_prot, rpc_binding_handle_t binding_h, rpc_auth_info_p_t *infop, unsigned32 *stp ) { unsigned32 st = rpc_s_ok; rpc_ntlmssp_auth_ident_t_p auth_info = NULL; rpc_ntlmauth_info_p_t ntlmauth_info = NULL; gss_name_t gss_server_name = {0}; unsigned char *str_server_name = NULL; gss_buffer_desc username_buf = {0}; gss_name_t gss_user_name = NULL; int gss_rc = 0; OM_uint32 minor_status = 0; gss_OID_set_desc desired_mech; gss_OID_set ret_mech; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; OM_uint32 time_rec = 0; gss_OID_desc gss_ntlm_oid_desc = {0}; gss_OID_desc gss_cred_opt_password_oid_desc = {0}; gss_buffer_desc auth_buffer = {0}; RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, ("(rpc__gssauth_bnd_set_auth)\n")); rpc_g_ntlmauth_alloc_count++; RPC_MEM_ALLOC(ntlmauth_info, rpc_ntlmauth_info_p_t, sizeof (*ntlmauth_info), RPC_C_MEM_NTLMAUTH_INFO, RPC_C_MEM_WAITOK); memset(ntlmauth_info, 0, sizeof(*ntlmauth_info)); if (authz_prot != rpc_c_authz_name) { st = rpc_s_authn_authz_mismatch; goto poison; } if ((level != rpc_c_authn_level_connect) && (level != rpc_c_authn_level_pkt_integrity) && (level != rpc_c_authn_level_pkt_privacy)) { st = rpc_s_unsupported_authn_level; goto poison; } if (server_name == NULL || auth_ident == NULL) { st = rpc_s_invalid_arg; goto poison; } auth_info = (rpc_ntlmssp_auth_ident_t_p)auth_ident; if (authz_prot == rpc_c_authz_name) { gss_buffer_desc input_name; /* GSS_KRB5_NT_PRINCIPAL_NAME */ gss_OID_desc nt_principal = {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"}; int gss_rc = 0; OM_uint32 minor_status = 0; if (server_name == NULL) { rpc_mgmt_inq_server_princ_name(binding_h, rpc_c_authn_winnt, &str_server_name, &st); if (st != rpc_s_ok) { goto poison; } } else { str_server_name = rpc_stralloc(server_name); } input_name.value = (void *)str_server_name; input_name.length = strlen((char *)str_server_name); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &gss_server_name); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__gssauth_bnd_set_auth): import: %s\n", msg)); goto poison; } } gss_ntlm_oid_desc.length = GSS_MECH_NTLM_LEN; gss_ntlm_oid_desc.elements = GSS_MECH_NTLM; gss_cred_opt_password_oid_desc.length = GSS_CRED_OPT_PW_LEN; gss_cred_opt_password_oid_desc.elements = GSS_CRED_OPT_PW; username_buf.value = auth_info->User; username_buf.length = auth_info->UserLength; gss_rc = gss_import_name(&minor_status, &username_buf, GSS_C_NT_USER_NAME, &gss_user_name); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } desired_mech.elements = (gss_OID)&gss_ntlm_oid_desc; desired_mech.count = 1; gss_rc = gss_acquire_cred(&minor_status, gss_user_name, 0, &desired_mech, GSS_C_INITIATE, &cred_handle, &ret_mech, &time_rec); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } auth_buffer.value = auth_info; auth_buffer.length = sizeof(*auth_info); gss_rc = gssspi_set_cred_option(&minor_status, cred_handle, (gss_OID)&gss_cred_opt_password_oid_desc, &auth_buffer); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } ntlmauth_info->auth_info.server_princ_name = str_server_name; ntlmauth_info->auth_info.authn_level = level; ntlmauth_info->auth_info.authn_protocol = rpc_c_authn_winnt; ntlmauth_info->auth_info.authz_protocol = authz_prot; ntlmauth_info->auth_info.is_server = 0; ntlmauth_info->auth_info.u.auth_identity = auth_ident; ntlmauth_info->auth_info.refcount = 1; ntlmauth_info->gss_server_name = gss_server_name; ntlmauth_info->gss_creds = cred_handle; if (gss_user_name) { gss_release_name(&minor_status, &gss_user_name); } *infop = &ntlmauth_info->auth_info; *stp = st; return; poison: *infop = NULL; *stp = st; return; }
PRIVATE dce_pointer_t rpc__list_element_alloc ( rpc_list_desc_p_t list_desc, boolean32 block ) { volatile dce_pointer_t element = NULL; unsigned32 wait_cnt; struct timespec delta; struct timespec abstime; RPC_LOG_LIST_ELT_ALLOC_NTR; for (wait_cnt = 0; wait_cnt < rpc_g_lookaside_rcb.max_wait_times; wait_cnt++) { /* * Acquire the global resource control lock for all lookaside * lists if the caller doesn't have their own lock. */ if (list_desc->use_global_mutex) { RPC_MUTEX_LOCK (rpc_g_lookaside_rcb.res_lock); } /* * Try allocating a structure off the lookaside list given. */ if (list_desc->cur_size > 0) { #define DEBUG 1 #ifdef DEBUG if (list_desc->list_head.next == NULL) { /* * rpc_m_lookaside_corrupt * "(%s) Lookaside list is corrupted" */ rpc_dce_svc_printf ( __FILE__, __LINE__, "%s", rpc_svc_general, svc_c_sev_fatal | svc_c_action_abort, rpc_m_lookaside_corrupt, "rpc__list_element_alloc" ); } #endif list_desc->cur_size--; RPC_LIST_REMOVE_HEAD (list_desc->list_head, element, dce_pointer_t); /* * Release the global resource control lock for all lookaside * lists if the caller doesn't have their own lock. */ if (list_desc->use_global_mutex) { RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock); } break; } else { /* * Release the global resource control lock if the * caller doesn't have their own lock for all lookaside lists * since the structure was available on the lookaside list. * * We do it now because allocating an element from heap is a relatively * time consuming operation. */ if (list_desc->use_global_mutex) { RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock); } /* * The lookaside list is empty. Try and allocate from * heap. */ RPC_MEM_ALLOC (element, dce_pointer_t, list_desc->element_size, list_desc->element_type, RPC_C_MEM_NOWAIT); if (element == NULL) { /* * The heap allocate failed. If the caller indicated * that we should not block return right now. */ if (block == false) { break; } delta.tv_sec = rpc_g_lookaside_rcb.wait_time; delta.tv_nsec = 0; dcethread_get_expiration (&delta, &abstime); /* * If we are using the global lookaside list lock * then reaquire the global lookaside list lock and * wait on the global lookaside list condition * variable otherwise use the caller's mutex and * condition variable. */ if (list_desc->use_global_mutex) { RPC_MUTEX_LOCK (rpc_g_lookaside_rcb.res_lock); RPC_COND_TIMED_WAIT (rpc_g_lookaside_rcb.wait_flg, rpc_g_lookaside_rcb.res_lock, &abstime); RPC_MUTEX_UNLOCK (rpc_g_lookaside_rcb.res_lock); } else { RPC_COND_TIMED_WAIT (*list_desc->cond, *list_desc->mutex, &abstime); } /* * Try to allocate the structure again. */ continue; } else { /* * The RPC_MEM_ALLOC succeeded. If an alloc routine * was specified when the lookaside list was inited * call it now. */ if (list_desc->alloc_rtn != NULL) { /* * Catch any exceptions which may occur in the * list-specific alloc routine. Any exceptions * will be caught and the memory will be freed. */ DCETHREAD_TRY { (*list_desc->alloc_rtn) (element); } DCETHREAD_CATCH_ALL(THIS_CATCH) { RPC_MEM_FREE (element, list_desc->element_type); element = NULL; /* * rpc_m_call_failed_no_status * "%s failed" */ rpc_dce_svc_printf ( __FILE__, __LINE__, "%s", rpc_svc_general, svc_c_sev_fatal | svc_c_action_abort, rpc_m_call_failed_no_status, "rpc__list_element_alloc/(*list_desc->alloc_rtn)(element)" ); } DCETHREAD_ENDTRY } break; } } }
PUBLIC void twr_ip_lower_flrs_to_sa ( byte_p_t tower_octet_string, sockaddr_p_t *sa, unsigned32 *sa_len, unsigned32 *status ) { unsigned8 id; byte_p_t tower; unsigned16 count, floor_count, id_size, addr_size; unsigned32 length; CODING_ERROR (status); RPC_VERIFY_INIT (); id_size = 0; /* * Make sure we have a pointer to some data structure. */ if ( !(tower = tower_octet_string)) { *status = twr_s_unknown_tower; return; } /* * Get the tower floor count */ memcpy ((char *)&floor_count, (char *)tower, TWR_C_TOWER_FLR_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (floor_count); tower += TWR_C_TOWER_FLR_COUNT_SIZE; /* * Skip over the (application's) upper floors while we look for the * beginning of the ip-specific lower floors. */ for ( count = 0; count < floor_count; count++ ) { /* * Get the length of this floor's protocol id field (don't advance * the pointer). */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); /* * Get the protocol id (don't advance the pointer). * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE), TWR_C_TOWER_PROT_ID_SIZE); /* * See if we support the protocol id. */ if ( (id_size == TWR_C_TOWER_PROT_ID_SIZE) && (id == TWR_C_FLR_PROT_ID_TCP || id == TWR_C_FLR_PROT_ID_UDP)) { /* * Indicate we found the beginning of the ip floors. */ *status = twr_s_ok; break; } else { /* * Skip this floor. Get the address size in order * to know how much to skip. */ memcpy ((char *)&addr_size, (char *)(tower + TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size), TWR_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size + TWR_C_TOWER_FLR_RHS_COUNT_SIZE + addr_size; /* * For now, assume we don't find the floors we're looking for. */ *status = twr_s_unknown_tower; } } if (*status != twr_s_ok) { return; } /* * Skip the floor's protocol id field length and protocol id * (now move the pointer). We already know it's * TWR_C_FLR_PROT_ID_TCP or TWR_C_FLR_PROT_ID_UDP. */ tower += (TWR_C_TOWER_FLR_LHS_COUNT_SIZE + id_size); /* * Allocate space for ip sockaddr */ length = sizeof(struct sockaddr_in); RPC_MEM_ALLOC ( *sa, sockaddr_p_t, length, RPC_C_MEM_SOCKADDR, RPC_C_MEM_WAITOK ); *sa_len = length; /* * make sure unused bytes are null */ memset ((char *) *sa, 0, length); /* * define this as an internet family socket */ ((struct sockaddr_in *)(*sa))->sin_family = RPC_C_NAF_ID_IP; /* * Get the length of in_port */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the port number to the sockaddr. */ memcpy ( &((struct sockaddr_in *)(*sa))->sin_port, tower, addr_size); tower += addr_size; /* * Get the length of host address floor protocol id */ memcpy ((char *)&id_size, (char *)tower, TWR_C_TOWER_FLR_LHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (id_size); tower += TWR_C_TOWER_FLR_LHS_COUNT_SIZE; /* * Get the protocol id * Expect one byte; no need to convert. */ memcpy ((char *)&id, (char *)tower, TWR_C_TOWER_PROT_ID_SIZE); tower += id_size; if ( (id_size != TWR_C_TOWER_PROT_ID_SIZE) || (id != TWR_C_FLR_PROT_ID_IP) ) { *status = twr_s_unknown_tower; RPC_MEM_FREE (*sa, RPC_C_MEM_SOCKADDR); return; } /* * Get the length of in_address */ memcpy ((char *)&addr_size, (char *)tower, RPC_C_TOWER_FLR_RHS_COUNT_SIZE); RPC_RESOLVE_ENDIAN_INT16 (addr_size); tower += RPC_C_TOWER_FLR_RHS_COUNT_SIZE; /* * Copy the host address to the sockaddr */ memcpy (&((struct sockaddr_in *)(*sa))->sin_addr.s_addr, (char *)tower, addr_size); *status = twr_s_ok; }