#include <sys/stat.h>
#include <stdarg.h>
#include <sys/types.h>
-#include <pwd.h>
#include "su.h"
#include "utils.h"
-int get_shell_uid() {
+unsigned get_shell_uid() {
struct passwd* ppwd = getpwnam("shell");
if (NULL == ppwd) {
- return -1;
+ return 2000;
}
return ppwd->pw_uid;
free(data);
int sdk = atoi(sdk_ver);
- if (sdk < 16)
+ if (sdk < 17)
return MULTIUSER_MODE_NONE;
int ret = MULTIUSER_MODE_OWNER_ONLY;
char mode[12];
FILE *fp;
if ((fp = fopen(REQUESTOR_MULTIUSER_MODE, "r"))) {
+ fgets(mode, sizeof(mode), fp);
int last = strlen(mode) - 1;
if (mode[last] == '\n')
mode[last] = '\0';
- fgets(mode, sizeof(mode), fp);
- LOGD("multiuser mode: %s", mode);
if (strcmp(mode, MULTIUSER_VALUE_USER) == 0) {
ret = MULTIUSER_MODE_USER;
} else if (strcmp(mode, MULTIUSER_VALUE_OWNER_MANAGED) == 0) {
exit(128 + sig);
}
-void sigchld_handler(int sig) {
- child_cleanup(su_ctx);
- (void)sig;
-}
-
static int socket_create_temp(char *path, size_t len) {
int fd;
struct sockaddr_un sun;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(serv_fd, &fds);
- LOGD("select");
do {
rc = select(serv_fd + 1, &fds, NULL, NULL, &tv);
} while (rc < 0 && errno == EINTR);
write_token(fd, "version", PROTO_VERSION);
write_token(fd, "pid", ctx->from.pid);
- write_token(fd, "from.name", ctx->from.name);
- write_token(fd, "to.name", ctx->to.name);
+ write_string(fd, "from.name", ctx->from.name);
+ write_string(fd, "to.name", ctx->to.name);
write_token(fd, "from.uid", ctx->from.uid);
write_token(fd, "to.uid", ctx->to.uid);
write_string(fd, "from.bin", ctx->from.bin);
read_options(&ctx);
user_init(&ctx);
- if (ctx.user.multiuser_mode == MULTIUSER_MODE_OWNER_ONLY && ctx.user.android_user_id != 0) {
- deny(&ctx);
- }
-
- if (access_disabled(&ctx.from)) {
- LOGD("access_disabled");
- deny(&ctx);
- }
-
- ctx.umask = umask(027);
-
+ // TODO: customizable behavior for shell? It can currently be toggled via settings.
if (ctx.from.uid == AID_ROOT || ctx.from.uid == AID_SHELL) {
LOGD("Allowing root/shell.");
allow(&ctx);
}
+ // verify superuser is installed
if (stat(ctx.user.base_path, &st) < 0) {
+ // send to market
+ if (0 == strcmp(JAVA_PACKAGE_NAME, REQUESTOR))
+ silent_run("am start -d http://www.clockworkmod.com/superuser/install.html -a android.intent.action.VIEW");
PLOGE("stat %s", ctx.user.base_path);
deny(&ctx);
}
+ // odd perms on superuser data dir
if (st.st_gid != st.st_uid) {
LOGE("Bad uid/gid %d/%d for Superuser Requestor application",
(int)st.st_uid, (int)st.st_gid);
deny(&ctx);
}
+
+ // always allow if this is the superuser uid
+ // superuser needs to be able to reenable itself when disabled...
+ if (ctx.from.uid == st.st_uid) {
+ allow(&ctx);
+ }
+
+ // check if superuser is disabled completely
+ if (access_disabled(&ctx.from)) {
+ LOGD("access_disabled");
+ deny(&ctx);
+ }
+
+ // deny if this is a non owner request and owner mode only
+ if (ctx.user.multiuser_mode == MULTIUSER_MODE_OWNER_ONLY && ctx.user.android_user_id != 0) {
+ deny(&ctx);
+ }
+
+ ctx.umask = umask(027);
int ret = mkdir(REQUESTOR_CACHE_PATH, 0770);
- LOGD("mkdir: %d", ret);
if (chown(REQUESTOR_CACHE_PATH, st.st_uid, st.st_gid)) {
PLOGE("chown (%s, %ld, %ld)", REQUESTOR_CACHE_PATH, st.st_uid, st.st_gid);
deny(&ctx);