blob: b98a8c7f509424d6002f942df4d048d93261c7ce [file] [log] [blame]
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -04001/*
2 Copyright 2012 bigbiff/Dees_Troy TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <iostream>
20#include <fstream>
21#include <sstream>
22#include <string>
23#include <vector>
24#include <string.h>
25#include <libgen.h>
26#include <unistd.h>
27#include <sys/stat.h>
28#include <dirent.h>
bigbiff bigbiff84a3f1a2013-12-28 18:32:15 -050029#include <errno.h>
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040030#include "gui/rapidxml.hpp"
31#include "fixPermissions.hpp"
32#include "twrp-functions.hpp"
Dees_Troy2673cec2013-04-02 20:22:16 +000033#include "twcommon.h"
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040034#ifdef HAVE_SELINUX
35#include "selinux/selinux.h"
36#include "selinux/label.h"
37#include "selinux/android.h"
38#include "selinux/label.h"
39#endif
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -040040
41using namespace std;
42using namespace rapidxml;
43
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040044#ifdef HAVE_SELINUX
bigbiff bigbiff731df792014-02-20 18:26:13 -050045struct selabel_handle *sehandle;
46struct selinux_opt selinux_options[] = {
47 { SELABEL_OPT_PATH, "/file_contexts" }
48};
49
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040050int fixPermissions::restorecon(string entry, struct stat *sb) {
51 char *oldcontext, *newcontext;
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040052 if (lgetfilecon(entry.c_str(), &oldcontext) < 0) {
53 LOGINFO("Couldn't get selinux context for %s\n", entry.c_str());
54 return -1;
55 }
56 if (selabel_lookup(sehandle, &newcontext, entry.c_str(), sb->st_mode) < 0) {
57 LOGINFO("Couldn't lookup selinux context for %s\n", entry.c_str());
58 return -1;
59 }
bigbiff bigbiff731df792014-02-20 18:26:13 -050060 if (strcmp(oldcontext, newcontext) != 0) {
61 LOGINFO("Relabeling %s from %s to %s\n", entry.c_str(), oldcontext, newcontext);
62 if (lsetfilecon(entry.c_str(), newcontext) < 0) {
63 LOGINFO("Couldn't label %s with %s: %s\n", entry.c_str(), newcontext, strerror(errno));
64 }
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040065 }
66 freecon(oldcontext);
67 freecon(newcontext);
68 return 0;
69}
70
71int fixPermissions::fixDataDataContexts(void) {
bigbiff bigbiff731df792014-02-20 18:26:13 -050072 string dir = "/data/data/";
73 sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
74 if (TWFunc::Path_Exists(dir)) {
75 fixContextsRecursively(dir, 0);
76 }
77 selabel_close(sehandle);
78 return 0;
79}
80
81int fixPermissions::fixContextsRecursively(string name, int level) {
bigbiff bigbiff872a3b92013-10-18 20:50:25 -040082 DIR *d;
83 struct dirent *de;
84 struct stat sb;
bigbiff bigbiff731df792014-02-20 18:26:13 -050085 string path;
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050086
bigbiff bigbiff731df792014-02-20 18:26:13 -050087 if (!(d = opendir(name.c_str())))
88 return -1;
89 if (!(de = readdir(d)))
90 return -1;
bigbiff bigbiff6b600f92014-01-05 18:13:43 -050091
bigbiff bigbiff731df792014-02-20 18:26:13 -050092 do {
93 if (de->d_type == DT_DIR) {
94 if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
95 continue;
96 path = name + "/" + de->d_name;
97 restorecon(path, &sb);
98 fixContextsRecursively(path, level + 1);
99 }
100 else {
101 path = name + "/" + de->d_name;
102 restorecon(path, &sb);
103 }
104 } while (de = readdir(d));
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500105 closedir(d);
106 return 0;
107}
108
109int fixPermissions::fixDataInternalContexts(void) {
110 DIR *d;
111 struct dirent *de;
112 struct stat sb;
bigbiff bigbiff731df792014-02-20 18:26:13 -0500113 string dir, androiddir;
114 sehandle = selabel_open(SELABEL_CTX_FILE, selinux_options, 1);
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500115
bigbiff bigbiff731df792014-02-20 18:26:13 -0500116 if (TWFunc::Path_Exists("/data/media/0"))
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500117 dir = "/data/media/0";
bigbiff bigbiff731df792014-02-20 18:26:13 -0500118 else
119 dir = "/data/media";
Ethan Yonker5eac2222014-06-11 12:22:55 -0500120 if (!TWFunc::Path_Exists(dir)) {
121 LOGINFO("fixDataInternalContexts: '%s' does not exist!\n", dir.c_str());
122 return 0;
123 }
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500124 LOGINFO("Fixing %s contexts\n", dir.c_str());
bigbiff bigbiff731df792014-02-20 18:26:13 -0500125 restorecon(dir, &sb);
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500126 d = opendir(dir.c_str());
127
128 while (( de = readdir(d)) != NULL) {
129 stat(de->d_name, &sb);
130 string f;
bigbiff bigbiff731df792014-02-20 18:26:13 -0500131 f = dir + "/" + de->d_name;
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500132 restorecon(f, &sb);
133 }
134 closedir(d);
bigbiff bigbiff731df792014-02-20 18:26:13 -0500135
136 androiddir = dir + "/Android/";
137 if (TWFunc::Path_Exists(androiddir)) {
138 fixContextsRecursively(androiddir, 0);
139 }
140 selabel_close(sehandle);
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400141 return 0;
142}
143#endif
144
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400145int fixPermissions::fixPerms(bool enable_debug, bool remove_data_for_missing_apps) {
146 packageFile = "/data/system/packages.xml";
147 debug = enable_debug;
148 remove_data = remove_data_for_missing_apps;
Dees_Troy201d76b2012-11-16 17:12:02 +0000149 multi_user = TWFunc::Path_Exists("/data/user");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400150
151 if (!(TWFunc::Path_Exists(packageFile))) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000152 gui_print("Can't check permissions\n");
153 gui_print("after Factory Reset.\n");
154 gui_print("Please boot rom and try\n");
155 gui_print("again after you reboot into\n");
156 gui_print("recovery.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400157 return -1;
158 }
159
Dees_Troy2673cec2013-04-02 20:22:16 +0000160 gui_print("Fixing permissions...\nLoading packages...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400161 if ((getPackages()) != 0) {
162 return -1;
163 }
Dees_Troy32f2ca82013-02-02 17:03:12 +0000164
Dees_Troy2673cec2013-04-02 20:22:16 +0000165 gui_print("Fixing /system/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400166 if ((fixSystemApps()) != 0) {
167 return -1;
168 }
169
grimsrudcbec59f2013-07-29 15:46:22 +0200170 gui_print("Fixing /data/app permissions...\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400171 if ((fixDataApps()) != 0) {
172 return -1;
173 }
174
Dees_Troy201d76b2012-11-16 17:12:02 +0000175 if (multi_user) {
176 DIR *d = opendir("/data/user");
177 string new_path, user_id;
178
179 if (d == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000180 LOGERR("Error opening '/data/user'\n");
Dees_Troy201d76b2012-11-16 17:12:02 +0000181 return -1;
182 }
183
184 if (d) {
185 struct dirent *p;
186 while ((p = readdir(d))) {
187 if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
188 continue;
189
190 new_path = "/data/user/";
191 new_path.append(p->d_name);
192 user_id = "u";
193 user_id += p->d_name;
194 user_id += "_";
195 if (p->d_type == DT_LNK) {
196 char link[512], realPath[512];
197 strcpy(link, new_path.c_str());
198 memset(realPath, 0, sizeof(realPath));
199 while (readlink(link, realPath, sizeof(realPath)) > 0) {
200 strcpy(link, realPath);
201 memset(realPath, 0, sizeof(realPath));
202 }
203 new_path = link;
204 } else if (p->d_type != DT_DIR) {
205 continue;
206 } else {
207 new_path.append("/");
208 // We're probably going to need to fix permissions on multi user but
209 // it will have to wait for another time. Need to figure out where
210 // the uid and gid is stored for other users.
211 continue;
212 }
Dees_Troy2673cec2013-04-02 20:22:16 +0000213 gui_print("Fixing %s permissions...\n", new_path.c_str());
Dees_Troy201d76b2012-11-16 17:12:02 +0000214 if ((fixDataData(new_path)) != 0) {
215 closedir(d);
216 return -1;
217 }
218 }
219 closedir(d);
220 }
221 } else {
grimsrudcbec59f2013-07-29 15:46:22 +0200222 gui_print("Fixing /data/data permissions...\n");
Dees_Troy201d76b2012-11-16 17:12:02 +0000223 if ((fixDataData("/data/data/")) != 0) {
224 return -1;
225 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400226 }
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400227 #ifdef HAVE_SELINUX
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500228 gui_print("Fixing /data/data/ contexts.\n");
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400229 fixDataDataContexts();
bigbiff bigbiff6b600f92014-01-05 18:13:43 -0500230 fixDataInternalContexts();
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400231 #endif
Dees_Troy2673cec2013-04-02 20:22:16 +0000232 gui_print("Done fixing permissions.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400233 return 0;
234}
235
236int fixPermissions::pchown(string fn, int puid, int pgid) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000237 LOGINFO("Fixing %s, uid: %d, gid: %d\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400238 if (chown(fn.c_str(), puid, pgid) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000239 LOGERR("Unable to chown '%s' %i %i\n", fn.c_str(), puid, pgid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400240 return -1;
241 }
242 return 0;
243}
244
245int fixPermissions::pchmod(string fn, string mode) {
246 long mask = 0;
Dees_Troy2673cec2013-04-02 20:22:16 +0000247 LOGINFO("Fixing %s, mode: %s\n", fn.c_str(), mode.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400248 for ( std::string::size_type n = 0; n < mode.length(); ++n) {
249 if (n == 0) {
250 if (mode[n] == '0')
251 continue;
252 else if (mode[n] == '1')
253 mask = S_ISVTX;
254 else if (mode[n] == '2')
255 mask = S_ISGID;
256 }
257 else if (n == 1) {
258 if (mode[n] == '7') {
259 mask |= S_IRWXU;
260 }
261 if (mode[n] == '6') {
262 mask |= S_IRUSR;
263 mask |= S_IWUSR;
264 }
265 if (mode[n] == '5') {
266 mask |= S_IRUSR;
267 mask |= S_IXUSR;
268 }
269 if (mode[n] == '4')
270 mask |= S_IRUSR;
271 if (mode[n] == '3') {
272 mask |= S_IWUSR;
273 mask |= S_IRUSR;
274 }
275 if (mode[n] == '2')
276 mask |= S_IWUSR;
277 if (mode[n] == '1')
278 mask |= S_IXUSR;
279 }
280 else if (n == 2) {
281 if (mode[n] == '7') {
282 mask |= S_IRWXG;
283 }
284 if (mode[n] == '6') {
285 mask |= S_IRGRP;
286 mask |= S_IWGRP;
287 }
288 if (mode[n] == '5') {
289 mask |= S_IRGRP;
290 mask |= S_IXGRP;
291 }
292 if (mode[n] == '4')
293 mask |= S_IRGRP;
294 if (mode[n] == '3') {
295 mask |= S_IWGRP;
296 mask |= S_IXGRP;
297 }
298 if (mode[n] == '2')
299 mask |= S_IWGRP;
300 if (mode[n] == '1')
301 mask |= S_IXGRP;
302 }
303 else if (n == 3) {
304 if (mode[n] == '7') {
305 mask |= S_IRWXO;
306 }
307 if (mode[n] == '6') {
308 mask |= S_IROTH;
309 mask |= S_IWOTH;
310 }
311 if (mode[n] == '5') {
312 mask |= S_IROTH;
313 mask |= S_IXOTH;
314 }
315 if (mode[n] == '4')
316 mask |= S_IROTH;
317 if (mode[n] == '3') {
318 mask |= S_IWOTH;
319 mask |= S_IXOTH;
320 }
321 if (mode[n] == '2')
Dees_Troy6480ce02012-10-10 10:26:54 -0400322 mask |= S_IWOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400323 if (mode[n] == '1')
Dees_Troy6480ce02012-10-10 10:26:54 -0400324 mask |= S_IXOTH;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400325 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500326 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400327
328 if (chmod(fn.c_str(), mask) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000329 LOGERR("Unable to chmod '%s' %l\n", fn.c_str(), mask);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400330 return -1;
331 }
332
333 return 0;
334}
335
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400336int fixPermissions::fixSystemApps() {
337 temp = head;
338 while (temp != NULL) {
339 if (TWFunc::Path_Exists(temp->codePath)) {
bigbiff bigbiffa886ea62014-04-02 20:38:53 -0400340 if (temp->appDir.compare("/system/app") == 0 || temp->appDir.compare("/system/priv-app") == 0) {
bigbiff bigbiff872a3b92013-10-18 20:50:25 -0400341 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000342 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
343 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
344 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
345 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400346 }
347 if (pchown(temp->codePath, 0, 0) != 0)
348 return -1;
349 if (pchmod(temp->codePath, "0644") != 0)
350 return -1;
351 }
352 } else {
353 //Remove data directory since app isn't installed
354 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
355 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000356 LOGINFO("Looking at '%s', removing data dir: '%s', appDir: '%s'", temp->codePath.c_str(), temp->dDir.c_str(), temp->appDir.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500357 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000358 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400359 return -1;
360 }
361 }
362 }
363 temp = temp->next;
364 }
365 return 0;
366}
367
368int fixPermissions::fixDataApps() {
369 bool fix = false;
370 int new_gid = 0;
371 string perms = "0000";
372
373 temp = head;
374 while (temp != NULL) {
375 if (TWFunc::Path_Exists(temp->codePath)) {
376 if (temp->appDir.compare("/data/app") == 0 || temp->appDir.compare("/sd-ext/app") == 0) {
377 fix = true;
378 new_gid = 1000;
379 perms = "0644";
380 } else if (temp->appDir.compare("/data/app-private") == 0 || temp->appDir.compare("/sd-ext/app-private") == 0) {
381 fix = true;
382 new_gid = temp->gid;
383 perms = "0640";
384 } else
385 fix = false;
386 if (fix) {
387 if (debug) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000388 LOGINFO("Looking at '%s'\n", temp->codePath.c_str());
389 LOGINFO("Fixing permissions on '%s'\n", temp->pkgName.c_str());
390 LOGINFO("Directory: '%s'\n", temp->appDir.c_str());
391 LOGINFO("Original package owner: %d, group: %d\n", temp->uid, temp->gid);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400392 }
393 if (pchown(temp->codePath, 1000, new_gid) != 0)
394 return -1;
395 if (pchmod(temp->codePath, perms) != 0)
396 return -1;
397 }
398 } else {
399 //Remove data directory since app isn't installed
400 if (remove_data && TWFunc::Path_Exists(temp->dDir) && temp->appDir.size() >= 9 && temp->appDir.substr(0, 9) != "/mnt/asec") {
401 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000402 LOGINFO("Looking at '%s', removing data dir: '%s', appDir: '%s'", temp->codePath.c_str(), temp->dDir.c_str(), temp->appDir.c_str());
bigbiff bigbiff9c754052013-01-09 09:09:08 -0500403 if (TWFunc::removeDir(temp->dDir, false) != 0) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000404 LOGINFO("Unable to removeDir '%s'\n", temp->dDir.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400405 return -1;
406 }
407 }
408 }
409 temp = temp->next;
410 }
411 return 0;
412}
413
414int fixPermissions::fixAllFiles(string directory, int gid, int uid, string file_perms) {
415 vector <string> files;
416 string file;
417
418 files = listAllFiles(directory);
419 for (unsigned i = 0; i < files.size(); ++i) {
420 file = directory + "/";
421 file.append(files.at(i));
422 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000423 LOGINFO("Looking at file '%s'\n", file.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400424 if (pchmod(file, file_perms) != 0)
425 return -1;
426 if (pchown(file, uid, gid) != 0)
427 return -1;
428 }
429 return 0;
430}
431
Dees_Troy201d76b2012-11-16 17:12:02 +0000432int fixPermissions::fixDataData(string dataDir) {
433 string directory, dir;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400434
435 temp = head;
436 while (temp != NULL) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000437 dir = dataDir + temp->dDir;
438 if (TWFunc::Path_Exists(dir)) {
439 vector <string> dataDataDirs = listAllDirectories(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400440 for (unsigned n = 0; n < dataDataDirs.size(); ++n) {
Dees_Troy201d76b2012-11-16 17:12:02 +0000441 directory = dir + "/";
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400442 directory.append(dataDataDirs.at(n));
443 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000444 LOGINFO("Looking at data directory: '%s'\n", directory.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400445 if (dataDataDirs.at(n) == ".") {
Dees_Troy201d76b2012-11-16 17:12:02 +0000446 if (pchmod(directory, "0755") != 0)
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400447 return -1;
448 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
449 return -1;
450 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
451 return -1;
452 }
453 else if (dataDataDirs.at(n) == "..") {
454 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000455 LOGINFO("Skipping ..\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400456 continue;
457 }
458 else if (dataDataDirs.at(n) == "lib") {
459 if (pchmod(directory.c_str(), "0755") != 0)
460 return -1;
461 if (pchown(directory.c_str(), 1000, 1000) != 0)
462 return -1;
463 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
464 return -1;
465 }
466 else if (dataDataDirs.at(n) == "shared_prefs") {
467 if (pchmod(directory.c_str(), "0771") != 0)
468 return -1;
469 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
470 return -1;
471 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
472 return -1;
473 }
474 else if (dataDataDirs.at(n) == "databases") {
475 if (pchmod(directory.c_str(), "0771") != 0)
476 return -1;
477 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
478 return -1;
479 if (fixAllFiles(directory, temp->uid, temp->gid, "0660") != 0)
480 return -1;
481 }
482 else if (dataDataDirs.at(n) == "cache") {
483 if (pchmod(directory.c_str(), "0771") != 0)
484 return -1;
485 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
486 return -1;
487 if (fixAllFiles(directory, temp->uid, temp->gid, "0600") != 0)
488 return -1;
489 }
490 else {
491 if (pchmod(directory.c_str(), "0771") != 0)
492 return -1;
493 if (pchown(directory.c_str(), temp->uid, temp->gid) != 0)
494 return -1;
495 if (fixAllFiles(directory, temp->uid, temp->gid, "0755") != 0)
496 return -1;
497 }
498 }
499 }
500 temp = temp->next;
501 }
502 return 0;
503}
504
505vector <string> fixPermissions::listAllDirectories(string path) {
506 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400507 vector <string> dirs;
508
509 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000510 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400511 return dirs;
512 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000513 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400514 while (entry != NULL) {
515 if (entry->d_type == DT_DIR)
516 dirs.push_back(entry->d_name);
517 entry = readdir(dir);
518 }
519 closedir(dir);
520 return dirs;
521}
522
523vector <string> fixPermissions::listAllFiles(string path) {
524 DIR *dir = opendir(path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400525 vector <string> files;
526
527 if (dir == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000528 LOGERR("Error opening '%s'\n", path.c_str());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400529 return files;
530 }
Dees_Troy201d76b2012-11-16 17:12:02 +0000531 struct dirent *entry = readdir(dir);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400532 while (entry != NULL) {
533 if (entry->d_type == DT_REG)
534 files.push_back(entry->d_name);
535 entry = readdir(dir);
536 }
537 closedir(dir);
538 return files;
539}
540
541int fixPermissions::getPackages() {
542 int len = 0;
543 bool skiploop = false;
544 vector <string> skip;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400545 string name;
546 head = NULL;
547
548 skip.push_back("/system/framework/framework-res.apk");
549 skip.push_back("/system/framework/com.htc.resources.apk");
550
551 ifstream xmlFile(packageFile.c_str());
552 xmlFile.seekg(0, ios::end);
553 len = (int) xmlFile.tellg();
554 xmlFile.seekg(0, ios::beg);
555 char xmlBuf[len + 1];
556 xmlFile.read(&xmlBuf[0], len);
557 xmlBuf[len] = '\0';
558 xml_document<> pkgDoc;
Dees_Troy34614eb2013-04-05 12:02:14 -0500559 LOGINFO("parsing package, %i...\n", len);
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400560 pkgDoc.parse<parse_full>(&xmlBuf[0]);
561
562 xml_node<> * pkgNode = pkgDoc.first_node("packages");
Dees_Troy34614eb2013-04-05 12:02:14 -0500563 if (pkgNode == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000564 LOGERR("No packages found to fix.\n");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400565 return -1;
566 }
Dees_Troy34614eb2013-04-05 12:02:14 -0500567 xml_node <> * next = pkgNode->first_node("package");
568 if (next == NULL) {
569 LOGERR("No package found to fix.\n");
570 return -1;
571 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400572
573 //Get packages
574 while (next->first_attribute("name") != NULL) {
575 package* temp = new package;
576 for (unsigned n = 0; n < skip.size(); ++n) {
577 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
578 skiploop = true;
579 break;
580 }
581 }
582
583 if (skiploop == true) {
584 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000585 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400586 free(temp);
587 next = next->next_sibling();
588 skiploop = false;
589 continue;
590 }
591 name.append((next->first_attribute("name")->value()));
592 temp->pkgName = next->first_attribute("name")->value();
593 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000594 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000595 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000596 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000597 } else {
598 temp->codePath = next->first_attribute("codePath")->value();
599 temp->app = basename(next->first_attribute("codePath")->value());
600 temp->appDir = dirname(next->first_attribute("codePath")->value());
601 }
602 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400603 if ( next->first_attribute("sharedUserId") != NULL) {
604 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
605 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
606 }
607 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000608 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000609 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000610 } else {
611 temp->uid = atoi(next->first_attribute("userId")->value());
612 temp->gid = atoi(next->first_attribute("userId")->value());
613 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400614 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400615 temp->next = head;
616 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000617 if (next->next_sibling("package") == NULL)
618 break;
619 name.clear();
620 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400621 }
Matt Mowerfb1c4ff2014-04-16 13:43:36 -0500622 //Get updated packages
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400623 next = pkgNode->first_node("updated-package");
624 if (next != NULL) {
625 while (next->first_attribute("name") != NULL) {
626 package* temp = new package;
627 for (unsigned n = 0; n < skip.size(); ++n) {
628 if (skip.at(n).compare(next->first_attribute("codePath")->value()) == 0) {
629 skiploop = true;
630 break;
631 }
632 }
633
634 if (skiploop == true) {
635 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000636 LOGINFO("Skipping package %s\n", next->first_attribute("codePath")->value());
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400637 free(temp);
638 next = next->next_sibling();
639 skiploop = false;
640 continue;
641 }
642 name.append((next->first_attribute("name")->value()));
643 temp->pkgName = next->first_attribute("name")->value();
644 if (debug)
Dees_Troy2673cec2013-04-02 20:22:16 +0000645 LOGINFO("Loading pkg: %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000646 if (next->first_attribute("codePath") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000647 LOGINFO("Problem with codePath on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000648 } else {
649 temp->codePath = next->first_attribute("codePath")->value();
650 temp->app = basename(next->first_attribute("codePath")->value());
651 temp->appDir = dirname(next->first_attribute("codePath")->value());
652 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400653
Dees_Troy201d76b2012-11-16 17:12:02 +0000654 temp->dDir = name;
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400655 if ( next->first_attribute("sharedUserId") != NULL) {
656 temp->uid = atoi(next->first_attribute("sharedUserId")->value());
657 temp->gid = atoi(next->first_attribute("sharedUserId")->value());
658 }
659 else {
Dees_Troy201d76b2012-11-16 17:12:02 +0000660 if (next->first_attribute("userId") == NULL) {
Dees_Troy2673cec2013-04-02 20:22:16 +0000661 LOGINFO("Problem with userID on %s\n", next->first_attribute("name")->value());
Dees_Troy201d76b2012-11-16 17:12:02 +0000662 } else {
663 temp->uid = atoi(next->first_attribute("userId")->value());
664 temp->gid = atoi(next->first_attribute("userId")->value());
665 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400666 }
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400667 temp->next = head;
668 head = temp;
Dees_Troy201d76b2012-11-16 17:12:02 +0000669 if (next->next_sibling("package") == NULL)
670 break;
671 name.clear();
672 next = next->next_sibling("package");
bigbiff bigbiffa0f8a592012-10-09 21:01:03 -0400673 }
674 }
675 return 0;
676}