Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f98304f
lib/nss.c: seperate nss lib open and check logic
YiPrograms Mar 2, 2026
3b65abb
lib/nss.c, lib/prototypes.h: linked list for nss_ops
YiPrograms Mar 2, 2026
25ebd69
lib/nss.c: parse multiple subid databases from nsswitch.conf
YiPrograms Mar 2, 2026
4376b03
lib/nss.c: free subid NSS database list on exit
YiPrograms Mar 2, 2026
5c96c85
lib/nss.c, lib/prototypes.h: remove old NSS handle defs
YiPrograms Mar 2, 2026
1b8aeaf
lib/nss.c: update comments and formatting
YiPrograms Mar 2, 2026
1861699
lib/subordinateio.c: want_subuid/gid_file: check for files in nss db …
YiPrograms Mar 2, 2026
c56db79
lib/subordinateio.c: restrict subid mutations to files as first source
YiPrograms Mar 2, 2026
23d79a9
lib/subordinateio.c: have_sub_uids/gids: multi-provider lookup
YiPrograms Mar 2, 2026
c3a81ba
lib/subordinateio.c: have_range: fix check for sub_uid/gid_open()
YiPrograms Mar 2, 2026
529d41c
lib/subordinateio.c: refactor list_owner_ranges to list_local_owner_r…
YiPrograms Mar 2, 2026
4d8d60a
lib/subordinateio.c: list_owner_ranges: multi-database range listing
YiPrograms Mar 2, 2026
2cb6cbd
lib/subordinateio.c: refactor find_subid_owners to find_local_subid_o…
YiPrograms Mar 2, 2026
2a36cc2
lib/subordinateio.c: find_subid_owners: multi-database owner search
YiPrograms Mar 2, 2026
b526c5a
lib/subordinateio.c: free_subid_pointer: use standard free
YiPrograms Mar 2, 2026
90fa9b8
tests/libsubid/04_nss: Improve mock implementation
YiPrograms Mar 2, 2026
4dfa195
tests/libsubid/04_nss: Update and extend test_nss
YiPrograms Mar 2, 2026
3d4cfa9
tests/libsubid/04_nss: Extend range tests to multiple NSS providers
YiPrograms Mar 2, 2026
768ad6f
man/subuid.5, man/subgid.5: document multiple subid delegation support
YiPrograms Mar 2, 2026
ec8afae
tests/libsubid/04_nss: add tests for range listing
YiPrograms Mar 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 60 additions & 32 deletions lib/nss.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static atomic_flag nss_init_started;
static atomic_bool nss_init_completed;

static struct subid_nss_ops *subid_nss;
static struct subid_nss_db *subid_nss_db_head;

bool nss_is_initialized() {
return atomic_load(&nss_init_completed);
Expand All @@ -48,6 +49,55 @@ static void nss_exit(void) {
}
}

static struct subid_nss_ops *
open_and_check_nss_module(const char *libname) {
void *h;
struct subid_nss_ops *nss_ops;

h = dlopen(libname, RTLD_LAZY);
if (!h) {
fprintf(log_get_logfd(), "Error opening %s: %s\n", libname, dlerror());
fprintf(log_get_logfd(), "Using files\n");
return NULL;
}

nss_ops = malloc_T(1, struct subid_nss_ops);
if (!nss_ops) {
fprintf(log_get_logfd(), "Failed to allocate memory for subid NSS module %s\n", libname);
dlclose(h);
return NULL;
}

nss_ops->has_range = dlsym(h, "shadow_subid_has_range");
if (!nss_ops->has_range) {
fprintf(log_get_logfd(), "%s did not provide @has_range@\n", libname);
goto close_lib;
}
nss_ops->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges");
if (!nss_ops->list_owner_ranges) {
fprintf(log_get_logfd(), "%s did not provide @list_owner_ranges@\n", libname);
goto close_lib;
}
nss_ops->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners");
if (!nss_ops->find_subid_owners) {
fprintf(log_get_logfd(), "%s did not provide @find_subid_owners@\n", libname);
goto close_lib;
}
nss_ops->free = dlsym(h, "shadow_subid_free");
if (!nss_ops->free) {
fprintf(log_get_logfd(), "%s did not provide @free@\n", libname);
goto close_lib;
}

nss_ops->handle = h;
return nss_ops;

close_lib:
dlclose(h);
free(nss_ops);
return NULL;
}

// nsswitch_path is an argument only to support testing.
void
nss_init(const char *nsswitch_path) {
Expand Down Expand Up @@ -108,42 +158,13 @@ nss_init(const char *nsswitch_path) {
goto null_subid;
}
stprintf_a(libname, "libsubid_%s.so", p);
h = dlopen(libname, RTLD_LAZY);
if (!h) {
Comment on lines -111 to -112

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h is now unused in this function. You should remove the declaration.

fprintf(log_get_logfd(), "Error opening %s: %s\n", libname, dlerror());
fprintf(log_get_logfd(), "Using files\n");
Comment thread
YiPrograms marked this conversation as resolved.
goto null_subid;
}
subid_nss = malloc_T(1, struct subid_nss_ops);
subid_nss = open_and_check_nss_module(libname);
if (!subid_nss) {
goto close_lib;
}
subid_nss->has_range = dlsym(h, "shadow_subid_has_range");
if (!subid_nss->has_range) {
fprintf(log_get_logfd(), "%s did not provide @has_range@\n", libname);
goto close_lib;
}
subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges");
if (!subid_nss->list_owner_ranges) {
fprintf(log_get_logfd(), "%s did not provide @list_owner_ranges@\n", libname);
goto close_lib;
}
subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners");
if (!subid_nss->find_subid_owners) {
fprintf(log_get_logfd(), "%s did not provide @find_subid_owners@\n", libname);
goto close_lib;
}
subid_nss->free = dlsym(h, "shadow_subid_free");
if (!subid_nss->free) {
fprintf(log_get_logfd(), "%s did not provide @subid_free@\n", libname);
goto close_lib;
fprintf(log_get_logfd(), "Failed to initialize subid NSS module %s\n", libname);
goto null_subid;
}
subid_nss->handle = h;
goto done;

close_lib:
dlclose(h);
free(subid_nss);
null_subid:
subid_nss = NULL;

Expand All @@ -160,3 +181,10 @@ struct subid_nss_ops *get_subid_nss_handle() {
nss_init(NULL);
return subid_nss;
}

struct subid_nss_db *
get_subid_nss_db(void) {
nss_init(NULL);
return subid_nss_db_head;
}

6 changes: 6 additions & 0 deletions lib/prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ extern /*@null@*//*@only@*/struct passwd *get_my_pwent (void);
extern void nss_init(const char *nsswitch_path);
extern bool nss_is_initialized(void);

struct subid_nss_db {
struct subid_nss_ops *ops;
struct subid_nss_db *next;
};

Comment on lines +231 to +235

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have a linked list? Or is an array simpler?

struct subid_nss_ops {
/*
* nss_has_range: does a user own a given subid range
Expand Down Expand Up @@ -290,6 +295,7 @@ struct subid_nss_ops {
};

extern struct subid_nss_ops *get_subid_nss_handle(void);
extern struct subid_nss_db *get_subid_nss_db(void);


/* pam_pass_non_interactive.c */
Expand Down