示例#1
0
bool prs_dcerpc_status(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
{
	char *q = prs_mem_get(ps, sizeof(uint32));
	if (q == NULL)
		return False;

	if (UNMARSHALLING(ps)) {
		if (ps->bigendian_data)
			*status = NT_STATUS(RIVAL(q,0));
		else
			*status = NT_STATUS(IVAL(q,0));
	} else {
		if (ps->bigendian_data)
			RSIVAL(q,0,NT_STATUS_V(*status));
		else
			SIVAL(q,0,NT_STATUS_V(*status));
	}

	DEBUGADD(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name,
		 dcerpc_errstr(talloc_tos(), NT_STATUS_V(*status))));

	ps->data_offset += sizeof(uint32);

	return True;
}
示例#2
0
文件: parse_prs.c 项目: jophxy/samba
BOOL prs_ntstatus(const char *name, prs_struct *ps, int depth, NTSTATUS *status)
{
	char *q = prs_mem_get(ps, sizeof(uint32));
	if (q == NULL)
		return False;

	if (UNMARSHALLING(ps)) {
		if (ps->bigendian_data)
			*status = NT_STATUS(RIVAL(q,0));
		else
			*status = NT_STATUS(IVAL(q,0));
	} else {
		if (ps->bigendian_data)
			RSIVAL(q,0,NT_STATUS_V(*status));
		else
			SIVAL(q,0,NT_STATUS_V(*status));
	}

	DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth), ps->data_offset, name, 
		 get_nt_error_msg(*status)));

	ps->data_offset += sizeof(uint32);

	return True;
}
示例#3
0
static bool torture_winbind_struct_check_machacc(struct torture_context *torture)
{
	bool ok;
	bool strict = torture_setting_bool(torture, "strict mode", false);
	struct winbindd_response rep;

	ZERO_STRUCT(rep);

	torture_comment(torture, "Running WINBINDD_CHECK_MACHACC (struct based)\n");

	ok = true;
	DO_STRUCT_REQ_REP_EXT(WINBINDD_CHECK_MACHACC, NULL, &rep,
			      NSS_STATUS_SUCCESS, strict, ok = false,
			      "WINBINDD_CHECK_MACHACC");

	if (!ok) {
		torture_assert(torture,
			       strlen(rep.data.auth.nt_status_string)>0,
			       "Failed with empty nt_status_string");

		torture_warning(torture,"%s:%s:%s:%d\n",
				nt_errstr(NT_STATUS(rep.data.auth.nt_status)),
				rep.data.auth.nt_status_string,
				rep.data.auth.error_string,
				rep.data.auth.pam_error);
		return true;
	}

	torture_assert_ntstatus_ok(torture,
				   NT_STATUS(rep.data.auth.nt_status),
				   "WINBINDD_CHECK_MACHACC ok: nt_status");

	torture_assert_str_equal(torture,
				 rep.data.auth.nt_status_string,
				 nt_errstr(NT_STATUS_OK),
				 "WINBINDD_CHECK_MACHACC ok:nt_status_string");

	torture_assert_str_equal(torture,
				 rep.data.auth.error_string,
				 get_friendly_nt_error_msg(NT_STATUS_OK),
				 "WINBINDD_CHECK_MACHACC ok: error_string");

	torture_assert_int_equal(torture,
				 rep.data.auth.pam_error,
				 nt_status_to_pam(NT_STATUS_OK),
				 "WINBINDD_CHECK_MACHACC ok: pam_error");

	return true;
}
示例#4
0
static bool api_spoolss_addprinterdriver(pipes_struct *p)
{
	SPOOL_Q_ADDPRINTERDRIVER q_u;
	SPOOL_R_ADDPRINTERDRIVER r_u;
	prs_struct *data = &p->in_data.data;
	prs_struct *rdata = &p->out_data.rdata;
	
	ZERO_STRUCT(q_u);
	ZERO_STRUCT(r_u);
	
	if(!spoolss_io_q_addprinterdriver("", &q_u, data, 0)) {
		if (q_u.level != 3 && q_u.level != 6) {
			/* Clever hack from Martin Zielinski <*****@*****.**>
			 * to allow downgrade from level 8 (Vista).
			 */
			DEBUG(3,("api_spoolss_addprinterdriver: unknown SPOOL_Q_ADDPRINTERDRIVER level %u.\n",
				(unsigned int)q_u.level ));
			setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_INVALID_TAG));
			return True;
		}
		DEBUG(0,("spoolss_io_q_addprinterdriver: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVER.\n"));
		return False;
	}
	
	r_u.status = _spoolss_addprinterdriver(p, &q_u, &r_u);
				
	if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) {
		DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n"));
		return False;
	}
	
	return True;
}
示例#5
0
bool create_next_pdu(struct pipes_struct *p)
{
	size_t pdu_size = 0;
	NTSTATUS status;

	/*
	 * If we're in the fault state, keep returning fault PDU's until
	 * the pipe gets closed. JRA.
	 */
	if (p->fault_state) {
		setup_fault_pdu(p, NT_STATUS(p->fault_state));
		return true;
	}

	status = create_next_packet(p->mem_ctx, &p->auth,
				    p->call_id, &p->out_data.rdata,
				    p->out_data.data_sent_length,
				    &p->out_data.frag, &pdu_size);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to create packet with error %s, "
			  "(auth level %u / type %u)\n",
			  nt_errstr(status),
			  (unsigned int)p->auth.auth_level,
			  (unsigned int)p->auth.auth_type));
		return false;
	}

	/* Setup the counts for this PDU. */
	p->out_data.data_sent_length += pdu_size;
	p->out_data.current_pdu_sent = 0;
	return true;
}
示例#6
0
文件: srv_samr.c 项目: hajuuk/R7000
static BOOL api_samr_set_userinfo(pipes_struct *p)
{
	SAMR_Q_SET_USERINFO q_u;
	SAMR_R_SET_USERINFO r_u;
	prs_struct *data = &p->in_data.data;
	prs_struct *rdata = &p->out_data.rdata;

	ZERO_STRUCT(q_u);
	ZERO_STRUCT(r_u);

	if (!samr_io_q_set_userinfo("", &q_u, data, 0)) {
		DEBUG(0,("api_samr_set_userinfo: Unable to unmarshall SAMR_Q_SET_USERINFO.\n"));
		/* Fix for W2K SP2 */
		/* what is that status-code ? - gd */
		if (q_u.switch_value == 0x1a) {
			setup_fault_pdu(p, NT_STATUS(0x1c000006));
			return True;
		}
		return False;
	}

	r_u.status = _samr_set_userinfo(p, &q_u, &r_u);

	if(!samr_io_r_set_userinfo("", &r_u, rdata, 0)) {
		DEBUG(0,("api_samr_set_userinfo: Unable to marshall SAMR_R_SET_USERINFO.\n"));
		return False;
	}

	return True;
}
示例#7
0
static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
						void *my_private_data, 
						TALLOC_CTX *mem_ctx,
						const struct auth_usersupplied_info *user_info,
						struct auth_serversupplied_info **server_info)
{
	NTSTATUS nt_status;
	fstring user;
	long error_num;

	DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));

	fstrcpy(user, user_info->client.account_name);

	if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) {
		if (!strupper_m(user)) {
			return NT_STATUS_INVALID_PARAMETER;
		}
		return nt_status_string_to_code(user);
	}

	if (!strlower_m(user)) {
		return NT_STATUS_INVALID_PARAMETER;
	}
	error_num = strtoul(user, NULL, 16);

	DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num));

	nt_status = NT_STATUS(error_num);

	return nt_status;
}
示例#8
0
static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
						void *my_private_data, 
						TALLOC_CTX *mem_ctx,
						const auth_usersupplied_info *user_info, 
						auth_serversupplied_info **server_info)
{
	NTSTATUS nt_status;
	fstring user;
	long error_num;
	fstrcpy(user, user_info->smb_name);
	
	if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) {
		strupper_m(user);
		return nt_status_string_to_code(user);
	}

	strlower_m(user);
	error_num = strtoul(user, NULL, 16);
	
	DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num));

	nt_status = NT_STATUS(error_num);
	
	return nt_status;
}
示例#9
0
void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode)
{
    int  flgs2;

    if(!cli->initialised) {
        return;
    }

    /* Deal with socket errors first. */
    if (cli->fd == -1 && cli->smb_rw_error) {
        NTSTATUS status = cli_smb_rw_error_to_ntstatus(cli);
        ntstatus_to_dos( status, eclass, ecode);
        return;
    }

    flgs2 = SVAL(cli->inbuf,smb_flg2);

    if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
        NTSTATUS ntstatus = NT_STATUS(IVAL(cli->inbuf, smb_rcls));
        ntstatus_to_dos(ntstatus, eclass, ecode);
        return;
    }

    *eclass  = CVAL(cli->inbuf,smb_rcls);
    *ecode  = SVAL(cli->inbuf,smb_err);
}
示例#10
0
文件: ndr_basic.c 项目: gojdic/samba
/*
  pull a NTSTATUS
*/
_PUBLIC_ enum ndr_err_code ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
{
	uint32_t v;
	NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
	*status = NT_STATUS(v);
	return NDR_ERR_SUCCESS;
}
示例#11
0
文件: netapi.c 项目: gojdic/samba
const char *libnetapi_errstr(NET_API_STATUS status)
{
	if (status & 0xc0000000) {
		return get_friendly_nt_error_msg(NT_STATUS(status));
	}

	return get_friendly_werror_msg(W_ERROR(status));
}
示例#12
0
static NTSTATUS rpcint_dispatch(struct pipes_struct *p,
				TALLOC_CTX *mem_ctx,
				uint32_t opnum,
				const DATA_BLOB *in_data,
				DATA_BLOB *out_data)
{
	struct pipe_rpc_fns *fns = find_pipe_fns_by_context(p->contexts, 0);
	uint32_t num_cmds = fns->n_cmds;
	const struct api_struct *cmds = fns->cmds;
	uint32_t i;
	bool ok;

	/* set opnum */
	p->opnum = opnum;

	for (i = 0; i < num_cmds; i++) {
		if (cmds[i].opnum == opnum && cmds[i].fn != NULL) {
			break;
		}
	}

	if (i == num_cmds) {
		return NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE;
	}

	p->in_data.data = *in_data;
	p->out_data.rdata = data_blob_null;

	ok = cmds[i].fn(p);
	p->in_data.data = data_blob_null;
	if (!ok) {
		data_blob_free(&p->out_data.rdata);
		talloc_free_children(p->mem_ctx);
		return NT_STATUS_RPC_CALL_FAILED;
	}

	if (p->fault_state) {
		NTSTATUS status;

		status = NT_STATUS(p->fault_state);
		p->fault_state = 0;
		data_blob_free(&p->out_data.rdata);
		talloc_free_children(p->mem_ctx);
		return status;
	}

	*out_data = p->out_data.rdata;
	talloc_steal(mem_ctx, out_data->data);
	p->out_data.rdata = data_blob_null;

	talloc_free_children(p->mem_ctx);
	return NT_STATUS_OK;
}
示例#13
0
static BOOL cli_dfs_check_error( struct cli_state *cli, NTSTATUS status )
{
	uint32 flgs2 = SVAL(cli->inbuf,smb_flg2);

	/* only deal with DS when we negotiated NT_STATUS codes and UNICODE */

	if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) )
		return False;

	if ( NT_STATUS_EQUAL( status, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) )
		return True;

	return False;
}
示例#14
0
char *libnetapi_errstr(NET_API_STATUS status)
{
	TALLOC_CTX *frame = talloc_stackframe();
	char *ret;
	if (status & 0xc0000000) {
		ret = talloc_strdup(NULL, 
				     get_friendly_nt_error_msg(NT_STATUS(status)));
	} else {
		ret = talloc_strdup(NULL,
				    get_friendly_werror_msg(W_ERROR(status)));
	}
	TALLOC_FREE(frame);
	return ret;
}
示例#15
0
NTSTATUS cli_nt_error(struct cli_state *cli)
{
    int flgs2 = SVAL(cli->inbuf,smb_flg2);

    /* Deal with socket errors first. */
    if (cli->fd == -1 && cli->smb_rw_error) {
        return cli_smb_rw_error_to_ntstatus(cli);
    }

    if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) {
        int e_class  = CVAL(cli->inbuf,smb_rcls);
        int code  = SVAL(cli->inbuf,smb_err);
        return dos_to_ntstatus(e_class, code);
    }

    return NT_STATUS(IVAL(cli->inbuf,smb_rcls));
}
示例#16
0
文件: signing.c 项目: rchicoli/samba
bool srv_check_sign_mac(struct smbd_server_connection *conn,
                        const char *inbuf, uint32_t *seqnum,
                        bool trusted_channel)
{
    const uint8_t *inhdr;
    size_t len;

    /* Check if it's a non-session message. */
    if(CVAL(inbuf,0)) {
        return true;
    }

    len = smb_len(inbuf);
    inhdr = (const uint8_t *)inbuf + NBT_HDR_SIZE;

    if (trusted_channel) {
        NTSTATUS status;

        if (len < (HDR_SS_FIELD + 8)) {
            DEBUG(1,("smb_signing_check_pdu: Can't check signature "
                     "on short packet! smb_len = %u\n",
                     (unsigned)len));
            return false;
        }

        status = NT_STATUS(IVAL(inhdr, HDR_SS_FIELD + 4));
        if (!NT_STATUS_IS_OK(status)) {
            DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n",
                     nt_errstr(status)));
            return false;
        }

        *seqnum = IVAL(inhdr, HDR_SS_FIELD);
        return true;
    }

    *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false);
    return smb_signing_check_pdu(conn->smb1.signing_state,
                                 inhdr, len,
                                 *seqnum);
}
示例#17
0
bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status)
{
	enum tevent_req_state state;
	uint64_t err;

	if (!tevent_req_is_error(req, &state, &err)) {
		return false;
	}
	switch (state) {
	case TEVENT_REQ_TIMED_OUT:
		*status = NT_STATUS_IO_TIMEOUT;
		break;
	case TEVENT_REQ_NO_MEMORY:
		*status = NT_STATUS_NO_MEMORY;
		break;
	case TEVENT_REQ_USER_ERROR:
		*status = NT_STATUS(err);
		break;
	default:
		*status = NT_STATUS_INTERNAL_ERROR;
		break;
	}
	return true;
}
示例#18
0
文件: errormap.c 项目: Arkhont/samba
	{ERRDOS,	ERRbadfid,	NT_STATUS_INVALID_HANDLE},
	{ERRDOS,	ERRnomem,	NT_STATUS_INSUFFICIENT_RESOURCES},
	{ERRDOS,	ERRbadaccess,	NT_STATUS_ACCESS_DENIED},
	{ERRDOS,	ERRbaddata,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	14,	NT_STATUS_SECTION_NOT_EXTENDED},
	{ERRDOS,	ERRremcd,	NT_STATUS_DIRECTORY_NOT_EMPTY},
	{ERRDOS,	ERRdiffdevice,	NT_STATUS_NOT_SAME_DEVICE},
	{ERRDOS,	ERRnofiles,	STATUS_NO_MORE_FILES},
	{ERRDOS,	19,	NT_STATUS_MEDIA_WRITE_PROTECTED},
	{ERRDOS,	21,	NT_STATUS_NO_MEDIA_IN_DEVICE},
	{ERRDOS,	22,	NT_STATUS_INVALID_DEVICE_STATE},
	{ERRDOS,	23,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	24,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	26,	NT_STATUS_DISK_CORRUPT_ERROR},
	{ERRDOS,	27,	NT_STATUS_NONEXISTENT_SECTOR},
	{ERRDOS,	28,	NT_STATUS(0x8000000e)},
	{ERRDOS,	31,	NT_STATUS_UNSUCCESSFUL},
	{ERRDOS,	ERRbadshare,	NT_STATUS_SHARING_VIOLATION},
	{ERRDOS,	ERRlock,	NT_STATUS_FILE_LOCK_CONFLICT},
	{ERRDOS,	34,	NT_STATUS_WRONG_VOLUME},
	{ERRDOS,	38,	NT_STATUS_END_OF_FILE},
	{ERRDOS,	ERRunsup,	NT_STATUS_CTL_FILE_NOT_SUPPORTED},
	{ERRDOS,	51,	NT_STATUS_REMOTE_NOT_LISTENING},
	{ERRDOS,	52,	NT_STATUS_DUPLICATE_NAME},
	{ERRDOS,	53,	NT_STATUS_BAD_NETWORK_PATH},
	{ERRDOS,	54,	NT_STATUS_NETWORK_BUSY},
	{ERRDOS,	55,	NT_STATUS_DEVICE_DOES_NOT_EXIST},
	{ERRDOS,	56,	NT_STATUS_TOO_MANY_COMMANDS},
	{ERRDOS,	57,	NT_STATUS_ADAPTER_HARDWARE_ERROR},
	{ERRDOS,	58,	NT_STATUS_INVALID_NETWORK_RESPONSE},
	{ERRDOS,	59,	NT_STATUS_UNEXPECTED_NETWORK_ERROR},
