This repository has been archived by the owner on May 2, 2024. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from ubuntu/nss_module_in_c
Nss module in c
- Loading branch information
Showing
45 changed files
with
447 additions
and
1 deletion.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
CC=gcc | ||
CFLAGS=-g -Wall -Wextra $(shell pkg-config --cflags glib-2.0) | ||
LDFLAGS=$(shell pkg-config --libs glib-2.0) | ||
|
||
all: clean libnss_aad.so.2 copy | ||
|
||
libnss_aad.so.2: | ||
$(CC) -DSCRIPTPATH=\"/home/u/getent.sh\" passwd.c group.c shadow.c common.c $(CFLAGS) $(LDFLAGS) -fPIC -shared -Wl,-soname,libnss_aad.so.2 -o libnss_aad.so.2 | ||
|
||
clean: | ||
rm -f libnss_aad.so.2 | ||
|
||
check: | ||
make clean | ||
codechecker check -b "make libnss_aad.so.2" | ||
|
||
copy: | ||
scp libnss_aad.so.2 u@192.168.122.144:~/ | ||
scp getent.sh u@192.168.122.144:~/ | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdarg.h> | ||
#include <nss.h> | ||
#include <pwd.h> | ||
#include <string.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <ctype.h> | ||
|
||
#include <glib.h> | ||
#include <glib/gprintf.h> | ||
|
||
#ifndef SCRIPTPATH | ||
#define SCRIPTPATH "/usr/libexec/aad-auth" | ||
#endif | ||
|
||
gint run_aad_auth(const char *db, const char *name, const uid_t uid, enum nss_status *nss_exit_status, int *errnop, GPtrArray *entries) | ||
{ | ||
gchar *stdout = NULL; | ||
gchar *stderr = NULL; | ||
GError *error = NULL; | ||
gchar *cmd; | ||
|
||
if (name) | ||
{ | ||
// Concatenate name with cmd | ||
cmd = g_strconcat(SCRIPTPATH, " ", "getent", " ", db, " ", name, NULL); | ||
} | ||
else if (uid != 0) | ||
{ | ||
gchar *uid_s = NULL; | ||
uid_s = g_strdup_printf(" %u", uid); | ||
cmd = g_strconcat(SCRIPTPATH, " ", "getent", " ", db, " ", uid_s, NULL); | ||
g_free(uid_s); | ||
} | ||
else | ||
{ | ||
cmd = g_strconcat(SCRIPTPATH, " ", "getent", " ", db, NULL); | ||
} | ||
|
||
gint exit_status; | ||
if (!g_spawn_command_line_sync(cmd, &stdout, &stderr, &exit_status, &error) || exit_status != 0) | ||
{ | ||
*errnop = ENOENT; | ||
g_free(cmd); | ||
return exit_status; | ||
} | ||
g_free(cmd); | ||
|
||
gchar **lines = g_strsplit(stdout, "\n", -1); | ||
for (gint i = 0; lines[i]; i++) | ||
{ | ||
// first line is nss_exit_status:errno | ||
if (i == 0) | ||
{ | ||
gchar **statuses = g_strsplit(lines[i], ":", 2); | ||
*nss_exit_status = atoi(statuses[0]); | ||
*errnop = atoi(statuses[1]); | ||
g_strfreev(statuses); | ||
continue; | ||
} | ||
|
||
gchar *v = g_strdup(lines[i]); | ||
g_ptr_array_add(entries, (gpointer)v); | ||
} | ||
g_strfreev(lines); | ||
|
||
return 0; | ||
} | ||
|
||
enum nss_status fetch_info(const char *db, const char *name, const uid_t uid, GPtrArray *all_entries, guint *all_entries_index, gchar **entry, int *errnop) | ||
{ | ||
gint nss_exit_status = NSS_STATUS_SUCCESS; | ||
|
||
if (name != NULL || uid != 0) | ||
{ | ||
GPtrArray *entries = g_ptr_array_new(); | ||
gint exit_status = run_aad_auth(db, name, uid, &nss_exit_status, errnop, entries); | ||
if (exit_status != 0) | ||
{ | ||
*errnop = ENOENT; | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
*entry = g_strdup((gchar *)g_ptr_array_index(entries, 0)); | ||
g_ptr_array_free(entries, TRUE); | ||
} | ||
else if (all_entries->len == 0) | ||
{ | ||
gint exit_status = run_aad_auth(db, name, uid, &nss_exit_status, errnop, all_entries); | ||
if (exit_status != 0) | ||
{ | ||
*errnop = ENOENT; | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
*entry = g_strdup((gchar *)g_ptr_array_index(all_entries, *all_entries_index)); | ||
(*all_entries_index)++; | ||
} | ||
else if (*all_entries_index < all_entries->len) | ||
{ | ||
*entry = g_strdup((gchar *)g_ptr_array_index(all_entries, *all_entries_index)); | ||
(*all_entries_index)++; | ||
} | ||
else | ||
{ | ||
// iteration has ended, return our own status | ||
(*all_entries_index) = 0; | ||
*errnop = ENOENT; | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
|
||
return nss_exit_status; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#include <nss.h> | ||
#include <glib.h> | ||
|
||
#define UNUSED(x) (void)(x) | ||
|
||
enum nss_status fetch_info(const char *db, const char *name, const uid_t uid, GPtrArray *all_entries, guint *all_entries_index, gchar **entry, int *errnop); |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdarg.h> | ||
#include <nss.h> | ||
#include <grp.h> | ||
#include <string.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <ctype.h> | ||
|
||
#include <glib.h> | ||
#include <glib/gprintf.h> | ||
|
||
#include "common.h" | ||
|
||
GPtrArray *all_grp_entries = NULL; | ||
guint all_grp_entries_index = 0; | ||
|
||
enum nss_status grp_search(const char *name, const gid_t gid, struct group *gr, int *errnop, char *buffer, size_t buflen) | ||
{ | ||
UNUSED(buffer); | ||
UNUSED(buflen); | ||
|
||
if (all_grp_entries == NULL) | ||
{ | ||
all_grp_entries = g_ptr_array_new(); | ||
} | ||
|
||
gchar *entry = calloc(1000, sizeof(gchar)); | ||
gint exit_status = fetch_info("group", name, gid, all_grp_entries, &all_grp_entries_index, &entry, errnop); | ||
|
||
// return the exit status if no success | ||
if (exit_status != NSS_STATUS_SUCCESS) | ||
{ | ||
g_free(entry); | ||
return exit_status; | ||
} | ||
|
||
gchar **tokens = g_strsplit(entry, ":", 4); | ||
g_free(entry); | ||
|
||
gr->gr_name = g_strdup(tokens[0]); | ||
gr->gr_passwd = g_strdup(tokens[1]); | ||
gr->gr_gid = strtol(tokens[2], NULL, 10); | ||
gr->gr_mem = g_strsplit(tokens[3], ",", -1); | ||
|
||
g_strfreev(tokens); | ||
|
||
return exit_status; | ||
} | ||
|
||
enum nss_status _nss_aad_getgrgid_r(gid_t gid, struct group *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = 0; | ||
if (result) | ||
return grp_search(NULL, gid, result, errnop, buf, buflen); | ||
else | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
|
||
enum nss_status _nss_aad_getgrnam_r(const char *name, struct group *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = 0; | ||
if (result) | ||
return grp_search(name, 0, result, errnop, buf, buflen); | ||
else | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
|
||
enum nss_status _nss_aad_setgrent(void) | ||
{ | ||
if (all_grp_entries != NULL) | ||
{ | ||
g_ptr_array_free(all_grp_entries, TRUE); | ||
all_grp_entries = NULL; | ||
} | ||
|
||
all_grp_entries_index = 0; | ||
return NSS_STATUS_SUCCESS; | ||
} | ||
|
||
enum nss_status _nss_aad_endgrent(void) | ||
{ | ||
if (all_grp_entries != NULL) | ||
{ | ||
g_ptr_array_free(all_grp_entries, TRUE); | ||
all_grp_entries = NULL; | ||
} | ||
|
||
all_grp_entries_index = 0; | ||
return NSS_STATUS_SUCCESS; | ||
} | ||
|
||
enum nss_status _nss_aad_getgrent_r(struct group *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = -1; | ||
|
||
if (result) | ||
return grp_search(NULL, 0, result, errnop, buf, buflen); | ||
|
||
return NSS_STATUS_UNAVAIL; | ||
} |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <stdarg.h> | ||
#include <nss.h> | ||
#include <pwd.h> | ||
#include <string.h> | ||
#include <sys/types.h> | ||
#include <unistd.h> | ||
#include <errno.h> | ||
#include <ctype.h> | ||
|
||
#include <glib.h> | ||
#include <glib/gprintf.h> | ||
|
||
#include "common.h" | ||
|
||
GPtrArray *all_pwd_entries = NULL; | ||
guint all_pwd_entries_index = 0; | ||
|
||
enum nss_status pwd_search(const char *name, const uid_t uid, struct passwd *pw, int *errnop, char *buffer, size_t buflen) | ||
{ | ||
UNUSED(buffer); | ||
UNUSED(buflen); | ||
|
||
if (all_pwd_entries == NULL) | ||
{ | ||
all_pwd_entries = g_ptr_array_new(); | ||
} | ||
|
||
gchar *entry = calloc(1000, sizeof(gchar)); | ||
gint exit_status = fetch_info("passwd", name, uid, all_pwd_entries, &all_pwd_entries_index, &entry, errnop); | ||
|
||
// return the exit status if no success | ||
if (exit_status != NSS_STATUS_SUCCESS) | ||
{ | ||
g_free(entry); | ||
return exit_status; | ||
} | ||
|
||
gchar **tokens = g_strsplit(entry, ":", 7); | ||
g_free(entry); | ||
|
||
pw->pw_name = g_strdup(tokens[0]); | ||
pw->pw_passwd = g_strdup(tokens[1]); | ||
pw->pw_uid = strtol(tokens[2], NULL, 10); | ||
pw->pw_gid = strtol(tokens[3], NULL, 10); | ||
pw->pw_gecos = g_strdup(tokens[4]); | ||
pw->pw_dir = g_strdup(tokens[5]); | ||
pw->pw_shell = g_strdup(tokens[6]); | ||
g_strfreev(tokens); | ||
|
||
return exit_status; | ||
} | ||
|
||
enum nss_status _nss_aad_getpwuid_r(uid_t uid, struct passwd *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = 0; | ||
if (result) | ||
return pwd_search(NULL, uid, result, errnop, buf, buflen); | ||
else | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
|
||
enum nss_status _nss_aad_getpwnam_r(const char *name, struct passwd *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = 0; | ||
if (result) | ||
return pwd_search(name, 0, result, errnop, buf, buflen); | ||
else | ||
return NSS_STATUS_UNAVAIL; | ||
} | ||
|
||
enum nss_status _nss_aad_setpwent(void) | ||
{ | ||
if (all_pwd_entries != NULL) | ||
{ | ||
g_ptr_array_free(all_pwd_entries, TRUE); | ||
all_pwd_entries = NULL; | ||
} | ||
|
||
all_pwd_entries_index = 0; | ||
return NSS_STATUS_SUCCESS; | ||
} | ||
|
||
enum nss_status _nss_aad_endpwent(void) | ||
{ | ||
if (all_pwd_entries != NULL) | ||
{ | ||
g_ptr_array_free(all_pwd_entries, TRUE); | ||
all_pwd_entries = NULL; | ||
} | ||
|
||
all_pwd_entries_index = 0; | ||
return NSS_STATUS_SUCCESS; | ||
} | ||
|
||
enum nss_status _nss_aad_getpwent_r(struct passwd *result, char *buf, size_t buflen, int *errnop) | ||
{ | ||
*errnop = -1; | ||
|
||
if (result) | ||
return pwd_search(NULL, 0, result, errnop, buf, buflen); | ||
|
||
return NSS_STATUS_UNAVAIL; | ||
} |
Oops, something went wrong.