Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement <gshadow.h> functions. #40

Merged
merged 2 commits into from
May 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ debian/debhelper-build-stamp
/tmpconfig.yml
/.ghi.yml
/libnss_cache.so
/gen_getent.c.gcov
/*.c.gcov
/build/
61 changes: 45 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@ LIBNSSCACHE = nss_cache.o compat/getpwent_r.o compat/getgrent_r.o
SOURCES = Makefile gen_getent.c lookup.c nss_cache.c nss_cache.h nss_test.h COPYING version libnss-cache.spec
VERSION = $(shell git describe --tags --always | sed -E 's@.*/([^-]*).*@\1@')

GETENT_DATA_TOUCH = $(TESTDATA)/.touch.getent_data
LOOKUP_DATA_TOUCH = $(TESTDATA)/.touch.lookup_data
INDEX_DATA_TOUCH = $(TESTDATA)/.touch.index_data

.PHONY: all
all: $(LIBRARY)

.PHONY: test
test: test_getent time_lookups

.PHONY: check
check: CFLAGS += -O0 -g --coverage
check: LDFLAGS += --coverage
Expand All @@ -23,41 +31,43 @@ check: test_getent time_lookups
lookup: lookup.o $(LIBNSSCACHE)

.PHONY: time_lookups
time_lookups: $(TESTDATA) lookup_data lookup
time_lookups: lookup_data index_data lookup
@echo Linear username lookups
rm -f $(TESTDATA)/passwd.cache.ixname
time -f %E ./lookup -c getpwnam -f $(TESTDATA)/rand_pwnames
@echo Binary username lookups
./scripts/index.sh $(TESTDATA)/passwd.cache 1 $(TESTDATA)/passwd.cache.ixname
ln -sf passwd_cache_ixname_disabled $(TESTDATA)/passwd.cache.ixname
time -f %E ./lookup -c getpwnam -f $(TESTDATA)/rand_pwnames

@echo Linear UID lookups
rm -f $(TESTDATA)/passwd.cache.ixuid
time -f %E ./lookup -c getpwuid -f $(TESTDATA)/rand_pwuids
@echo Binary UID lookups
./scripts/index.sh $(TESTDATA)/passwd.cache 3 $(TESTDATA)/passwd.cache.ixuid
ln -sf passwd_cache_ixuid_disabled $(TESTDATA)/passwd.cache.ixuid
time -f %E ./lookup -c getpwuid -f $(TESTDATA)/rand_pwuids

@echo Linear groupname lookups
rm -f $(TESTDATA)/group.cache.ixname
time -f %E ./lookup -c getgrnam -f $(TESTDATA)/rand_grnames
@echo Binary groupname lookups
./scripts/index.sh $(TESTDATA)/group.cache 1 $(TESTDATA)/group.cache.ixname
ln -sf group_cache_ixname_disabled $(TESTDATA)/group.cache.ixname
time -f %E ./lookup -c getgrnam -f $(TESTDATA)/rand_grnames

@echo Linear GID lookups
rm -f $(TESTDATA)/group.cache.ixgid
time -f %E ./lookup -c getgrgid -f $(TESTDATA)/rand_grgids
@echo Binary GID lookups
./scripts/index.sh $(TESTDATA)/group.cache 3 $(TESTDATA)/group.cache.ixgid
ln -sf group_cache_ixuid_disabled $(TESTDATA)/group.cache.ixuid
time -f %E ./lookup -c getgrgid -f $(TESTDATA)/rand_grgids

@echo Linear shadow lookups
rm -f $(TESTDATA)/shadow.cache.ixname
time -f %E ./lookup -c getspnam -f $(TESTDATA)/rand_spnames
@echo Binary shadow lookups
./scripts/index.sh $(TESTDATA)/shadow.cache 1 $(TESTDATA)/shadow.cache.ixname
ln -sf shadow_cache_ixname_disabled $(TESTDATA)/shadow.cache.ixname
time -f %E ./lookup -c getspnam -f $(TESTDATA)/rand_spnames
@echo Linear gshadow lookups
rm -f $(TESTDATA)/gshadow.cache.ixname
time -f %E ./lookup -c getsgnam -f $(TESTDATA)/rand_sgnames
@echo Binary gshadow lookups
ln -sf gshadow_cache_ixname_disabled $(TESTDATA)/gshadow.cache.ixname
time -f %E ./lookup -c getsgnam -f $(TESTDATA)/rand_sgnames
gcov --all-blocks --branch-probabilities --branch-counts --function-summaries --unconditional-branches ./lookup

