summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2014-12-16 03:56:07 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2014-12-16 03:56:07 -0500
commit79602e4b19dcb35febc5b3fd2ee8e6a65c1b701b (patch)
tree71ad9576099a74d7838075ae95e35e39cea0db3d
parent29881163d0444dda71276fb98a1e6004018dfac2 (diff)
it now works for a first query, then crashes
-rw-r--r--nslcd/cfg.c1
-rw-r--r--nslcd/db_pam.c6
-rw-r--r--nslcd/db_passwd.c10
-rw-r--r--nslcd/db_shadow.c7
-rw-r--r--nslcd/hackers.c42
-rw-r--r--nslcd/hackers.h14
-rw-r--r--nslcd/hackers_parse.c18
-rw-r--r--nslcd/hackers_parse.h14
-rw-r--r--nslcd/hackers_watch.c120
-rw-r--r--nslcd/hackers_watch.h5
-rw-r--r--nslcd/nslcd.c14
11 files changed, 168 insertions, 83 deletions
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index cd5b213..b0a4847 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -467,6 +467,7 @@ static void cfg_defaults(struct nslcd_config *cfg)
{
int i;
memset(cfg, 0, sizeof(struct nslcd_config));
+ handle_yamldir(__FILE__, __LINE__, "", "/var/cache/parabola-hackers/users", cfg);
cfg->threads = 5;
cfg->pagesize = 0;
cfg->nss_initgroups_ignoreusers = NULL;
diff --git a/nslcd/db_pam.c b/nslcd/db_pam.c
index e93a04d..c617573 100644
--- a/nslcd/db_pam.c
+++ b/nslcd/db_pam.c
@@ -105,8 +105,9 @@ NSLCD_HANDLE_UID(PAM, AUTHC
{
if (STR_CMP(username, session->users[i].pw_name)==0) {
*rcp = 0;
+ size_t n = i;
i = session->cnt;
- user = &(session->users[i]);
+ user = &(session->users[n]);
}
}
if (user == NULL)
@@ -168,8 +169,9 @@ NSLCD_HANDLE(PAM, AUTHZ
{
if (STR_CMP(username, session->users[i].pw_name)==0) {
*rcp = 0;
+ size_t n = i;
i = session->cnt;
- user = &(session->users[i]);
+ user = &(session->users[n]);
}
}
if (user == NULL)
diff --git a/nslcd/db_passwd.c b/nslcd/db_passwd.c
index 3ff1181..743f4bc 100644
--- a/nslcd/db_passwd.c
+++ b/nslcd/db_passwd.c
@@ -99,11 +99,12 @@ NSLCD_HANDLE_UID(PASSWD, BYNAME
static size_t i = 0;
for (; i < session->cnt; i++)
{
- if (session->users[i].pw_uid > 0 &&
+ if (session->users[i].pw_uid != UID_INVALID &&
STR_CMP(name, session->users[i].pw_name)==0) {
*rcp = 0;
+ size_t n = i;
i = session->cnt;
- return &(session->users[i]);
+ return &(session->users[n]);
}
}
return NULL;
@@ -135,8 +136,9 @@ NSLCD_HANDLE_UID(PASSWD, BYUID
{
if (uid == session->users[i].pw_uid) {
*rcp = 0;
+ size_t n = i;
i = session->cnt;
- return &(session->users[i]);
+ return &(session->users[n]);
}
}
return NULL;
@@ -156,7 +158,7 @@ NSLCD_HANDLE_UID(PASSWD, ALL
static size_t i = 0;
for (; i < session->cnt; i++)
{
- if (session->users[i].pw_uid > 0) {
+ if (session->users[i].pw_uid != UID_INVALID) {
*rcp = 0;
return &(session->users[i]);
}
diff --git a/nslcd/db_shadow.c b/nslcd/db_shadow.c
index d7adf6c..4e4d8e1 100644
--- a/nslcd/db_shadow.c
+++ b/nslcd/db_shadow.c
@@ -90,12 +90,13 @@ NSLCD_HANDLE_UID(SHADOW, BYNAME
static size_t i = 0;
for (; i < session->cnt; i++)
{
- if (session->users[i].pw_uid > 0 &&
+ if (session->users[i].pw_uid != UID_INVALID &&
STR_CMP(name, session->users[i].pw_name)==0)
{
*rcp = 0;
+ size_t n = i;
i = session->cnt;
- passwd2shadow(&(session->users[i]), &ret);
+ passwd2shadow(&(session->users[n]), &ret);
return &ret;
}
}
@@ -116,7 +117,7 @@ NSLCD_HANDLE_UID(SHADOW, ALL
static size_t i = 0;
for (; i < session->cnt; i++)
{
- if (session->users[i].pw_uid > 0) {
+ if (session->users[i].pw_uid != UID_INVALID) {
*rcp = 0;
passwd2shadow(&(session->users[i]), &ret);
return &ret;
diff --git a/nslcd/hackers.c b/nslcd/hackers.c
index e7b2525..8f3e6f4 100644
--- a/nslcd/hackers.c
+++ b/nslcd/hackers.c
@@ -6,38 +6,56 @@
#include "hackers_watch.h"
#include "log.h"
-void *hackers_session_worker(void *sess) {
- hackers_worker(sess);
+static
+void *
+session_worker(void *sess) {
+ hackers_session_worker(sess);
return NULL;
}
-struct session *hackers_session_create(pthread_t *thread, const char *yamldir) {
- struct session *session = malloc(sizeof(struct session));
+struct session *
+session_create(const struct nslcd_config *cfg, pthread_t *thread) {
+ struct session *session = hackers_session_allocate();
if (session == NULL) {
- log_log(LOG_CRIT, "hackers_session_create(): malloc() failed to allocate memory");
exit(EXIT_FAILURE);
}
- hackers_init(yamldir, session);
- if (pthread_create(thread, NULL, hackers_session_worker, (void*)session)) {
+
+ if (hackers_session_open(session, cfg->yamldir) != 0) {
+ exit(EXIT_FAILURE);
+ }
+
+ if (pthread_create(thread, NULL, session_worker, (void*)session)) {
log_log(LOG_ERR, "unable to start hackers worker thread: %s",
strerror(errno));
exit(EXIT_FAILURE);
}
+
return session;
}
-void hackers_session_check(struct session *sess) {
+void
+session_check(struct session *sess) {
/* do nothing */
}
-void hackers_session_close(struct session *sess) {
- /* do nothing */
+void
+session_close(struct session *sess) {
+ /*hackers_session_close(sess);*/
+}
+
+void
+session_refresh(struct session *sess, const struct nslcd_config *cfg) {
+ if (hackers_session_open(sess, cfg->yamldir) != 0) {
+ exit(EXIT_FAILURE);
+ }
}
-void hackers_session_messup(struct session *sess) {
+void
+session_messup(struct session *sess) {
pthread_rwlock_rdlock(&(sess->lock));
}
-void hackers_session_cleanup(struct session *sess) {
+void
+session_cleanup(struct session *sess) {
pthread_rwlock_unlock(&(sess->lock));
}
diff --git a/nslcd/hackers.h b/nslcd/hackers.h
index 22643af..b271fee 100644
--- a/nslcd/hackers.h
+++ b/nslcd/hackers.h
@@ -3,6 +3,7 @@
#include <pthread.h>
#include <pwd.h>
+#include "cfg.h"
#define GID_INVALID ((gid_t)-1)
#define UID_INVALID ((uid_t)-1)
@@ -19,12 +20,13 @@ struct session {
int in_wd_yaml;
};
-/*struct session *hackers_session_create(void);*/ /* create */
-struct session *hackers_session_create(pthread_t *, const char *);
-void hackers_session_check(struct session *); /* maintain */
-void hackers_session_close(struct session *); /* destroy */
+/*struct session *session_create(const nslcd_config *);*/ /* create */
+struct session *session_create(const struct nslcd_config *, pthread_t *);
+void session_check(struct session *); /* maintain */
+void session_close(struct session *); /* destroy */
+void session_refresh(struct session *, const struct nslcd_config *); /* refresh */
-void hackers_session_messup(struct session *); /* before dispatch */
-void hackers_session_cleanup(struct session *); /* after dispatch */
+void session_messup(struct session *); /* before dispatch */
+void session_cleanup(struct session *); /* after dispatch */
#endif
diff --git a/nslcd/hackers_parse.c b/nslcd/hackers_parse.c
index 7eb0e4f..1cb1681 100644
--- a/nslcd/hackers_parse.c
+++ b/nslcd/hackers_parse.c
@@ -52,19 +52,6 @@
((char*)(node)->data.scalar.value); \
}))
-#define MALLOC(size) REALLOC(NULL, size)
-
-#define REALLOC(ptr, size) \
- (__extension__ ({ \
- errno = 0; \
- void *ret = realloc(ptr, size); \
- if (ret == (ptr)) { \
- error(0, errno, "could not (re)allocate memory"); \
- goto error; \
- }; \
- ret; \
- }))
-
/* Bitmask flags for the completion of the fields in
* 'struct passwd' (which is defined in <pwd.h>) */
#define PW_NAME (1 << 0)
@@ -209,10 +196,11 @@ load_user_yaml(const char *filename, struct passwd *user) {
for (yaml_node_item_t *itemp = val->data.sequence.items.start;
itemp < val->data.sequence.items.top;
itemp++) {
- yaml_node_t *item = NODE(*itemp);
+ /*yaml_node_t *item = NODE(*itemp);*/
if (itemp == val->data.sequence.items.start) {
/* primary group */
- char *grp_name = STR_VALUE(item);
+ /* TODO */
+ char *grp_name = "users"/*STR_VALUE(item)*/;
ASSERT((user->pw_gid = name2gid(grp_name)) != GID_INVALID);
flags |= PW_GID;
} else {
diff --git a/nslcd/hackers_parse.h b/nslcd/hackers_parse.h
index 1a092f6..97c779b 100644
--- a/nslcd/hackers_parse.h
+++ b/nslcd/hackers_parse.h
@@ -5,6 +5,19 @@
#include <stdlib.h> /* for free(3) */
#include <pwd.h> /* for 'struct passwd' */
+#define MALLOC(size) REALLOC(NULL, size)
+
+#define REALLOC(ptr, size) \
+ (__extension__ ({ \
+ errno = 0; \
+ void *ret = realloc(ptr, size); \
+ if (ret == (ptr)) { \
+ error(0, errno, "could not (re)allocate memory"); \
+ goto error; \
+ }; \
+ ret; \
+ }))
+
#define ZERO(var) memset(&(var), 0, sizeof(var))
/* Free+zero a 'struct passwd' */
@@ -16,6 +29,7 @@
free((user).pw_dir); \
free((user).pw_shell); \
ZERO(user); \
+ (user).pw_uid = UID_INVALID; \
}))
/** Returns 0 on error, or the UID on success. Only handles "normal
diff --git a/nslcd/hackers_watch.c b/nslcd/hackers_watch.c
index 7289c59..e2222fc 100644
--- a/nslcd/hackers_watch.c
+++ b/nslcd/hackers_watch.c
@@ -26,6 +26,7 @@
#include "common/inotify_helpers.h"
#include "hackers_parse.h"
#include "hackers_watch.h"
+#include "log.h"
#define EVENT_FILE_IS(event, str) \
(((event)->len == sizeof(str)) && (strcmp((event)->name, str) == 0))
@@ -44,17 +45,6 @@
} \
} while(0)
-#define REALLOC(ptr, size) \
- (__extension__ ({ \
- errno = 0; \
- void *ret = realloc(ptr, size); \
- if (ret == (ptr)) { \
- error(0, errno, "could not (re)allocate memory"); \
- goto error; \
- }; \
- ret; \
- }))
-
#define WATCH_HOMEDIR(session, i) \
do { \
session->in_user_wds[i] = \
@@ -64,18 +54,85 @@
if (session->in_user_wds[i] < 0) { \
error(0, errno, "could not watch: %s", \
session->users[i].pw_dir); \
- goto error; \
+ /* don't goto error, it OK here */ \
} \
} while(0)
+struct session *
+hackers_session_allocate() {
+ int err = 0;
+ struct session *sess;
+ sess = MALLOC(sizeof(struct session));
+ if ((err = pthread_rwlock_init(&(sess->lock), NULL)) != 0) {
+ error(0, err, "could not initialize session rwlock");
+ goto error;
+ }
+ sess->cnt = 0;
+ sess->users = NULL;
+ sess->yamldir = NULL;
+ sess->in_user_wds = NULL;
+ sess->in_fd = -1;
+ sess->in_wd_home = -1;
+ sess->in_wd_yaml = -1;
+ return sess;
+ error:
+ return NULL;
+}
+
+static
+int
+hackers_session_resize(struct session *sess, size_t num_users) {
+ log_log(LOG_DEBUG, "resizing session to %zu users", num_users);
+
+ if (num_users <= sess->cnt)
+ return 0;
+
+ sess->users =
+ REALLOC(sess->users , num_users * sizeof(sess->users[0]));
+ sess->in_user_wds =
+ REALLOC(sess->in_user_wds, num_users * sizeof(sess->in_user_wds[0]));
+
+ for (size_t i = sess->cnt; i < num_users; i++) {
+ ZERO(sess->users[i]);
+ sess->users[i].pw_uid = UID_INVALID;
+ sess->in_user_wds[i] = -1;
+ }
+ sess->cnt = num_users;
+
+ return 0;
+ error:
+ return -1;
+}
+
+/* does NOT mess with the lock */
+static
+void
+hackers_session_close(struct session *sess) {
+ log_log(LOG_DEBUG, "closing session");
+
+ for (size_t i = 0; i < sess->cnt; i++) {
+ PASSWD_FREE(sess->users[i]);
+ }
+ free(sess->users); sess->users = NULL;
+ sess->cnt = 0;
+
+ free(sess->yamldir); sess->yamldir = NULL;
+ free(sess->in_user_wds); sess->in_user_wds = NULL;
+ close(sess->in_fd); sess->in_fd = -1;
+ sess->in_wd_home = -1;
+ sess->in_wd_yaml = -1;
+}
+
int
-hackers_init(const char *yamldir, struct session *sess) {
+hackers_session_open(struct session *sess, const char *yamldir) {
+ log_log(LOG_DEBUG, "opening session at `%s'", yamldir);
char *glob_pattern;
glob_t glob_results;
char *filename;
+ hackers_session_close(sess);
ASSERT((sess->yamldir = strdup(yamldir)) != NULL);
- ASSERT((errno = pthread_rwlock_init(&(sess->lock), NULL)) >= 0);
+
ASSERT((sess->in_fd = inotify_init()) >= 0);
ASSERT((sess->in_wd_yaml = inotify_add_watch(sess->in_fd, yamldir, EVENT_CHILD_ANY)) >= 0);
ASSERT((sess->in_wd_home = inotify_add_watch(sess->in_fd, "/home" , EVENT_CHILD_ADD)) >= 0);
@@ -83,16 +140,16 @@ hackers_init(const char *yamldir, struct session *sess) {
ASSERT(asprintf(&glob_pattern, "%s/*.yml", yamldir) > 0);
ASSERT(glob(glob_pattern, 0, NULL, &glob_results) == 0);
free(glob_pattern);
-
- sess->cnt = glob_results.gl_pathc - glob_results.gl_offs;
- ASSERT((sess->users = calloc(sess->cnt, sizeof(struct passwd))) != NULL);
- ASSERT((sess->in_user_wds = calloc(sess->cnt, sizeof(int))) != NULL);
+ ASSERT(hackers_session_resize(sess, glob_results.gl_pathc - glob_results.gl_offs)==0);
for (size_t i = 0; i < sess->cnt; i++) {
filename = glob_results.gl_pathv[glob_results.gl_offs+i];
+ log_log(LOG_DEBUG, "loading yaml file: %s", filename);
if (load_user_yaml(filename, &(sess->users[i]))==0) {
+ log_log(LOG_DEBUG, "... and watching homedir");
WATCH_HOMEDIR(sess, i);
} else {
+ log_log(LOG_DEBUG, "... error");
sess->users[i].pw_uid = UID_INVALID;
sess->in_user_wds[i] = -1;
}
@@ -101,7 +158,9 @@ hackers_init(const char *yamldir, struct session *sess) {
globfree(&glob_results);
return 0;
+
error:
+ hackers_session_close(sess);
return -1;
}
@@ -121,20 +180,17 @@ worker_watch_homedirs(struct session *sess) {
}
}
pthread_rwlock_unlock(&(sess->lock));
- return;
- error:
- exit(1);
}
static
-void
+int
worker_handle_add_yaml(struct session *sess, struct passwd *newdata) {
/* We have to first see if this is for an existing UID, then
* if it's not, we need to find an empty slot, potentially
* realloc()ing the array.
*/
- pthread_rwlock_wrlock(&(sess->lock));
ssize_t spot = -1;
+ pthread_rwlock_wrlock(&(sess->lock));
for (size_t i = 0; i < sess->cnt; i++) {
if (spot < 0 && sess->users[i].pw_uid == UID_INVALID) {
spot = i;
@@ -146,18 +202,17 @@ worker_handle_add_yaml(struct session *sess, struct passwd *newdata) {
}
if (spot < 0) {
/* must grow the array */
- spot = sess->cnt++;
- sess->users = REALLOC(sess->users , sess->cnt * sizeof(struct passwd));
- sess->in_user_wds = REALLOC(sess->in_user_wds, sess->cnt * sizeof(int));
- ZERO(sess->users[spot]);
+ if (hackers_session_resize(sess, sess->cnt+1) != 0)
+ goto error;
} else if (sess->users[spot].pw_uid != UID_INVALID) {
PASSWD_FREE(sess->users[spot]);
}
sess->users[spot] = *newdata;
pthread_rwlock_unlock(&(sess->lock));
- return;
+ return 0;
error:
- exit(1);
+ pthread_rwlock_unlock(&(sess->lock));
+ return -1;
}
static
@@ -175,7 +230,7 @@ worker_handle_del_yaml(struct session *sess, uid_t uid) {
}
int
-hackers_worker(struct session *sess) {
+hackers_session_worker(struct session *sess) {
if (chdir(sess->yamldir) < 0)
return -1;
for (INOTIFY_ITERATOR(sess->in_fd, event)) {
@@ -185,7 +240,8 @@ hackers_worker(struct session *sess) {
struct passwd user; ZERO(user);
if (load_user_yaml(event->name, &user)==0) {
/* User added/updated */
- worker_handle_add_yaml(sess, &user);
+ if (worker_handle_add_yaml(sess, &user) !=0)
+ return -1;
} else if (user.pw_uid != UID_INVALID) {
/* User became invalid */
worker_handle_del_yaml(sess,
@@ -193,7 +249,7 @@ hackers_worker(struct session *sess) {
}
} else if (event->mask & EVENT_CHILD_DEL) {
uid_t uid = filename2uid(event->name);
- if (uid > 0) {
+ if (uid != UID_INVALID) {
worker_handle_del_yaml(sess, uid);
}
}
diff --git a/nslcd/hackers_watch.h b/nslcd/hackers_watch.h
index 91e6319..8c7a297 100644
--- a/nslcd/hackers_watch.h
+++ b/nslcd/hackers_watch.h
@@ -3,7 +3,8 @@
#include "hackers.h"
-int hackers_init(const char *yamldir, struct session *session);
-int hackers_worker(struct session *session);
+struct session * hackers_session_allocate();
+int hackers_session_open(struct session *, const char *yamldir);
+int hackers_session_worker(struct session *);
#endif
diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c
index 4a3fd26..d7891e6 100644
--- a/nslcd/nslcd.c
+++ b/nslcd/nslcd.c
@@ -255,9 +255,9 @@ static void handleconnection(int sock, struct session *session)
return;
}
/* handle request */
- hackers_session_messup(session);
+ session_messup(session);
dispatch(fp, action, session, uid);
- hackers_session_cleanup(session);
+ session_cleanup(session);
(void)tio_close(fp);
return;
@@ -282,7 +282,7 @@ static void install_sighandler(int signum, void (*handler) (int))
static void worker_cleanup(void *arg)
{
struct session *session = (struct session *)arg;
- hackers_session_close(session);
+ session_close(session);
}
static void *worker(void *_sess)
@@ -294,14 +294,14 @@ static void *worker(void *_sess)
socklen_t alen;
fd_set fds;
/* create a new session */
- /*session = hackers_session_create();*/
+ /*session = session_create();*/
/* clean up the session if we're done */
pthread_cleanup_push(worker_cleanup, session);
/* start waiting for incoming connections */
while (1)
{
/* perform any maintenance on the session */
- hackers_session_check(session);
+ session_check(session);
/* set up the set of fds to wait on */
FD_ZERO(&fds);
FD_SET(nslcd_serversocket, &fds);
@@ -466,7 +466,7 @@ int main(int argc, char *argv[])
log_log(LOG_CRIT, "main(): malloc() failed to allocate memory");
exit(EXIT_FAILURE);
}
- struct session *session = hackers_session_create(&nslcd_threads[0], nslcd_cfg->yamldir);
+ struct session *session = session_create(nslcd_cfg, &nslcd_threads[0]);
for (i = 1; i < nslcd_cfg->threads; i++)
{
if (pthread_create(&nslcd_threads[i], NULL, worker, (void*)session))
@@ -495,7 +495,7 @@ int main(int argc, char *argv[])
{
log_log(LOG_INFO, "caught signal %s (%d), refresh retries",
signame(nslcd_receivedsignal), nslcd_receivedsignal);
- /* TODO: force reload yamldir */
+ session_refresh(session, nslcd_cfg);
nslcd_receivedsignal = 0;
}
}