Skip to content

Instantly share code, notes, and snippets.

@AlexTalker
Created June 28, 2022 16:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexTalker/b14bd685aa20e7f8047144188eb125b4 to your computer and use it in GitHub Desktop.
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.
#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