// SPDX-License-Identifier: GPL-3.0-or-later #ifndef NETDATA_SYSTEM_USERS_H #define NETDATA_SYSTEM_USERS_H #include "libnetdata/libnetdata.h" // -------------------------------------------------------------------------------------------------------------------- // hashtable for caching uid to username mappings // key is the uid, value is username (STRING) #define SIMPLE_HASHTABLE_VALUE_TYPE STRING #define SIMPLE_HASHTABLE_NAME _USERNAMES_CACHE #include "libnetdata/simple_hashtable.h" typedef struct usernames_cache { SPINLOCK spinlock; SIMPLE_HASHTABLE_USERNAMES_CACHE ht; } USERNAMES_CACHE; static inline STRING *system_usernames_cache_lookup_uid(USERNAMES_CACHE *uc, uid_t uid) { spinlock_lock(&uc->spinlock); SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_get_slot_USERNAMES_CACHE(&uc->ht, uid, &uid, true); STRING *u = SIMPLE_HASHTABLE_SLOT_DATA(sl); if(!u) { char tmp[1024 + 1]; struct passwd pw, *result = NULL; if (getpwuid_r(uid, &pw, tmp, sizeof(tmp), &result) != 0 || !result || !pw.pw_name || !(*pw.pw_name)) { char name[50]; snprintfz(name, sizeof(name), "%u", uid); u = string_strdupz(name); } else u = string_strdupz(pw.pw_name); simple_hashtable_set_slot_USERNAMES_CACHE(&uc->ht, sl, uid, u); } u = string_dup(u); spinlock_unlock(&uc->spinlock); return u; } static inline USERNAMES_CACHE *system_usernames_cache_init(void) { USERNAMES_CACHE *uc = callocz(1, sizeof(*uc)); spinlock_init(&uc->spinlock); simple_hashtable_init_USERNAMES_CACHE(&uc->ht, 100); return uc; } static inline void system_usernames_cache_destroy(USERNAMES_CACHE *uc) { spinlock_lock(&uc->spinlock); for(SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_first_read_only_USERNAMES_CACHE(&uc->ht); sl; sl = simple_hashtable_next_read_only_USERNAMES_CACHE(&uc->ht, sl)) { STRING *u = SIMPLE_HASHTABLE_SLOT_DATA(sl); string_freez(u); } simple_hashtable_destroy_USERNAMES_CACHE(&uc->ht); freez(uc); } #endif //NETDATA_SYSTEM_USERS_H