Ejemplo n.º 1
0
DWORD
VmDnsCheckAccess(
    handle_t IDL_handle,
    BOOL bNeedAdminPrivilage
    )
{
    DWORD dwError = 0;
    rpc_authz_cred_handle_t hPriv = { 0 };
    DWORD dwProtectLevel = 0;
    ULONG rpc_status = rpc_s_ok;
    unsigned char *authPrinc = NULL;

    rpc_binding_inq_auth_caller(
                IDL_handle,
                &hPriv,
                &authPrinc,
                &dwProtectLevel,
                NULL, /* unsigned32 *authn_svc, */
                NULL, /* unsigned32 *authz_svc, */
                &rpc_status);

    /* Deny if connection is not encrypted */
    if (dwProtectLevel < rpc_c_protect_level_pkt_privacy)
    {
        dwError = ERROR_ACCESS_DENIED;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    /* Deny if no auth identity is provided.  */
    if (rpc_status == rpc_s_binding_has_no_auth || !authPrinc || !*authPrinc)
    {
        dwError = ERROR_ACCESS_DENIED;
        BAIL_ON_VMDNS_ERROR(dwError);
    }

    if (bNeedAdminPrivilage)
    {
        dwError = VmDnsLdapAccessCheck(authPrinc, VMDNS_ADMINISTRATORS);
        BAIL_ON_VMDNS_ERROR(dwError);
    }

error:
    if (authPrinc)
    {
        rpc_string_free((unsigned_char_t **)&authPrinc, &rpc_status);
    }

    return dwError;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
/*
 * 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);
	}
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
BOOLEAN
CreateRpcBinding(
    PVOID            *phBinding,
    RPC_BINDING_TYPE  eBindingType,
    PCWSTR            pwszHostname,
    PCWSTR            pwszBinding,
    PCREDENTIALS      pCredentials
    )
{
    PCSTR pszNtlmsspAuth = "ntlmssp";
    PCSTR pszSign = "sign";
    PCSTR pszSeal = "seal";

    BOOLEAN bRet = TRUE;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    DWORD dwError = ERROR_SUCCESS;
    unsigned32 rpcStatus = RPC_S_OK;
    LSA_BINDING hBinding = NULL;
    LW_PIO_CREDS pIoCreds = NULL;
    PWSTR pwszBindingString = NULL;
    size_t sBindingStringLen = 0;
    PSTR pszBindingString = NULL;
    PSTR *ppszOptions = NULL;
    DWORD iOpt = 0;
    DWORD i = 0;
    DWORD dwNumValidOptions = 0;
    unsigned32 AuthType = 0;
    unsigned32 ProtectionLevel = 0;
    SEC_WINNT_AUTH_IDENTITY *pNtlmSspAuthInfo = NULL;
    PVOID pAuthInfo = NULL;
    unsigned char *pszUuid = NULL;
    unsigned char *pszProtSeq = NULL;
    unsigned char *pszNetworkAddr = NULL;
    unsigned char *pszEndpoint = NULL;
    unsigned char *pszOptions = NULL;
    PSTR pszHostname = NULL;

    if (phBinding == NULL)
    {
        ntStatus = STATUS_INVALID_PARAMETER;
        BAIL_ON_NT_STATUS(ntStatus);
    }

    if (pwszBinding)
    {
        dwError = LwAllocateWc16String(&pwszBindingString,
                                       pwszBinding);
        BAIL_ON_WIN_ERROR(dwError);

        dwError = LwWc16sLen(pwszBindingString, &sBindingStringLen);
        BAIL_ON_WIN_ERROR(dwError);

        dwError = LwWc16sToMbs(pwszBindingString,
                               &pszBindingString);
        BAIL_ON_WIN_ERROR(dwError);

        ppszOptions = get_string_list(pszBindingString, ':');
        if (ppszOptions == NULL)
        {
            ntStatus = STATUS_INVALID_PARAMETER;
            BAIL_ON_NT_STATUS(ntStatus);
        }

        /*
         * Find and identify valid options
         */
        while (ppszOptions[iOpt])
        {
            if (!strcasecmp(pszNtlmsspAuth, ppszOptions[iOpt]))
            {
                AuthType = rpc_c_authn_winnt;
                dwNumValidOptions++;
            }
            else if (!strcasecmp(pszSign, ppszOptions[iOpt]))
            {
                ProtectionLevel = rpc_c_authn_level_pkt_integrity;
                dwNumValidOptions++;
            }
            else if (!strcasecmp(pszSeal, ppszOptions[iOpt]))
            {
                ProtectionLevel = rpc_c_authn_level_pkt_privacy;
                dwNumValidOptions++;
            }

            iOpt++;
        }
    }

    /*
     * Cut off the options from the binding string so it can
     * be passed to rpc routines
     */
    if (dwNumValidOptions > 0)
    {
        i = sBindingStringLen;
        while (dwNumValidOptions &&
               pwszBindingString[--i])
        {
            if (pwszBindingString[i] == (WCHAR)':')
            {
                dwNumValidOptions--;
            }
        }

        pwszBindingString[i] = (WCHAR)'\0';
        pszBindingString[i] = '\0';
    }

    ntStatus = LwIoGetActiveCreds(NULL, &pIoCreds);
    BAIL_ON_NT_STATUS(ntStatus);

    if (pwszBindingString)
    {
        ntStatus = RpcInitBindingFromBindingString(
                                         (handle_t*)&hBinding,
                                         pwszBindingString,
                                         pIoCreds);
    }
    else
    {
        switch (eBindingType)
        {
        case RPC_LSA_BINDING:
            ntStatus = LsaInitBindingDefault(&hBinding,
                                             pwszHostname,
                                             pIoCreds);
            break;

        case RPC_SAMR_BINDING:
            ntStatus = SamrInitBindingDefault(&hBinding,
                                              pwszHostname,
                                              pIoCreds);
            break;

        case RPC_NETLOGON_BINDING:
            ntStatus = NetrInitBindingDefault(&hBinding,
                                              pwszHostname,
                                              pIoCreds);
            break;

        case RPC_DSSETUP_BINDING:
            ntStatus = DsrInitBindingDefault(&hBinding,
                                             pwszHostname,
                                             pIoCreds);
            break;

        case RPC_WKSSVC_BINDING:
            ntStatus = WkssInitBindingDefault(&hBinding,
                                              pwszHostname,
                                              pIoCreds);
            break;

        default:
            ntStatus = STATUS_NOT_IMPLEMENTED;
            break;
        }
    }
    BAIL_ON_NT_STATUS(ntStatus);

    switch (AuthType)
    {
    case rpc_c_authn_winnt:
        dwError = LwAllocateMemory(sizeof(*pNtlmSspAuthInfo),
                                   OUT_PPVOID(&pNtlmSspAuthInfo));
        BAIL_ON_WIN_ERROR(dwError);

        if (pCredentials->Ntlm.pwszDomain)
        {
            dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszDomain,
                                   &pNtlmSspAuthInfo->Domain);
            BAIL_ON_WIN_ERROR(dwError);

            pNtlmSspAuthInfo->DomainLength = strlen(pNtlmSspAuthInfo->Domain);
        }

        dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszUsername,
                               &pNtlmSspAuthInfo->User);
        BAIL_ON_WIN_ERROR(dwError);

        pNtlmSspAuthInfo->UserLength = strlen(pNtlmSspAuthInfo->User);

        dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszPassword,
                               &pNtlmSspAuthInfo->Password);
        BAIL_ON_WIN_ERROR(dwError);

        pNtlmSspAuthInfo->PasswordLength = strlen(pNtlmSspAuthInfo->Password);

        pAuthInfo = (PVOID)pNtlmSspAuthInfo;
        break;

    default:
        pAuthInfo = NULL;
        break;
    }

    if (pwszHostname)
    {
        dwError = LwWc16sToMbs(pwszHostname,
                               &pszHostname);
        BAIL_ON_WIN_ERROR(dwError);
    }
    else
    {
        rpc_string_binding_parse((unsigned char*)pszBindingString,
                                 &pszUuid,
                                 &pszProtSeq,
                                 &pszNetworkAddr,
                                 &pszEndpoint,
                                 &pszOptions,
                                 &rpcStatus);
        if (rpcStatus)
        {
            ntStatus = LwRpcStatusToNtStatus(rpcStatus);
            BAIL_ON_NT_STATUS(ntStatus);
        }

        dwError = LwAllocateString((PSTR)pszNetworkAddr,
                                   &pszHostname);
        BAIL_ON_WIN_ERROR(dwError);
    }

    if (AuthType)
    {
        rpc_binding_set_auth_info(hBinding,
                                  (unsigned char*)pszHostname,
                                  ProtectionLevel,
                                  AuthType,
                                  (rpc_auth_identity_handle_t)pAuthInfo,
                                  rpc_c_authz_name, /* authz_protocol */
                                  &rpcStatus);
        if (rpcStatus)
        {
            ntStatus = LwRpcStatusToNtStatus(rpcStatus);
            BAIL_ON_NT_STATUS(ntStatus);
        }
    }

    *phBinding = hBinding;

