bool ParseJsonToGroups()

in src/oslogin_utils.cc [578:636]


bool ParseJsonToGroups(const string& json, std::vector<Group>* result) {
  bool ret = false;

  json_object* root = ParseJsonRoot(json);
  if (root == NULL) {
    return ret;
  }
  json_object* groups;
  json_type groupType;
  if (!json_object_object_get_ex(root, "posixGroups", &groups)) {
    SysLogErr("failed to parse POSIX groups from \"%s\"", json.c_str());
    goto cleanup;
  }
  groupType = json_object_get_type(groups);
  if (groupType != json_type_array) {
    SysLogErr("parsed unexpected type for field \"posixGroups\"; "
              "want a list, got %s", groupType);
    goto cleanup;
  }
  for (int idx = 0; idx < (int)json_object_array_length(groups); idx++) {
    json_object* group = json_object_array_get_idx(groups, idx);

    json_object* gid;
    if (!json_object_object_get_ex(group, "gid", &gid)) {
      SysLogErr("failed to parse gid from group %s", json_object_get_string(group));
      goto cleanup;
    }
    json_object* name;
    if (!json_object_object_get_ex(group, "name", &name)) {
      SysLogErr("failed to parse name from group %s", json_object_get_string(group));
      goto cleanup;
    }

    Group g;
    // We use json_object_get_int64 because GIDs are unsigned and may use all
    // 32 bits, but there is no json_object_get_uint32.
    // Because the GID should never exceed 32 bits, truncation is safe.
    g.gid = (uint32_t)json_object_get_int64(gid);

    // get_int64 will confusingly return 0 if the string can't be converted to
    // an integer. We can't rely on type check as it may be a string in the API.
    // Also 0 is invalid because it creates a 'root group'.
    if (g.gid == 0) {
      goto cleanup;
    }

    g.name = json_object_get_string(name);
    if (g.name == "") {
      goto cleanup;
    }

    result->push_back(g);
  }
  ret = true;

cleanup:
  json_object_put(root);
  return ret;
}