s3-auth: Split out get_user_sid_info3_and_extra() from create_local_nt_token_from_info3()
[amitay/samba.git] / source3 / modules / vfs_shadow_copy2.c
index f2a80f4b456746525dc3e74b32e272c880f38f4d..2afc5954e7d26f5a4cc8b681c378e8f87d89e263 100644 (file)
@@ -1109,15 +1109,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle,
 {
        time_t timestamp_src = 0;
        time_t timestamp_dst = 0;
+       char *snappath_src = NULL;
+       char *snappath_dst = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle,
                                         smb_fname_src->base_name,
-                                        &timestamp_src, NULL)) {
+                                        &timestamp_src, NULL, &snappath_src)) {
                return -1;
        }
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle,
                                         smb_fname_dst->base_name,
-                                        &timestamp_dst, NULL)) {
+                                        &timestamp_dst, NULL, &snappath_dst)) {
                return -1;
        }
        if (timestamp_src != 0) {
@@ -1128,6 +1130,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle,
                errno = EROFS;
                return -1;
        }
+       /*
+        * Don't allow rename on already converted paths.
+        */
+       if (snappath_src != NULL) {
+               errno = EXDEV;
+               return -1;
+       }
+       if (snappath_dst != NULL) {
+               errno = EROFS;
+               return -1;
+       }
        return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
 }
 
@@ -1136,19 +1149,28 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle,
 {
        time_t timestamp_old = 0;
        time_t timestamp_new = 0;
+       char *snappath_old = NULL;
+       char *snappath_new = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname,
-                                        &timestamp_old, NULL)) {
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
+                                        &timestamp_old, NULL, &snappath_old)) {
                return -1;
        }
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname,
-                                        &timestamp_new, NULL)) {
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
+                                        &timestamp_new, NULL, &snappath_new)) {
                return -1;
        }
        if ((timestamp_old != 0) || (timestamp_new != 0)) {
                errno = EROFS;
                return -1;
        }
+       /*
+        * Don't allow symlinks on already converted paths.
+        */
+       if ((snappath_old != NULL) || (snappath_new != NULL)) {
+               errno = EROFS;
+               return -1;
+       }
        return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
 }
 
@@ -1157,19 +1179,28 @@ static int shadow_copy2_link(vfs_handle_struct *handle,
 {
        time_t timestamp_old = 0;
        time_t timestamp_new = 0;
+       char *snappath_old = NULL;
+       char *snappath_new = NULL;
 
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname,
-                                        &timestamp_old, NULL)) {
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
+                                        &timestamp_old, NULL, &snappath_old)) {
                return -1;
        }
-       if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname,
-                                        &timestamp_new, NULL)) {
+       if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
+                                        &timestamp_new, NULL, &snappath_new)) {
                return -1;
        }
        if ((timestamp_old != 0) || (timestamp_new != 0)) {
                errno = EROFS;
                return -1;
        }
+       /*
+        * Don't allow links on already converted paths.
+        */
+       if ((snappath_old != NULL) || (snappath_new != NULL)) {
+               errno = EROFS;
+               return -1;
+       }
        return SMB_VFS_NEXT_LINK(handle, oldname, newname);
 }
 
@@ -1842,6 +1873,9 @@ static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle,
                }
                /* Extract the prefix */
                tmp = strstr(tmpstr, priv->config->delimiter);
+               if (tmp == NULL) {
+                       goto done;
+               }
                *tmp = '\0';
 
                /* Parse regex */