示例#19
0
文件: auth_wbc.c 项目: endisd/samba
static NTSTATUS check_wbc_security(const struct auth_context *auth_context,
				       void *my_private_data,
				       TALLOC_CTX *mem_ctx,
				       const struct auth_usersupplied_info *user_info,
				       struct auth_serversupplied_info **server_info)
{
	NTSTATUS nt_status;
	wbcErr wbc_status;
	struct wbcAuthUserParams params;
	struct wbcAuthUserInfo *info = NULL;
	struct wbcAuthErrorInfo *err = NULL;

	if (!user_info || !auth_context || !server_info) {
		return NT_STATUS_INVALID_PARAMETER;
	}
	/* Send off request */

	params.account_name	= user_info->smb_name;
	params.domain_name	= user_info->domain;
	params.workstation_name	= user_info->wksta_name;

	params.flags		= 0;
	params.parameter_control= user_info->logon_parameters;

	/* Handle plaintext */
	if (!user_info->encrypted) {
		DEBUG(3,("Checking plaintext password for %s.\n",
			 user_info->internal_username));
		params.level = WBC_AUTH_USER_LEVEL_PLAIN;

		params.password.plaintext = (char *)user_info->plaintext_password.data;
	} else {
		DEBUG(3,("Checking encrypted password for %s.\n",
			 user_info->internal_username));
		params.level = WBC_AUTH_USER_LEVEL_RESPONSE;

		memcpy(params.password.response.challenge,
		    auth_context->challenge.data,
		    sizeof(params.password.response.challenge));

		params.password.response.nt_length = user_info->nt_resp.length;
		params.password.response.nt_data = user_info->nt_resp.data;
		params.password.response.lm_length = user_info->lm_resp.length;
		params.password.response.lm_data = user_info->lm_resp.data;

	}

	/* we are contacting the privileged pipe */
	become_root();
	wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
	unbecome_root();

	if (!WBC_ERROR_IS_OK(wbc_status)) {
		DEBUG(10,("wbcAuthenticateUserEx failed (%d): %s\n",
			wbc_status, wbcErrorString(wbc_status)));
	}

	if (wbc_status == WBC_ERR_NO_MEMORY) {
		return NT_STATUS_NO_MEMORY;
	}

	if (wbc_status == WBC_ERR_AUTH_ERROR) {
		nt_status = NT_STATUS(err->nt_status);
		wbcFreeMemory(err);
		return nt_status;
	}

	if (!WBC_ERROR_IS_OK(wbc_status)) {
		return NT_STATUS_LOGON_FAILURE;
	}

	DEBUG(10,("wbcAuthenticateUserEx succeeded\n"));

	nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
						     user_info->smb_name,
						     user_info->domain,
						     info, server_info);
	wbcFreeMemory(info);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	(*server_info)->nss_token |= user_info->was_mapped;

        return nt_status;
}
示例#20
0
文件: clierror.c 项目: jophxy/samba
const char *cli_errstr(struct cli_state *cli)
{   
	static fstring cli_error_message;
	uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum;
        uint8 errclass;
        int i;
	
	if (!cli->initialised) {
		fstrcpy(cli_error_message, "[Programmer's error] cli_errstr called on unitialized cli_stat struct!\n");
		return cli_error_message;
	}
		
	/* Was it server socket error ? */
	if (cli->fd == -1 && cli->smb_rw_error) {
		switch(cli->smb_rw_error) {
			case READ_TIMEOUT:
				slprintf(cli_error_message, sizeof(cli_error_message) - 1,
					"Call timed out: server did not respond after %d milliseconds", 
					cli->timeout);
				break;
			case READ_EOF:
				slprintf(cli_error_message, sizeof(cli_error_message) - 1,
					"Call returned zero bytes (EOF)\n" );
				break;
			case READ_ERROR:
				slprintf(cli_error_message, sizeof(cli_error_message) - 1,
					"Read error: %s\n", strerror(errno) );
				break;
			case WRITE_ERROR:
				slprintf(cli_error_message, sizeof(cli_error_message) - 1,
					"Write error: %s\n", strerror(errno) );
				break;
			default:
				slprintf(cli_error_message, sizeof(cli_error_message) - 1,
					"Unknown error code %d\n", cli->smb_rw_error );
				break;
		}
		return cli_error_message;
	}

        /* Case #1: RAP error */
	if (cli->rap_error) {
		for (i = 0; rap_errmap[i].message != NULL; i++) {
			if (rap_errmap[i].err == cli->rap_error) {
				return rap_errmap[i].message;
			}
		} 

		slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d", 
			cli->rap_error);

		return cli_error_message;
	}

        /* Case #2: 32-bit NT errors */
	if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
                NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls));

                return get_nt_error_msg(status);
        }

        cli_dos_error(cli, &errclass, &errnum);

        /* Case #3: SMB error */

	return cli_smb_errstr(cli);
}
示例#21
0
/*
  we have a full request in our receive buffer - match it to a pending request
  and process
 */
