The branch, v3-6-test has been updated via 6aeb139 struct make "struct shadow_copy_data" its own talloc context (cherry picked from commit d77854fbb22bc9237cea14aae1179bbfe3bd0998) via 0b78d42 s3: Remove SHADOW_COPY_DATA typedef (cherry picked from commit 0ec9a90c29b86435f32c1d47d89df85fa51742f2) via 82187ec s3: Support shadow copy display over SMB2 from 06a02e2 Split the ACE flag mapping between nfs4 and Windows into two separate functions rather than trying to do it inline. Allows us to carefully control what flags are mapped to what in one place. Modification to bug #8191 - vfs_gpfs dosn't honor ACE_FLAG_INHERITED_ACE
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 6aeb13996b2a7c1529a9083ad1a41c724ae1a35c Author: Volker Lendecke <v...@samba.org> Date: Mon May 30 12:11:53 2011 +0200 struct make "struct shadow_copy_data" its own talloc context (cherry picked from commit d77854fbb22bc9237cea14aae1179bbfe3bd0998) The last 3 patches address bug #8189 (Snapshot display not supported over SMB2). commit 0b78d42187ea7da6c14e26dc56b02447aa42eb49 Author: Volker Lendecke <v...@samba.org> Date: Mon May 30 12:06:31 2011 +0200 s3: Remove SHADOW_COPY_DATA typedef (cherry picked from commit 0ec9a90c29b86435f32c1d47d89df85fa51742f2) commit 82187ece14c7162baec43a31970ef4ba2561f67b Author: Volker Lendecke <v...@samba.org> Date: Mon May 30 17:14:56 2011 +0200 s3: Support shadow copy display over SMB2 Autobuild-User: Volker Lendecke <vlen...@samba.org> Autobuild-Date: Tue May 31 12:53:10 CEST 2011 on sn-devel-104 (cherry picked from commit 0fcafbf69b345b703dc759518afc8620a7d6f2e8) ----------------------------------------------------------------------- Summary of changes: source3/include/ntioctl.h | 5 +- source3/modules/vfs_default.c | 5 +- source3/modules/vfs_full_audit.c | 3 +- source3/modules/vfs_shadow_copy.c | 7 ++- source3/modules/vfs_shadow_copy2.c | 6 +- source3/modules/vfs_time_audit.c | 2 +- source3/smbd/nttrans.c | 24 ++----- source3/smbd/smb2_ioctl.c | 121 ++++++++++++++++++++++++++++++++++++ source3/smbd/vfs.c | 2 +- 9 files changed, 146 insertions(+), 29 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/ntioctl.h b/source3/include/ntioctl.h index 41b1dce..18707c5 100644 --- a/source3/include/ntioctl.h +++ b/source3/include/ntioctl.h @@ -77,13 +77,12 @@ /* For FSCTL_GET_SHADOW_COPY_DATA ...*/ typedef char SHADOW_COPY_LABEL[25]; -typedef struct shadow_copy_data { - TALLOC_CTX *mem_ctx; +struct shadow_copy_data { /* Total number of shadow volumes currently mounted */ uint32 num_volumes; /* Concatenated list of labels */ SHADOW_COPY_LABEL *labels; -} SHADOW_COPY_DATA; +}; #endif /* _NTIOCTL_H */ diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 5d6b512..4d06a10 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -84,7 +84,10 @@ static int vfswrap_set_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_T #endif } -static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels) +static int vfswrap_get_shadow_copy_data(struct vfs_handle_struct *handle, + struct files_struct *fsp, + struct shadow_copy_data *shadow_copy_data, + bool labels) { errno = ENOSYS; return -1; /* Not implemented. */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index a723a0c..17713f0 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -695,7 +695,8 @@ static int smb_full_audit_set_quota(struct vfs_handle_struct *handle, static int smb_full_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, - SHADOW_COPY_DATA *shadow_copy_data, bool labels) + struct shadow_copy_data *shadow_copy_data, + bool labels) { int result; diff --git a/source3/modules/vfs_shadow_copy.c b/source3/modules/vfs_shadow_copy.c index b93f98d..1db47d2 100644 --- a/source3/modules/vfs_shadow_copy.c +++ b/source3/modules/vfs_shadow_copy.c @@ -216,7 +216,10 @@ static int shadow_copy_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *_dirp return 0; } -static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels) +static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, + files_struct *fsp, + struct shadow_copy_data *shadow_copy_data, + bool labels) { SMB_STRUCT_DIR *p = SMB_VFS_NEXT_OPENDIR(handle,fsp->conn->connectpath,NULL,0); @@ -250,7 +253,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str continue; } - tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data->mem_ctx, + tlabels = (SHADOW_COPY_LABEL *)TALLOC_REALLOC(shadow_copy_data, shadow_copy_data->labels, (shadow_copy_data->num_volumes+1)*sizeof(SHADOW_COPY_LABEL)); if (tlabels == NULL) { diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index df3bde7..fedfb53 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -837,7 +837,7 @@ static int shadow_copy2_label_cmp_desc(const void *x, const void *y) sort the shadow copy data in ascending or descending order */ static void shadow_copy2_sort_data(vfs_handle_struct *handle, - SHADOW_COPY_DATA *shadow_copy2_data) + struct shadow_copy_data *shadow_copy2_data) { int (*cmpfunc)(const void *, const void *); const char *sort; @@ -869,7 +869,7 @@ static void shadow_copy2_sort_data(vfs_handle_struct *handle, static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, files_struct *fsp, - SHADOW_COPY_DATA *shadow_copy2_data, + struct shadow_copy_data *shadow_copy2_data, bool labels) { SMB_STRUCT_DIR *p; @@ -918,7 +918,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle, continue; } - tlabels = talloc_realloc(shadow_copy2_data->mem_ctx, + tlabels = talloc_realloc(shadow_copy2_data, shadow_copy2_data->labels, SHADOW_COPY_LABEL, shadow_copy2_data->num_volumes+1); if (tlabels == NULL) { diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 37fe1c6..d21542c 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -144,7 +144,7 @@ static int smb_time_audit_set_quota(struct vfs_handle_struct *handle, static int smb_time_audit_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, - SHADOW_COPY_DATA *shadow_copy_data, + struct shadow_copy_data *shadow_copy_data, bool labels) { int result; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 5b14182..427e566 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -2214,8 +2214,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, * Allocate the correct amount and return the pointer to let * it be deallocated when we return. */ - SHADOW_COPY_DATA *shadow_data = NULL; - TALLOC_CTX *shadow_mem_ctx = NULL; + struct shadow_copy_data *shadow_data = NULL; bool labels = False; uint32 labels_data_count = 0; uint32 i; @@ -2236,28 +2235,19 @@ static void call_nt_transact_ioctl(connection_struct *conn, labels = True; } - shadow_mem_ctx = talloc_init("SHADOW_COPY_DATA"); - if (shadow_mem_ctx == NULL) { - DEBUG(0,("talloc_init(SHADOW_COPY_DATA) failed!\n")); - reply_nterror(req, NT_STATUS_NO_MEMORY); - return; - } - - shadow_data = TALLOC_ZERO_P(shadow_mem_ctx,SHADOW_COPY_DATA); + shadow_data = TALLOC_ZERO_P(talloc_tos(), + struct shadow_copy_data); if (shadow_data == NULL) { DEBUG(0,("TALLOC_ZERO() failed!\n")); - talloc_destroy(shadow_mem_ctx); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } - shadow_data->mem_ctx = shadow_mem_ctx; - /* * Call the VFS routine to actually do the work. */ if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) { - talloc_destroy(shadow_data->mem_ctx); + TALLOC_FREE(shadow_data); if (errno == ENOSYS) { DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n", conn->connectpath)); @@ -2282,14 +2272,14 @@ static void call_nt_transact_ioctl(connection_struct *conn, if (max_data_count<data_count) { DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: max_data_count(%u) too small (%u) bytes needed!\n", max_data_count,data_count)); - talloc_destroy(shadow_data->mem_ctx); + TALLOC_FREE(shadow_data); reply_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } pdata = nttrans_realloc(ppdata, data_count); if (pdata == NULL) { - talloc_destroy(shadow_data->mem_ctx); + TALLOC_FREE(shadow_data); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -2322,7 +2312,7 @@ static void call_nt_transact_ioctl(connection_struct *conn, } } - talloc_destroy(shadow_data->mem_ctx); + TALLOC_FREE(shadow_data); send_nt_replies(conn, req, NT_STATUS_OK, NULL, 0, pdata, data_count); diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index 6dc0cec..3ee0453 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -24,6 +24,7 @@ #include "../libcli/smb/smb_common.h" #include "../lib/util/tevent_ntstatus.h" #include "rpc_server/srv_pipe_hnd.h" +#include "include/ntioctl.h" static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -377,6 +378,126 @@ static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx, req); return req; + case 0x00144064: /* FSCTL_SRV_ENUMERATE_SNAPSHOTS */ + { + /* + * This is called to retrieve the number of Shadow Copies (a.k.a. snapshots) + * and return their volume names. If max_data_count is 16, then it is just + * asking for the number of volumes and length of the combined names. + * + * pdata is the data allocated by our caller, but that uses + * total_data_count (which is 0 in our case) rather than max_data_count. + * Allocate the correct amount and return the pointer to let + * it be deallocated when we return. + */ + struct shadow_copy_data *shadow_data = NULL; + bool labels = False; + uint32_t labels_data_count = 0; + uint32_t data_count; + uint32_t i; + char *pdata; + NTSTATUS status; + + if (in_max_output < 16) { + DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " + "in_max_output(%u) < 16 is invalid!\n", + in_max_output)); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + if (in_max_output > 16) { + labels = True; + } + + shadow_data = TALLOC_ZERO_P(talloc_tos(), + struct shadow_copy_data); + if (tevent_req_nomem(shadow_data, req)) { + DEBUG(0,("TALLOC_ZERO() failed!\n")); + return tevent_req_post(req, ev); + } + + /* + * Call the VFS routine to actually do the work. + */ + if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels) + != 0) { + if (errno == ENOSYS) { + DEBUG(5, ("FSCTL_GET_SHADOW_COPY_DATA: " + "connectpath %s, not supported.\n", + smbreq->conn->connectpath)); + status = NT_STATUS_NOT_SUPPORTED; + } else { + DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: " + "connectpath %s, failed.\n", + smbreq->conn->connectpath)); + status = map_nt_error_from_unix(errno); + } + TALLOC_FREE(shadow_data); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + } + + labels_data_count = + (shadow_data->num_volumes*2*sizeof(SHADOW_COPY_LABEL)) + + 2; + + if (labels) { + data_count = 12+labels_data_count+4; + } else { + data_count = 16; + } + + if (labels && (in_max_output < data_count)) { + DEBUG(0, ("FSCTL_GET_SHADOW_COPY_DATA: " + "in_max_output(%u) too small (%u) bytes " + "needed!\n", in_max_output, data_count)); + TALLOC_FREE(shadow_data); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + return tevent_req_post(req, ev); + } + + state->out_output = data_blob_talloc(state, NULL, data_count); + if (tevent_req_nomem(state->out_output.data, req)) { + return tevent_req_post(req, ev); + } + + pdata = (char *)state->out_output.data; + + /* num_volumes 4 bytes */ + SIVAL(pdata, 0, shadow_data->num_volumes); + + if (labels) { + /* num_labels 4 bytes */ + SIVAL(pdata, 4, shadow_data->num_volumes); + } + + /* needed_data_count 4 bytes */ + SIVAL(pdata, 8, labels_data_count+4); + + pdata += 12; + + DEBUG(10,("FSCTL_GET_SHADOW_COPY_DATA: %u volumes for " + "path[%s].\n", + shadow_data->num_volumes, fsp_str_dbg(fsp))); + if (labels && shadow_data->labels) { + for (i=0; i<shadow_data->num_volumes; i++) { + srvstr_push(pdata, smbreq->flags2, + pdata, shadow_data->labels[i], + 2*sizeof(SHADOW_COPY_LABEL), + STR_UNICODE|STR_TERMINATE); + pdata += 2*sizeof(SHADOW_COPY_LABEL); + DEBUGADD(10, ("Label[%u]: '%s'\n", i, + shadow_data->labels[i])); + } + } + + TALLOC_FREE(shadow_data); + + tevent_req_done(req); + return tevent_req_post(req, ev); + } + default: if (IS_IPC(smbreq->conn)) { tevent_req_nterror(req, NT_STATUS_FS_DRIVER_REQUIRED); diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 3bde0a3..bdcb8e4 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1174,7 +1174,7 @@ int smb_vfs_call_set_quota(struct vfs_handle_struct *handle, int smb_vfs_call_get_shadow_copy_data(struct vfs_handle_struct *handle, struct files_struct *fsp, - SHADOW_COPY_DATA *shadow_copy_data, + struct shadow_copy_data *shadow_copy_data, bool labels) { VFS_FIND(get_shadow_copy_data); -- Samba Shared Repository