cleanup:
    if (pIoCreds)
    {
        LwIoDeleteCreds(pIoCreds);
    }

    LW_SAFE_FREE_MEMORY(pwszBindingString);
    LW_SAFE_FREE_MEMORY(pszBindingString);
    LW_SAFE_FREE_MEMORY(pszHostname);

    rpc_string_free(&pszUuid, &rpcStatus);
    rpc_string_free(&pszProtSeq, &rpcStatus);
    rpc_string_free(&pszNetworkAddr, &rpcStatus);
    rpc_string_free(&pszEndpoint, &rpcStatus);
    rpc_string_free(&pszOptions, &rpcStatus);

    if (ppszOptions)
    {
        free_string_list(ppszOptions);
    }

    if (ntStatus == STATUS_SUCCESS &&
        dwError != ERROR_SUCCESS)
    {
        ntStatus = LwWin32ErrorToNtStatus(dwError);
    }

    if (ntStatus != STATUS_SUCCESS)
    {
        bRet = FALSE;
    }

    return bRet;

error:
    *phBinding = NULL;
    bRet       = FALSE;

    goto cleanup;
}
Ejemplo n.º 7
0
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);
	}
}
Ejemplo n.º 8
0
/*
 * 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);
	}
}
Ejemplo n.º 9
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);

}
Ejemplo n.º 10
0
// Return an appropriate binding for the given ServerName.
rpc_binding
make_rpc_binding(
				 const char * ServerName,
				 const char * EndPoint)
{
    char * binding_string = NULL;
    char * endpoint_string = NULL;
    uint32_t status;
	
    if (!EndPoint) {
        return rpc_binding();
    }
	
    if (ServerName) {
        /* add in the "\pipe\" to the endpoint */
        asprintf(&endpoint_string, "\\pipe\\%s]", EndPoint);
        
        rpc_string_binding_compose(NULL, 
                                   (idl_char *) "ncacn_np", 
                                   (idl_char *) ServerName, 
                                   (idl_char *) endpoint_string, 
                                   NULL,
                                   (idl_char **) &binding_string, 
                                   &status);
        if (status != 0) {
            SMBLogInfo("rpc_string_binding_compose failed on <%s>:<%s> status %#08x", 
                       ASL_LEVEL_ERR, 
                       ServerName == NULL ? "nullstr" : ServerName, 
                       EndPoint == NULL ? "nullstr" : EndPoint, 
                       status);
            
            /* fallback to the old way instead */
            asprintf(&binding_string, "ncacn_np:%s[%s]",
                     ServerName, endpoint_string);
        }
        
        if (endpoint_string != NULL) {
            free(endpoint_string);
        }
    } 
    else {
        rpc_string_binding_compose(NULL, 
                                   (idl_char *) "ncalrpc", 
                                   NULL, 
                                   (idl_char *) EndPoint, 
                                   NULL, 
                                   (idl_char **) &binding_string, 
                                   &status);
        if (status != 0) {
            SMBLogInfo("rpc_string_binding_compose failed on <%s> status %#08x", 
                       ASL_LEVEL_ERR, 
                       EndPoint == NULL ? "nullstr" : EndPoint, 
                       status);
            
            /* fallback to the old way instead */
            asprintf(&binding_string, "ncalrpc:[%s]", EndPoint);
        }
    }
	
    if (!binding_string) {
        platform::invoke_new_handler();
    }
	
    rpc_binding binding(binding_string);
    
    if (status == 0) {
        /* rpc_string_binding_compose worked */
        if (binding_string != NULL) {
            rpc_string_free((idl_char **) &binding_string, &status);
            if (status != 0) {
                SMBLogInfo("rpc_string_free failed on <%s> status %#08x", 
                           ASL_LEVEL_ERR, 
                           binding_string == NULL ? "nullstr" : binding_string, 
                           status);
            }
        }
    }
    else {
        /* must have used asprintf */
        if (binding_string != NULL) {
            free(binding_string);
        }
    }
    
    return binding;
}
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
PRIVATE void rpc__dg_plog_dump(void)
{
    unsigned16 i;
    unsigned32 st;
    static char *lossy_action = "d?r "; /* (0)drop, (1)?, (2)rexmit, (3)normal */

    RPC_LOCK_ASSERT(0);

    if (rpc_g_dg_pkt_log == NULL)
    {
	RPC_DBG_PRINTF(rpc_e_dbg_dg_pktlog, 1,
            ("rpc__dg_plog_dump called, but DG Pkt Logging never enabled\n") );
        return;
    }

    RPC_DBG_PRINTF(rpc_e_dbg_dg_pktlog, 1,
	("tstamp   ver ptyp f1 f2     seq/fnum/sn    ihnt ahnt  len              interface/ver/op                            activity                  sboot                    object              drep   at\n") );
    RPC_DBG_PRINTF(rpc_e_dbg_dg_pktlog, 1,
	("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n") );

    for (i = 0; i < RPC_C_DG_PKT_LOG_SIZE; i++)
    {
        pktlog_elt_p_t p = &rpc_g_dg_pkt_log[i];
        unsigned_char_p_t obj, iface, act;
        rpc_dg_pkt_hdr_p_t hdrp;

#ifndef MISPACKED_HDR
        hdrp = (rpc_dg_pkt_hdr_p_t) &p->hdr;
#else
        hdrp = converted local rep of raw hdr
#endif

        if (p->timestamp == 0)
            break;

        dce_uuid_to_string(&hdrp->object, &obj, &st);
        dce_uuid_to_string(&hdrp->if_id, &iface, &st);
        dce_uuid_to_string(&hdrp->actuid, &act, &st);

        RPC_DBG_PRINTF(rpc_e_dbg_dg_pktlog, 1,
	    ("%08x %c%c%1u %-4.4s %02x %02x %08x/%04x/%04x %04x %04x %4d %s/%02u/%03u %s %9u %s %02x%02x%02x %02x\n",
                p->timestamp,
                (hdrp->_rpc_vers & 0x80) ? 'R' : lossy_action[p->lossy_action],
                ((i + 1) % RPC_C_DG_PKT_LOG_SIZE == pkt_log_index) ? '*' : ' ',
                hdrp->_rpc_vers & 0x7f,
                rpc__dg_pkt_name(RPC_DG_HDR_INQ_PTYPE(hdrp)),
                hdrp->flags, hdrp->flags2,
                hdrp->seq, hdrp->fragnum,
                hdrp->serial_hi << 8 | hdrp->serial_lo,
                hdrp->ihint, hdrp->ahint,
                hdrp->len,
                iface, hdrp->if_vers, hdrp->opnum, act,
                hdrp->server_boot, obj,
                hdrp->drep[0], hdrp->drep[1], hdrp->drep[2],
                hdrp->auth_proto) );

        rpc_string_free(&obj, &st);
        rpc_string_free(&act, &st);
        rpc_string_free(&iface, &st);
    }
}
Ejemplo n.º 13
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;
}