Beispiel #1
0
rpc_binding::~rpc_binding()
{
    if (binding_handle) {
        error_status_t status;
	
        rpc_network_close(binding_handle, &status);
        rpc_binding_free(&binding_handle, &status);
    }
}
Beispiel #2
0
DWORD
VmDirRpcFreeBinding(
    handle_t* pBinding
)
{
    DWORD dwError = ERROR_SUCCESS;
#if !defined(_WIN32) || defined(HAVE_DCERPC_WIN32)
     rpc_binding_free(pBinding, &dwError);
#else
    dwError = RpcBindingFree(pBinding);
#endif
    return dwError;
}
Beispiel #3
0
VMDNS_API
VOID
VmDnsCloseServer(PVMDNS_SERVER_CONTEXT pServerContext)
{
	if(pServerContext)
	{
		if (pServerContext->hBinding)
		{
			DWORD dwError = 0;
			rpc_binding_free(&pServerContext->hBinding, &dwError);
			pServerContext->hBinding = NULL;
		}

		VMDNS_SAFE_FREE_MEMORY(pServerContext);
	}
}
Beispiel #4
0
VOID
FreeRpcBinding(
    PVOID            *phBinding,
    RPC_BINDING_TYPE  eBindingType
    )
{
    unsigned32 rpcStatus = RPC_S_OK;
    PVOID hBinding = NULL;

    if (phBinding) return;

    hBinding = *phBinding;

    switch (eBindingType)
    {
    case RPC_LSA_BINDING:
        LsaFreeBinding(hBinding);
        break;

    case RPC_SAMR_BINDING:
        SamrFreeBinding(hBinding);
        break;

    case RPC_NETLOGON_BINDING:
        NetrFreeBinding(hBinding);
        break;

    case RPC_DSSETUP_BINDING:
        DsrFreeBinding(hBinding);
        break;

    case RPC_WKSSVC_BINDING:
        WkssFreeBinding(hBinding);
        break;

    default:
        if (phBinding && *phBinding)
        {
            rpc_binding_free((handle_t*)phBinding, &rpcStatus);
        }
        break;
    }

    *phBinding = NULL;
}
Beispiel #5
0
DWORD
VMCAGetClientName(handle_t IDL_handle)
{
#if DEBUG_RPC
  rpc_binding_handle_t Srv;
  PSTR pszBinding = NULL;
  PSTR pszObjUUID = NULL;
  PSTR pszProtoSeq = NULL;
  PSTR pszNetworkAddress = NULL;
  PSTR pszEndPoint = NULL;
  PSTR pszNetworkOptions = NULL;


  unsigned32 rs = 0;
  rpc_binding_server_from_client (IDL_handle, &Srv, &rs);
  BAIL_ON_VMCA_ERROR(rs);
  rpc_binding_to_string_binding(Srv,
                        (unsigned char **) &pszBinding, &rs);
  printf("Binding Info : %s\n", pszBinding);
  rpc_binding_free(&Srv, &rs);

  rpc_string_binding_parse(pszBinding,
                        (unsigned_char_t **) &pszObjUUID,
                        (unsigned_char_t **) &pszProtoSeq,
                        (unsigned_char_t **) &pszNetworkAddress,
                        (unsigned_char_t **) &pszEndPoint,
                        (unsigned_char_t **) &pszNetworkOptions,
                        &rs);
  printf("Obj UUID : %s, Proto : %s, Network : %s, \
            EndPoint %s, Network Options : %s \n",
            pszObjUUID,
            pszProtoSeq,
            pszNetworkAddress,
            pszEndPoint,
            pszNetworkOptions);

    rpc_string_free((unsigned_char_t **) &pszBinding, &rs);
    rpc_string_free((unsigned_char_t **) &pszObjUUID, &rs);
    rpc_string_free((unsigned_char_t **) &pszProtoSeq, &rs);
    rpc_string_free((unsigned_char_t **) &pszNetworkAddress, &rs);
    rpc_string_free((unsigned_char_t **) &pszEndPoint, &rs);
    rpc_string_free((unsigned_char_t **) &pszNetworkOptions, &rs);
#endif
    return 0;
}
Beispiel #6
0
VOID
LsaFreeBinding(
    IN OUT PLSA_BINDING  phBinding
    )
{
    unsigned32 rpcStatus = RPC_S_OK;

    /* Free the binding itself */

    if (phBinding && *phBinding)
    {
	    rpc_binding_free((handle_t*)phBinding, &rpcStatus);
        BAIL_ON_RPC_STATUS(rpcStatus);

        *phBinding = NULL;
    }

cleanup:
    return;

error:
    goto cleanup;
}
Beispiel #7
0
INTERNAL int is_unpriv_handle( handle_t h, error_status_t *st )
{

    error_status_t status,status1;
    rpc_binding_vector_p_t bv;
    handle_t binding;
    unsigned_char_p_t stb,our_netaddr,client_netaddr;
    unsigned32 i;
    static unsigned_char_p_t *local_netaddr = NULL;
    static unsigned32 addr_count = 0;
    unsigned32 prot_seq = 0;
    rpc_transport_info_handle_t info;
    unsigned32 uid = (unsigned32) -1;
    unsigned32 gid = (unsigned32) -1;

    rpc_binding_inq_prot_seq(h, &prot_seq, &status);

    if (! STATUS_OK(&status))
    {
        *st = status;
        return(1);
    }

    if (prot_seq == rpc_c_protseq_id_ncalrpc)
    {
        rpc_binding_inq_transport_info(h, &info, &status);

        if (! STATUS_OK(&status))
        {
            *st = status;
            return(1);
        }

        rpc_lrpc_transport_info_inq_peer_eid(info, &uid, &gid);

        *st = rpc_s_ok;

        return (uid != 0);
    }

/* Get client network address from binding handle (client_netaddr) */

    rpc_binding_server_from_client(h,&binding,&status);
    if (! STATUS_OK(&status))
    {
        *st = status;
        return(1);
    }
    rpc_binding_to_string_binding(binding,&stb,&status);

    if (! STATUS_OK(&status))
    {
        rpc_binding_free(&binding,&status1);
        *st = status;
        return(1);
    }
    rpc_binding_free(&binding,&status1);

    rpc_string_binding_parse(stb,NULL,NULL,&client_netaddr,NULL,NULL,&status);
    if (! STATUS_OK(&status))
    {
        rpc_string_free(&stb,&status1);
        *st = status;
        return(1);
    }
    rpc_string_free(&stb,&status1);

    /*
     * Lookup all of the addresses which this node answers to.
     * Cache these in static storage so we only do this work once.
     */
    if (addr_count == 0)
    {
        rpc_server_inq_bindings(&bv,&status);
        if (! STATUS_OK(&status))
        {
            rpc_string_free(&client_netaddr,&status1);
            *st = status;
            return(1);
        }

        addr_count = bv->count;
        local_netaddr = (unsigned_char_p_t *) malloc(
                        (size_t) (addr_count * sizeof(unsigned_char_p_t)));
        if (local_netaddr == NULL)
        {
            rpc_string_free(&client_netaddr,&status1);
            rpc_binding_vector_free(&bv,&status1);
            *st = ept_s_no_memory;
            return(1);
        }

        for ( i=0; i < bv->count; i++ )
        {
            rpc_binding_to_string_binding(bv->binding_h[i],&stb,&status);
            if (! STATUS_OK(&status))
            {
                rpc_binding_vector_free(&bv,&status1);
                rpc_string_free(&client_netaddr,&status1);
                *st = status;
                return(1);
            }
            rpc_string_binding_parse(stb,NULL,NULL,
                                     &our_netaddr,NULL,NULL,&status);
            if (! STATUS_OK(&status))
            {
                rpc_binding_vector_free(&bv,&status1);
                rpc_string_free(&stb,&status1);
                rpc_string_free(&client_netaddr,&status1);
                *st = status;
                return(1);
            }

            local_netaddr[i] = our_netaddr;
            rpc_string_free(&stb,&status1);
        }
        rpc_binding_vector_free(&bv,&status1);
    }

    /*
     * Compare the addresses with the client address
     */
    *st = rpc_s_ok;
    for ( i=0; i < addr_count; i++ )
    {
        if(strcmp((char*) client_netaddr, (char*) local_netaddr[i]) == 0)
        {
            rpc_string_free(&client_netaddr,&status1);
            return(0);
        }
    }
    rpc_string_free(&client_netaddr,&status1);
    return(1);

}
Beispiel #8
0
static int
rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
    struct share_info **entries_listp)
{
	char ctx_string[2+16+1];	/* enough for 64-bit pointer, in hex */
	unsigned_char_p_t binding;
	unsigned32 binding_status;
	rpc_binding_handle_t binding_h;
	int error, i, entries;
	char *addrstr, *srvnamestr;
	unsigned short *usrvnamestr;
	unsigned32 level;
	SHARE_ENUM_STRUCT share_info;
	SHARE_INFO_1_CONTAINER share_info_1_container;
	SHARE_INFO_1 *shares, *share;
	unsigned32 total_entries;
	unsigned32 status, free_status;
	struct share_info *entry_list, *elp;
	static EXCEPTION rpc_x_connect_rejected;
	static int exceptions_initialized;

