File: 0006-Revert-ensure-no-any-user-writable-permissions-in-Ne.patch

package info (click to toggle)
nextcloud-desktop 3.16.7-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 50,092 kB
  • sloc: cpp: 115,410; javascript: 1,297; objc: 751; python: 650; ansic: 391; sh: 383; makefile: 185; ruby: 174; xml: 6
file content (169 lines) | stat: -rw-r--r-- 9,213 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
From: =?utf-8?q?Sandro_Knau=C3=9F?= <hefee@debian.org>
Date: Sun, 27 Jul 2025 12:24:51 +0200
Subject: Revert "ensure no any user writable permissions in Nextcloud sync
 folder"

This reverts commit 5b2af166d3d9c8537c565922750392d4a3f6610e.

Updated to apply and match for 3.16.6.

Origin: backport
Bug-Debian: https://bugs.debian.org/1091614
Bug: https://github.com/nextcloud/desktop/issues/7613
Forwarded: not-needed
Last-Update: 2025-07-25
---
 src/csync/csync.h                      |  2 --
 src/csync/vio/csync_vio_local_unix.cpp |  1 -
 src/libsync/discovery.cpp              | 11 -----------
 src/libsync/discoveryphase.cpp         |  1 -
 src/libsync/discoveryphase.h           |  1 -
 src/libsync/owncloudpropagator.cpp     |  7 +++++++
 src/libsync/syncengine.cpp             |  4 ----
 src/libsync/syncfileitem.h             |  2 --
 8 files changed, 7 insertions(+), 22 deletions(-)

diff --git a/src/csync/csync.h b/src/csync/csync.h
index 8329020..ff1ec56 100644
--- a/src/csync/csync.h
+++ b/src/csync/csync.h
@@ -218,7 +218,6 @@ struct OCSYNC_EXPORT csync_file_stat_s {
   bool is_hidden BITFIELD(1); // Not saved in the DB, only used during discovery for local files.
   bool isE2eEncrypted BITFIELD(1);
   bool is_metadata_missing BITFIELD(1); // Indicates the file has missing metadata, f.ex. the file is not a placeholder in case of vfs.
-  bool isPermissionsInvalid BITFIELD(1);
 
   QByteArray path;
   QByteArray rename_path;
@@ -246,7 +245,6 @@ struct OCSYNC_EXPORT csync_file_stat_s {
     , is_hidden(false)
     , isE2eEncrypted(false)
     , is_metadata_missing(false)
-    , isPermissionsInvalid(false)
   { }
 };
 
diff --git a/src/csync/vio/csync_vio_local_unix.cpp b/src/csync/vio/csync_vio_local_unix.cpp
index 8f319a3..55cd0f0 100644
--- a/src/csync/vio/csync_vio_local_unix.cpp
+++ b/src/csync/vio/csync_vio_local_unix.cpp
@@ -169,7 +169,6 @@ static int _csync_vio_local_stat_mb(const mbchar_t *wuri, csync_file_stat_t *buf
   buf->inode = sb.st_ino;
   buf->modtime = sb.st_mtime;
   buf->size = sb.st_size;
-  buf->isPermissionsInvalid = (sb.st_mode & S_IWOTH) == S_IWOTH;
 
   return 0;
 }
diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp
index c95af63..39c65a2 100644
--- a/src/libsync/discovery.cpp
+++ b/src/libsync/discovery.cpp
@@ -1130,10 +1130,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
         if (_queryLocal != NormalQuery && _queryServer != NormalQuery)
             recurse = false;
 
-        if (localEntry.isPermissionsInvalid) {
-            recurse = true;
-        }
-
         if ((item->_direction == SyncFileItem::Down || item->_instruction == CSYNC_INSTRUCTION_CONFLICT || item->_instruction == CSYNC_INSTRUCTION_NEW || item->_instruction == CSYNC_INSTRUCTION_SYNC) &&
                 item->_direction != SyncFileItem::Up &&
                 (item->_modtime <= 0 || item->_modtime >= 0xFFFFFFFF)) {
@@ -1162,13 +1158,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
             }
         }
 
