Esempio n. 1
0
/*
 * This is the SMB2 handler for new smb requests, called from
 * smb_session_reader after SMB negotiate is done.  For most SMB2
 * requests, we just enqueue them for the smb_session_worker to
 * execute via the task queue, so they can block for resources
 * without stopping the reader thread.  A few protocol messages
 * are special cases and are handled directly here in the reader
 * thread so they don't wait for taskq scheduling.
 *
 * This function must either enqueue the new request for
 * execution via the task queue, or execute it directly
 * and then free it.  If this returns non-zero, the caller
 * will drop the session.
 */
int
smb2sr_newrq(smb_request_t *sr)
{
	uint32_t magic;
	uint16_t command;
	int rc;

	magic = LE_IN32(sr->sr_request_buf);
	if (magic != SMB2_PROTOCOL_MAGIC) {
		smb_request_free(sr);
		/* will drop the connection */
		return (EPROTO);
	}

	/*
	 * Execute Cancel requests immediately, (here in the
	 * reader thread) so they won't wait for any other
	 * commands we might already have in the task queue.
	 * Cancel also skips signature verification and
	 * does not consume a sequence number.
	 * [MS-SMB2] 3.2.4.24 Cancellation...
	 */
	command = LE_IN16((uint8_t *)sr->sr_request_buf + 12);
	if (command == SMB2_CANCEL) {
		rc = smb2sr_newrq_cancel(sr);
		smb_request_free(sr);
		return (rc);
	}

	/*
	 * XXX With SMB3 this is supposed to increment based on
	 * the number of credits consumed by a request.  Todo
	 */
	if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
		/* XXX MS-SMB2 is unclear on this. todo */
		sr->session->signing.seqnum++;
		sr->sr_seqnum = sr->session->signing.seqnum;
		sr->reply_seqnum = sr->sr_seqnum;
	}

	/*
	 * Submit the request to the task queue, which calls
	 * smb2_dispatch_request when the workload permits.
	 */
	sr->sr_time_submitted = gethrtime();
	sr->sr_state = SMB_REQ_STATE_SUBMITTED;
	sr->work_func = smb2sr_work;
	smb_srqueue_waitq_enter(sr->session->s_srqueue);
	(void) taskq_dispatch(sr->session->s_server->sv_worker_pool,
	    smb_session_worker, sr, TQ_SLEEP);

	return (0);

}
Esempio n. 2
0
/*
 * smb_auth_qnd_unicode
 *
 * Quick and dirty unicode conversion!
 * Returns the length of dst in bytes.
 */
int
smb_auth_qnd_unicode(smb_wchar_t *dst, const char *src, int length)
{
    int i;
    unsigned int count;
    smb_wchar_t new_char;

    if ((count = oemtoucs(dst, src, length, OEM_CPG_1252)) == 0) {
        for (i = 0; i < length; ++i) {
            new_char = (smb_wchar_t)src[i] & 0xff;
            dst[i] = LE_IN16(&new_char);
        }
        dst[i] = 0;
        count = length;
    }

    return (count * sizeof (smb_wchar_t));
}