	sprintf(ctx_string, "%p", ctx);
	rpc_string_binding_compose(NULL, "ncacn_np", ctx_string,
	    "srvsvc", NULL, &binding, &binding_status);
	if (binding_status != rpc_s_ok) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "rpc_string_binding_compose failed with %d"),
		    0, binding_status);
		return (EINVAL);
	}
	rpc_binding_from_string_binding(binding, &binding_h, &status);
	rpc_string_free(&binding, (unsigned32 *)&free_status);
	if (binding_status != rpc_s_ok) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "rpc_binding_from_string_binding failed with %d"), 0,
		    binding_status);
		return (EINVAL);
	}
	level = 1;
	share_info.share_union.level = 1;
	share_info.share_union.tagged_union.share1 = &share_info_1_container;
	share_info_1_container.share_count = 0;
	share_info_1_container.shares = NULL;
	/*
	 * Convert the server IP address to a string, and send that as
	 * the "server name" - that's what Windows appears to do, and
	 * that avoids problems with NetBIOS names containing
	 * non-ASCII characters.
	 */
	addrstr = inet_ntoa(ctx->ct_srvinaddr.sin_addr);
	srvnamestr = malloc(strlen(addrstr) + 3);
	if (srvnamestr == NULL) {
		status = errno;
		smb_error(dgettext(TEXT_DOMAIN,
		    "can't allocate string for server address"), status);
		rpc_binding_free(&binding_h, &free_status);
		return (status);
	}
	strcpy(srvnamestr, "\\\\");
	strcat(srvnamestr, addrstr);
	usrvnamestr = convert_utf8_to_leunicode(srvnamestr);
	if (usrvnamestr == NULL) {
		smb_error(dgettext(TEXT_DOMAIN,
		    "can't convert string for server address to Unicode"), 0);
		rpc_binding_free(&binding_h, &free_status);
		free(srvnamestr);
		return (EINVAL);
	}
	if (!exceptions_initialized) {
		EXCEPTION_INIT(rpc_x_connect_rejected);
		exc_set_status(&rpc_x_connect_rejected, rpc_s_connect_rejected);
		exceptions_initialized = 1;
	}
	/* printf("Calling NetrShareEnum.."); XXX */
	TRY
		status = NetrShareEnum(binding_h, usrvnamestr, &level,
		    &share_info, 4294967295U, &total_entries, NULL);
		if (status != 0)
			smb_error(dgettext(TEXT_DOMAIN,
			    "error from NetrShareEnum call: status = 0x%08x"),
			    0, status);
	/*CSTYLED*/
	CATCH (rpc_x_connect_rejected)
		/*
		 * This is what we get if we can't open the pipe.
		 * That's a normal occurrence when we're talking
		 * to a system that (presumably) doesn't support
		 * DCE RPC on the server side, such as Windows 95/98/Me,
		 * so we don't log an error.
		 */
		/*CSTYLED*/
		status = ENOTSUP;
	CATCH_ALL
		/*
		 * XXX - should we handle some exceptions differently,
		 * returning different errors, and try RAP only for
		 * ENOTSUP?
		 */
		smb_error(dgettext(TEXT_DOMAIN,
		    "error from NetrShareEnum call: exception = %u"),
		    0, THIS_CATCH->match.value);
		status = ENOTSUP;
	ENDTRY
	rpc_binding_free(&binding_h, &free_status);
	free(srvnamestr);
	free(usrvnamestr);
	if (status != 0)
		return (ENOTSUP);

	/*
	 * XXX - if the IDL is correct, it's not clear whether the
	 * unmarshalling code will properly handle the case where
	 * a packet where "share_count" and the max count for the
	 * array of shares don't match; a valid DCE RPC implementation
	 * won't marshal something like that, but there's no guarantee
	 * that the server we're talking to has a valid implementation
	 * (which could be a *malicious* implementation!).
	 */
	entries = share_info.share_union.tagged_union.share1->share_count;
	shares = share_info.share_union.tagged_union.share1->shares;
	entry_list = calloc(entries, sizeof (struct share_info));
	if (entry_list == NULL) {
		error = errno;
		goto cleanup_and_return;
	}
	for (share = shares, elp = entry_list, i = 0; i < entries;
	    i++, share++) {
		elp->type = share->shi1_type;
		elp->netname = convert_unicode_to_utf8(share->shi1_share);
		if (elp->netname == NULL)
			goto fail;
		elp->remark = convert_unicode_to_utf8(share->shi1_remark);
		if (elp->remark == NULL)
			goto fail;
		elp++;
	}
	*entriesp = entries;
	*totalp = total_entries;
	*entries_listp = entry_list;
	error = 0;
	goto cleanup_and_return;

