return E_OUTOFMEMORY; /* FIXME */
}
-static NTSTATUS fss_vfs_conn_become(TALLOC_CTX *mem_ctx,
+static NTSTATUS fss_vfs_conn_create(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct messaging_context *msg_ctx,
struct auth_session_info *session_info,
goto err_free_conn;
}
- if (!become_user_by_session(conn, session_info)) {
- DEBUG(0, ("failed to become user\n"));
- status = NT_STATUS_ACCESS_DENIED;
- goto err_free_conn;
- }
*conn_out = conn;
return NT_STATUS_OK;
return status;
}
-static void fss_vfs_conn_unbecome(struct connection_struct *conn)
+static void fss_vfs_conn_destroy(struct connection_struct *conn)
{
- unbecome_user();
/* vfs_ChDir(conn, oldcwd); needed? */
SMB_VFS_DISCONNECT(conn);
conn_free(conn);
return E_OUTOFMEMORY;
}
- status = fss_vfs_conn_become(tmp_ctx, server_event_context(),
+ status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
p->msg_ctx, p->session_info, snum, &conn);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
return E_ACCESSDENIED;
}
+ if (!become_user_by_session(conn, p->session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ fss_vfs_conn_destroy(conn);
+ talloc_free(tmp_ctx);
+ return E_ACCESSDENIED;
+ }
+
status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx, path_name, &base_vol);
- fss_vfs_conn_unbecome(conn);
+ unbecome_user();
+ fss_vfs_conn_destroy(conn);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
return FSRVP_E_NOT_SUPPORTED;
return 0;
}
-struct fss_commit_state {
+struct fss_sc_commit_state {
+ struct auth_session_info *session_info;
+ struct connection_struct *conn;
+ char *base_path;
+ char *snap_path;
+};
+
+static void commit_sc_with_conn_done(struct tevent_req *subreq);
+
+static struct tevent_req *commit_sc_with_conn_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct messaging_context *msg_ctx,
+ struct auth_session_info *session_info,
+ struct fss_sc *sc)
+{
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct fss_sc_commit_state *sc_commit_state;
+ NTSTATUS status;
+ bool rw;
+
+ req = tevent_req_create(mem_ctx, &sc_commit_state,
+ struct fss_sc_commit_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ sc_commit_state->session_info = session_info;
+
+ status = fss_vfs_conn_create(sc_commit_state,
+ ev, msg_ctx, session_info,
+ sc->smaps->snum,
+ &sc_commit_state->conn);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
+ }
+
+ if (!become_user_by_session(sc_commit_state->conn, session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ fss_vfs_conn_destroy(sc_commit_state->conn);
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
+ }
+ rw = ((sc->sc_set->context & ATTR_AUTO_RECOVERY) == ATTR_AUTO_RECOVERY);
+ subreq = SMB_VFS_SNAP_CREATE_SEND(sc_commit_state->conn,
+ sc_commit_state,
+ ev, sc->volume_name,
+ &sc->create_ts, rw);
+ unbecome_user();
+ if (tevent_req_nomem(subreq, req)) {
+ fss_vfs_conn_destroy(sc_commit_state->conn);
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, commit_sc_with_conn_done, req);
+ return req;
+}
+
+static void commit_sc_with_conn_done(struct tevent_req *subreq)
+{
+ NTSTATUS status;
+ struct tevent_req *req
+ = tevent_req_callback_data(subreq, struct tevent_req);
+ struct fss_sc_commit_state *sc_commit_state
+ = tevent_req_data(req, struct fss_sc_commit_state);
+
+ if (!become_user_by_session(sc_commit_state->conn,
+ sc_commit_state->session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ tevent_req_done(req);
+ return;
+ }
+ status = SMB_VFS_SNAP_CREATE_RECV(sc_commit_state->conn, subreq,
+ sc_commit_state,
+ &sc_commit_state->base_path,
+ &sc_commit_state->snap_path);
+ if (tevent_req_nterror(req, status)) {
+ DEBUG(0, ("snap create failed: %s\n", nt_errstr(status)));
+ }
+ unbecome_user();
+ fss_vfs_conn_destroy(sc_commit_state->conn);
+ tevent_req_done(req);
+}
+
+static NTSTATUS commit_sc_with_conn_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ char **base_path, char **snap_path)
+{
+ NTSTATUS status;
+ struct fss_sc_commit_state *sc_commit_state
+ = tevent_req_data(req, struct fss_sc_commit_state);
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+ *base_path = talloc_strdup(mem_ctx, sc_commit_state->base_path);
+ *snap_path = talloc_strdup(mem_ctx, sc_commit_state->snap_path);
+ tevent_req_received(req);
+
+ return NT_STATUS_OK;
+}
+
+struct fss_sc_set_commit_state {
struct auth_session_info *session_info;
struct GUID sc_set_id; /* use guid as handle in case of abort */
uint32_t dispatch_count;
uint32_t bad_recv_count; /* number of failed completions */
NTSTATUS status;
};
-static void fss_commit_vfs_done(struct tevent_req *subreq);
+static void fss_commit_sc_set_done(struct tevent_req *subreq);
struct tevent_req *_fss_CommitShadowCopySet_send(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
struct fss_CommitShadowCopySet *r)
{
struct tevent_req *req;
- struct fss_commit_state *commit_state = NULL;
+ struct fss_sc_set_commit_state *commit_state = NULL;
struct fss_sc_set *sc_set;
struct fss_sc *sc;
- bool rw;
req = tevent_req_create(mem_ctx, &commit_state,
- struct fss_commit_state);
+ struct fss_sc_set_commit_state);
if (req == NULL) {
return NULL;
}
/* TODO stop Message Sequence Timer */
commit_state->session_info = p->session_info;
commit_state->sc_set_id = sc_set->id;
- rw = ((sc_set->context & ATTR_AUTO_RECOVERY) == ATTR_AUTO_RECOVERY);
for (sc = sc_set->scs; sc; sc = sc->next) {
- struct tevent_req *vfs_req = NULL;
- struct connection_struct *conn;
- NTSTATUS status;
- /* XXX error path is a bit complex here */
- status = fss_vfs_conn_become(commit_state,
- ev, p->msg_ctx, p->session_info,
- sc->smaps->snum, &conn);
- if (NT_STATUS_IS_OK(status)) {
- status = NT_STATUS_NO_MEMORY;
- vfs_req = SMB_VFS_SNAP_CREATE_SEND(conn, commit_state,
- ev, sc->volume_name,
- &sc->create_ts, rw);
- fss_vfs_conn_unbecome(conn);
- }
+ struct tevent_req *vfs_req;
+ vfs_req = commit_sc_with_conn_send(commit_state, ev, p->msg_ctx,
+ p->session_info, sc);
if (vfs_req == NULL) {
- commit_state->status = status;
+ commit_state->status = NT_STATUS_NO_MEMORY;
if (commit_state->dispatch_count == 0) {
/* nothing dispatched, return immediately */
tevent_req_nterror(sc_set->commit_req,
}
}
/* XXX set timeout r->in.TimeOutInMilliseconds */
- tevent_req_set_callback(vfs_req, fss_commit_vfs_done, sc);
+ tevent_req_set_callback(vfs_req, fss_commit_sc_set_done, sc);
sc->vfs_req = vfs_req;
commit_state->dispatch_count++;
}
return sc_set->commit_req;
}
-static void fss_commit_vfs_done(struct tevent_req *subreq)
+static void fss_commit_sc_set_done(struct tevent_req *subreq)
{
- /* FIXME use a sc handle */
struct fss_sc *sc = tevent_req_callback_data(subreq,
struct fss_sc);
struct tevent_req *req = sc->sc_set->commit_req;
- struct fss_commit_state *commit_state = tevent_req_data(req,
- struct fss_commit_state);
+ struct fss_sc_set_commit_state *commit_state = tevent_req_data(req,
+ struct fss_sc_set_commit_state);
char *snap_path;
char *base_path;
NTSTATUS status;
- struct connection_struct *conn;
commit_state->recv_count++;
- status = fss_vfs_conn_become(commit_state, server_event_context(),
- server_messaging_context(),
- commit_state->session_info,
- sc->smaps->snum, &conn);
- if (NT_STATUS_IS_OK(status)) {
- status = SMB_VFS_SNAP_CREATE_RECV(conn, subreq, sc,
- &base_path, &snap_path);
- fss_vfs_conn_unbecome(conn);
- }
+ status = commit_sc_with_conn_recv(subreq, sc, &base_path, &snap_path);
if (NT_STATUS_IS_OK(status)) {
DEBUG(10, ("good snap create recv %d of %d\n",
commit_state->recv_count,
sc->sc_path = snap_path;
} else {
DEBUG(0, ("snap create failed for shadow copy of "
- "%s\n", base_path));
+ "%s\n", sc->volume_name));
commit_state->bad_recv_count++;
commit_state->status = status; /* may overwrite previous failure */
}
uint32_t _fss_CommitShadowCopySet_recv(struct tevent_req *req)
{
- struct fss_commit_state *commit_state
- = tevent_req_data(req, struct fss_commit_state);
+ struct fss_sc_set_commit_state *commit_state
+ = tevent_req_data(req, struct fss_sc_set_commit_state);
if (!NT_STATUS_IS_OK(commit_state->status)) {
uint32_t ret;
return E_INVALIDARG;
}
- status = fss_vfs_conn_become(tmp_ctx, server_event_context(),
+ status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
p->msg_ctx, p->session_info, snum, &conn);
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(tmp_ctx);
+ return E_ACCESSDENIED;
+ }
+ if (!become_user_by_session(conn, p->session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ talloc_free(tmp_ctx);
+ fss_vfs_conn_destroy(conn);
return E_ACCESSDENIED;
}
status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx,
lp_pathname(tmp_ctx, snum),
&base_vol);
- fss_vfs_conn_unbecome(conn);
+ unbecome_user();
+ fss_vfs_conn_destroy(conn);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
return FSRVP_E_NOT_SUPPORTED;
struct fss_sc_set *sc_set;
struct fss_sc *sc;
struct fss_sc_smap *sc_smap;
+ struct connection_struct *conn;
int snum;
};
static void fss_delete_vfs_done(struct tevent_req *subreq);
struct tevent_req *vfs_req = NULL;
struct fss_sc_smap *sc_smap;
char *share;
- struct connection_struct *conn;
NTSTATUS status;
req = tevent_req_create(mem_ctx, &delete_state,
return tevent_req_post(req, ev);
}
- status = fss_vfs_conn_become(delete_state, ev, p->msg_ctx,
+ status = fss_vfs_conn_create(delete_state, ev, p->msg_ctx,
delete_state->session_info,
- delete_state->snum, &conn);
+ delete_state->snum,
+ &delete_state->conn);
if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
+ if (!become_user_by_session(delete_state->conn, p->session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ fss_vfs_conn_destroy(delete_state->conn);
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
+ }
- vfs_req = SMB_VFS_SNAP_DELETE_SEND(conn, delete_state, ev,
- sc->volume_name, sc->sc_path);
- fss_vfs_conn_unbecome(conn);
+ vfs_req = SMB_VFS_SNAP_DELETE_SEND(delete_state->conn, delete_state,
+ ev, sc->volume_name, sc->sc_path);
+ unbecome_user();
if (tevent_req_nomem(vfs_req, req)) {
+ fss_vfs_conn_destroy(delete_state->conn);
return tevent_req_post(req, ev);
}
struct fss_delete_state *delete_state = tevent_req_data(req,
struct fss_delete_state);
NTSTATUS status;
- struct connection_struct *conn;
- status = fss_vfs_conn_become(delete_state, server_event_context(),
- server_messaging_context(),
- delete_state->session_info,
- delete_state->snum, &conn);
- if (tevent_req_nterror(req, status)) {
+ if (!become_user_by_session(delete_state->conn,
+ delete_state->session_info)) {
+ DEBUG(0, ("failed to become user\n"));
+ fss_vfs_conn_destroy(delete_state->conn);
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
return;
}
- status = SMB_VFS_SNAP_DELETE_RECV(conn, subreq);
- fss_vfs_conn_unbecome(conn);
+ status = SMB_VFS_SNAP_DELETE_RECV(delete_state->conn, subreq);
+ unbecome_user();
+ fss_vfs_conn_destroy(delete_state->conn);
if (tevent_req_nterror(req, status)) {
DEBUG(0, ("bad snap delete recv: %s\n",
nt_errstr(status)));