-        if (localEntry.isPermissionsInvalid && item->_instruction == CSyncEnums::CSYNC_INSTRUCTION_NONE) {
-            item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
-            item->_direction = SyncFileItem::Down;
-        }
-
-        item->isPermissionsInvalid = localEntry.isPermissionsInvalid;
-
         auto recurseQueryLocal = _queryLocal == ParentNotChanged ? ParentNotChanged : localEntry.isDirectory || item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist;
         if (item->isDirectory() && serverEntry.isValid() && dbEntry.isValid() && serverEntry.etag == dbEntry._etag && serverEntry.remotePerm != dbEntry._remotePerm) {
             recurseQueryServer = ParentNotChanged;
diff --git a/src/libsync/discoveryphase.cpp b/src/libsync/discoveryphase.cpp
index 7edd684..f881a21 100644
--- a/src/libsync/discoveryphase.cpp
+++ b/src/libsync/discoveryphase.cpp
@@ -370,7 +370,6 @@ void DiscoverySingleLocalDirectoryJob::run() {
         i.isSymLink = dirent->type == ItemTypeSoftLink;
         i.isVirtualFile = dirent->type == ItemTypeVirtualFile || dirent->type == ItemTypeVirtualFileDownload;
         i.isMetadataMissing = dirent->is_metadata_missing;
-        i.isPermissionsInvalid = dirent->isPermissionsInvalid;
         i.type = dirent->type;
         results.push_back(i);
     }
diff --git a/src/libsync/discoveryphase.h b/src/libsync/discoveryphase.h
index 0c9edce..913f37f 100644
--- a/src/libsync/discoveryphase.h
+++ b/src/libsync/discoveryphase.h
@@ -107,7 +107,6 @@ struct LocalInfo
     bool isVirtualFile = false;
     bool isSymLink = false;
     bool isMetadataMissing = false;
-    bool isPermissionsInvalid = false;
     [[nodiscard]] bool isValid() const { return !name.isNull(); }
 };
 
diff --git a/src/libsync/owncloudpropagator.cpp b/src/libsync/owncloudpropagator.cpp
index fba85c5..10eedaf 100644
--- a/src/libsync/owncloudpropagator.cpp
+++ b/src/libsync/owncloudpropagator.cpp
@@ -1472,12 +1472,18 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
                 try {
                     if (const auto fileName = propagator()->fullLocalPath(_item->_file); FileSystem::fileExists(fileName)) {
                         FileSystem::setFolderPermissions(fileName, FileSystem::FolderPermissions::ReadOnly);
+                        qCDebug(lcDirectory) << fileName << "permissions changed: old permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
+                        std::filesystem::permissions(fileName.toStdWString(), std::filesystem::perms::owner_write | std::filesystem::perms::group_write | std::filesystem::perms::others_write, std::filesystem::perm_options::remove);
                         Q_EMIT propagator()->touchedFile(fileName);
+                        qCDebug(lcDirectory) << fileName << "applied new permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
                     }
                     if (!_item->_renameTarget.isEmpty() && FileSystem::fileExists(propagator()->fullLocalPath(_item->_renameTarget))) {
                         const auto fileName = propagator()->fullLocalPath(_item->_renameTarget);
                         FileSystem::setFolderPermissions(fileName, FileSystem::FolderPermissions::ReadOnly);
+                        qCDebug(lcDirectory) << fileName << "permissions changed: old permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
+                        std::filesystem::permissions(fileName.toStdWString(), std::filesystem::perms::owner_write | std::filesystem::perms::group_write | std::filesystem::perms::others_write, std::filesystem::perm_options::remove);
                         Q_EMIT propagator()->touchedFile(fileName);
+                        qCDebug(lcDirectory) << fileName << "applied new permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
                     }
                 }
                 catch (const std::filesystem::filesystem_error &e)
@@ -1504,6 +1510,7 @@ void PropagateDirectory::slotSubJobsFinished(SyncFileItem::Status status)
                     {
                         qCDebug(lcDirectory) << fileName << "permissions changed: old permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
                         FileSystem::setFolderPermissions(fileName, FileSystem::FolderPermissions::ReadWrite);
+                        std::filesystem::permissions(fileName.toStdWString(), std::filesystem::perms::owner_write, std::filesystem::perm_options::add);
                         Q_EMIT propagator()->touchedFile(fileName);
                         qCDebug(lcDirectory) << fileName << "applied new permissions" << static_cast<int>(std::filesystem::status(fileName.toStdWString()).permissions());
                     };
diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp
index e24ce8a..8237905 100644
--- a/src/libsync/syncengine.cpp
+++ b/src/libsync/syncengine.cpp
@@ -362,10 +362,6 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
                 const bool isReadOnly = !item->_remotePerm.isNull() && !item->_remotePerm.hasPermission(RemotePermissions::CanWrite);
                 modificationHappened = FileSystem::setFileReadOnlyWeak(filePath, isReadOnly);
             }
-            if (item->isPermissionsInvalid) {
-                const auto isReadOnly = !item->_remotePerm.isNull() && !item->_remotePerm.hasPermission(RemotePermissions::CanWrite);
-                FileSystem::setFileReadOnly(filePath, isReadOnly);
-            }
 
             modificationHappened |= item->_size != prev._fileSize;
 
diff --git a/src/libsync/syncfileitem.h b/src/libsync/syncfileitem.h
index 154d13a..041e48d 100644
--- a/src/libsync/syncfileitem.h
+++ b/src/libsync/syncfileitem.h
@@ -344,8 +344,6 @@ public:
     bool _isLivePhoto = false;
     QString _livePhotoFile;
 
-    bool isPermissionsInvalid = false;
-
     QString _discoveryResult;
 
     /// if true, requests the file to be permanently deleted instead of moved to the trashbin