PRIVATE void rpc__dg_binding_free ( rpc_binding_rep_p_t *h_, unsigned32 *st ) { /* * The binding and the call binding are public at this point (remember * the call monitor) hence we need to ensure that things remain * orderly. */ RPC_LOCK_ASSERT(0); if ((*h_)->is_server == 0) { release_cached_ccall((rpc_dg_binding_client_p_t) *h_); RPC_MEM_FREE(*h_, RPC_C_MEM_DG_CHAND); } else { RPC_MEM_FREE(*h_, RPC_C_MEM_DG_SHAND); } *h_ = NULL; *st = rpc_s_ok; }
void rpc_ns_binding_unexport ( unsigned32 entry_name_syntax, unsigned_char_p_t entry_name, rpc_if_handle_t if_spec, uuid_vector_p_t object_uuid_vector ATTRIBUTE_UNUSED, unsigned32 *status ) { LDAP *ld = NULL; unsigned_char_p_t elementDN = NULL; unsigned_char_p_t serverDN = NULL; rpc_ns__ldap_connect_to_server(&ld, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_lookup_server_element(ld, serverDN, if_spec, &elementDN, status); if (*status == rpc_s_ok) { if (ldap_delete_s(ld, elementDN) != LDAP_SUCCESS) { *status = rpc_s_update_failed; goto out; } } if (ldap_delete_s(ld, serverDN) != LDAP_SUCCESS) { *status = rpc_s_update_failed; goto out; } *status = rpc_s_ok; out: if (ld != NULL) { ldap_unbind(ld); } if (elementDN != NULL) { RPC_MEM_FREE(elementDN, RPC_C_MEM_NSRESOLUTION); } if (serverDN != NULL) { RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); } }
PRIVATE void rpc_tower_vector_free ( rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { unsigned32 i; CODING_ERROR (status); /* * Free each tower reference in the vector. */ for (i=0; i < (*twr_vector)->count; i++) { rpc__tower_free (&((*twr_vector)->tower[i]), status); if (*status != rpc_s_ok) { return; } } /* * Free the tower vector structure and set pointer to NULL. */ RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); *twr_vector = NULL; *status = rpc_s_ok; return; }
void rpc_ns_binding_import_begin( /* [in] */ unsigned32 entry_name_syntax, /* [in] */ unsigned_char_p_t entry_name, /* [in] */ rpc_if_handle_t if_spec, /* [in] */ uuid_p_t object_uuid ATTRIBUTE_UNUSED, /* [out] */ rpc_ns_handle_t *import_context, /* [out] */ unsigned32 *status ) { unsigned_char_p_t serverDN = NULL; LDAP *ld; rpc_ns__ldap_connect_to_server(&ld, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_import_server_element(ld, serverDN, if_spec, import_context, status); out: if (serverDN != NULL) { RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); } if (ld != NULL) { ldap_unbind(ld); } }
PRIVATE void rpc__tower_ref_free ( rpc_tower_ref_p_t *tower_ref, unsigned32 *status ) { unsigned32 i; CODING_ERROR (status); /* * Free the tower floors in the tower, freeing the octet string * associated with the each floor only if the free floor flag is set. */ for (i=0; i < (*tower_ref)->count; i++) { rpc__tower_flr_free (&((*tower_ref)->floor[i]), status); if (*status != rpc_s_ok) { return; } } /* * Free the tower reference and set the pointer to NULL. */ RPC_MEM_FREE (*tower_ref, RPC_C_MEM_TOWER_REF); *tower_ref = NULL; *status = rpc_s_ok; return; }
void rpc_ns_binding_export( /* [in] */ unsigned32 entry_name_syntax, /* [in] */ unsigned_char_p_t entry_name, /* [in] */ rpc_if_handle_t if_spec, /* [in] */ rpc_binding_vector_p_t binding_vector, /* [in] */ uuid_vector_p_t object_uuid_vector ATTRIBUTE_UNUSED, /* [out] */ unsigned32 *status ) { LDAP *ld = NULL; unsigned_char_p_t elementDN = NULL; unsigned_char_p_t serverDN = NULL; rpc_ns__ldap_connect_to_server(&ld, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); if (*status != rpc_s_ok) { goto out; } rpc_ns__ldap_lookup_server_element(ld, serverDN, if_spec, &elementDN, status); if (*status != rpc_s_ok) { rpc_ns__ldap_export_server(ld, serverDN, if_spec, status); if (*status == rpc_s_ok) { rpc_ns__ldap_export_server_element(ld, serverDN, if_spec, binding_vector, status); } } else { rpc_ns__ldap_export_server_element_ext(ld, elementDN, if_spec, binding_vector, LDAP_MOD_REPLACE, status); } out: if (ld != NULL) { ldap_unbind(ld); } if (elementDN != NULL) { RPC_MEM_FREE(elementDN, RPC_C_MEM_NSRESOLUTION); } if (serverDN != NULL) { RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); } }
void rpc_ns_binding_import_done( /* [in, out] */ rpc_ns_handle_t *import_context, /* [out] */ unsigned32 *status ) { rpc_ns_handle_rep_t *rep = (rpc_ns_handle_rep_t *)import_context; if (rep != NULL) { unsigned_char_p_t *p; for (p = rep->bindings; *p != NULL; p++) { RPC_MEM_FREE(*p, RPC_C_MEM_NSRESOLUTION); } RPC_MEM_FREE(rep, RPC_C_MEM_NSRESOLUTION); } *status = rpc_s_ok; }
PRIVATE void rpc__tower_free ( twr_p_t *tower, unsigned32 *status ) { CODING_ERROR (status); RPC_MEM_FREE (*tower, RPC_C_MEM_TOWER); *tower = NULL; *status = rpc_s_ok; return; }
INTERNAL void rpc__ntlmauth_free_info ( rpc_auth_info_p_t *info ) { rpc_ntlmauth_info_p_t ntlmauth_info = NULL; unsigned32 st = 0; OM_uint32 minor_status = 0; RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, ("(rpc__ntlmauth_free_info)\n")); if (info == NULL || *info == NULL) { return; } ntlmauth_info = (rpc_ntlmauth_info_p_t)(*info); if (ntlmauth_info->auth_info.server_princ_name) { rpc_string_free(&ntlmauth_info->auth_info.server_princ_name, &st); } if (ntlmauth_info->gss_server_name) { gss_release_name(&minor_status, &ntlmauth_info->gss_server_name); } if (ntlmauth_info->gss_creds) { gss_release_cred(&minor_status, &ntlmauth_info->gss_creds); } memset(ntlmauth_info, 0, sizeof(*ntlmauth_info)); RPC_MEM_FREE(ntlmauth_info, RPC_C_MEM_NTLMAUTH_INFO); rpc_g_ntlmauth_free_count++; RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_free_info) freeing %s auth_info (now %d active).\n", ntlmauth_info->auth_info.is_server ? "server" : "client", rpc_g_ntlmauth_alloc_count - rpc_g_ntlmauth_free_count)); *info = NULL; }
PUBLIC void rpc_string_free ( unsigned_char_p_t *string, unsigned32 *status ) { CODING_ERROR (status); if (*string != NULL) { RPC_MEM_FREE (*string, RPC_C_MEM_STRING); *string = NULL; } *status = rpc_s_ok; return; }
PRIVATE void rpc__dg_client_free ( rpc_client_handle_t client_h ) { unsigned16 probe; rpc_dg_client_rep_p_t client = (rpc_dg_client_rep_p_t) client_h; rpc_dg_client_rep_p_t ptr, prev = NULL; RPC_MUTEX_LOCK(monitor_mutex); /* * Hash into the client rep table based on the client handle's UUID. */ probe = CLIENT_HASH_PROBE(&client->cas_uuid, &st); ptr = client_table[probe]; /* * Scan down the hash chain, looking for the reference to the client * handle */ while (ptr != NULL) { if (ptr == client) { if (prev == NULL) client_table[probe] = ptr->next; else prev->next = ptr->next; RPC_MEM_FREE(client, RPC_C_MEM_DG_CLIENT_REP); RPC_DBG_PRINTF(rpc_e_dbg_general, 3, ("(client_free) Freeing client handle\n")); RPC_MUTEX_UNLOCK(monitor_mutex); return; } prev = ptr; ptr = ptr->next; } RPC_MUTEX_UNLOCK(monitor_mutex); }
PRIVATE void rpc__dg_scall_free ( rpc_dg_scall_p_t scall ) { RPC_DG_CALL_LOCK_ASSERT(&scall->c); assert(scall->c.refcnt == 0); /* * Release all CALL common resources. * This must be the last step. */ rpc__dg_call_free(&scall->c); RPC_MEM_FREE(scall, RPC_C_MEM_DG_SCALL); /* scall may no longer be referenced */ }
INTERNAL void addr_free ( rpc_addr_p_t *rpc_addr, unsigned32 *status ) { CODING_ERROR (status); /* * free memory of RPC addr */ RPC_MEM_FREE (*rpc_addr, RPC_C_MEM_RPC_ADDR); /* * indicate that the rpc_addr is now empty */ *rpc_addr = NULL; *status = rpc_s_ok; }
/* * 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 void rpc__naf_addr_vector_free ( rpc_addr_vector_p_t *rpc_addr_vec, unsigned32 *status ) { unsigned16 i; /* * In case the vector is empty. */ *status = rpc_s_ok; for (i = 0; i < (*rpc_addr_vec)->len; i++) { if ((*rpc_addr_vec)->addrs[i] != NULL) { (*rpc_g_naf_id[(*rpc_addr_vec)->addrs[i]->sa.family].epv->naf_addr_free) (&(*rpc_addr_vec)->addrs[i], status); } } RPC_MEM_FREE (*rpc_addr_vec, RPC_C_MEM_RPC_ADDR_VEC); }
PRIVATE void rpc__ntlmauth_free_info ( rpc_auth_info_p_t *info ) { rpc_ntlmauth_info_p_t ntlmauth_info = (rpc_ntlmauth_info_p_t)*info ; char *info_type = (*info)->is_server?"server":"client"; unsigned32 tst; RPC_MUTEX_DELETE(ntlmauth_info->lock); if ((*info)->server_princ_name) rpc_string_free (&(*info)->server_princ_name, &tst); (*info)->u.s.privs = 0; // sec_id_pac_util_free (&ntlmauth_info->client_pac); memset (ntlmauth_info, 0x69, sizeof(*ntlmauth_info)); RPC_MEM_FREE (ntlmauth_info, RPC_C_MEM_UTIL); rpc_g_ntlmauth_free_count++; RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, ( "(rpc__ntlmauth_release) freeing %s auth_info (now %d active).\n", info_type, rpc_g_ntlmauth_alloc_count - rpc_g_ntlmauth_free_count)); *info = NULL; }
PUBLIC void rpc_tower_vector_from_binding ( rpc_if_handle_t if_spec, rpc_binding_handle_t binding, rpc_tower_vector_p_t *twr_vector, unsigned32 *status ) { rpc_tower_ref_vector_t *tower_ref_vector; unsigned int i; unsigned32 temp_status; CODING_ERROR (status); RPC_VERIFY_INIT (); /* * Null the twr_vector in case of error before finishing. */ *twr_vector = NULL; if (if_spec == NULL) { *status = rpc_s_no_interfaces; return; } /* * Convert the binding to a vector of tower refs. */ rpc__tower_ref_vec_from_binding ((rpc_if_rep_p_t)if_spec, binding, &tower_ref_vector, status); if (*status != rpc_s_ok) { /* * No need to goto CLEANUP; since a tower_ref_vector wasn't * returned to us. */ return; } /* * Allocate a rpc_tower_vector_t based on the number of returned * tower refs. */ RPC_MEM_ALLOC ( *twr_vector, rpc_tower_vector_p_t, sizeof (rpc_tower_vector_t) + (tower_ref_vector->count - 1) * sizeof (twr_p_t), RPC_C_MEM_TOWER_VECTOR, RPC_C_MEM_WAITOK ); (*twr_vector)->count = tower_ref_vector->count; /* * For each returned tower ref convert the tower ref to a twr_t and * store the twr_t in the rpc_tower_vector_t. */ for (i = 0; i < tower_ref_vector->count; i++) { rpc__tower_from_tower_ref (tower_ref_vector->tower[i], &(*twr_vector)->tower[i], status); if (*status != rpc_s_ok) { RPC_MEM_FREE (*twr_vector, RPC_C_MEM_TOWER_VECTOR); goto CLEANUP; } } CLEANUP: /* * Free the tower_ref_vector returned from * rpc__tower_ref_vec_from_binding(). */ rpc__tower_ref_vec_free (&tower_ref_vector, &temp_status); /* * If we got this far successfully, return whatever the result from * rpc__tower_ref_vec_free(). Otherwise, return the previous error * in status. */ if (*status == rpc_s_ok) { *status = temp_status; } return; }
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); } }
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; }
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); } }
/* * 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); } }
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; }
/* * 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; }
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; }
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 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. */ }
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 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; } } }
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; } }