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