mirror of
https://github.com/samba-team/samba.git
synced 2025-03-24 10:50:22 +03:00
s3:smbd: make use of smbXsrv_tcon and smbXsrv_session for smb2
The removes the protocol specific smbd_smb2_session and smbd_smb2_tcon. Pair-Programmed-With: Michael Adam <obnox@samba.org> metze
This commit is contained in:
parent
ef408e5068
commit
463b308f16
@ -280,6 +280,7 @@ struct share_params {
|
||||
typedef struct connection_struct {
|
||||
struct connection_struct *next, *prev;
|
||||
struct smbd_server_connection *sconn; /* can be NULL */
|
||||
struct smbXsrv_tcon0 *tcon; /* for now NULL for SMB1 */
|
||||
uint32_t cnum; /* an index passed over the wire */
|
||||
struct share_params *params;
|
||||
bool force_user;
|
||||
|
@ -160,7 +160,6 @@ interface smbXsrv
|
||||
[ignore] gensec_security *gensec;
|
||||
[ignore] user_struct *compat;
|
||||
[ignore] smbXsrv_tcon_table *tcon_table;
|
||||
[ignore] smbd_smb2_session *smb2sess;
|
||||
} smbXsrv_session0;
|
||||
|
||||
typedef union {
|
||||
|
@ -88,19 +88,7 @@ bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
|
||||
void conn_close_all(struct smbd_server_connection *sconn)
|
||||
{
|
||||
if (sconn->using_smb2) {
|
||||
/* SMB2 */
|
||||
struct smbd_smb2_session *sess;
|
||||
|
||||
for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
|
||||
struct smbd_smb2_tcon *tcon, *tc_next;
|
||||
|
||||
file_close_user(sconn, sess->vuid);
|
||||
|
||||
for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
|
||||
tc_next = tcon->next;
|
||||
TALLOC_FREE(tcon);
|
||||
}
|
||||
}
|
||||
smbXsrv_session_logoff_all(sconn->conn);
|
||||
} else {
|
||||
/* SMB1 */
|
||||
connection_struct *conn, *next;
|
||||
@ -131,21 +119,20 @@ void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename
|
||||
}
|
||||
|
||||
if (sconn->using_smb2) {
|
||||
/* SMB2 */
|
||||
struct smbd_smb2_session *sess;
|
||||
for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
|
||||
struct smbd_smb2_tcon *tcon, *tc_next;
|
||||
for (conn=sconn->connections;conn;conn=next) {
|
||||
struct smbXsrv_tcon *tcon;
|
||||
|
||||
for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
|
||||
tc_next = tcon->next;
|
||||
if (tcon->compat_conn &&
|
||||
strequal(lp_servicename(SNUM(tcon->compat_conn)),
|
||||
sharename)) {
|
||||
DEBUG(1,("Forcing close of share %s cnum=%d\n",
|
||||
sharename, tcon->compat_conn->cnum));
|
||||
TALLOC_FREE(tcon);
|
||||
}
|
||||
next = conn->next;
|
||||
tcon = conn->tcon;
|
||||
|
||||
if (!strequal(lp_servicename(SNUM(conn)), sharename)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG(1,("Forcing close of share %s cnum=%d\n",
|
||||
sharename, conn->cnum));
|
||||
smbXsrv_tcon_disconnect(tcon, conn->vuid);
|
||||
TALLOC_FREE(tcon);
|
||||
}
|
||||
} else {
|
||||
/* SMB1 */
|
||||
|
@ -680,7 +680,7 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smb2req->tcon->compat_conn != fsp->conn) {
|
||||
if (smb2req->tcon->compat != fsp->conn) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -688,7 +688,11 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smb2req->session->vuid != fsp->vuid) {
|
||||
if (smb2req->session->compat == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (smb2req->session->compat->vuid != fsp->vuid) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,6 @@ extern bool exit_firsttime;
|
||||
|
||||
struct tstream_context;
|
||||
struct smbd_smb2_request;
|
||||
struct smbd_smb2_session;
|
||||
struct smbd_smb2_tcon;
|
||||
|
||||
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn);
|
||||
|
||||
@ -411,11 +409,11 @@ struct smbd_smb2_request {
|
||||
struct smbd_server_connection *sconn;
|
||||
|
||||
/* the session the request operates on, maybe NULL */
|
||||
struct smbd_smb2_session *session;
|
||||
struct smbXsrv_session *session;
|
||||
uint64_t last_session_id;
|
||||
|
||||
/* the tcon the request operates on, maybe NULL */
|
||||
struct smbd_smb2_tcon *tcon;
|
||||
struct smbXsrv_tcon *tcon;
|
||||
uint32_t last_tid;
|
||||
|
||||
int current_idx;
|
||||
@ -487,37 +485,6 @@ struct smbd_smb2_request {
|
||||
struct smbd_server_connection;
|
||||
struct user_struct;
|
||||
|
||||
struct smbd_smb2_session {
|
||||
struct smbd_smb2_session *prev, *next;
|
||||
struct smbd_server_connection *sconn;
|
||||
NTSTATUS status;
|
||||
uint64_t vuid;
|
||||
struct gensec_security *gensec_security;
|
||||
struct auth_session_info *session_info;
|
||||
|
||||
struct smbXsrv_session *smbXsrv;
|
||||
|
||||
struct user_struct *compat_vuser;
|
||||
|
||||
struct {
|
||||
/* an id tree used to allocate tids */
|
||||
struct idr_context *idtree;
|
||||
|
||||
/* this is the limit of tid values for this connection */
|
||||
uint32_t limit;
|
||||
|
||||
struct smbd_smb2_tcon *list;
|
||||
} tcons;
|
||||
};
|
||||
|
||||
struct smbd_smb2_tcon {
|
||||
struct smbd_smb2_tcon *prev, *next;
|
||||
struct smbd_smb2_session *session;
|
||||
uint32_t tid;
|
||||
int snum;
|
||||
connection_struct *compat_conn;
|
||||
};
|
||||
|
||||
struct pending_message_list;
|
||||
struct pending_auth_data;
|
||||
|
||||
@ -673,9 +640,6 @@ struct smbd_server_connection {
|
||||
struct tevent_queue *send_queue;
|
||||
struct tstream_context *stream;
|
||||
bool negprot_2ff;
|
||||
struct {
|
||||
struct smbd_smb2_session *list;
|
||||
} sessions;
|
||||
struct {
|
||||
/* The event that makes us process our blocking lock queue */
|
||||
struct timed_event *brl_timeout;
|
||||
|
@ -145,6 +145,7 @@ void invalidate_vuid(struct smbd_server_connection *sconn, uint64_t vuid)
|
||||
void invalidate_all_vuids(struct smbd_server_connection *sconn)
|
||||
{
|
||||
if (sconn->using_smb2) {
|
||||
smbXsrv_session_logoff_all(sconn->conn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -988,9 +988,10 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
|
||||
void load_registry_shares(void);
|
||||
int add_home_service(const char *service, const char *username, const char *homedir);
|
||||
int find_service(TALLOC_CTX *ctx, const char *service, char **p_service_out);
|
||||
struct smbd_smb2_tcon;
|
||||
struct smbXsrv_tcon0;
|
||||
connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
|
||||
struct smbd_smb2_tcon *tcon,
|
||||
struct smbXsrv_tcon0 *tcon,
|
||||
int snum,
|
||||
struct user_struct *vuser,
|
||||
const char *pdev,
|
||||
NTSTATUS *pstatus);
|
||||
|
@ -941,7 +941,8 @@ static connection_struct *make_connection_smb1(struct smbd_server_connection *sc
|
||||
****************************************************************************/
|
||||
|
||||
connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
|
||||
struct smbd_smb2_tcon *tcon,
|
||||
struct smbXsrv_tcon *tcon,
|
||||
int snum,
|
||||
struct user_struct *vuser,
|
||||
const char *pdev,
|
||||
NTSTATUS *pstatus)
|
||||
@ -952,10 +953,13 @@ connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
|
||||
*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
return NULL;
|
||||
}
|
||||
conn->cnum = tcon->tid;
|
||||
|
||||
conn->cnum = tcon->global->tcon_wire_id;
|
||||
conn->tcon = tcon;
|
||||
|
||||
*pstatus = make_connection_snum(sconn,
|
||||
conn,
|
||||
tcon->snum,
|
||||
snum,
|
||||
vuser,
|
||||
pdev);
|
||||
if (!NT_STATUS_IS_OK(*pstatus)) {
|
||||
|
@ -158,7 +158,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct smb_request *smbreq;
|
||||
connection_struct *conn = req->tcon->compat_conn;
|
||||
connection_struct *conn = req->tcon->compat;
|
||||
struct smb_filename *smb_fname = NULL;
|
||||
struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
|
||||
uint64_t allocation_size = 0;
|
||||
|
@ -435,7 +435,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
ZERO_STRUCT(out_context_blobs);
|
||||
|
||||
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
|
||||
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
|
||||
requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
|
||||
} else {
|
||||
requested_oplock_level = in_oplock_level;
|
||||
@ -783,7 +783,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
smb2req->compat_chain_fsp = smb1req->chain_fsp;
|
||||
|
||||
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
|
||||
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
|
||||
state->out_oplock_level = in_oplock_level;
|
||||
} else {
|
||||
state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);
|
||||
|
@ -211,7 +211,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req;
|
||||
struct smbd_smb2_find_state *state;
|
||||
struct smb_request *smbreq;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
NTSTATUS status;
|
||||
NTSTATUS empty_status;
|
||||
uint32_t info_level;
|
||||
|
@ -253,7 +253,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req;
|
||||
struct smbd_smb2_getinfo_state *state;
|
||||
struct smb_request *smbreq;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
NTSTATUS status;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
|
@ -37,9 +37,9 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
|
||||
}
|
||||
|
||||
smbreq->request_time = req->request_time;
|
||||
smbreq->vuid = req->session->compat_vuser->vuid;
|
||||
smbreq->tid = req->tcon->compat_conn->cnum;
|
||||
smbreq->conn = req->tcon->compat_conn;
|
||||
smbreq->vuid = req->session->compat->vuid;
|
||||
smbreq->tid = req->tcon->compat->cnum;
|
||||
smbreq->conn = req->tcon->compat;
|
||||
smbreq->sconn = req->sconn;
|
||||
smbreq->smbpid = (uint16_t)IVAL(inhdr, SMB2_HDR_PID);
|
||||
smbreq->flags2 = FLAGS2_UNICODE_STRINGS |
|
||||
|
@ -195,7 +195,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req;
|
||||
struct smbd_smb2_notify_state *state;
|
||||
struct smb_request *smbreq;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
bool recursive = (in_flags & SMB2_WATCH_TREE) ? true : false;
|
||||
NTSTATUS status;
|
||||
|
||||
|
@ -389,7 +389,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req = NULL;
|
||||
struct smbd_smb2_read_state *state = NULL;
|
||||
struct smb_request *smbreq = NULL;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
ssize_t nread = -1;
|
||||
struct lock_struct lock;
|
||||
int saved_errno;
|
||||
|
@ -108,7 +108,6 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
sconn->smb2.sessions.list = NULL;
|
||||
sconn->smb2.seqnum_low = 0;
|
||||
sconn->smb2.credits_granted = 0;
|
||||
sconn->smb2.max_credits = lp_smb2_max_credits();
|
||||
@ -811,7 +810,7 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
|
||||
/* Re-sign if needed. */
|
||||
if (nreq->do_signing) {
|
||||
NTSTATUS status;
|
||||
struct smbXsrv_session *x = nreq->session->smbXsrv;
|
||||
struct smbXsrv_session *x = nreq->session;
|
||||
struct smbXsrv_connection *conn = x->connection;
|
||||
DATA_BLOB signing_key = x->global->channels[0].signing_key;
|
||||
|
||||
@ -1100,7 +1099,7 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
|
||||
|
||||
if (req->do_signing) {
|
||||
NTSTATUS status;
|
||||
struct smbXsrv_session *x = req->session->smbXsrv;
|
||||
struct smbXsrv_session *x = req->session;
|
||||
struct smbXsrv_connection *conn = x->connection;
|
||||
DATA_BLOB signing_key = x->global->channels[0].signing_key;
|
||||
|
||||
@ -1203,8 +1202,9 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
|
||||
int i = req->current_idx;
|
||||
uint32_t in_flags;
|
||||
uint32_t in_tid;
|
||||
void *p;
|
||||
struct smbd_smb2_tcon *tcon;
|
||||
struct smbXsrv_tcon0 *tcon;
|
||||
NTSTATUS status;
|
||||
NTTIME now = timeval_to_nttime(&req->request_time);
|
||||
|
||||
req->tcon = NULL;
|
||||
|
||||
@ -1217,19 +1217,18 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
|
||||
in_tid = req->last_tid;
|
||||
}
|
||||
|
||||
/* lookup an existing session */
|
||||
p = idr_find(req->session->tcons.idtree, in_tid);
|
||||
if (p == NULL) {
|
||||
return NT_STATUS_NETWORK_NAME_DELETED;
|
||||
status = smb2srv_tcon_lookup(req->session,
|
||||
in_tid, now, &tcon);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon);
|
||||
|
||||
if (!change_to_user(tcon->compat_conn,req->session->vuid)) {
|
||||
if (!change_to_user(tcon->compat, req->session->compat->vuid)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
/* should we pass FLAG_CASELESS_PATHNAMES here? */
|
||||
if (!set_current_service(tcon->compat_conn, 0, true)) {
|
||||
if (!set_current_service(tcon->compat, 0, true)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
@ -1249,8 +1248,8 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
|
||||
int i = req->current_idx;
|
||||
uint32_t in_flags;
|
||||
uint64_t in_session_id;
|
||||
struct smbd_smb2_session *session;
|
||||
struct smbXsrv_session *smbXsrv;
|
||||
struct smbXsrv_session *session;
|
||||
struct auth_session_info *session_info;
|
||||
NTSTATUS status;
|
||||
NTTIME now = timeval_to_nttime(&req->request_time);
|
||||
|
||||
@ -1269,18 +1268,19 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
|
||||
/* lookup an existing session */
|
||||
status = smb2srv_session_lookup(req->sconn->conn,
|
||||
in_session_id, now,
|
||||
&smbXsrv);
|
||||
&session);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
session = smbXsrv->smb2sess;
|
||||
if (!NT_STATUS_IS_OK(session->status)) {
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
|
||||
session_info = session->global->auth_session_info;
|
||||
if (session_info == NULL) {
|
||||
return NT_STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
set_current_user_info(session->session_info->unix_info->sanitized_username,
|
||||
session->session_info->unix_info->unix_name,
|
||||
session->session_info->info->domain_name);
|
||||
set_current_user_info(session_info->unix_info->sanitized_username,
|
||||
session_info->unix_info->unix_name,
|
||||
session_info->info->domain_name);
|
||||
|
||||
req->session = session;
|
||||
req->last_session_id = in_session_id;
|
||||
@ -1445,9 +1445,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
|
||||
* we defer the check of the session_status
|
||||
*/
|
||||
session_status = smbd_smb2_request_check_session(req);
|
||||
if (req->session) {
|
||||
x = req->session->smbXsrv;
|
||||
}
|
||||
x = req->session;
|
||||
|
||||
req->do_signing = false;
|
||||
if (flags & SMB2_HDR_FLAG_SIGNED) {
|
||||
@ -1949,7 +1947,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
|
||||
|
||||
if (req->do_signing) {
|
||||
NTSTATUS status;
|
||||
struct smbXsrv_session *x = req->session->smbXsrv;
|
||||
struct smbXsrv_session *x = req->session;
|
||||
struct smbXsrv_connection *conn = x->connection;
|
||||
DATA_BLOB signing_key = x->global->channels[0].signing_key;
|
||||
|
||||
|
@ -174,33 +174,7 @@ static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
|
||||
}
|
||||
}
|
||||
|
||||
static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
|
||||
{
|
||||
if (session->sconn == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file_close_user(session->sconn, session->vuid);
|
||||
|
||||
/* first free all tcons */
|
||||
while (session->tcons.list) {
|
||||
talloc_free(session->tcons.list);
|
||||
}
|
||||
|
||||
DLIST_REMOVE(session->sconn->smb2.sessions.list, session);
|
||||
invalidate_vuid(session->sconn, session->vuid);
|
||||
|
||||
session->vuid = 0;
|
||||
session->status = NT_STATUS_USER_SESSION_DELETED;
|
||||
session->sconn = NULL;
|
||||
|
||||
session->smbXsrv->compat = NULL;
|
||||
TALLOC_FREE(session->smbXsrv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
|
||||
static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
|
||||
struct smbd_smb2_request *smb2req,
|
||||
uint8_t in_security_mode,
|
||||
uint64_t in_previous_session_id,
|
||||
@ -211,16 +185,24 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
|
||||
NTSTATUS status;
|
||||
bool guest = false;
|
||||
uint8_t session_key[16];
|
||||
struct smbXsrv_session *x = session->smbXsrv;
|
||||
struct auth_session_info *session_info = session->session_info;
|
||||
struct smbXsrv_connection *conn = x->connection;
|
||||
struct smbXsrv_session *x = session;
|
||||
struct auth_session_info *session_info;
|
||||
struct smbXsrv_connection *conn = session->connection;
|
||||
|
||||
if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
|
||||
lp_server_signing() == SMB_SIGNING_REQUIRED) {
|
||||
x->global->signing_required = true;
|
||||
}
|
||||
|
||||
if (security_session_user_level(session->session_info, NULL) < SECURITY_USER) {
|
||||
status = gensec_session_info(session->gensec,
|
||||
session->global,
|
||||
&session_info);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(session);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
|
||||
/* we map anonymous to guest internally */
|
||||
*out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
|
||||
*out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
|
||||
@ -230,8 +212,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
|
||||
}
|
||||
|
||||
ZERO_STRUCT(session_key);
|
||||
memcpy(session_key, session->session_info->session_key.data,
|
||||
MIN(session->session_info->session_key.length, sizeof(session_key)));
|
||||
memcpy(session_key, session_info->session_key.data,
|
||||
MIN(session_info->session_key.length, sizeof(session_key)));
|
||||
|
||||
x->global->signing_key = data_blob_talloc(x->global,
|
||||
session_key,
|
||||
@ -286,55 +268,53 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
session->compat_vuser = talloc_zero(session, struct user_struct);
|
||||
if (session->compat_vuser == NULL) {
|
||||
session->compat = talloc_zero(session, struct user_struct);
|
||||
if (session->compat == NULL) {
|
||||
TALLOC_FREE(session);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
session->compat_vuser->gensec_security = session->gensec_security;
|
||||
session->compat_vuser->homes_snum = -1;
|
||||
session->compat_vuser->session_info = session->session_info;
|
||||
session->compat_vuser->session_keystr = NULL;
|
||||
session->compat_vuser->vuid = session->vuid;
|
||||
DLIST_ADD(session->sconn->users, session->compat_vuser);
|
||||
session->sconn->num_users++;
|
||||
session->compat->session = session;
|
||||
session->compat->homes_snum = -1;
|
||||
session->compat->session_info = session_info;
|
||||
session->compat->session_keystr = NULL;
|
||||
session->compat->vuid = session->global->session_wire_id;
|
||||
DLIST_ADD(smb2req->sconn->users, session->compat);
|
||||
smb2req->sconn->num_users++;
|
||||
|
||||
if (security_session_user_level(session->session_info, NULL) >= SECURITY_USER) {
|
||||
session->compat_vuser->homes_snum =
|
||||
register_homes_share(session->session_info->unix_info->unix_name);
|
||||
if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
|
||||
session->compat->homes_snum =
|
||||
register_homes_share(session_info->unix_info->unix_name);
|
||||
}
|
||||
|
||||
if (!session_claim(session->sconn, session->compat_vuser)) {
|
||||
if (!session_claim(smb2req->sconn, session->compat)) {
|
||||
DEBUG(1, ("smb2: Failed to claim session "
|
||||
"for vuid=%llu\n",
|
||||
(unsigned long long)session->compat_vuser->vuid));
|
||||
(unsigned long long)session->compat->vuid));
|
||||
TALLOC_FREE(session);
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
set_current_user_info(session->session_info->unix_info->sanitized_username,
|
||||
session->session_info->unix_info->unix_name,
|
||||
session->session_info->info->domain_name);
|
||||
set_current_user_info(session_info->unix_info->sanitized_username,
|
||||
session_info->unix_info->unix_name,
|
||||
session_info->info->domain_name);
|
||||
|
||||
reload_services(smb2req->sconn, conn_snum_used, true);
|
||||
|
||||
session->smbXsrv->status = NT_STATUS_OK;
|
||||
session->smbXsrv->global->auth_session_info = session->session_info;
|
||||
session->smbXsrv->global->auth_session_info_seqnum += 1;
|
||||
session->smbXsrv->global->channels[0].auth_session_info_seqnum =
|
||||
session->smbXsrv->global->auth_session_info_seqnum;
|
||||
session->status = NT_STATUS_OK;
|
||||
session->global->auth_session_info = session_info;
|
||||
session->global->auth_session_info_seqnum += 1;
|
||||
session->global->channels[0].auth_session_info_seqnum =
|
||||
session->global->auth_session_info_seqnum;
|
||||
|
||||
status = smbXsrv_session_update(session->smbXsrv);
|
||||
status = smbXsrv_session_update(session);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
|
||||
(unsigned long long)session->compat_vuser->vuid,
|
||||
(unsigned long long)session->compat->vuid,
|
||||
nt_errstr(status)));
|
||||
TALLOC_FREE(session);
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
session->status = NT_STATUS_OK;
|
||||
|
||||
/*
|
||||
* we attach the session to the request
|
||||
* so that the response can be signed
|
||||
@ -346,12 +326,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
|
||||
|
||||
global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
|
||||
|
||||
*out_session_id = session->vuid;
|
||||
*out_session_id = session->global->session_wire_id;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
|
||||
static NTSTATUS smbd_smb2_auth_generic(struct smbXsrv_session *session,
|
||||
struct smbd_smb2_request *smb2req,
|
||||
uint8_t in_security_mode,
|
||||
uint64_t in_previous_session_id,
|
||||
@ -364,18 +344,20 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
|
||||
|
||||
*out_security_buffer = data_blob_null;
|
||||
|
||||
if (session->gensec_security == NULL) {
|
||||
status = auth_generic_prepare(session, session->sconn->remote_address,
|
||||
&session->gensec_security);
|
||||
if (session->gensec == NULL) {
|
||||
status = auth_generic_prepare(session,
|
||||
session->connection->remote_address,
|
||||
&session->gensec);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(session);
|
||||
return status;
|
||||
}
|
||||
|
||||
gensec_want_feature(session->gensec_security, GENSEC_FEATURE_SESSION_KEY);
|
||||
gensec_want_feature(session->gensec_security, GENSEC_FEATURE_UNIX_TOKEN);
|
||||
gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
|
||||
gensec_want_feature(session->gensec, GENSEC_FEATURE_UNIX_TOKEN);
|
||||
|
||||
status = gensec_start_mech_by_oid(session->gensec_security, GENSEC_OID_SPNEGO);
|
||||
status = gensec_start_mech_by_oid(session->gensec,
|
||||
GENSEC_OID_SPNEGO);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(session);
|
||||
return status;
|
||||
@ -383,7 +365,7 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
|
||||
}
|
||||
|
||||
become_root();
|
||||
status = gensec_update(session->gensec_security,
|
||||
status = gensec_update(session->gensec,
|
||||
smb2req, NULL,
|
||||
in_security_buffer,
|
||||
out_security_buffer);
|
||||
@ -395,20 +377,10 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
*out_session_id = session->vuid;
|
||||
*out_session_id = session->global->session_wire_id;
|
||||
return status;
|
||||
}
|
||||
|
||||
status = gensec_session_info(session->gensec_security,
|
||||
session,
|
||||
&session->session_info);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(session);
|
||||
return status;
|
||||
}
|
||||
*out_session_id = session->vuid;
|
||||
|
||||
return smbd_smb2_auth_generic_return(session,
|
||||
smb2req,
|
||||
in_security_mode,
|
||||
@ -428,7 +400,6 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
|
||||
DATA_BLOB *out_security_buffer,
|
||||
uint64_t *out_session_id)
|
||||
{
|
||||
struct smbd_smb2_session *smb2sess;
|
||||
struct smbXsrv_session *session;
|
||||
NTSTATUS status;
|
||||
NTTIME now = timeval_to_nttime(&smb2req->request_time);
|
||||
@ -438,33 +409,11 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
|
||||
|
||||
if (in_session_id == 0) {
|
||||
/* create a new session */
|
||||
smb2sess = talloc_zero(smb2req->sconn, struct smbd_smb2_session);
|
||||
if (smb2sess == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
status = smbXsrv_session_create(smb2req->sconn->conn,
|
||||
now, &session);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
smb2sess->smbXsrv = session;
|
||||
session->smb2sess = smb2sess;
|
||||
talloc_set_destructor(smb2sess, smbd_smb2_session_destructor);
|
||||
|
||||
smb2sess->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
|
||||
smb2sess->vuid = session->global->session_wire_id;
|
||||
|
||||
smb2sess->tcons.idtree = idr_init(smb2sess);
|
||||
if (smb2sess->tcons.idtree == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
smb2sess->tcons.limit = 0x0000FFFE;
|
||||
smb2sess->tcons.list = NULL;
|
||||
|
||||
DLIST_ADD_END(smb2req->sconn->smb2.sessions.list, smb2sess,
|
||||
struct smbd_smb2_session *);
|
||||
smb2sess->sconn = smb2req->sconn;
|
||||
} else {
|
||||
status = smb2srv_session_lookup(smb2req->sconn->conn,
|
||||
in_session_id, now,
|
||||
@ -473,18 +422,11 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
|
||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||
}
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
smb2sess = session->smb2sess;
|
||||
}
|
||||
|
||||
if (NT_STATUS_IS_OK(smb2sess->status)) {
|
||||
return NT_STATUS_REQUEST_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
return smbd_smb2_auth_generic(smb2sess,
|
||||
return smbd_smb2_auth_generic(session,
|
||||
smb2req,
|
||||
in_security_mode,
|
||||
in_previous_session_id,
|
||||
@ -596,9 +538,19 @@ NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
|
||||
|
||||
/*
|
||||
* TODO: cancel all outstanding requests on the session
|
||||
* and delete all tree connections.
|
||||
*/
|
||||
smbd_smb2_session_destructor(req->session);
|
||||
status = smbXsrv_session_logoff(req->session);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("smbd_smb2_request_process_logoff: "
|
||||
"smbXsrv_session_logoff() failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
/*
|
||||
* If we hit this case, there is something completely
|
||||
* wrong, so we better disconnect the transport connection.
|
||||
*/
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* we may need to sign the response, so we need to keep
|
||||
* the session until the response is sent to the wire.
|
||||
|
@ -172,7 +172,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req = NULL;
|
||||
struct smbd_smb2_setinfo_state *state = NULL;
|
||||
struct smb_request *smbreq = NULL;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
NTSTATUS status;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
|
@ -169,27 +169,6 @@ static void smbd_smb2_request_tcon_done(struct tevent_req *subreq)
|
||||
}
|
||||
}
|
||||
|
||||
static int smbd_smb2_tcon_destructor(struct smbd_smb2_tcon *tcon)
|
||||
{
|
||||
if (tcon->session == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
idr_remove(tcon->session->tcons.idtree, tcon->tid);
|
||||
DLIST_REMOVE(tcon->session->tcons.list, tcon);
|
||||
|
||||
if (tcon->compat_conn) {
|
||||
set_current_service(tcon->compat_conn, 0, true);
|
||||
close_cnum(tcon->compat_conn, tcon->session->vuid);
|
||||
}
|
||||
|
||||
tcon->compat_conn = NULL;
|
||||
tcon->tid = 0;
|
||||
tcon->session = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
|
||||
const char *in_path,
|
||||
uint8_t *out_share_type,
|
||||
@ -201,11 +180,12 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
|
||||
const char *share = in_path;
|
||||
char *service = NULL;
|
||||
int snum = -1;
|
||||
struct smbd_smb2_tcon *tcon;
|
||||
struct smbXsrv_tcon *tcon;
|
||||
NTTIME now = timeval_to_nttime(&req->request_time);
|
||||
connection_struct *compat_conn = NULL;
|
||||
struct user_struct *compat_vuser = req->session->compat_vuser;
|
||||
int id;
|
||||
struct user_struct *compat_vuser = req->session->compat;
|
||||
NTSTATUS status;
|
||||
const char *share_name = NULL;
|
||||
|
||||
if (strncmp(share, "\\\\", 2) == 0) {
|
||||
const char *p = strchr(share+2, '\\');
|
||||
@ -253,39 +233,42 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
|
||||
}
|
||||
|
||||
/* create a new tcon as child of the session */
|
||||
tcon = talloc_zero(req->session, struct smbd_smb2_tcon);
|
||||
if (tcon == NULL) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
status = smb2srv_tcon_create(req->session, now, &tcon);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
id = idr_get_new_random(req->session->tcons.idtree,
|
||||
tcon,
|
||||
req->session->tcons.limit);
|
||||
if (id == -1) {
|
||||
TALLOC_FREE(tcon);
|
||||
return NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
tcon->tid = id;
|
||||
tcon->snum = snum;
|
||||
|
||||
DLIST_ADD_END(req->session->tcons.list, tcon,
|
||||
struct smbd_smb2_tcon *);
|
||||
tcon->session = req->session;
|
||||
talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);
|
||||
|
||||
compat_conn = make_connection_smb2(req->sconn,
|
||||
tcon,
|
||||
req->session->compat_vuser,
|
||||
tcon, snum,
|
||||
req->session->compat,
|
||||
"???",
|
||||
&status);
|
||||
if (compat_conn == NULL) {
|
||||
TALLOC_FREE(tcon);
|
||||
return status;
|
||||
}
|
||||
tcon->compat_conn = talloc_move(tcon, &compat_conn);
|
||||
|
||||
if (IS_PRINT(tcon->compat_conn)) {
|
||||
share_name = lp_servicename(SNUM(compat_conn));
|
||||
tcon->global->share_name = talloc_strdup(tcon->global, share_name);
|
||||
if (tcon->global->share_name == NULL) {
|
||||
conn_free(compat_conn);
|
||||
TALLOC_FREE(tcon);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
tcon->compat = talloc_move(tcon, &compat_conn);
|
||||
|
||||
tcon->status = NT_STATUS_OK;
|
||||
|
||||
status = smbXsrv_tcon_update(tcon);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
TALLOC_FREE(tcon);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (IS_PRINT(tcon->compat)) {
|
||||
*out_share_type = SMB2_SHARE_TYPE_PRINT;
|
||||
} else if (IS_IPC(tcon->compat_conn)) {
|
||||
} else if (IS_IPC(tcon->compat)) {
|
||||
*out_share_type = SMB2_SHARE_TYPE_PIPE;
|
||||
} else {
|
||||
*out_share_type = SMB2_SHARE_TYPE_DISK;
|
||||
@ -293,14 +276,14 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
|
||||
|
||||
*out_share_flags = 0;
|
||||
|
||||
if (lp_msdfs_root(SNUM(tcon->compat_conn)) && lp_host_msdfs()) {
|
||||
if (lp_msdfs_root(SNUM(tcon->compat)) && lp_host_msdfs()) {
|
||||
*out_share_flags |= (SMB2_SHAREFLAG_DFS|SMB2_SHAREFLAG_DFS_ROOT);
|
||||
*out_capabilities = SMB2_SHARE_CAP_DFS;
|
||||
} else {
|
||||
*out_capabilities = 0;
|
||||
}
|
||||
|
||||
switch(lp_csc_policy(SNUM(tcon->compat_conn))) {
|
||||
switch(lp_csc_policy(SNUM(tcon->compat))) {
|
||||
case CSC_POLICY_MANUAL:
|
||||
break;
|
||||
case CSC_POLICY_DOCUMENTS:
|
||||
@ -316,14 +299,14 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
|
||||
break;
|
||||
}
|
||||
|
||||
if (lp_hideunreadable(SNUM(tcon->compat_conn)) ||
|
||||
lp_hideunwriteable_files(SNUM(tcon->compat_conn))) {
|
||||
if (lp_hideunreadable(SNUM(tcon->compat)) ||
|
||||
lp_hideunwriteable_files(SNUM(tcon->compat))) {
|
||||
*out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM;
|
||||
}
|
||||
|
||||
*out_maximal_access = tcon->compat_conn->share_access;
|
||||
*out_maximal_access = tcon->compat->share_access;
|
||||
|
||||
*out_tree_id = tcon->tid;
|
||||
*out_tree_id = tcon->global->tcon_wire_id;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -406,8 +389,19 @@ NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
|
||||
|
||||
/*
|
||||
* TODO: cancel all outstanding requests on the tcon
|
||||
* and delete all file handles.
|
||||
*/
|
||||
status = smbXsrv_tcon_disconnect(req->tcon, req->tcon->compat->vuid);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(0, ("smbd_smb2_request_process_tdis: "
|
||||
"smbXsrv_tcon_disconnect() failed: %s\n",
|
||||
nt_errstr(status)));
|
||||
/*
|
||||
* If we hit this case, there is something completely
|
||||
* wrong, so we better disconnect the transport connection.
|
||||
*/
|
||||
return status;
|
||||
}
|
||||
|
||||
TALLOC_FREE(req->tcon);
|
||||
|
||||
outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
|
||||
|
@ -246,7 +246,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_req *req = NULL;
|
||||
struct smbd_smb2_write_state *state = NULL;
|
||||
struct smb_request *smbreq = NULL;
|
||||
connection_struct *conn = smb2req->tcon->compat_conn;
|
||||
connection_struct *conn = smb2req->tcon->compat;
|
||||
ssize_t nwritten;
|
||||
struct lock_struct lock;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user