Files
lidm/src/users.c
javalsai 0b2d0bdf03 fixes: improve login environment handling (#114)
* chore(organization): allow nested header and c files

* feat: add shell login "middleware" & etc:
  * lidm now calls `bash` (or other shells, depends on PACKAGE cfg) in
  login mode as a session wrapper to source most env (can be disabled)
  * this fixes a lot of env problems with all `/etc/profile` and more

Extra:
* implemented a musl compatible version of `execvpe` and now lidm should
  search for PATH everywhere it needs to
* `search_path` now also checks if the found binary is properly
  executable
* lidm now uses `confstr` for a decent PATH default if none is found
* logs are unbuffered for cases where debug logs appear empty (exit
  without handlers moment)

* chore: one-time evaluate certain makefile vars

---------

Co-authored-by: grialion <48643945+grialion@users.noreply.github.com>
2026-02-07 17:12:03 +01:00

67 lines
1.7 KiB
C

#include <pwd.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "log.h"
#include "macros.h"
#include "users.h"
#include "util/vec.h"
// NOLINTNEXTLINE(readability-identifier-length)
int build_user(struct user* NNULLABLE user, struct passwd* p) {
char* shell = strdup(p->pw_shell);
char* username = strdup(p->pw_name);
char* displayname;
if (strlen(p->pw_gecos) == 0)
displayname = username;
else {
displayname = strdup(p->pw_gecos);
}
if (!shell || !username || !displayname) {
free(shell);
free(username);
if (displayname != username) free(displayname);
// actually tidy struggles with the line i have avobe
// NOLINTNEXTLINE(clang-analyzer-unix.Malloc)
return -1;
}
*user = (struct user){
.shell = shell,
.username = username,
.display_name = displayname,
};
return 0;
}
// This code is designed to be run purely single threaded
#define LIKELY_BOUND_USERS 4
struct Vector get_human_users() {
struct Vector users = VEC_NEW;
vec_reserve(&users, LIKELY_BOUND_USERS);
struct passwd* NULLABLE pwd;
while ((pwd = getpwent()) != NULL) {
log_printf("[I] handling user %s\n", pwd->pw_name);
// `- 1` bcs sizeof counts the nullbyte
if (pwd->pw_dir &&
strncmp(pwd->pw_dir, "/home/", sizeof("/home/") - 1) != 0)
continue;
log_printf("[I] found %s\n", pwd->pw_name);
struct user* user_i = malloc(sizeof(struct user));
if (user_i == NULL) continue; // malloc error
if (build_user(user_i, pwd) != 0) {
log_printf("[E] failed to allocate allocate memory for %s\n",
pwd->pw_name);
}
vec_push(&users, user_i);
}
return users;
}