Skip to content

Commit 794fb00

Browse files
committed
Multi-user support with 3 modes
1 parent de0050d commit 794fb00

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

activity.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ int send_intent(struct su_context *ctx, allow_t allow, const char *action)
9191
"exec /system/bin/am broadcast --user %d -a %s --es socket '%s' "
9292
"--ei caller_uid %d --ei allow %d --es desired_cmd '%s' "
9393
"--ei all %d --ei version_code %d",
94-
ctx->from.user, action, socket_path, uid, allow, get_command(&ctx->to),
94+
ctx->user.userid, action, socket_path, uid, allow, get_command(&ctx->to),
9595
ctx->to.all, VERSION_CODE);
9696
char *args[] = { "sh", "-c", command, NULL, };
9797

db.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,14 @@ int database_check(struct su_context *ctx)
2626
char filename[PATH_MAX];
2727
char allow[7];
2828
int last = 0;
29+
int from_uid = ctx->from.uid;
30+
31+
if (ctx->user.owner_mode) {
32+
from_uid = from_uid % 100000;
33+
}
2934

3035
snprintf(filename, sizeof(filename),
31-
REQUESTOR_STORED_PATH "/%u-%u", ctx->from.uid, ctx->to.uid);
36+
"%s/%u-%u", ctx->user.store_path, from_uid, ctx->to.uid);
3237
if ((fp = fopen(filename, "r"))) {
3338
LOGD("Found file %s", filename);
3439

@@ -55,8 +60,8 @@ int database_check(struct su_context *ctx)
5560
strcpy(allow, "prompt");
5661
}
5762
fclose(fp);
58-
} else if ((fp = fopen(REQUESTOR_STORED_DEFAULT, "r"))) {
59-
LOGD("Using default file %s", REQUESTOR_STORED_DEFAULT);
63+
} else if ((fp = fopen(ctx->user.store_default, "r"))) {
64+
LOGD("Using default file %s", ctx->user.store_default);
6065
fgets(allow, sizeof(allow), fp);
6166
last = strlen(allow) - 1;
6267
if (last >=0)
@@ -70,6 +75,10 @@ int database_check(struct su_context *ctx)
7075
} else if (strcmp(allow, "deny") == 0) {
7176
return DENY;
7277
} else {
73-
return INTERACTIVE;
78+
if (ctx->user.userid != 0 && ctx->user.owner_mode) {
79+
return DENY;
80+
} else {
81+
return INTERACTIVE;
82+
}
7483
}
7584
}

su.c

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,35 @@ static int from_init(struct su_initiator *from)
101101
return 0;
102102
}
103103

104+
static void read_options(struct su_context *ctx)
105+
{
106+
char mode[12];
107+
FILE *fp;
108+
if ((fp = fopen(REQUESTOR_OPTIONS, "r"))) {
109+
fgets(mode, sizeof(mode), fp);
110+
if (strcmp(mode, "user\n") == 0) {
111+
ctx->user.owner_mode = 0;
112+
} else if (strcmp(mode, "owner\n") == 0) {
113+
ctx->user.owner_mode = 1;
114+
}
115+
}
116+
}
117+
118+
static void user_init(struct su_context *ctx)
119+
{
120+
if (ctx->from.uid > 99999) {
121+
ctx->user.userid = ctx->from.uid / 100000;
122+
if (!ctx->user.owner_mode) {
123+
snprintf(ctx->user.data_path, PATH_MAX, "/data/user/%d/%s",
124+
ctx->user.userid, REQUESTOR);
125+
snprintf(ctx->user.store_path, PATH_MAX, "/data/user/%d/%s/files/stored",
126+
ctx->user.userid, REQUESTOR);
127+
snprintf(ctx->user.store_default, PATH_MAX, "/data/user/%d/%s/files/stored/default",
128+
ctx->user.userid, REQUESTOR);
129+
}
130+
}
131+
}
132+
104133
static void populate_environment(const struct su_context *ctx)
105134
{
106135
struct passwd *pw;
@@ -452,6 +481,7 @@ int access_disabled(const struct su_initiator *from)
452481
"enable it under settings -> developer options");
453482
return 1;
454483
}
484+
455485
}
456486
return 0;
457487
}
@@ -475,6 +505,13 @@ int main(int argc, char *argv[])
475505
.argc = argc,
476506
.optind = 0,
477507
},
508+
.user = {
509+
.userid = 0,
510+
.owner_mode = -1,
511+
.data_path = REQUESTOR_DATA_PATH,
512+
.store_path = REQUESTOR_STORED_PATH,
513+
.store_default = REQUESTOR_STORED_DEFAULT,
514+
},
478515
.child = 0,
479516
};
480517
struct stat st;
@@ -554,6 +591,12 @@ int main(int argc, char *argv[])
554591
if (from_init(&ctx.from) < 0) {
555592
deny(&ctx);
556593
}
594+
595+
read_options(&ctx);
596+
user_init(&ctx);
597+
598+
if (ctx.user.owner_mode == -1 && ctx.user.userid != 0)
599+
deny(&ctx);
557600

558601
if (access_disabled(&ctx.from))
559602
deny(&ctx);
@@ -568,7 +611,7 @@ int main(int argc, char *argv[])
568611
if (ctx.from.uid == AID_ROOT || ctx.from.uid == AID_SHELL)
569612
allow(&ctx);
570613

571-
if (stat(REQUESTOR_DATA_PATH, &st) < 0) {
614+
if (stat(ctx.user.data_path, &st) < 0) {
572615
PLOGE("stat");
573616
deny(&ctx);
574617
}

su.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
#define REQUESTOR_STORED_PATH REQUESTOR_DATA_PATH "/files/stored"
3131
#define REQUESTOR_STORED_DEFAULT REQUESTOR_STORED_PATH "/default"
32+
#define REQUESTOR_OPTIONS REQUESTOR_STORED_PATH "/options"
3233

3334
/* intent actions */
3435
#define ACTION_REQUEST REQUESTOR ".REQUEST"
@@ -51,6 +52,7 @@
5152
struct su_initiator {
5253
pid_t pid;
5354
unsigned uid;
55+
unsigned user;
5456
char bin[PATH_MAX];
5557
char args[4096];
5658
};
@@ -68,9 +70,18 @@ struct su_request {
6870
int all;
6971
};
7072

73+
struct su_user_info {
74+
unsigned userid;
75+
int owner_mode;
76+
char data_path[PATH_MAX];
77+
char store_path[PATH_MAX];
78+
char store_default[PATH_MAX];
79+
};
80+
7181
struct su_context {
7282
struct su_initiator from;
7383
struct su_request to;
84+
struct su_user_info user;
7485
mode_t umask;
7586
volatile pid_t child;
7687
char sock_path[PATH_MAX];

0 commit comments

Comments
 (0)