summaryrefslogtreecommitdiffstats
path: root/src/responder/nss
diff options
context:
space:
mode:
Diffstat (limited to 'src/responder/nss')
-rw-r--r--src/responder/nss/nsssrv_cmd.c75
-rw-r--r--src/responder/nss/nsssrv_netgroup.c14
-rw-r--r--src/responder/nss/nsssrv_private.h22
-rw-r--r--src/responder/nss/nsssrv_services.c27
4 files changed, 43 insertions, 95 deletions
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 1dff829ee..43ae947c5 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -77,31 +77,26 @@ int nss_cmd_done(struct nss_cmd_ctx *cmdctx, int ret)
/***************************
* Enumeration procedures *
***************************/
-
-errno_t setent_add_ref(TALLOC_CTX *memctx,
- struct getent_ctx *getent_ctx,
- struct tevent_req *req)
+struct tevent_req *nss_setent_get_req(struct getent_ctx *getent_ctx)
{
- struct setent_req_list *entry =
- talloc_zero(memctx, struct setent_req_list);
- if (!entry) {
- return ENOMEM;
- }
+ return setent_get_req(getent_ctx->reqs);
+}
- entry->req = req;
- entry->getent_ctx = getent_ctx;
- DLIST_ADD_END(getent_ctx->reqs, entry, struct setent_req_list *);
+errno_t nss_setent_add_ref(TALLOC_CTX *memctx,
+ struct getent_ctx *getent_ctx,
+ struct tevent_req *req)
+{
+ return setent_add_ref(memctx, getent_ctx, &getent_ctx->reqs, req);
+}
- talloc_set_destructor((TALLOC_CTX *)entry, setent_remove_ref);
- return EOK;
+void nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret)
+{
+ return setent_notify(getent_ctx->reqs, ret);
}
-int setent_remove_ref(TALLOC_CTX *ctx)
+void nss_setent_notify_done(struct getent_ctx *getent_ctx)
{
- struct setent_req_list *entry =
- talloc_get_type(ctx, struct setent_req_list);
- DLIST_REMOVE(entry->getent_ctx->reqs, entry);
- return 0;
+ return setent_notify_done(getent_ctx->reqs);
}
struct setent_ctx {
@@ -1246,7 +1241,7 @@ struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx,
* Register for notification when it's
* ready.
*/
- ret = setent_add_ref(state->client, state->nctx->pctx, req);
+ ret = nss_setent_add_ref(state->client, state->nctx->pctx, req);
if (ret != EOK) {
talloc_free(req);
return NULL;
@@ -1268,7 +1263,8 @@ struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx,
state->getent_ctx = nctx->pctx;
/* Add a callback reference for ourselves */
- setent_add_ref(state->client, state->nctx->pctx, req);
+ ret = nss_setent_add_ref(state->client, state->nctx->pctx, req);
+ if (ret) goto error;
/* ok, start the searches */
step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx);
@@ -1323,7 +1319,6 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx)
struct nss_ctx *nctx = step_ctx->nctx;
struct sysdb_ctx *sysdb;
struct ldb_result *res;
- struct setent_req_list *req;
struct timeval tv;
struct tevent_timer *te;
struct tevent_req *dpreq;
@@ -1434,13 +1429,7 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx)
}
/* Notify the waiting clients */
- while (nctx->pctx->reqs) {
- tevent_req_done(nctx->pctx->reqs->req);
- /* Freeing each entry in the list removes it from the dlist */
- req = nctx->pctx->reqs;
- nctx->pctx->reqs = nctx->pctx->reqs->next;
- talloc_free(req);
- }
+ setent_notify_done(nctx->pctx->reqs);
if (step_ctx->returned_to_mainloop) {
return EAGAIN;
@@ -1470,7 +1459,6 @@ static void nss_cmd_setpwent_dp_callback(uint16_t err_maj, uint32_t err_min,
{
struct setent_step_ctx *step_ctx =
talloc_get_type(ptr, struct setent_step_ctx);
- struct getent_ctx *pctx = step_ctx->nctx->pctx;
int ret;
if (err_maj) {
@@ -1483,11 +1471,7 @@ static void nss_cmd_setpwent_dp_callback(uint16_t err_maj, uint32_t err_min,
ret = nss_cmd_setpwent_step(step_ctx);
if (ret != EOK && ret != EAGAIN) {
/* Notify any waiting processes of failure */
- while(step_ctx->nctx->pctx->reqs) {
- tevent_req_error(pctx->reqs->req, ret);
- /* Freeing each entry in the list removes it from the dlist */
- talloc_free(pctx->reqs);
- }
+ nss_setent_notify_error(step_ctx->nctx->pctx, ret);
}
}
@@ -2555,7 +2539,7 @@ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx,
* Register for notification when it's
* ready.
*/
- ret = setent_add_ref(state->client, state->nctx->gctx, req);
+ ret = nss_setent_add_ref(state->client, state->nctx->gctx, req);
if (ret != EOK) {
talloc_free(req);
return NULL;
@@ -2577,7 +2561,8 @@ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx,
state->getent_ctx = nctx->gctx;
/* Add a callback reference for ourselves */
- setent_add_ref(state->client, state->nctx->gctx, req);
+ ret = nss_setent_add_ref(state->client, state->nctx->gctx, req);
+ if (ret) goto error;
/* ok, start the searches */
step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx);
@@ -2632,7 +2617,6 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx)
struct nss_ctx *nctx = step_ctx->nctx;
struct sysdb_ctx *sysdb;
struct ldb_result *res;
- struct setent_req_list *req;
struct timeval tv;
struct tevent_timer *te;
struct tevent_req *dpreq;
@@ -2741,13 +2725,7 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx)
}
/* Notify the waiting clients */
- while (nctx->gctx->reqs) {
- tevent_req_done(nctx->gctx->reqs->req);
- /* Freeing each entry in the list removes it from the dlist */
- req = nctx->gctx->reqs;
- nctx->gctx->reqs = nctx->gctx->reqs->next;
- talloc_free(req);
- }
+ setent_notify_done(nctx->gctx->reqs);
if (step_ctx->returned_to_mainloop) {
return EAGAIN;
@@ -2778,7 +2756,6 @@ static void nss_cmd_setgrent_dp_callback(uint16_t err_maj, uint32_t err_min,
{
struct setent_step_ctx *step_ctx =
talloc_get_type(ptr, struct setent_step_ctx);
- struct getent_ctx *gctx = step_ctx->nctx->gctx;
int ret;
if (err_maj) {
@@ -2791,11 +2768,7 @@ static void nss_cmd_setgrent_dp_callback(uint16_t err_maj, uint32_t err_min,
ret = nss_cmd_setgrent_step(step_ctx);
if (ret != EOK && ret != EAGAIN) {
/* Notify any waiting processes of failure */
- while(step_ctx->nctx->gctx->reqs) {
- tevent_req_error(gctx->reqs->req, ret);
- /* Freeing each entry in the list removes it from the dlist */
- talloc_free(gctx->reqs);
- }
+ nss_setent_notify_error(step_ctx->nctx->gctx, ret);
}
}
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 2b9707ab8..9943bca60 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -254,7 +254,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
/* Result object is still being constructed
* Register for notification when it's ready
*/
- ret = setent_add_ref(cmdctx->cctx, state->netgr, req);
+ ret = nss_setent_add_ref(cmdctx->cctx, state->netgr, req);
if (ret != EOK) {
goto error;
}
@@ -281,7 +281,7 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
state->netgr->lookup_table = nctx->netgroups;
/* Add a reference for ourselves */
- ret = setent_add_ref(cmdctx->cctx, state->netgr, req);
+ ret = nss_setent_add_ref(cmdctx->cctx, state->netgr, req);
if (ret != EOK) {
talloc_free(state->netgr);
goto error;
@@ -557,15 +557,7 @@ static void lookup_netgr_dp_callback(uint16_t err_maj, uint32_t err_min,
}
/* We have results to return */
- while(dctx->netgr->reqs) {
- if (ret == EOK) {
- tevent_req_done(dctx->netgr->reqs->req);
- } else {
- tevent_req_error(dctx->netgr->reqs->req, ret);
- }
- /* Freeing each entry in the list removes it from the dlist */
- talloc_free(dctx->netgr->reqs);
- }
+ nss_setent_notify_error(dctx->netgr, ret);
}
static void setnetgrent_result_timeout(struct tevent_context *ev,
diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h
index 876552fb9..0f581574a 100644
--- a/src/responder/nss/nsssrv_private.h
+++ b/src/responder/nss/nsssrv_private.h
@@ -45,14 +45,6 @@ struct dom_ctx {
struct ldb_result *res;
};
-struct setent_req_list {
- struct setent_req_list *prev;
- struct setent_req_list *next;
- struct getent_ctx *getent_ctx;
-
- struct tevent_req *req;
-};
-
struct getent_ctx {
struct dom_ctx *doms;
int num;
@@ -109,10 +101,16 @@ struct setent_step_ctx {
/* Finish the request */
int nss_cmd_done(struct nss_cmd_ctx *cmdctx, int ret);
-int setent_remove_ref(TALLOC_CTX *ctx);
-errno_t setent_add_ref(TALLOC_CTX *memctx,
- struct getent_ctx *getent_ctx,
- struct tevent_req *req);
+/* Respond with no entries */
+int fill_empty(struct sss_packet *packet);
+
+errno_t nss_setent_add_ref(TALLOC_CTX *memctx,
+ struct getent_ctx *getent_ctx,
+ struct tevent_req *req);
+struct tevent_req *nss_setent_get_req(struct getent_ctx *getent_ctx);
+
+void nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret);
+void nss_setent_notify_done(struct getent_ctx *getent_ctx);
errno_t check_cache(struct nss_dom_ctx *dctx,
struct nss_ctx *nctx,
diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c
index da37708b4..3ce3d0902 100644
--- a/src/responder/nss/nsssrv_services.c
+++ b/src/responder/nss/nsssrv_services.c
@@ -1215,7 +1215,7 @@ setservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx)
* Register for notification when it's
* ready.
*/
- ret = setent_add_ref(state, state->nctx->svcctx, req);
+ ret = nss_setent_add_ref(state, state->nctx->svcctx, req);
if (ret != EOK) goto immediate;
}
return req;
@@ -1252,7 +1252,10 @@ setservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx)
}
/* Add a callback reference for ourselves */
- setent_add_ref(state, state->nctx->svcctx, req);
+ ret = nss_setent_add_ref(state, state->nctx->svcctx, req);
+ if (ret != EOK) {
+ goto immediate;
+ }
/* ok, start the searches */
step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx);
@@ -1510,7 +1513,6 @@ setservent_finalize(struct setent_step_ctx *step_ctx)
struct resp_ctx *rctx = step_ctx->rctx;
struct timeval tv;
struct tevent_timer *te;
- struct setent_req_list *reql;
/* We've finished all our lookups
* The result object is now safe to read.
@@ -1530,24 +1532,7 @@ setservent_finalize(struct setent_step_ctx *step_ctx)
"Entries may become stale.\n"));
}
- /* Notify the waiting clients */
- while ((reql = nctx->svcctx->reqs)) {
- /* Each tevent_req_done() call will free
- * the request, removing it from the list.
- */
- tevent_req_done(reql->req);
-
- if (reql == nctx->svcctx->reqs) {
- /* The consumer failed to free the
- * request. Log a bug and continue.
- */
- DEBUG(SSSDBG_FATAL_FAILURE,
- ("BUG: a callback did not free its request. "
- "May leak memory\n"));
- /* Skip to the next since a memory leak is non-fatal */
- nctx->svcctx->reqs = nctx->svcctx->reqs->next;
- }
- }
+ nss_setent_notify_done(nctx->svcctx);
}
static void