static NTSTATUS smbcli_transport_finish_recv(void *private_data, DATA_BLOB blob)
{
	struct smbcli_transport *transport = talloc_get_type(private_data,
							     struct smbcli_transport);
	uint8_t *buffer, *hdr, *vwv;
	int len;
	uint16_t wct=0, mid = 0, op = 0;
	struct smbcli_request *req = NULL;

	buffer = blob.data;
	len = blob.length;

	hdr = buffer+NBT_HDR_SIZE;
	vwv = hdr + HDR_VWV;

	/* see if it could be an oplock break request */
	if (smbcli_handle_oplock_break(transport, len, hdr, vwv)) {
		talloc_free(buffer);
		return NT_STATUS_OK;
	}

	/* at this point we need to check for a readbraw reply, as
	   these can be any length */
	if (transport->readbraw_pending) {
		transport->readbraw_pending = 0;

		/* it must match the first entry in the pending queue
		   as the client is not allowed to have outstanding
		   readbraw requests */
		req = transport->pending_recv;
		if (!req) goto error;

		req->in.buffer = buffer;
		talloc_steal(req, buffer);
		req->in.size = len;
		req->in.allocated = req->in.size;
		goto async;
	}

	if (len >= MIN_SMB_SIZE) {
		/* extract the mid for matching to pending requests */
		mid = SVAL(hdr, HDR_MID);
		wct = CVAL(hdr, HDR_WCT);
		op  = CVAL(hdr, HDR_COM);
	}

	/* match the incoming request against the list of pending requests */
	for (req=transport->pending_recv; req; req=req->next) {
		if (req->mid == mid) break;
	}

	/* see if it's a ntcancel reply for the current MID */
	req = smbcli_handle_ntcancel_reply(req, len, hdr);

	if (!req) {
		DEBUG(1,("Discarding unmatched reply with mid %d op %d\n", mid, op));
		goto error;
	}

	/* fill in the 'in' portion of the matching request */
	req->in.buffer = buffer;
	talloc_steal(req, buffer);
	req->in.size = len;
	req->in.allocated = req->in.size;

	/* handle NBT session replies */
	if (req->in.size >= 4 && req->in.buffer[0] != 0) {
		req->status = NT_STATUS_OK;
		goto async;
	}

	/* handle non-SMB replies */
	if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE) {
		req->state = SMBCLI_REQUEST_ERROR;
		goto error;
	}

	if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
		DEBUG(2,("bad reply size for mid %d\n", mid));
		req->status = NT_STATUS_UNSUCCESSFUL;
		req->state = SMBCLI_REQUEST_ERROR;
		goto error;
	}

	req->in.hdr = hdr;
	req->in.vwv = vwv;
	req->in.wct = wct;
	if (req->in.size >= NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct)) {
		req->in.data = req->in.vwv + VWV(wct) + 2;
		req->in.data_size = SVAL(req->in.vwv, VWV(wct));
		if (req->in.size < NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct) + req->in.data_size) {
			DEBUG(3,("bad data size for mid %d\n", mid));
			/* blergh - w2k3 gives a bogus data size values in some
			   openX replies */
			req->in.data_size = req->in.size - (NBT_HDR_SIZE + MIN_SMB_SIZE + VWV(wct));
		}
	}
	req->in.ptr = req->in.data;
	req->flags2 = SVAL(req->in.hdr, HDR_FLG2);

	smb_setup_bufinfo(req);

	if (!(req->flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
		int eclass = CVAL(req->in.hdr,HDR_RCLS);
		int code = SVAL(req->in.hdr,HDR_ERR);
		if (eclass == 0 && code == 0) {
			transport->error.e.nt_status = NT_STATUS_OK;
		} else {
			transport->error.e.nt_status = NT_STATUS_DOS(eclass, code);
		}
	} else {
		transport->error.e.nt_status = NT_STATUS(IVAL(req->in.hdr, HDR_RCLS));
	}

	req->status = transport->error.e.nt_status;
	if (NT_STATUS_IS_OK(req->status)) {
		transport->error.etype = ETYPE_NONE;
	} else {
		transport->error.etype = ETYPE_SMB;
	}

	if (!smbcli_request_check_sign_mac(req)) {
		transport->error.etype = ETYPE_SOCKET;
		transport->error.e.socket_error = SOCKET_READ_BAD_SIG;
		req->state = SMBCLI_REQUEST_ERROR;
		req->status = NT_STATUS_ACCESS_DENIED;
		goto error;
	};

async:
	/* if this request has an async handler then call that to
	   notify that the reply has been received. This might destroy
	   the request so it must happen last */

	req->state = SMBCLI_REQUEST_DONE;

	if (req->recv_helper.fn) {
		/*
		 * let the recv helper decide in
		 * what state the request really is
		 */
		req->state = req->recv_helper.fn(req);

		/* if more parts are needed, wait for them */
		if (req->state <= SMBCLI_REQUEST_RECV) {
			return NT_STATUS_OK;
		}
	}
	DLIST_REMOVE(transport->pending_recv, req);
	if (req->async.fn) {
		req->async.fn(req);
	}
	return NT_STATUS_OK;

error:
	if (req) {
		DLIST_REMOVE(transport->pending_recv, req);
		req->state = SMBCLI_REQUEST_ERROR;
		if (req->async.fn) {
			req->async.fn(req);
		}
	} else {
		talloc_free(buffer);
	}
	return NT_STATUS_OK;
}
示例#22
0
static bool srv_pipe_check_verification_trailer(struct pipes_struct *p,
						struct ncacn_packet *pkt,
						struct pipe_rpc_fns *pipe_fns)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct dcerpc_sec_verification_trailer *vt = NULL;
	const uint32_t bitmask1 =
		p->auth.client_hdr_signing ? DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
	const struct dcerpc_sec_vt_pcontext pcontext = {
		.abstract_syntax = pipe_fns->syntax,
		.transfer_syntax = ndr_transfer_syntax_ndr,
	};
	const struct dcerpc_sec_vt_header2 header2 =
	       dcerpc_sec_vt_header2_from_ncacn_packet(pkt);
	struct ndr_pull *ndr;
	enum ndr_err_code ndr_err;
	bool ret = false;

	ndr = ndr_pull_init_blob(&p->in_data.data, frame);
	if (ndr == NULL) {
		goto done;
	}

	ndr_err = ndr_pop_dcerpc_sec_verification_trailer(ndr, frame, &vt);
	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		goto done;
	}

	ret = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
						    &pcontext, &header2);
done:
	TALLOC_FREE(frame);
	return ret;
}

/****************************************************************************
 Find the correct RPC function to call for this request.
 If the pipe is authenticated then become the correct UNIX user
 before doing the call.
****************************************************************************/

static bool api_pipe_request(struct pipes_struct *p,
				struct ncacn_packet *pkt)
{
	TALLOC_CTX *frame = talloc_stackframe();
	bool ret = False;
	struct pipe_rpc_fns *pipe_fns;

	if (!p->pipe_bound) {
		DEBUG(1, ("Pipe not bound!\n"));
		data_blob_free(&p->out_data.rdata);
		TALLOC_FREE(frame);
		return false;
	}

	/* get the set of RPC functions for this context */
	pipe_fns = find_pipe_fns_by_context(p->contexts,
					    pkt->u.request.context_id);
	if (pipe_fns == NULL) {
		DEBUG(0, ("No rpc function table associated with context "
			  "[%d]\n",
			  pkt->u.request.context_id));
		data_blob_free(&p->out_data.rdata);
		TALLOC_FREE(frame);
		return false;
	}

	if (!srv_pipe_check_verification_trailer(p, pkt, pipe_fns)) {
		DEBUG(1, ("srv_pipe_check_verification_trailer: failed\n"));
		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_ACCESS_DENIED));
		data_blob_free(&p->out_data.rdata);
		TALLOC_FREE(frame);
		return true;
	}

	if (!become_authenticated_pipe_user(p->session_info)) {
		DEBUG(1, ("Failed to become pipe user!\n"));
		data_blob_free(&p->out_data.rdata);
		TALLOC_FREE(frame);
		return false;
	}

	DEBUG(5, ("Requested %s rpc service\n",
		  ndr_interface_name(&pipe_fns->syntax.uuid,
				     pipe_fns->syntax.if_version)));

	ret = api_rpcTNP(p, pkt, pipe_fns->cmds, pipe_fns->n_cmds,
			 &pipe_fns->syntax);
	unbecome_authenticated_pipe_user();

	TALLOC_FREE(frame);
	return ret;
}
示例#23
0
	{NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE},
	{NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT},
	{NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE},
	{NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH},
	{NT_STATUS_IO_TIMEOUT, ETIMEDOUT},
	{NT_STATUS_RETRY, EAGAIN},
#ifdef ENOTUNIQ
	{NT_STATUS_DUPLICATE_NAME, ENOTUNIQ},
#endif
#ifdef ECOMM
	{NT_STATUS_NET_WRITE_FAULT, ECOMM},
#endif
#ifdef EXDEV
	{NT_STATUS_NOT_SAME_DEVICE, EXDEV},
#endif
	{NT_STATUS(0), 0}
};

int map_errno_from_nt_status(NTSTATUS status)
{
	int i;
	DEBUG(10,("map_errno_from_nt_status: 32 bit codes: code=%08x\n",
		NT_STATUS_V(status)));

	/* Status codes without this bit set are not errors */

	if (!(NT_STATUS_V(status) & 0xc0000000)) {
		return 0;
	}

	for (i=0;nt_errno_map[i].error;i++) {
示例#24
0
static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
		       const struct api_struct *api_rpc_cmds, int n_cmds,
		       const struct ndr_syntax_id *syntax)
{
	int fn_num;
	uint32_t offset1;
	const struct ndr_interface_table *table;

	/* interpret the command */
	DEBUG(4,("api_rpcTNP: %s op 0x%x - ",
		 ndr_interface_name(&syntax->uuid, syntax->if_version),
		 pkt->u.request.opnum));

	table = ndr_table_by_uuid(&syntax->uuid);
	if (table == NULL) {
		DEBUG(0,("unknown interface\n"));
		return false;
	}

	if (DEBUGLEVEL >= 50) {
		fstring name;
		slprintf(name, sizeof(name)-1, "in_%s",
			 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
		dump_pdu_region(name, pkt->u.request.opnum,
				&p->in_data.data, 0,
				p->in_data.data.length);
	}

	for (fn_num = 0; fn_num < n_cmds; fn_num++) {
		if (api_rpc_cmds[fn_num].opnum == pkt->u.request.opnum &&
		    api_rpc_cmds[fn_num].fn != NULL) {
			DEBUG(3, ("api_rpcTNP: rpc command: %s\n",
				  api_rpc_cmds[fn_num].name));
			break;
		}
	}

	if (fn_num == n_cmds) {
		/*
		 * For an unknown RPC just return a fault PDU but
		 * return True to allow RPC's on the pipe to continue
		 * and not put the pipe into fault state. JRA.
		 */
		DEBUG(4, ("unknown\n"));
		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
		return True;
	}

	offset1 = p->out_data.rdata.length;

        DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n", 
                fn_num, api_rpc_cmds[fn_num].fn));
	/* do the actual command */
	if(!api_rpc_cmds[fn_num].fn(p)) {
		DEBUG(0,("api_rpcTNP: %s: %s failed.\n",
			 ndr_interface_name(&syntax->uuid, syntax->if_version),
			 api_rpc_cmds[fn_num].name));
		data_blob_free(&p->out_data.rdata);
		return False;
	}

	if (p->fault_state) {
		DEBUG(4,("api_rpcTNP: fault(%d) return.\n", p->fault_state));
		setup_fault_pdu(p, NT_STATUS(p->fault_state));
		p->fault_state = 0;
		return true;
	}

	if (DEBUGLEVEL >= 50) {
		fstring name;
		slprintf(name, sizeof(name)-1, "out_%s",
			 dcerpc_default_transport_endpoint(pkt, NCACN_NP, table));
		dump_pdu_region(name, pkt->u.request.opnum,
				&p->out_data.rdata, offset1,
				p->out_data.rdata.length);
	}

	DEBUG(5,("api_rpcTNP: called %s successfully\n",
		 ndr_interface_name(&syntax->uuid, syntax->if_version)));

	/* Check for buffer underflow in rpc parsing */
	if ((DEBUGLEVEL >= 10) &&
	    (pkt->frag_length < p->in_data.data.length)) {
		DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
		dump_data(10, p->in_data.data.data + pkt->frag_length,
			      p->in_data.data.length - pkt->frag_length);
	}

	return True;
}
示例#25
0
static void process_complete_pdu(pipes_struct *p)
{
    prs_struct rpc_in;
    size_t data_len = p->in_data.pdu_received_len - RPC_HEADER_LEN;
    char *data_p = (char *)&p->in_data.current_in_pdu[RPC_HEADER_LEN];
    bool reply = False;

    if(p->fault_state) {
        DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
                  get_pipe_name_from_iface(&p->syntax)));
        set_incoming_fault(p);
        setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
        return;
    }

    prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);

    /*
     * Ensure we're using the corrent endianness for both the
     * RPC header flags and the raw data we will be reading from.
     */

    prs_set_endian_data( &rpc_in, p->endian);
    prs_set_endian_data( &p->in_data.data, p->endian);

    prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);

    DEBUG(10,("process_complete_pdu: processing packet type %u\n",
              (unsigned int)p->hdr.pkt_type ));

    switch (p->hdr.pkt_type) {
    case RPC_REQUEST:
        reply = process_request_pdu(p, &rpc_in);
        break;

    case RPC_PING: /* CL request - ignore... */
        DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
                 (unsigned int)p->hdr.pkt_type,
                 get_pipe_name_from_iface(&p->syntax)));
        break;

    case RPC_RESPONSE: /* No responses here. */
        DEBUG(0,("process_complete_pdu: Error. RPC_RESPONSE received from client on pipe %s.\n",
                 get_pipe_name_from_iface(&p->syntax)));
        break;

    case RPC_FAULT:
    case RPC_WORKING: /* CL request - reply to a ping when a call in process. */
    case RPC_NOCALL: /* CL - server reply to a ping call. */
    case RPC_REJECT:
    case RPC_ACK:
    case RPC_CL_CANCEL:
    case RPC_FACK:
    case RPC_CANCEL_ACK:
        DEBUG(0,("process_complete_pdu: Error. Connectionless packet type %u received on pipe %s.\n",
                 (unsigned int)p->hdr.pkt_type,
                 get_pipe_name_from_iface(&p->syntax)));
        break;

    case RPC_BIND:
        /*
         * We assume that a pipe bind is only in one pdu.
         */
        if(pipe_init_outgoing_data(p)) {
            reply = api_pipe_bind_req(p, &rpc_in);
        }
        break;

    case RPC_BINDACK:
    case RPC_BINDNACK:
        DEBUG(0,("process_complete_pdu: Error. RPC_BINDACK/RPC_BINDNACK packet type %u received on pipe %s.\n",
                 (unsigned int)p->hdr.pkt_type,
                 get_pipe_name_from_iface(&p->syntax)));
        break;


    case RPC_ALTCONT:
        /*
         * We assume that a pipe bind is only in one pdu.
         */
        if(pipe_init_outgoing_data(p)) {
            reply = api_pipe_alter_context(p, &rpc_in);
        }
        break;

    case RPC_ALTCONTRESP:
        DEBUG(0,("process_complete_pdu: Error. RPC_ALTCONTRESP on pipe %s: Should only be server -> client.\n",
                 get_pipe_name_from_iface(&p->syntax)));
        break;

    case RPC_AUTH3:
        /*
         * The third packet in an NTLMSSP auth exchange.
         */
        if(pipe_init_outgoing_data(p)) {
            reply = api_pipe_bind_auth3(p, &rpc_in);
        }
        break;

    case RPC_SHUTDOWN:
        DEBUG(0,("process_complete_pdu: Error. RPC_SHUTDOWN on pipe %s: Should only be server -> client.\n",
                 get_pipe_name_from_iface(&p->syntax)));
        break;

    case RPC_CO_CANCEL:
        /* For now just free all client data and continue processing. */
        DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
        /* As we never do asynchronous RPC serving, we can never cancel a
           call (as far as I know). If we ever did we'd have to send a cancel_ack
           reply. For now, just free all client data and continue processing. */
        reply = True;
        break;