gen_getent: gen_getent.o $(LIBNSSCACHE)
Expand All @@ -69,10 +79,25 @@ test_getent: getent_data gen_getent nss_cache.c
diff $(TESTDATA)/passwd.cache $(TESTDATA)/passwd.cache.out
diff $(TESTDATA)/group.cache $(TESTDATA)/group.cache.out
diff $(TESTDATA)/shadow.cache $(TESTDATA)/shadow.cache.out
diff $(TESTDATA)/gshadow.cache $(TESTDATA)/gshadow.cache.out
gcov --all-blocks --branch-probabilities --branch-counts --function-summaries --unconditional-branches ./gen_getent


.PHONY: index_data
index_data: $(INDEX_DATA_TOUCH)

$(INDEX_DATA_TOUCH): $(LOOKUP_DATA_TOUCH)
./scripts/index.sh $(TESTDATA)/passwd.cache 1 $(TESTDATA)/passwd_cache_ixname_disabled
./scripts/index.sh $(TESTDATA)/passwd.cache 3 $(TESTDATA)/passwd_cache_ixuid_disabled
./scripts/index.sh $(TESTDATA)/group.cache 1 $(TESTDATA)/group_cache_ixname_disabled
./scripts/index.sh $(TESTDATA)/group.cache 3 $(TESTDATA)/group_cache_ixgid_disabled
./scripts/index.sh $(TESTDATA)/shadow.cache 1 $(TESTDATA)/shadow_cache_ixname_disabled
./scripts/index.sh $(TESTDATA)/gshadow.cache 1 $(TESTDATA)/gshadow_cache_ixname_disabled

.PHONY: lookup_data
lookup_data: getent_data
lookup_data: $(LOOKUP_DATA_TOUCH)

$(LOOKUP_DATA_TOUCH): $(GETENT_DATA_TOUCH)
cut -d : -f 1 $(TESTDATA)/passwd.cache |\
sort -R | head -500 > $(TESTDATA)/rand_pwnames
cut -d : -f 3 $(TESTDATA)/passwd.cache |\
Expand All @@ -83,16 +108,20 @@ lookup_data: getent_data
sort -R | head -500 > $(TESTDATA)/rand_grgids
cut -d : -f 1 $(TESTDATA)/shadow.cache |\
sort -R | head -500 > $(TESTDATA)/rand_spnames
cut -d : -f 1 $(TESTDATA)/gshadow.cache |\
sort -R | head -500 > $(TESTDATA)/rand_sgnames
touch $@

.PHONY: getent_data
getent_data: $(TESTDATA)
getent_data: $(GETENT_DATA_TOUCH)

$(GETENT_DATA_TOUCH): scripts/gentestdata.sh
mkdir -p $(TESTDATA)
./scripts/gentestdata.sh $(TESTDATA)
touch $@

last_pw_errno_test: test/last_pw_errno_test.c

$(TESTDATA):
mkdir -p $(TESTDATA)

$(LIBRARY): LDFLAGS += -shared $(LD_SONAME)
$(LIBRARY): $(LIBNSSCACHE)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(LIBRARY) $+
Expand All @@ -110,7 +139,7 @@ install: $(SONAME)

