aboutsummaryrefslogtreecommitdiff
path: root/nss/nss_test1.c
diff options
context:
space:
mode:
Diffstat (limited to 'nss/nss_test1.c')
-rw-r--r--nss/nss_test1.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/nss/nss_test1.c b/nss/nss_test1.c
new file mode 100644
index 0000000000..3beb488fcf
--- /dev/null
+++ b/nss/nss_test1.c
@@ -0,0 +1,154 @@
+#include <errno.h>
+#include <nss.h>
+#include <pthread.h>
+#include <string.h>
+
+
+#define COPY_IF_ROOM(s) \
+ ({ size_t len_ = strlen (s) + 1; \
+ char *start_ = cp; \
+ buflen - (cp - buffer) < len_ \
+ ? NULL \
+ : (cp = mempcpy (cp, s, len_), start_); })
+
+
+/* Password handling. */
+#include <pwd.h>
+
+static struct passwd pwd_data[] =
+ {
+#define PWD(u) \
+ { .pw_name = (char *) "name" #u, .pw_passwd = (char *) "*", .pw_uid = u, \
+ .pw_gid = 100, .pw_gecos = (char *) "*", .pw_dir = (char *) "*", \
+ .pw_shell = (char *) "*" }
+ PWD (100),
+ PWD (30),
+ PWD (200),
+ PWD (60),
+ PWD (20000)
+ };
+#define npwd_data (sizeof (pwd_data) / sizeof (pwd_data[0]))
+
+static size_t pwd_iter;
+#define CURPWD pwd_data[pwd_iter]
+
+static pthread_mutex_t pwd_lock = PTHREAD_MUTEX_INITIALIZER;
+
+
+enum nss_status
+_nss_test1_setpwent (int stayopen)
+{
+ pwd_iter = 0;
+ return NSS_STATUS_SUCCESS;
+}
+
+
+enum nss_status
+_nss_test1_endpwent (void)
+{
+ return NSS_STATUS_SUCCESS;
+}
+
+
+enum nss_status
+_nss_test1_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
+ int *errnop)
+{
+ char *cp = buffer;
+ int res = NSS_STATUS_SUCCESS;
+
+ pthread_mutex_lock (&pwd_lock);
+
+ if (pwd_iter >= npwd_data)
+ res = NSS_STATUS_NOTFOUND;
+ else
+ {
+ result->pw_name = COPY_IF_ROOM (CURPWD.pw_name);
+ result->pw_passwd = COPY_IF_ROOM (CURPWD.pw_passwd);
+ result->pw_uid = CURPWD.pw_uid;
+ result->pw_gid = CURPWD.pw_gid;
+ result->pw_gecos = COPY_IF_ROOM (CURPWD.pw_gecos);
+ result->pw_dir = COPY_IF_ROOM (CURPWD.pw_dir);
+ result->pw_shell = COPY_IF_ROOM (CURPWD.pw_shell);
+
+ if (result->pw_name == NULL || result->pw_passwd == NULL
+ || result->pw_gecos == NULL || result->pw_dir == NULL
+ || result->pw_shell == NULL)
+ {
+ *errnop = ERANGE;
+ res = NSS_STATUS_TRYAGAIN;
+ }
+
+ ++pwd_iter;
+ }
+
+ pthread_mutex_unlock (&pwd_lock);
+
+ return res;
+}
+
+
+enum nss_status
+_nss_test1_getpwuid_r (uid_t uid, struct passwd *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ for (size_t idx = 0; idx < npwd_data; ++idx)
+ if (pwd_data[idx].pw_uid == uid)
+ {
+ char *cp = buffer;
+ int res = NSS_STATUS_SUCCESS;
+
+ result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
+ result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
+ result->pw_uid = pwd_data[idx].pw_uid;
+ result->pw_gid = pwd_data[idx].pw_gid;
+ result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
+ result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
+ result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
+
+ if (result->pw_name == NULL || result->pw_passwd == NULL
+ || result->pw_gecos == NULL || result->pw_dir == NULL
+ || result->pw_shell == NULL)
+ {
+ *errnop = ERANGE;
+ res = NSS_STATUS_TRYAGAIN;
+ }
+
+ return res;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}
+
+
+enum nss_status
+_nss_test1_getpwnam_r (const char *name, struct passwd *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ for (size_t idx = 0; idx < npwd_data; ++idx)
+ if (strcmp (pwd_data[idx].pw_name, name) == 0)
+ {
+ char *cp = buffer;
+ int res = NSS_STATUS_SUCCESS;
+
+ result->pw_name = COPY_IF_ROOM (pwd_data[idx].pw_name);
+ result->pw_passwd = COPY_IF_ROOM (pwd_data[idx].pw_passwd);
+ result->pw_uid = pwd_data[idx].pw_uid;
+ result->pw_gid = pwd_data[idx].pw_gid;
+ result->pw_gecos = COPY_IF_ROOM (pwd_data[idx].pw_gecos);
+ result->pw_dir = COPY_IF_ROOM (pwd_data[idx].pw_dir);
+ result->pw_shell = COPY_IF_ROOM (pwd_data[idx].pw_shell);
+
+ if (result->pw_name == NULL || result->pw_passwd == NULL
+ || result->pw_gecos == NULL || result->pw_dir == NULL
+ || result->pw_shell == NULL)
+ {
+ *errnop = ERANGE;
+ res = NSS_STATUS_TRYAGAIN;
+ }
+
+ return res;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}