#if 0
        /* Enable this if we're doing async rpc. */
        /* We must check the call-id matches the outstanding callid. */
        if(pipe_init_outgoing_data(p)) {
            /* Send a cancel_ack PDU reply. */
            /* We should probably check the auth-verifier here. */
            reply = setup_cancel_ack_reply(p, &rpc_in);
        }
        break;
#endif

    case RPC_ORPHANED:
        /* We should probably check the auth-verifier here.
           For now just free all client data and continue processing. */
        DEBUG(3,("process_complete_pdu: RPC_ORPHANED. Abandoning rpc call.\n"));
        reply = True;
        break;

    default:
        DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
        break;
    }

    /* Reset to little endian. Probably don't need this but it won't hurt. */
    prs_set_endian_data( &p->in_data.data, RPC_LITTLE_ENDIAN);

    if (!reply) {
        DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on "
                 "pipe %s\n", get_pipe_name_from_iface(&p->syntax)));
        set_incoming_fault(p);
        setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
        prs_mem_free(&rpc_in);
    } else {
        /*
         * Reset the lengths. We're ready for a new pdu.
         */
        TALLOC_FREE(p->in_data.current_in_pdu);
        p->in_data.pdu_needed_len = 0;
        p->in_data.pdu_received_len = 0;
    }

    prs_mem_free(&rpc_in);
}
示例#26
0
NTSTATUS contact_winbind_auth_crap(const char *username, 
				   const char *domain, 
				   const char *workstation,
				   const DATA_BLOB *challenge, 
				   const DATA_BLOB *lm_response, 
				   const DATA_BLOB *nt_response, 
				   uint32 flags, 
				   uint8 lm_key[8], 
				   uint8 user_session_key[16], 
				   char **error_string, 
				   char **unix_name) 
{
	NTSTATUS nt_status;
        NSS_STATUS result;
	struct winbindd_request request;
	struct winbindd_response response;

	if (!get_require_membership_sid()) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	ZERO_STRUCT(request);
	ZERO_STRUCT(response);

	request.flags = flags;

	request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;

	if (require_membership_of_sid)
		fstrcpy(request.data.auth_crap.require_membership_of_sid, require_membership_of_sid);

        fstrcpy(request.data.auth_crap.user, username);
	fstrcpy(request.data.auth_crap.domain, domain);

	fstrcpy(request.data.auth_crap.workstation, 
		workstation);

	memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));

	if (lm_response && lm_response->length) {
		memcpy(request.data.auth_crap.lm_resp, 
		       lm_response->data, 
		       MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
		request.data.auth_crap.lm_resp_len = lm_response->length;
	}

	if (nt_response && nt_response->length) {
		memcpy(request.data.auth_crap.nt_resp, 
		       nt_response->data, 
		       MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
                request.data.auth_crap.nt_resp_len = nt_response->length;
	}
	
	result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);

	/* Display response */

	if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
		nt_status = NT_STATUS_UNSUCCESSFUL;
		if (error_string)
			*error_string = smb_xstrdup("Reading winbind reply failed!");
		free_response(&response);
		return nt_status;
	}
	
	nt_status = (NT_STATUS(response.data.auth.nt_status));
	if (!NT_STATUS_IS_OK(nt_status)) {
		if (error_string) 
			*error_string = smb_xstrdup(response.data.auth.error_string);
		free_response(&response);
		return nt_status;
	}

	if ((flags & WBFLAG_PAM_LMKEY) && lm_key) {
		memcpy(lm_key, response.data.auth.first_8_lm_hash, 
		       sizeof(response.data.auth.first_8_lm_hash));
	}
	if ((flags & WBFLAG_PAM_USER_SESSION_KEY) && user_session_key) {
		memcpy(user_session_key, response.data.auth.user_session_key, 
			sizeof(response.data.auth.user_session_key));
	}

	if (flags & WBFLAG_PAM_UNIX_NAME) {
		*unix_name = SMB_STRDUP((char *)response.extra_data.data);
		if (!*unix_name) {
			free_response(&response);
			return NT_STATUS_NO_MEMORY;
		}
	}

	free_response(&response);
	return nt_status;
}
示例#27
0
void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt)
{
	bool reply = false;

	/* Store the call_id */
	p->call_id = pkt->call_id;

	DEBUG(10, ("Processing packet type %u\n", (unsigned int)pkt->ptype));

	if (!pipe_init_outgoing_data(p)) {
		goto done;
	}

	switch (pkt->ptype) {
	case DCERPC_PKT_REQUEST:
		reply = process_request_pdu(p, pkt);
		break;

	case DCERPC_PKT_PING: /* CL request - ignore... */
		DEBUG(0, ("Error - Connectionless packet type %u received\n",
			  (unsigned int)pkt->ptype));
		break;

	case DCERPC_PKT_RESPONSE: /* No responses here. */
		DEBUG(0, ("Error - DCERPC_PKT_RESPONSE received from client"));
		break;

	case DCERPC_PKT_FAULT:
	case DCERPC_PKT_WORKING:
		/* CL request - reply to a ping when a call in process. */
	case DCERPC_PKT_NOCALL:
		/* CL - server reply to a ping call. */
	case DCERPC_PKT_REJECT:
	case DCERPC_PKT_ACK:
	case DCERPC_PKT_CL_CANCEL:
	case DCERPC_PKT_FACK:
	case DCERPC_PKT_CANCEL_ACK:
		DEBUG(0, ("Error - Connectionless packet type %u received\n",
			  (unsigned int)pkt->ptype));
		break;

	case DCERPC_PKT_BIND:
		/*
		 * We assume that a pipe bind is only in one pdu.
		 */
		reply = api_pipe_bind_req(p, pkt);
		break;

	case DCERPC_PKT_BIND_ACK:
	case DCERPC_PKT_BIND_NAK:
		DEBUG(0, ("Error - DCERPC_PKT_BINDACK/DCERPC_PKT_BINDNACK "
			  "packet type %u received.\n",
			  (unsigned int)pkt->ptype));
		break;


	case DCERPC_PKT_ALTER:
		/*
		 * We assume that a pipe bind is only in one pdu.
		 */
		reply = api_pipe_alter_context(p, pkt);
		break;

	case DCERPC_PKT_ALTER_RESP:
		DEBUG(0, ("Error - DCERPC_PKT_ALTER_RESP received: "
			  "Should only be server -> client.\n"));
		break;

	case DCERPC_PKT_AUTH3:
		/*
		 * The third packet in an auth exchange.
		 */
		reply = api_pipe_bind_auth3(p, pkt);
		break;

	case DCERPC_PKT_SHUTDOWN:
		DEBUG(0, ("Error - DCERPC_PKT_SHUTDOWN received: "
			  "Should only be server -> client.\n"));
		break;

	case DCERPC_PKT_CO_CANCEL:
		/* For now just free all client data and continue
		 * processing. */
		DEBUG(3,("process_complete_pdu: DCERPC_PKT_CO_CANCEL."
			 " Abandoning rpc call.\n"));
		/* As we never do asynchronous RPC serving, we can
		 * never cancel a call (as far as I know).
		 * If we ever did we'd have to send a cancel_ack reply.
		 * For now, just free all client data and continue
		 * processing. */
		reply = True;
		break;

#if 0
		/* Enable this if we're doing async rpc. */
		/* We must check the outstanding callid matches. */
		if (pipe_init_outgoing_data(p)) {
			/* Send a cancel_ack PDU reply. */
			/* We should probably check the auth-verifier here. */
			reply = setup_cancel_ack_reply(p, pkt);
		}
		break;
#endif

	case DCERPC_PKT_ORPHANED:
		/* We should probably check the auth-verifier here.
		 * For now just free all client data and continue
		 * processing. */
		DEBUG(3, ("process_complete_pdu: DCERPC_PKT_ORPHANED."
			  " Abandoning rpc call.\n"));
		reply = True;
		break;

	default:
		DEBUG(0, ("process_complete_pdu: "
			  "Unknown rpc type = %u received.\n",
			  (unsigned int)pkt->ptype));
		break;
	}

done:
	if (!reply) {
		DEBUG(3,("DCE/RPC fault sent!"));
		set_incoming_fault(p);
		setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR));
	}
	/* pkt and p->in_data.pdu.data freed by caller */
}
示例#28
0
static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
                                       void *my_private_data,
                                       TALLOC_CTX *mem_ctx,
                                       const struct auth_usersupplied_info *user_info,
                                       struct auth_serversupplied_info **server_info)
{
    NTSTATUS nt_status;
    wbcErr wbc_status;
    struct wbcAuthUserParams params;
    struct wbcAuthUserInfo *info = NULL;
    struct wbcAuthErrorInfo *err = NULL;

