Add preliminary OEM UID/GID support.

Until we implement full support for passwd/group files, add a simple
way to use the new OEM UID/GID range (5000-5999).

oem_XXX -> 5000 + XXX iff 0 <= XXX < 1000.

Bug: 23225475

Change-Id: If48b88135d5df538313414f747d6c4c63bf0a103
This commit is contained in:
Jorge Lucangeli Obes 2015-09-22 11:46:43 -07:00
parent 822c40a338
commit a39e30141d
2 changed files with 85 additions and 1 deletions

View File

@ -206,7 +206,7 @@ static group* android_name_to_group(group_state_t* state, const char* name) {
// u0_a1234 -> 0 * AID_USER + AID_APP + 1234
// u2_i1000 -> 2 * AID_USER + AID_ISOLATED_START + 1000
// u1_system -> 1 * AID_USER + android_ids['system']
// returns 0 and sets errno to ENOENT in case of error
// returns 0 and sets errno to ENOENT in case of error.
static id_t app_id_from_name(const char* name, bool is_group) {
char* end;
unsigned long userid;
@ -312,6 +312,54 @@ static void print_app_name_from_gid(const gid_t gid, char* buffer, const int buf
}
}
// Translate an OEM name to the corresponding user/group id.
// oem_XXX -> AID_OEM_RESERVED_2_START + XXX, iff XXX is within range.
static id_t oem_id_from_name(const char* name) {
unsigned int id;
if (sscanf(name, "oem_%u", &id) != 1) {
return 0;
}
// Check OEM id is within range.
if (id > (AID_OEM_RESERVED_2_END - AID_OEM_RESERVED_2_START)) {
return 0;
}
return AID_OEM_RESERVED_2_START + static_cast<id_t>(id);
}
static passwd* oem_id_to_passwd(uid_t uid, passwd_state_t* state) {
if (uid < AID_OEM_RESERVED_2_START || uid > AID_OEM_RESERVED_2_END) {
return NULL;
}
snprintf(state->name_buffer_, sizeof(state->name_buffer_), "oem_%u",
uid - AID_OEM_RESERVED_2_START);
snprintf(state->dir_buffer_, sizeof(state->dir_buffer_), "/");
snprintf(state->sh_buffer_, sizeof(state->sh_buffer_), "/system/bin/sh");
passwd* pw = &state->passwd_;
pw->pw_name = state->name_buffer_;
pw->pw_dir = state->dir_buffer_;
pw->pw_shell = state->sh_buffer_;
pw->pw_uid = uid;
pw->pw_gid = uid;
return pw;
}
static group* oem_id_to_group(gid_t gid, group_state_t* state) {
if (gid < AID_OEM_RESERVED_2_START || gid > AID_OEM_RESERVED_2_END) {
return NULL;
}
snprintf(state->group_name_buffer_, sizeof(state->group_name_buffer_),
"oem_%u", gid - AID_OEM_RESERVED_2_START);
group* gr = &state->group_;
gr->gr_name = state->group_name_buffer_;
gr->gr_gid = gid;
gr->gr_mem[0] = gr->gr_name;
return gr;
}
// Translate a uid into the corresponding name.
// 0 to AID_APP-1 -> "system", "radio", etc.
// AID_APP to AID_ISOLATED_START-1 -> u0_a1234
@ -371,6 +419,11 @@ passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
if (pw != NULL) {
return pw;
}
// Handle OEM range.
pw = oem_id_to_passwd(uid, state);
if (pw != NULL) {
return pw;
}
return app_id_to_passwd(uid, state);
}
@ -384,6 +437,11 @@ passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
if (pw != NULL) {
return pw;
}
// Handle OEM range.
pw = oem_id_to_passwd(oem_id_from_name(login), state);
if (pw != NULL) {
return pw;
}
return app_id_to_passwd(app_id_from_name(login, false), state);
}
@ -407,6 +465,11 @@ static group* getgrgid_internal(gid_t gid, group_state_t* state) {
if (grp != NULL) {
return grp;
}
// Handle OEM range.
grp = oem_id_to_group(gid, state);
if (grp != NULL) {
return grp;
}
return app_id_to_group(gid, state);
}
@ -423,6 +486,11 @@ static group* getgrnam_internal(const char* name, group_state_t* state) {
if (grp != NULL) {
return grp;
}
// Handle OEM range.
grp = oem_id_to_group(oem_id_from_name(name), state);
if (grp != NULL) {
return grp;
}
return app_id_to_group(app_id_from_name(name, true), state);
}

View File

@ -122,6 +122,14 @@ TEST(getpwnam, app_id_radio) {
check_get_passwd("radio", 1001, TYPE_SYSTEM);
}
TEST(getpwnam, oem_id_0) {
check_get_passwd("oem_0", 5000, TYPE_SYSTEM);
}
TEST(getpwnam, oem_id_999) {
check_get_passwd("oem_999", 5999, TYPE_SYSTEM);
}
TEST(getpwnam, app_id_nobody) {
check_get_passwd("nobody", 9999, TYPE_SYSTEM);
}
@ -247,6 +255,14 @@ TEST(getgrnam, app_id_radio) {
check_get_group("radio", 1001);
}
TEST(getgrnam, oem_id_0) {
check_get_group("oem_0", 5000);
}
TEST(getgrnam, oem_id_999) {
check_get_group("oem_999", 5999);
}
TEST(getgrnam, app_id_nobody) {
check_get_group("nobody", 9999);
}