shadow_copy2: add comment header describing shadow_copy2_strip_snapshot()
[mat/samba.git] / source3 / modules / vfs_shadow_copy2.c
index 227453d27794303dd7538dc3846e691fdc44ff5d..8bbb7b824c29f125fb01b674b818790c95145011 100644 (file)
 #include <ccan/hash/hash.h>
 #include "util_tdb.h"
 
-#define GMT_NAME_LEN 24 /* length of a @GMT- name */
-#define GMT_FORMAT "@GMT-%Y.%m.%d-%H.%M.%S"
-
 static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str,
                                      size_t **poffsets,
                                      unsigned *pnum_offsets)
@@ -150,27 +147,34 @@ static char *shadow_copy2_insert_string(TALLOC_CTX *mem_ctx,
 {
        const char *fmt;
        struct tm snap_tm;
-       fstring gmt;
-       size_t gmt_len;
+       fstring snaptime_string;
+       size_t snaptime_len;
 
-       if (localtime_r(&snapshot, &snap_tm) == 0) {
-               DEBUG(10, ("gmtime_r failed\n"));
-               return NULL;
-       }
        fmt = lp_parm_const_string(SNUM(handle->conn), "shadow",
                                   "format", GMT_FORMAT);
 
        if (lp_parm_bool(SNUM(handle->conn), "shadow", "sscanf", false)) {
-               gmt_len = snprintf(gmt, sizeof(gmt), fmt,
+               snaptime_len = snprintf(snaptime_string, sizeof(snaptime_string), fmt,
                                   (unsigned long)snapshot);
-               if (gmt_len == 0) {
+               if (snaptime_len <= 0) {
                        DEBUG(10, ("snprintf failed\n"));
                        return NULL;
                }
        } else {
-               gmt_len = strftime(gmt, sizeof(gmt), fmt,
+               if (lp_parm_bool(SNUM(handle->conn), "shadow", "localtime", false)) {
+                       if (localtime_r(&snapshot, &snap_tm) == 0) {
+                               DEBUG(10, ("gmtime_r failed\n"));
+                               return NULL;
+                       }
+               } else {
+                       if (gmtime_r(&snapshot, &snap_tm) == 0) {
+                               DEBUG(10, ("gmtime_r failed\n"));
+                               return NULL;
+                       }
+               }
+               snaptime_len = strftime(snaptime_string, sizeof(snaptime_string), fmt,
                                   &snap_tm);
-               if (gmt_len == 0) {
+               if (snaptime_len == 0) {
                        DEBUG(10, ("strftime failed\n"));
                        return NULL;
                }
@@ -179,9 +183,14 @@ static char *shadow_copy2_insert_string(TALLOC_CTX *mem_ctx,
                               lp_parm_const_string(
                                       SNUM(handle->conn), "shadow", "snapdir",
                                       ".snapshots"),
-                              gmt);
+                              snaptime_string);
 }
 
+/**
+ * Strip a snapshot component from an filename as
+ * handed in via the smb layer.
+ * Returns the parsed timestamp and the stripped filename.
+ */
 static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
                                        struct vfs_handle_struct *handle,
                                        const char *name,
@@ -207,7 +216,7 @@ static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
                goto no_snapshot;
        }
        tm.tm_isdst = -1;
-       timestamp = mktime(&tm);
+       timestamp = timegm(&tm);
        if (timestamp == (time_t)-1) {
                goto no_snapshot;
        }
@@ -703,7 +712,6 @@ static int shadow_copy2_unlink(vfs_handle_struct *handle,
        char *stripped;
        int ret, saved_errno;
        struct smb_filename *conv;
-       NTSTATUS status;
 
        if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
                                         smb_fname->base_name,
@@ -713,8 +721,8 @@ static int shadow_copy2_unlink(vfs_handle_struct *handle,
        if (timestamp == 0) {
                return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
        }
-       status = copy_smb_filename(talloc_tos(), smb_fname, &conv);
-       if (!NT_STATUS_IS_OK(status)) {
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
+       if (conv == NULL) {
                errno = ENOMEM;
                return -1;
        }
@@ -820,7 +828,6 @@ static int shadow_copy2_ntimes(vfs_handle_struct *handle,
        char *stripped;
        int ret, saved_errno;
        struct smb_filename *conv;
-       NTSTATUS status;
 
        if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
                                         smb_fname->base_name,
@@ -830,8 +837,8 @@ static int shadow_copy2_ntimes(vfs_handle_struct *handle,
        if (timestamp == 0) {
                return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
        }
-       status = copy_smb_filename(talloc_tos(), smb_fname, &conv);
-       if (!NT_STATUS_IS_OK(status)) {
+       conv = cp_smb_filename(talloc_tos(), smb_fname);
+       if (conv == NULL) {
                errno = ENOMEM;
                return -1;
        }
@@ -1028,7 +1035,8 @@ static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle,
        ZERO_STRUCT(timestamp);
        if (lp_parm_bool(SNUM(handle->conn), "shadow", "sscanf", false)) {
                if (sscanf(name, fmt, &timestamp_long) != 1) {
-                       DEBUG(10, ("shadow_copy2_snapshot_to_gmt: no sscanf match %s: %s\n",
+                       DEBUG(10, ("shadow_copy2_snapshot_to_gmt: "
+                                  "no sscanf match %s: %s\n",
                                   fmt, name));
                        return false;
                }
@@ -1036,11 +1044,13 @@ static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle,
                gmtime_r(&timestamp_t, &timestamp);
        } else {
                if (strptime(name, fmt, &timestamp) == NULL) {
-                       DEBUG(10, ("shadow_copy2_snapshot_to_gmt: no match %s: %s\n",
+                       DEBUG(10, ("shadow_copy2_snapshot_to_gmt: "
+                                  "no match %s: %s\n",
                                   fmt, name));
                        return false;
                }
-               DEBUG(10, ("shadow_copy2_snapshot_to_gmt: match %s: %s\n", fmt, name));
+               DEBUG(10, ("shadow_copy2_snapshot_to_gmt: match %s: %s\n",
+                          fmt, name));
                
                if (lp_parm_bool(SNUM(handle->conn), "shadow", "localtime", false)) {
                        timestamp.tm_isdst = -1;
@@ -1181,6 +1191,7 @@ static int shadow_copy2_get_shadow_copy_data(
 static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle,
                                        struct files_struct *fsp,
                                        uint32 security_info,
+                                        TALLOC_CTX *mem_ctx,
                                        struct security_descriptor **ppdesc)
 {
        time_t timestamp;
@@ -1195,6 +1206,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle,
        }
        if (timestamp == 0) {
                return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
+                                               mem_ctx,
                                                ppdesc);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
@@ -1202,7 +1214,8 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle,
        if (conv == NULL) {
                return map_nt_error_from_unix(errno);
        }
-       status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc);
+       status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info,
+                                        mem_ctx, ppdesc);
        TALLOC_FREE(conv);
        return status;
 }
@@ -1210,6 +1223,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle,
 static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
                                        const char *fname,
                                        uint32 security_info,
+                                       TALLOC_CTX *mem_ctx,
                                        struct security_descriptor **ppdesc)
 {
        time_t timestamp;
@@ -1223,14 +1237,15 @@ static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle,
        }
        if (timestamp == 0) {
                return SMB_VFS_NEXT_GET_NT_ACL(handle, fname, security_info,
-                                              ppdesc);
+                                              mem_ctx, ppdesc);
        }
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
        TALLOC_FREE(stripped);
        if (conv == NULL) {
                return map_nt_error_from_unix(errno);
        }
-       status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc);
+       status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info,
+                                        mem_ctx, ppdesc);
        TALLOC_FREE(conv);
        return status;
 }