    ZERO_STRUCT(params);

    if (!user_info) {
        return NT_STATUS_INVALID_PARAMETER;
    }

    DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name));

    if (!auth_context) {
        DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
                 user_info->mapped.account_name));
        return NT_STATUS_INVALID_PARAMETER;
    }

    if (strequal(user_info->mapped.domain_name, get_global_sam_name())) {
        DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n",
                 user_info->mapped.domain_name));
        return NT_STATUS_NOT_IMPLEMENTED;
    }

    /* Send off request */
    params.account_name	= user_info->client.account_name;
    /*
     * We need to send the domain name from the client to the DC. With
     * NTLMv2 the domain name is part of the hashed second challenge,
     * if we change the domain name, the DC will fail to verify the
     * challenge cause we changed the domain name, this is like a
     * man in the middle attack.
     */
    params.domain_name	= user_info->client.domain_name;
    params.workstation_name	= user_info->workstation_name;

    params.flags		= 0;
    params.parameter_control= user_info->logon_parameters;

    params.level		= WBC_AUTH_USER_LEVEL_RESPONSE;

    memcpy(params.password.response.challenge,
           auth_context->challenge.data,
           sizeof(params.password.response.challenge));

    if (user_info->password.response.nt.length != 0) {
        params.password.response.nt_length =
            user_info->password.response.nt.length;
        params.password.response.nt_data =
            user_info->password.response.nt.data;
    }
    if (user_info->password.response.lanman.length != 0) {
        params.password.response.lm_length =
            user_info->password.response.lanman.length;
        params.password.response.lm_data =
            user_info->password.response.lanman.data;
    }

    /* we are contacting the privileged pipe */
    become_root();
    wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
    unbecome_root();

    if (!WBC_ERROR_IS_OK(wbc_status)) {
        DEBUG(10,("check_winbind_security: wbcAuthenticateUserEx failed: %s\n",
                  wbcErrorString(wbc_status)));
    }

    if (wbc_status == WBC_ERR_NO_MEMORY) {
        return NT_STATUS_NO_MEMORY;
    }

    if (wbc_status == WBC_ERR_WINBIND_NOT_AVAILABLE) {
        struct auth_methods *auth_method =
            (struct auth_methods *)my_private_data;

        if ( auth_method )
            return auth_method->auth(auth_context, auth_method->private_data,
                                     mem_ctx, user_info, server_info);
        return NT_STATUS_LOGON_FAILURE;
    }

    if (wbc_status == WBC_ERR_AUTH_ERROR) {
        nt_status = NT_STATUS(err->nt_status);
        wbcFreeMemory(err);
        return nt_status;
    }

    if (!WBC_ERROR_IS_OK(wbc_status)) {
        return NT_STATUS_LOGON_FAILURE;
    }

    nt_status = make_server_info_wbcAuthUserInfo(mem_ctx,
                user_info->client.account_name,
                user_info->mapped.domain_name,
                info, server_info);
    wbcFreeMemory(info);
    if (!NT_STATUS_IS_OK(nt_status)) {
        return nt_status;
    }

    (*server_info)->nss_token |= user_info->was_mapped;

    return nt_status;
}
示例#29
0
static NTSTATUS name_to_ntstatus_check_password(struct auth_method_context *ctx,
        TALLOC_CTX *mem_ctx,
        const struct auth_usersupplied_info *user_info,
        struct auth_user_info_dc **_user_info_dc)
{
    NTSTATUS nt_status;
    struct auth_user_info_dc *user_info_dc;
    struct auth_user_info *info;
    uint32_t error_num;
    const char *user;

    user = user_info->client.account_name;

    if (strncasecmp("NT_STATUS", user, strlen("NT_STATUS")) == 0) {
        nt_status = nt_status_string_to_code(user);
    } else {
        error_num = strtoul(user, NULL, 16);
        DEBUG(5,("name_to_ntstatus_check_password: Error for user %s was 0x%08X\n", user, error_num));
        nt_status = NT_STATUS(error_num);
    }
    NT_STATUS_NOT_OK_RETURN(nt_status);

