OSDN Git Service

Add preliminary OEM UID/GID support.
authorJorge Lucangeli Obes <jorgelo@google.com>
Tue, 22 Sep 2015 18:46:43 +0000 (11:46 -0700)
committerJorge Lucangeli Obes <jorgelo@google.com>
Tue, 22 Sep 2015 20:33:17 +0000 (13:33 -0700)
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

libc/bionic/stubs.cpp
tests/stubs_test.cpp

index 41c78bc..0340f0e 100644 (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);
 }
 
index 2d1bdee..c81ca58 100644 (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);
 }