fail:
	error = errno;
	for (elp = entry_list, i = 0; i < entries; i++, elp++) {
		/*
		 * elp->netname is set before elp->remark, so if
		 * elp->netname is null, elp->remark is also null.
		 * If either of them is null, we haven't done anything
		 * to any entries after this one.
		 */
		if (elp->netname == NULL)
			break;
		free(elp->netname);
		if (elp->remark == NULL)
			break;
		free(elp->remark);
	}
	free(entry_list);

cleanup_and_return:
	for (share = shares, i = 0; i < entries; i++, share++) {
		free(share->shi1_share);
		free(share->shi1_remark);
	}
	free(shares);
	/*
	 * XXX - "share1" should be a unique pointer, but we haven't
	 * changed the marshalling code to support non-full pointers
	 * in unions, so we leave it as a full pointer.
	 *
	 * That means that this might, or might not, be changed from
	 * pointing to "share_info_1_container" to pointing to a
	 * mallocated structure, according to the DCE RPC 1.1 IDL spec;
	 * we free it only if it's changed.
	 */
	if (share_info.share_union.tagged_union.share1 !=
	    &share_info_1_container)
		free(share_info.share_union.tagged_union.share1);
	return (error);
}
Beispiel #9
0
static
NTSTATUS
LsaInitBindingFullA(
    OUT PLSA_BINDING   phBinding,
    IN  PCSTR          pszProtSeq,
    IN  PCSTR          pszHostname,
    IN  PCSTR          pszEndpoint,
    IN  PCSTR          pszUuid,
    IN  PCSTR          pszOptions,
    IN  PIO_CREDS      pCreds
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;
    unsigned32 rpcStatus = RPC_S_OK;
    unsigned32 rpcStatus2 = RPC_S_OK;
    PBYTE pbBindingString = NULL;
    PBYTE pbProtSeq = NULL;
    PBYTE pbEndpoint = NULL;
    PBYTE pbUuid = NULL;
    PBYTE pbOpts = NULL;
    PBYTE pbAddr = NULL;
    handle_t hBinding = NULL;
    rpc_transport_info_handle_t hInfo = NULL;

    BAIL_ON_INVALID_PTR(phBinding, ntStatus);
    BAIL_ON_INVALID_PTR(pszProtSeq, ntStatus);

    pbProtSeq = (PBYTE)strdup(pszProtSeq);
    BAIL_ON_NULL_PTR(pbProtSeq, ntStatus);

    if (pszEndpoint != NULL)
    {
        pbEndpoint = (PBYTE) strdup(pszEndpoint);
        BAIL_ON_NULL_PTR(pbEndpoint, ntStatus);
    }

    if (pszUuid != NULL)
    {
        pbUuid = (PBYTE)strdup(pszUuid);
        BAIL_ON_NULL_PTR(pbUuid, ntStatus);
    }

    if (pszOptions != NULL)
    {
        pbOpts = (PBYTE)strdup(pszOptions);
        BAIL_ON_NULL_PTR(pbOpts, ntStatus);
    }

    if (pszHostname)
    {
        pbAddr = (PBYTE)strdup(pszHostname);
        BAIL_ON_NULL_PTR(pbAddr, ntStatus);
    }

    rpc_string_binding_compose(
        pbUuid,
        pbProtSeq,
        pbAddr,
        pbEndpoint,
        pbOpts,
        &pbBindingString,
        &rpcStatus);
    BAIL_ON_RPC_STATUS(rpcStatus);

    rpc_binding_from_string_binding(
        pbBindingString,
        &hBinding,
        &rpcStatus);
    BAIL_ON_RPC_STATUS(rpcStatus);

    if (strcmp(pszProtSeq, "ncacn_np") == 0)
    {
        rpc_smb_transport_info_from_lwio_creds(
            pCreds,
            &hInfo,
            &rpcStatus);
        BAIL_ON_RPC_STATUS(rpcStatus);

        rpc_binding_set_transport_info(
            hBinding,
            hInfo,
            &rpcStatus);
        BAIL_ON_RPC_STATUS(rpcStatus);

        hInfo = NULL;
    }

    rpc_mgmt_set_com_timeout(hBinding, 6, &rpcStatus);
    BAIL_ON_RPC_STATUS(rpcStatus);

    *phBinding = (LSA_BINDING)hBinding;

cleanup:
    LW_SAFE_FREE_MEMORY(pbProtSeq);
    LW_SAFE_FREE_MEMORY(pbEndpoint);
    LW_SAFE_FREE_MEMORY(pbUuid);
    LW_SAFE_FREE_MEMORY(pbOpts);
    LW_SAFE_FREE_MEMORY(pbAddr);

    if (pbBindingString)
    {
        rpc_string_free(&pbBindingString, &rpcStatus2);
    }

    if ((rpcStatus == RPC_S_OK) && (rpcStatus2 != RPC_S_OK))
    {
        rpcStatus = rpcStatus2;
    }

    if (hInfo)
    {
        rpc_smb_transport_info_free(hInfo);
    }

    if (ntStatus == STATUS_SUCCESS &&
        rpcStatus != RPC_S_OK)
    {
        ntStatus = LwRpcStatusToNtStatus(rpcStatus);
    }

    return ntStatus;

error:
    if (hBinding)
    {
        rpc_binding_free(&hBinding, &rpcStatus2);
    }

    if (phBinding)
    {
        *phBinding = NULL;
    }

    goto cleanup;
}
Beispiel #10
0
PRIVATE void rpc__dg_binding_inq_client
(
    rpc_binding_rep_p_t binding_r,
    rpc_client_handle_t *client_h,
    unsigned32 *st
)
{       
    rpc_dg_binding_server_p_t shand = (rpc_dg_binding_server_p_t) binding_r;
    rpc_dg_scall_p_t scall = shand->scall;
    rpc_binding_handle_t h;
    dce_uuid_t cas_uuid;
    rpc_dg_client_rep_p_t client;
    unsigned32 temp_seq, tst;
                              
    *st = rpc_s_ok;

    /*
     * Lock down and make sure we're in an OK state.
     */

    RPC_LOCK(0);
    RPC_DG_CALL_LOCK(&scall->c);
                      
    if (scall->c.state == rpc_e_dg_cs_orphan)
    {
        *st = rpc_s_call_orphaned;
        RPC_DG_CALL_UNLOCK(&scall->c);
        RPC_UNLOCK(0);
        return;
    }
    
    /*
     * See if there is already a client handle associated with the scte
     * associated with this server binding handle.  If there is, just
     * return it.
     */

    if (scall->scte->client != NULL)
    {
        *client_h = (rpc_client_handle_t) scall->scte->client;
        RPC_DG_CALL_UNLOCK(&scall->c);
        RPC_UNLOCK(0);
        return;
    }

    /*
     * No client handle.  We need to do a call back to obtain a UUID
     * uniquely identifying this particular instance of the client.
     */

    h = rpc__dg_sct_make_way_binding(scall->scte, st);

    RPC_DG_CALL_UNLOCK(&scall->c);
    RPC_UNLOCK(0);

    if (h == NULL)
    {
        return;
    }

    RPC_DBG_PRINTF(rpc_e_dbg_general, 3, 
        ("(binding_inq_client) Doing whats-your-proc-id callback\n"));

    DCETHREAD_TRY
    {
        (*conv_v3_0_c_epv.conv_who_are_you2)
            (h, &scall->c.call_actid, rpc_g_dg_server_boot_time, 
            &temp_seq, &cas_uuid, st);
    }
    DCETHREAD_CATCH_ALL(THIS_CATCH)
    {
        *st = rpc_s_who_are_you_failed;
    }
    DCETHREAD_ENDTRY

    rpc_binding_free(&h, &tst);

    if (*st != rpc_s_ok)
        return;

    /*
     * Check to see if the UUID returned has already been built into
     * a client handle associated with another scte.  Since we have no
     * way of mapping actids to processes, we can't know that two actid
     * are in the same address space until we get the same address space
     * UUID from both.  In this case it is necessary to use the same
     * client handle for both actids.
     */
             
    RPC_LOCK(0);          
    RPC_DG_CALL_LOCK(&scall->c);

    if (scall->c.state == rpc_e_dg_cs_orphan)
    {
        *st = rpc_s_call_orphaned;
        RPC_DG_CALL_UNLOCK(&scall->c);
        RPC_UNLOCK(0);                                     
        return;
    }
    
    RPC_MUTEX_LOCK(monitor_mutex);

    client = find_client(&cas_uuid);

    if (client != NULL)
    {   
        client->refcnt++;
        scall->scte->client = client;
    }
    else
    {
        /*
         * If not, alloc up a client handle structure and thread
         * it onto the table.
         */

        unsigned16 probe;

        probe = CLIENT_HASH_PROBE(&cas_uuid, st);

        RPC_MEM_ALLOC(client, rpc_dg_client_rep_p_t, sizeof *client, 
            RPC_C_MEM_DG_CLIENT_REP, RPC_C_MEM_NOWAIT);

        client->next = client_table[probe];
        client->rundown = NULL;
        client->last_update = 0;
        client->cas_uuid = cas_uuid;

        client_table[probe] = client;
        scall->scte->client = client;
        client->refcnt = 2;
    }  

    RPC_MUTEX_UNLOCK(monitor_mutex);
    RPC_DG_CALL_UNLOCK(&scall->c);
    RPC_UNLOCK(0);                                     
    
    *client_h = (rpc_client_handle_t) client; 
}