    user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
    NT_STATUS_HAVE_NO_MEMORY(user_info_dc);

    /* This returns a pointer to a struct dom_sid, which is the
     * same as a 1 element list of struct dom_sid */
    user_info_dc->num_sids = 1;
    user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
    NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);

    /* annoying, but the Anonymous really does have a session key,
       and it is all zeros! */
    user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
    NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);

    user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
    NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);

    data_blob_clear(&user_info_dc->user_session_key);
    data_blob_clear(&user_info_dc->lm_session_key);

    user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
    NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);

    info->account_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user);
    NT_STATUS_HAVE_NO_MEMORY(info->account_name);

    info->domain_name = talloc_strdup(user_info_dc, "NT AUTHORITY");
    NT_STATUS_HAVE_NO_MEMORY(info->domain_name);

    info->full_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s Anonymous Logon", user);
    NT_STATUS_HAVE_NO_MEMORY(info->full_name);

    info->logon_script = talloc_strdup(user_info_dc, "");
    NT_STATUS_HAVE_NO_MEMORY(info->logon_script);

    info->profile_path = talloc_strdup(user_info_dc, "");
    NT_STATUS_HAVE_NO_MEMORY(info->profile_path);

    info->home_directory = talloc_strdup(user_info_dc, "");
    NT_STATUS_HAVE_NO_MEMORY(info->home_directory);

    info->home_drive = talloc_strdup(user_info_dc, "");
    NT_STATUS_HAVE_NO_MEMORY(info->home_drive);

    info->last_logon = 0;
    info->last_logoff = 0;
    info->acct_expiry = 0;
    info->last_password_change = 0;
    info->allow_password_change = 0;
    info->force_password_change = 0;

    info->logon_count = 0;
    info->bad_password_count = 0;

    info->acct_flags = ACB_NORMAL;

    info->authenticated = true;

    *_user_info_dc = user_info_dc;

    return nt_status;
}
示例#30
0
文件: srv_pipe.c 项目: hajuuk/R7000
BOOL create_next_pdu(pipes_struct *p)
{
	RPC_HDR_RESP hdr_resp;
	BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0);
	BOOL auth_seal   = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0);
	uint32 ss_padding_len = 0;
	uint32 data_len;
	uint32 data_space_available;
	uint32 data_len_left;
	prs_struct outgoing_pdu;
	uint32 data_pos;

	/*
	 * If we're in the fault state, keep returning fault PDU's until
	 * the pipe gets closed. JRA.
	 */

	if(p->fault_state) {
		setup_fault_pdu(p, NT_STATUS(0x1c010002));
		return True;
	}

	memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));

	/* Change the incoming request header to a response. */
	p->hdr.pkt_type = RPC_RESPONSE;

	/* Set up rpc header flags. */
	if (p->out_data.data_sent_length == 0) {
		p->hdr.flags = RPC_FLG_FIRST;
	} else {
		p->hdr.flags = 0;
	}

	/*
	 * Work out how much we can fit in a single PDU.
	 */

	data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
	if(p->ntlmssp_auth_validated) {
		data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
	} else if(p->netsec_auth_validated) {
		data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN);
	}

	/*
	 * The amount we send is the minimum of the available
	 * space and the amount left to send.
	 */

	data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;

	/*
	 * Ensure there really is data left to send.
	 */

	if(!data_len_left) {
		DEBUG(0,("create_next_pdu: no data left to send !\n"));
		return False;
	}

	data_len = MIN(data_len_left, data_space_available);

	/*
	 * Set up the alloc hint. This should be the data left to
	 * send.
	 */

	hdr_resp.alloc_hint = data_len_left;

	/*
	 * Work out if this PDU will be the last.
	 */

	if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) {
		p->hdr.flags |= RPC_FLG_LAST;
		if ((auth_seal || auth_verify) && (data_len_left % 8)) {
			ss_padding_len = 8 - (data_len_left % 8);
			DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n",
				ss_padding_len ));
		}
	}

	/*
	 * Set up the header lengths.
	 */

	if (p->ntlmssp_auth_validated) {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
			data_len + ss_padding_len +
			RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
		p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
	} else if (p->netsec_auth_validated) {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN +
			data_len + ss_padding_len +
			RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
		p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN;
	} else {
		p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
		p->hdr.auth_len = 0;
	}

	/*
	 * Init the parse struct to point at the outgoing
	 * data.
	 */

	prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL);
	prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);

	/* Store the header in the data stream. */
	if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
		DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
		DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	/* Store the current offset. */
	data_pos = prs_offset(&outgoing_pdu);

	/* Copy the data into the PDU. */

	if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) {
		DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
		prs_mem_free(&outgoing_pdu);
		return False;
	}

	/* Copy the sign/seal padding data. */
	if (ss_padding_len) {
		char pad[8];
		memset(pad, '\0', 8);
		if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) {
			DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len));
			prs_mem_free(&outgoing_pdu);
			return False;
		}
	}

	if (p->ntlmssp_auth_validated) {
		/*
		 * NTLMSSP processing. Mutually exclusive with Schannel.
		 */
		uint32 crc32 = 0;
		char *data;

		DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
			 BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len));

		/*
		 * Set data to point to where we copied the data into.
		 */

		data = prs_data_p(&outgoing_pdu) + data_pos;

		if (auth_seal) {
			crc32 = crc32_calc_buffer(data, data_len + ss_padding_len);
			NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len);
		}

		if (auth_seal || auth_verify) {
			RPC_HDR_AUTH auth_info;

			init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE,
					auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL,
					(auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0));
			if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
				DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
				prs_mem_free(&outgoing_pdu);
				return False;
			}
		}

		if (auth_verify) {
			RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
			char *auth_data = prs_data_p(&outgoing_pdu);

			p->ntlmssp_seq_num++;
			init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
					crc32, p->ntlmssp_seq_num++);
			auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
			if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
				DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
				prs_mem_free(&outgoing_pdu);
				return False;
			}
			NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
		}
	} else if (p->netsec_auth_validated) {
		/*
		 * Schannel processing. Mutually exclusive with NTLMSSP.
		 */
		int auth_type, auth_level;
		char *data;
		RPC_HDR_AUTH auth_info;

		RPC_AUTH_NETSEC_CHK verf;
		prs_struct rverf;
		prs_struct rauth;

		data = prs_data_p(&outgoing_pdu) + data_pos;
		/* Check it's the type of reply we were expecting to decode */

		get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level);
		init_rpc_hdr_auth(&auth_info, auth_type, auth_level, 
				  ss_padding_len, 1);

		if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
			DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
			prs_mem_free(&outgoing_pdu);
			return False;
		}

		prs_init(&rverf, 0, p->mem_ctx, MARSHALL);
		prs_init(&rauth, 0, p->mem_ctx, MARSHALL);

		netsec_encode(&p->netsec_auth, 
			      p->netsec_auth.auth_flags,
			      SENDER_IS_ACCEPTOR,
			      &verf, data, data_len + ss_padding_len);

		smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, 
			&verf, &outgoing_pdu, 0);

		p->netsec_auth.seq_num++;
	}

	/*
	 * Setup the counts for this PDU.
	 */

	p->out_data.data_sent_length += data_len;
	p->out_data.current_pdu_len = p->hdr.frag_len;
	p->out_data.current_pdu_sent = 0;

	prs_mem_free(&outgoing_pdu);
	return True;
}