Example #1
0
static void sesssetup_nt1_send(struct tevent_req *subreq)
{
    struct sesssetup_context *state = tevent_req_callback_data(subreq, struct sesssetup_context);
    struct smbsrv_request *req = state->req;
    union smb_sesssetup *sess = talloc_get_type(req->io_ptr, union smb_sesssetup);
    struct auth_user_info_dc *user_info_dc = NULL;
    struct auth_session_info *session_info;
    struct smbsrv_session *smb_sess;

    uint32_t flags;
    NTSTATUS status;

    status = auth_check_password_recv(subreq, req, &user_info_dc);
    TALLOC_FREE(subreq);
    if (!NT_STATUS_IS_OK(status)) goto failed;

    flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
    if (user_info_dc->info->authenticated) {
        flags |= AUTH_SESSION_INFO_AUTHENTICATED;
    }
    /* This references user_info_dc into session_info */
    status = state->auth_context->generate_session_info(state->auth_context,
             req,
             user_info_dc,
             sess->nt1.in.user,
             flags,
             &session_info);
    if (!NT_STATUS_IS_OK(status)) goto failed;

    /* allocate a new session */
    smb_sess = smbsrv_session_new(req->smb_conn, req, NULL);
    if (!smb_sess) {
        status = NT_STATUS_INSUFFICIENT_RESOURCES;
        goto failed;
    }

    /* Ensure this is marked as a 'real' vuid, not one
     * simply valid for the session setup leg */
    status = smbsrv_session_sesssetup_finished(smb_sess, session_info);
    if (!NT_STATUS_IS_OK(status)) goto failed;

    /* To correctly process any AndX packet (like a tree connect)
     * we need to fill in the session on the request here */
    req->session = smb_sess;
    sess->nt1.out.vuid = smb_sess->vuid;

    if (!smbsrv_setup_signing(req->smb_conn, &session_info->session_key, &sess->nt1.in.password2)) {
        /* Already signing, or disabled */
        goto done;
    }

done:
    status = NT_STATUS_OK;
failed:
    status = nt_status_squash(status);
    smbsrv_sesssetup_backend_send(req, sess, status);
}
Example #2
0
/*
  handler for NT1 style session setup
*/
static void sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *sess)
{
	NTSTATUS status;
	struct auth_usersupplied_info *user_info = NULL;
	struct tsocket_address *remote_address;
	const char *remote_machine = NULL;
	struct tevent_req *subreq;
	struct sesssetup_context *state;

	sess->nt1.out.vuid = 0;
	sess->nt1.out.action = 0;

	sesssetup_common_strings(req, 
				 &sess->nt1.out.os,
				 &sess->nt1.out.lanman,
				 &sess->nt1.out.domain);

	if (!req->smb_conn->negotiate.done_sesssetup) {
		req->smb_conn->negotiate.max_send = sess->nt1.in.bufsize;
		req->smb_conn->negotiate.client_caps = sess->nt1.in.capabilities;
	}

	state = talloc(req, struct sesssetup_context);
	if (!state) goto nomem;

	state->req = req;

	if (req->smb_conn->negotiate.oid) {
		if (sess->nt1.in.user && *sess->nt1.in.user) {
			/* We can't accept a normal login, because we
			 * don't have a challenge */
			status = NT_STATUS_LOGON_FAILURE;
			goto failed;
		}

		/* TODO: should we use just "anonymous" here? */
		status = auth_context_create(state,
					     req->smb_conn->connection->event.ctx,
					     req->smb_conn->connection->msg_ctx,
					     req->smb_conn->lp_ctx,
					     &state->auth_context);
		if (!NT_STATUS_IS_OK(status)) goto failed;
	} else if (req->smb_conn->negotiate.auth_context) {
		state->auth_context = req->smb_conn->negotiate.auth_context;
	} else {
		/* TODO: should we use just "anonymous" here? */
		status = auth_context_create(state,
					     req->smb_conn->connection->event.ctx,
					     req->smb_conn->connection->msg_ctx,
					     req->smb_conn->lp_ctx,
					     &state->auth_context);
		if (!NT_STATUS_IS_OK(status)) goto failed;
	}

	if (req->smb_conn->negotiate.calling_name) {
		remote_machine = req->smb_conn->negotiate.calling_name->name;
	}

	remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
	if (!remote_address) goto nomem;

	if (!remote_machine) {
		remote_machine = tsocket_address_inet_addr_string(remote_address, req);
		if (!remote_machine) goto nomem;
	}

	user_info = talloc_zero(req, struct auth_usersupplied_info);
	if (!user_info) goto nomem;

	user_info->mapped_state = false;
	user_info->logon_parameters = 0;
	user_info->flags = 0;
	user_info->client.account_name = sess->nt1.in.user;
	user_info->client.domain_name = sess->nt1.in.domain;
	user_info->workstation_name = remote_machine;
	user_info->remote_host = talloc_steal(user_info, remote_address);
	
	user_info->password_state = AUTH_PASSWORD_RESPONSE;
	user_info->password.response.lanman = sess->nt1.in.password1;
	user_info->password.response.lanman.data = talloc_steal(user_info, sess->nt1.in.password1.data);
	user_info->password.response.nt = sess->nt1.in.password2;
	user_info->password.response.nt.data = talloc_steal(user_info, sess->nt1.in.password2.data);

	subreq = auth_check_password_send(state,
					  req->smb_conn->connection->event.ctx,
					  state->auth_context,
					  user_info);
	if (!subreq) goto nomem;
	tevent_req_set_callback(subreq, sesssetup_nt1_send, state);

	return;

nomem:
	status = NT_STATUS_NO_MEMORY;
failed:
	status = nt_status_squash(status);
	smbsrv_sesssetup_backend_send(req, sess, status);
}
Example #3
0
/*
  handler for old style session setup
*/
static void sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *sess)
{
	struct auth_usersupplied_info *user_info = NULL;
	struct tsocket_address *remote_address;
	const char *remote_machine = NULL;
	struct tevent_req *subreq;
	struct sesssetup_context *state;

	sess->old.out.vuid = 0;
	sess->old.out.action = 0;

	sesssetup_common_strings(req, 
				 &sess->old.out.os,
				 &sess->old.out.lanman,
				 &sess->old.out.domain);

	if (!req->smb_conn->negotiate.done_sesssetup) {
		req->smb_conn->negotiate.max_send = sess->old.in.bufsize;
	}

	if (req->smb_conn->negotiate.calling_name) {
		remote_machine = req->smb_conn->negotiate.calling_name->name;
	}
	
	remote_address = socket_get_remote_addr(req->smb_conn->connection->socket, req);
	if (!remote_address) goto nomem;

	if (!remote_machine) {
		remote_machine = tsocket_address_inet_addr_string(remote_address, req);
		if (!remote_machine) goto nomem;
	}

	user_info = talloc_zero(req, struct auth_usersupplied_info);
	if (!user_info) goto nomem;
	
	user_info->mapped_state = false;
	user_info->logon_parameters = 0;
	user_info->flags = 0;
	user_info->client.account_name = sess->old.in.user;
	user_info->client.domain_name = sess->old.in.domain;
	user_info->workstation_name = remote_machine;
	user_info->remote_host = talloc_steal(user_info, remote_address);
	
	user_info->password_state = AUTH_PASSWORD_RESPONSE;
	user_info->password.response.lanman = sess->old.in.password;
	user_info->password.response.lanman.data = talloc_steal(user_info, sess->old.in.password.data);
	user_info->password.response.nt = data_blob(NULL, 0);

	state = talloc(req, struct sesssetup_context);
	if (!state) goto nomem;

	if (req->smb_conn->negotiate.auth_context) {
		state->auth_context = req->smb_conn->negotiate.auth_context;
	} else {
		/* TODO: should we use just "anonymous" here? */
		NTSTATUS status = auth_context_create(state,
						      req->smb_conn->connection->event.ctx,
						      req->smb_conn->connection->msg_ctx,
						      req->smb_conn->lp_ctx,
						      &state->auth_context);
		if (!NT_STATUS_IS_OK(status)) {
			smbsrv_sesssetup_backend_send(req, sess, status);
			return;
		}
	}

	state->req = req;

	subreq = auth_check_password_send(state,
					  req->smb_conn->connection->event.ctx,
					  req->smb_conn->negotiate.auth_context,
					  user_info);
	if (!subreq) goto nomem;
	tevent_req_set_callback(subreq, sesssetup_old_send, state);
	return;

nomem:
	smbsrv_sesssetup_backend_send(req, sess, NT_STATUS_NO_MEMORY);
}