bool ParseJsonToPasswd()

in src/oslogin_utils.cc [801:904]


bool ParseJsonToPasswd(const string& json, struct passwd* result, BufferManager*
                       buf, int* errnop) {
  bool ret = false;
  *errnop = EINVAL;
  json_object* root = NULL;
  json_object* origroot = NULL;

  origroot = root = ParseJsonRoot(json);
  if (root == NULL) {
    return false;
  }

  json_object* posix_accounts;
  json_object* login_profiles;
  // If this is called from getpwent_r, loginProfiles won't be in the response.
  if (json_object_object_get_ex(root, "loginProfiles", &login_profiles)) {
    if (json_object_get_type(login_profiles) != json_type_array) {
      goto cleanup;
    }
    // This overwrites root but we still have origroot for cleanup;
    root = json_object_array_get_idx(login_profiles, 0);
  }
  // Locate the posixAccounts object.
  if (!json_object_object_get_ex(root, "posixAccounts", &posix_accounts)) {
    goto cleanup;
  }
  if (json_object_get_type(posix_accounts) != json_type_array) {
    goto cleanup;
  }
  posix_accounts = json_object_array_get_idx(posix_accounts, 0);

  // Populate with some default values that ValidatePasswd can detect if they
  // are not set.
  result->pw_uid = 0;
  result->pw_shell = (char*)"";
  result->pw_name = (char*)"";
  result->pw_dir = (char*)"";
  result->pw_passwd = (char*)"";

  // Iterate through the json response and populate the passwd struct.
  if (json_object_get_type(posix_accounts) != json_type_object) {
    goto cleanup;
  }
  {
  // Extra braces to indicate scope of key, obj below to compiler. Otherwise
  // g++ complains that `goto` bypasses initializers.
  json_object_object_foreach(posix_accounts, key, val) {
    int val_type = json_object_get_type(val);
    // Convert char* to c++ string for easier comparison.
    string string_key(key);

    if (string_key == "uid") {
      if (val_type == json_type_int || val_type == json_type_string) {
        result->pw_uid = (uint32_t)json_object_get_int64(val);
        if (result->pw_uid == 0) {
          goto cleanup;
        }
      } else {
        goto cleanup;
      }
    } else if (string_key == "gid") {
      if (val_type == json_type_int || val_type == json_type_string) {
        result->pw_gid = (uint32_t)json_object_get_int64(val);
        // Use the uid as the default group when gid is not set or is zero.
        if (result->pw_gid == 0) {
          result->pw_gid = result->pw_uid;
        }
      } else {
        goto cleanup;
      }
    } else if (string_key == "username") {
      if (val_type != json_type_string) {
        goto cleanup;
      }
      if (!buf->AppendString(json_object_get_string(val),
                             &result->pw_name, errnop)) {
        goto cleanup;
      }
    } else if (string_key == "homeDirectory") {
      if (val_type != json_type_string) {
        goto cleanup;
      }
      if (!buf->AppendString(json_object_get_string(val),
                             &result->pw_dir, errnop)) {
        goto cleanup;
      }
    } else if (string_key == "shell") {
      if (val_type != json_type_string) {
        goto cleanup;
      }
      if (!buf->AppendString(json_object_get_string(val),
                             &result->pw_shell, errnop)) {
        goto cleanup;
      }
    }
  }
  }
  *errnop = 0;
  ret = ValidatePasswd(result, buf, errnop);

cleanup:
  json_object_put(origroot);
  return ret;
}