.PHONY: clean
clean:
rm -f $(LIBRARY)* *.o compat/*.o *.gcda *.gcno compat/*.gcda compat/*.gcno lookup gen_getent last_pw_errno_test
rm -f $(LIBRARY)* *.o compat/*.o *.gcov *.gcda *.gcno compat/*.gcda compat/*.gcno lookup gen_getent last_pw_errno_test

.PHONY: veryclean
veryclean: clean
Expand Down
110 changes: 97 additions & 13 deletions gen_getent.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ static int getgrent_to_file(FILE *output) {
result.gr_gid);
// unroll **gr_mem
for (idx = 0; result.gr_mem[idx] != NULL; idx++) {
fprintf(output, "%s", result.gr_mem[idx]);
if (result.gr_mem[idx + 1] != NULL) {
fprintf(output, ",");
if (idx != 0) {
fputs(",", output);
}
fputs(result.gr_mem[idx], output);
}
fprintf(output, "\n");
fputs("\n", output);
}
if (ret == NSS_STATUS_TRYAGAIN) {
buflen = buflen * 2;
Expand Down Expand Up @@ -134,37 +134,37 @@ static int getspent_to_file(FILE *output) {
if (result.sp_lstchg != -1) {
fprintf(output, "%ld:", result.sp_lstchg);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_min != -1) {
fprintf(output, "%ld:", result.sp_min);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_max != -1) {
fprintf(output, "%ld:", result.sp_max);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_warn != -1) {
fprintf(output, "%ld:", result.sp_warn);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_inact != -1) {
fprintf(output, "%ld:", result.sp_inact);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_expire != -1) {
fprintf(output, "%ld:", result.sp_expire);
} else {
fprintf(output, ":");
fputs(":", output);
}
if (result.sp_flag != -1) {
fprintf(output, "%ld", result.sp_flag);
}
fprintf(output, "\n");
fputs("\n", output);
}
if (ret == NSS_STATUS_TRYAGAIN) {
buflen = buflen * 2;
Expand All @@ -181,6 +181,59 @@ static int getspent_to_file(FILE *output) {

return 0;
}

// getsgent_to_file()
// Call the nss_cache getsgent function to dump the shadow store to a
// file.

static int getsgent_to_file(FILE *output) {
struct sgrp result;
char *buffer;
size_t buflen = 1024;
int errnop;
enum nss_status ret;
int idx;

_nss_cache_setsgent_path(GSHADOW_FILE);

buffer = malloc(buflen);

do {
ret = _nss_cache_getsgent_r(&result, buffer, buflen, &errnop);
if (ret == NSS_STATUS_SUCCESS) {
fprintf(output, "%s:%s:", result.sg_namp, result.sg_passwd);
// unroll **sg_adm
for (idx = 0; result.sg_adm[idx] != NULL; idx++) {
if (idx != 0) {
fputs(",", output);
}
fputs(result.sg_adm[idx], output);
}
fputs(":", output);
// unroll **sg_mem
for (idx = 0; result.sg_mem[idx] != NULL; idx++) {
if (idx != 0) {
fputs(",", output);
}
fputs(result.sg_mem[idx], output);
}
fputs("\n", output);
}
if (ret == NSS_STATUS_TRYAGAIN) {
buflen = buflen * 2;
buffer = realloc(buffer, buflen);
}
if (ret == NSS_STATUS_UNAVAIL) {
perror("ERROR: failed to access gshadow test data");
free(buffer);
return 1;
}
} while (ret == NSS_STATUS_SUCCESS || ret == NSS_STATUS_TRYAGAIN);

free(buffer);

return 0;
}
#endif // ifndef BSD

// gen_getpwent_data()
Expand Down Expand Up @@ -258,6 +311,31 @@ static int gen_getspent_data(void) {

return ret;
}

// gen_getsgent_data()
//
// creates a copy of the shadow map as read by nss_cache.c

static int gen_getsgent_data(void) {
char filename[NSS_CACHE_PATH_LENGTH];
FILE *output;
int ret;

strncpy(filename, GSHADOW_FILE, NSS_CACHE_PATH_LENGTH - 4);
int n = strlen(filename);
strncat(filename, ".out", NSS_CACHE_PATH_LENGTH - n - 1);
output = fopen(filename, "w");

if (output == NULL) {
fprintf(stderr, "failed to open %s!\n", filename);
return 255;
}

ret = getsgent_to_file(output);
fclose(output);

return ret;
}
#endif // ifndef BSD

// main()
Expand All @@ -277,14 +355,20 @@ int main(void) {

ret = gen_getgrent_data();
if (ret != 0) {
fprintf(stderr, "Failed to generate password file.\n");
fprintf(stderr, "Failed to generate group file.\n");
failed_tests = failed_tests + 1;
}

#ifndef BSD
ret = gen_getspent_data();
if (ret != 0) {
fprintf(stderr, "Failed to generate password file.\n");
fprintf(stderr, "Failed to generate shadow file.\n");
failed_tests = failed_tests + 1;
}

ret = gen_getsgent_data();
if (ret != 0) {
fprintf(stderr, "Failed to generate gshadow file.\n");
failed_tests = failed_tests + 1;
}
#endif
Expand Down
Loading