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;
}