Created
June 28, 2022 16:22
-
-
Save AlexTalker/b14bd685aa20e7f8047144188eb125b4 to your computer and use it in GitHub Desktop.
Simple example of how `getent ---service <service>` retrieves the information for specific service only.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <sys/types.h> | |
#include <grp.h> | |
#include <pwd.h> | |
#include <nss.h> | |
#include <stdio.h> | |
/* Possibly a memory leak according to documentation */ | |
#define SETUP_DB(db, service) if (service != NULL) { __nss_configure_lookup(db, service); } | |
void print_passwd(struct passwd *entry) { | |
printf("Name: %s\n", entry->pw_name); | |
/* entry->pw_passwd is likely always 'x' */ | |
printf("UID: %lu\n", entry->pw_uid); | |
printf("GID: %lu\n", entry->pw_gid); | |
printf("Info: %s\n", entry->pw_gecos); | |
printf("HOME: %s\n", entry->pw_dir); | |
printf("SHELL: %s\n", entry->pw_shell); | |
} | |
#define MAX_GROUPS 128 | |
void print_group_name(gid_t gid) { | |
struct group *entry = getgrgid(gid); | |
printf("%s", entry ? entry->gr_name : "(NULL)"); | |
} | |
/* Works for files and winbind */ | |
void print_passwd_groups(struct passwd *entry) { | |
int count = 0; | |
int ngroups = MAX_GROUPS; | |
gid_t groups[MAX_GROUPS]; | |
printf("Group: "); | |
print_group_name(entry->pw_gid); | |
printf("\n"); | |
count = getgrouplist(entry->pw_name, entry->pw_gid, groups, &ngroups); | |
printf("Groups:"); | |
for (int i = 0; i < count; i++) { | |
printf(" "); | |
print_group_name(groups[i]); | |
} | |
printf("\n"); | |
} | |
#define DB_PASSWD "passwd" | |
void handle_passwd(char* service) { | |
struct passwd *entry = NULL; | |
setpwent(); | |
while ((entry = getpwent()) != NULL) { | |
print_passwd(entry); | |
print_passwd_groups(entry); | |
printf("\n"); | |
} | |
endpwent(); | |
} | |
void print_group(struct group *entry) { | |
char **members = NULL; | |
char *member = NULL; | |
printf("Name: %s\n", entry->gr_name); | |
/* entry->gr_passwd is likely always 'x' */ | |
printf("GID: %lu\n", entry->gr_gid); | |
printf("Members:"); | |
/* Doesn't work for winbind */ | |
members = entry->gr_mem; | |
for (member = *members; member != NULL; member = *(++members)) { | |
printf(" %s", member); | |
} | |
printf("\n"); | |
} | |
#define DB_GROUP "group" | |
void handle_group(char* service) { | |
struct group *entry = NULL; | |
setgrent(); | |
while ((entry = getgrent()) != NULL) { | |
print_group(entry); | |
printf("\n"); | |
} | |
endgrent(); | |
} | |
int main(int argc, char** argv) { | |
/* files, winbind and the like */ | |
char* service = (argc > 1) ? argv[1] : NULL; | |
SETUP_DB(DB_PASSWD, service); | |
SETUP_DB(DB_GROUP, service); | |
printf("List of users:\n\n"); | |
handle_passwd(service); | |
printf("List of groups:\n\n"); | |
handle_group(service); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment