summaryrefslogtreecommitdiff
path: root/server/nss
diff options
context:
space:
mode:
Diffstat (limited to 'server/nss')
-rw-r--r--server/nss/nsssrv.c11
-rw-r--r--server/nss/nsssrv.h17
-rw-r--r--server/nss/nsssrv_cmd.c204
-rw-r--r--server/nss/nsssrv_dp.c231
-rw-r--r--server/nss/nsssrv_ldb.c57
-rw-r--r--server/nss/nsssrv_ldb.h2
-rw-r--r--server/nss/nsssrv_packet.c2
7 files changed, 404 insertions, 120 deletions
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index 32ab43db..bb5443f4 100644
--- a/server/nss/nsssrv.c
+++ b/server/nss/nsssrv.c
@@ -132,7 +132,9 @@ static void client_recv(struct event_context *ev, struct cli_ctx *cctx)
DEBUG(0, ("Failed to execute request, aborting client!\n"));
talloc_free(cctx);
}
- break;
+ /* past this point cctx can be freed at any time by callbacks
+ * in case of error, do not use it */
+ return;
case EAGAIN:
/* need to read still some data, loop again */
@@ -220,6 +222,9 @@ static int service_identity(DBusMessage *message, void *data, DBusMessage **r)
DBusMessage *reply;
dbus_bool_t ret;
+ DEBUG(4,("Sending ID reply: (%s,%d)\n",
+ name, version));
+
reply = dbus_message_new_method_return(message);
ret = dbus_message_append_args(reply,
DBUS_TYPE_STRING, &name,
@@ -405,7 +410,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = nss_cmd_init(nctx);
+ ret = nss_dp_init(nctx);
if (ret != EOK) {
DEBUG(0, ("fatal error setting up backend connector\n"));
return ret;
@@ -424,6 +429,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
+ DEBUG(1, ("NSS Initialization complete\n"));
+
return EOK;
}
diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h
index 90dda15e..00508a8e 100644
--- a/server/nss/nsssrv.h
+++ b/server/nss/nsssrv.h
@@ -28,6 +28,7 @@
#include "tevent.h"
#include "ldb.h"
#include "../nss_client/sss_nss.h"
+#include "dbus/dbus.h"
#define NSS_SBUS_SERVICE_VERSION 0x0001
#define NSS_SBUS_SERVICE_NAME "nss"
@@ -82,7 +83,21 @@ void nss_packet_get_body(struct nss_packet *packet, uint8_t **body, size_t *blen
void nss_packet_set_error(struct nss_packet *packet, int error);
/* from nsssrv_cmd.c */
-int nss_cmd_init(struct nss_ctx *nctx);
int nss_cmd_execute(struct cli_ctx *cctx);
+/* from nsssrv_dp.c */
+#define NSS_DP_USER 1
+#define NSS_DP_GROUP 2
+
+int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx,
+ DBusPendingCallNotifyFunction callback,
+ void *callback_ctx,
+ const char *domain, int type,
+ const char *opt_name, uint32_t opt_id);
+int nss_dp_get_reply(DBusPendingCall *pending,
+ dbus_uint16_t *err_maj,
+ dbus_uint32_t *err_min,
+ char **err_msg);
+int nss_dp_init(struct nss_ctx *nctx);
+
#endif /* __NSSSRV_H__ */
diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c
index a345c3a3..6838466e 100644
--- a/server/nss/nsssrv_cmd.c
+++ b/server/nss/nsssrv_cmd.c
@@ -24,10 +24,11 @@
#include "util/util.h"
#include "nss/nsssrv.h"
#include "nss/nsssrv_ldb.h"
-#include "providers/data_provider.h"
struct nss_cmd_ctx {
struct cli_ctx *cctx;
+ const char *name;
+ uint64_t id;
};
struct getent_ctx {
@@ -52,6 +53,31 @@ static void nss_cmd_done(struct nss_cmd_ctx *nctx)
talloc_free(nctx);
}
+static int nss_cmd_send_error(struct nss_cmd_ctx *nctx, int err)
+{
+ struct cli_ctx *cctx = nctx->cctx;
+ int ret;
+
+ /* create response packet */
+ ret = nss_packet_new(cctx->creq, 0,
+ nss_packet_get_cmd(cctx->creq->in),
+ &cctx->creq->out);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ nss_packet_set_error(cctx->creq->out, err);
+
+ nss_cmd_done(nctx);
+ return EOK;
+}
+
+#define NSS_CMD_FATAL_ERROR(cctx) do { \
+ DEBUG(1,("Fatal error, killing connection!")); \
+ talloc_free(cctx); \
+ return; \
+} while(0)
+
static int nss_cmd_get_version(struct cli_ctx *cctx)
{
struct nss_cmd_ctx *nctx;
@@ -159,8 +185,8 @@ done:
return EOK;
}
-static int nss_cmd_getpw_callback(void *ptr, int status,
- struct ldb_result *res)
+static void nss_cmd_getpw_callback(void *ptr, int status,
+ struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
struct cli_ctx *cctx = nctx->cctx;
@@ -173,7 +199,7 @@ static int nss_cmd_getpw_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -192,7 +218,7 @@ static int nss_cmd_getpw_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
nss_packet_get_body(cctx->creq->out, &body, &blen);
((uint32_t *)body)[0] = 0; /* 0 results */
@@ -205,13 +231,33 @@ static int nss_cmd_getpw_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
-static int nss_dispatch_getpwnam(struct cli_ctx *cctx)
+static void nss_cmd_getpwnam_callback(DBusPendingCall *pending, void *ptr)
{
+ struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
+ struct cli_ctx *cctx = nctx->cctx;
+ dbus_uint16_t cli_err_maj;
+ dbus_uint32_t cli_err_min;
+ char *cli_err_msg;
+ int ret;
- return EOK;
+ ret = nss_dp_get_reply(pending, &cli_err_maj, &cli_err_min, &cli_err_msg);
+ if (ret != EOK) {
+ DEBUG(2, ("Unable to get information from Data Provider\n"
+ "Will try to return what we have in cache\n"));
+ }
+
+ ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->nctx->lctx,
+ nctx->name, nss_cmd_getpw_callback, nctx);
+ if (ret != EOK) {
+ DEBUG(1, ("Failed to make request to our cache!"));
+
+ ret = nss_cmd_send_error(nctx, ret);
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ }
}
static int nss_cmd_getpwnam(struct cli_ctx *cctx)
@@ -220,24 +266,34 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
uint8_t *body;
size_t blen;
int ret;
- const char *name;
+
+ nctx = talloc(cctx, struct nss_cmd_ctx);
+ if (!nctx) {
+ return ENOMEM;
+ }
+ nctx->cctx = cctx;
/* get user name to query */
nss_packet_get_body(cctx->creq->in, &body, &blen);
- name = (const char *)body;
+ nctx->name = (const char *)body;
/* if not terminated fail */
- if (name[blen -1] != '\0') {
+ if (nctx->name[blen -1] != '\0') {
+ talloc_free(nctx);
return EINVAL;
}
- nctx = talloc(cctx, struct nss_cmd_ctx);
- if (!nctx) {
- return ENOMEM;
- }
- nctx->cctx = cctx;
+ DEBUG(4, ("Requesting info for [%s]\n", nctx->name));
- ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->nctx->lctx, name,
- nss_cmd_getpw_callback, nctx);
+ /* FIXME: Just ask all backends for now, until Steve provides for name
+ * parsing code */
+
+ ret = nss_dp_send_acct_req(cctx->nctx, nctx,
+ nss_cmd_getpwnam_callback, nctx,
+ "*", NSS_DP_USER, nctx->name, 0);
+ if (ret != EOK) {
+ talloc_free(nctx);
+ return ret;
+ }
return ret;
}
@@ -259,6 +315,8 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
uid = *((uint64_t *)body);
+ DEBUG(4, ("Requesting info for [%lu]\n", uid));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -282,7 +340,7 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
* even if the data is still being fetched
* - make getpwent() wait on the mutex
*/
-static int nss_cmd_setpwent_callback(void *ptr, int status,
+static void nss_cmd_setpwent_callback(void *ptr, int status,
struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
@@ -295,7 +353,7 @@ static int nss_cmd_setpwent_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -307,7 +365,6 @@ static int nss_cmd_setpwent_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_setpwent(struct cli_ctx *cctx)
@@ -316,6 +373,8 @@ static int nss_cmd_setpwent(struct cli_ctx *cctx)
struct getent_ctx *gctx;
int ret;
+ DEBUG(4, ("Requesting info for all accounts\n"));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -359,8 +418,8 @@ static int nss_cmd_retpwent(struct cli_ctx *cctx, int num)
/* used only if a process calls getpwent() without first calling setpwent()
* in this case we basically trigger an implicit setpwent() */
-static int nss_cmd_getpwent_callback(void *ptr, int status,
- struct ldb_result *res)
+static void nss_cmd_getpwent_callback(void *ptr, int status,
+ struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
struct cli_ctx *cctx = nctx->cctx;
@@ -373,7 +432,7 @@ static int nss_cmd_getpwent_callback(void *ptr, int status,
/* get max num of entries to return in one call */
nss_packet_get_body(cctx->creq->in, &body, &blen);
if (blen != sizeof(uint32_t)) {
- return EINVAL;
+ NSS_CMD_FATAL_ERROR(cctx);
}
num = *((uint32_t *)body);
@@ -382,7 +441,7 @@ static int nss_cmd_getpwent_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -397,7 +456,6 @@ static int nss_cmd_getpwent_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_getpwent(struct cli_ctx *cctx)
@@ -409,6 +467,8 @@ static int nss_cmd_getpwent(struct cli_ctx *cctx)
uint32_t num;
int ret;
+ DEBUG(4, ("Requesting info for all accounts\n"));
+
/* get max num of entries to return in one call */
nss_packet_get_body(cctx->creq->in, &body, &blen);
if (blen != sizeof(uint32_t)) {
@@ -458,6 +518,8 @@ static int nss_cmd_endpwent(struct cli_ctx *cctx)
struct nss_cmd_ctx *nctx;
int ret;
+ DEBUG(4, ("Terminating request info for all accounts\n"));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -580,8 +642,8 @@ done:
return EOK;
}
-static int nss_cmd_getgr_callback(void *ptr, int status,
- struct ldb_result *res)
+static void nss_cmd_getgr_callback(void *ptr, int status,
+ struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
struct cli_ctx *cctx = nctx->cctx;
@@ -594,7 +656,7 @@ static int nss_cmd_getgr_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -609,7 +671,7 @@ static int nss_cmd_getgr_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
nss_packet_get_body(cctx->creq->out, &body, &blen);
((uint32_t *)body)[0] = 0; /* 0 results */
@@ -622,7 +684,6 @@ static int nss_cmd_getgr_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_getgrnam(struct cli_ctx *cctx)
@@ -641,6 +702,8 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
return EINVAL;
}
+ DEBUG(4, ("Requesting info for [%s]\n", name));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -670,6 +733,8 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
gid = *((uint64_t *)body);
+ DEBUG(4, ("Requesting info for [%lu]\n", gid));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -693,7 +758,7 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
* even if the data is still being fetched
* - make getpwent() wait on the mutex
*/
-static int nss_cmd_setgrent_callback(void *ptr, int status,
+static void nss_cmd_setgrent_callback(void *ptr, int status,
struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
@@ -706,7 +771,7 @@ static int nss_cmd_setgrent_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -718,7 +783,6 @@ static int nss_cmd_setgrent_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_setgrent(struct cli_ctx *cctx)
@@ -727,6 +791,8 @@ static int nss_cmd_setgrent(struct cli_ctx *cctx)
struct getent_ctx *gctx;
int ret;
+ DEBUG(4, ("Requesting info for all groups\n"));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -770,7 +836,7 @@ static int nss_cmd_retgrent(struct cli_ctx *cctx, int num)
/* used only if a process calls getpwent() without first calling setpwent()
* in this case we basically trigger an implicit setpwent() */
-static int nss_cmd_getgrent_callback(void *ptr, int status,
+static void nss_cmd_getgrent_callback(void *ptr, int status,
struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
@@ -784,7 +850,10 @@ static int nss_cmd_getgrent_callback(void *ptr, int status,
/* get max num of entries to return in one call */
nss_packet_get_body(cctx->creq->in, &body, &blen);
if (blen != sizeof(uint32_t)) {
- return EINVAL;
+ ret = nss_cmd_send_error(nctx, EIO);
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
}
num = *((uint32_t *)body);
@@ -793,7 +862,7 @@ static int nss_cmd_getgrent_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -808,7 +877,6 @@ static int nss_cmd_getgrent_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_getgrent(struct cli_ctx *cctx)
@@ -820,6 +888,8 @@ static int nss_cmd_getgrent(struct cli_ctx *cctx)
uint32_t num;
int ret;
+ DEBUG(4, ("Requesting info for all groups\n"));
+
/* get max num of entries to return in one call */
nss_packet_get_body(cctx->creq->in, &body, &blen);
if (blen != sizeof(uint32_t)) {
@@ -869,6 +939,8 @@ static int nss_cmd_endgrent(struct cli_ctx *cctx)
struct nss_cmd_ctx *nctx;
int ret;
+ DEBUG(4, ("Terminating request info for all groups\n"));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -893,7 +965,7 @@ done:
return EOK;
}
-static int nss_cmd_initgr_callback(void *ptr, int status,
+static void nss_cmd_initgr_callback(void *ptr, int status,
struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
@@ -910,7 +982,7 @@ static int nss_cmd_initgr_callback(void *ptr, int status,
nss_packet_get_cmd(cctx->creq->in),
&cctx->creq->out);
if (ret != EOK) {
- return ret;
+ NSS_CMD_FATAL_ERROR(cctx);
}
if (status != LDB_SUCCESS) {
@@ -944,7 +1016,6 @@ static int nss_cmd_initgr_callback(void *ptr, int status,
done:
nss_cmd_done(nctx);
- return EOK;
}
static int nss_cmd_initgroups(struct cli_ctx *cctx)
@@ -963,6 +1034,8 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
return EINVAL;
}
+ DEBUG(4, ("Requesting groups for [%s]\n", name));
+
nctx = talloc(cctx, struct nss_cmd_ctx);
if (!nctx) {
return ENOMEM;
@@ -1007,52 +1080,3 @@ int nss_cmd_execute(struct cli_ctx *cctx)
return EINVAL;
}
-static int cmd_identity(DBusMessage *message, void *data, DBusMessage **r)
-{
- dbus_uint16_t version = DATA_PROVIDER_VERSION;
- dbus_uint16_t clitype = DP_CLI_FRONTEND;
- const char *cliname = "NSS";
- const char *nullname = "";
- DBusMessage *reply;
- dbus_bool_t ret;
-
- DEBUG(4,("Sending ID reply: (%d,%d,%s)\n",
- clitype, version, cliname));
-
- reply = dbus_message_new_method_return(message);
- ret = dbus_message_append_args(reply,
- DBUS_TYPE_UINT16, &clitype,
- DBUS_TYPE_UINT16, &version,
- DBUS_TYPE_STRING, &cliname,
- DBUS_TYPE_STRING, &nullname,
- DBUS_TYPE_INVALID);
- if (!ret) {
- return EIO;
- }
-
- *r = reply;
- return EOK;
-}
-
-struct sbus_method nss_dp_methods[] = {
- { DP_CLI_METHOD_IDENTITY, cmd_identity },
- { NULL, NULL }
-};
-
-int nss_cmd_init(struct nss_ctx *nctx)
-{
- int ret;
-
- /* Set up SBUS connection to the data provider */
- ret = dp_sbus_cli_init(nctx, nctx->ev, nctx->cdb,
- nss_dp_methods, &nctx->dp_ctx);
- if (ret != EOK) {
- return ret;
- }
-
- /* attach context to the connection */
- sbus_conn_set_private_data(nctx->dp_ctx->scon_ctx, nctx);
-
- return EOK;
-}
-
diff --git a/server/nss/nsssrv_dp.c b/server/nss/nsssrv_dp.c
new file mode 100644
index 00000000..f865e62b
--- /dev/null
+++ b/server/nss/nsssrv_dp.c
@@ -0,0 +1,231 @@
+/*
+ SSSD
+
+ NSS Responder - Data Provider Interfaces
+
+ Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "nss/nsssrv.h"
+#include "providers/data_provider.h"
+
+int nss_dp_send_acct_req(struct nss_ctx *nctx, TALLOC_CTX *memctx,
+ DBusPendingCallNotifyFunction callback,
+ void *callback_ctx,
+ const char *domain, int type,
+ const char *opt_name, uint32_t opt_id)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending_reply;
+ DBusConnection *conn;
+ DBusError dbus_error;
+ dbus_bool_t ret;
+ uint32_t be_type;
+ const char *attrs = "core";
+ char *filter;
+
+ /* either, or, not both */
+ if (opt_name && opt_id) {
+ return EINVAL;
+ }
+
+ switch (type) {
+ case NSS_DP_USER:
+ be_type = BE_REQ_USER;
+ break;
+ case NSS_DP_GROUP:
+ be_type = BE_REQ_GROUP;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ if (opt_name) {
+ filter = talloc_asprintf(memctx, "name=%s", opt_name);
+ } else if (opt_id) {
+ filter = talloc_asprintf(memctx, "idnumber=%u", opt_id);
+ } else {
+ filter = talloc_strdup(memctx, "name=*");
+ }
+ if (!filter) {
+ talloc_free(nctx);
+ return ENOMEM;
+ }
+
+ conn = sbus_get_connection(nctx->dp_ctx->scon_ctx);
+ dbus_error_init(&dbus_error);
+
+ /* create the message */
+ msg = dbus_message_new_method_call(NULL,
+ DP_CLI_PATH,
+ DP_CLI_INTERFACE,
+ DP_SRV_METHOD_GETACCTINFO);
+ if (msg == NULL) {
+ DEBUG(0,("Out of memory?!\n"));
+ return ENOMEM;
+ }
+
+ DEBUG(4, ("Sending request for [%s][%u][%s][%s]\n",
+ domain, be_type, attrs, filter));
+
+ ret = dbus_message_append_args(msg,
+ DBUS_TYPE_STRING, &domain,
+ DBUS_TYPE_UINT32, &be_type,
+ DBUS_TYPE_STRING, &attrs,
+ DBUS_TYPE_STRING, &filter,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Failed to build message\n"));
+ return EIO;
+ }
+
+ ret = dbus_connection_send_with_reply(conn, msg, &pending_reply,
+ 600000 /* TODO: set timeout */);
+ if (!ret) {
+ /*
+ * Critical Failure
+ * We can't communicate on this connection
+ * We'll drop it using the default destructor.
+ */
+ DEBUG(0, ("D-BUS send failed.\n"));
+ dbus_message_unref(msg);
+ return EIO;
+ }
+
+ /* Set up the reply handler */
+ dbus_pending_call_set_notify(pending_reply, callback, callback_ctx, NULL);
+ dbus_message_unref(msg);
+
+ return EOK;
+}
+
+int nss_dp_get_reply(DBusPendingCall *pending,
+ dbus_uint16_t *err_maj,
+ dbus_uint32_t *err_min,
+ char **err_msg)
+{
+ DBusMessage *reply;
+ DBusError dbus_error;
+ dbus_bool_t ret;
+ int type;
+ int err = EOK;
+
+ dbus_error_init(&dbus_error);
+
+ reply = dbus_pending_call_steal_reply(pending);
+ if (!reply) {
+ /* reply should never be null. This function shouldn't be called
+ * until reply is valid or timeout has occurred. If reply is NULL
+ * here, something is seriously wrong and we should bail out.
+ */
+ DEBUG(0, ("Severe error. A reply callback was called but no reply was received and no timeout occurred\n"));
+
+ /* FIXME: Destroy this connection ? */
+ err = EIO;
+ goto done;
+ }
+
+ type = dbus_message_get_type(reply);
+ switch (type) {
+ case DBUS_MESSAGE_TYPE_METHOD_RETURN:
+ ret = dbus_message_get_args(reply, &dbus_error,
+ DBUS_TYPE_UINT16, err_maj,
+ DBUS_TYPE_UINT32, err_min,
+ DBUS_TYPE_STRING, err_msg,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ DEBUG(1,("Filed to parse message\n"));
+ /* FIXME: Destroy this connection ? */
+ err = EIO;
+ goto done;
+ }
+
+ break;
+
+ case DBUS_MESSAGE_TYPE_ERROR:
+ DEBUG(0,("The Data Provider returned an error [%s]\n",
+ dbus_message_get_error_name(reply)));
+ /* Falling through to default intentionally*/
+ default:
+ /*
+ * Timeout or other error occurred or something
+ * unexpected happened.
+ * It doesn't matter which, because either way we
+ * know that this connection isn't trustworthy.
+ * We'll destroy it now.
+ */
+
+ /* FIXME: Destroy this connection ? */
+ err = EIO;
+ }
+
+done:
+ dbus_pending_call_unref(pending);
+ dbus_message_unref(reply);
+
+ return err;
+}
+
+static int nss_dp_identity(DBusMessage *message, void *data, DBusMessage **r)
+{
+ dbus_uint16_t version = DATA_PROVIDER_VERSION;
+ dbus_uint16_t clitype = DP_CLI_FRONTEND;
+ const char *cliname = "NSS";
+ const char *nullname = "";
+ DBusMessage *reply;
+ dbus_bool_t ret;
+
+ DEBUG(4,("Sending ID reply: (%d,%d,%s)\n",
+ clitype, version, cliname));
+
+ reply = dbus_message_new_method_return(message);
+ ret = dbus_message_append_args(reply,
+ DBUS_TYPE_UINT16, &clitype,
+ DBUS_TYPE_UINT16, &version,
+ DBUS_TYPE_STRING, &cliname,
+ DBUS_TYPE_STRING, &nullname,
+ DBUS_TYPE_INVALID);
+ if (!ret) {
+ return EIO;
+ }
+
+ *r = reply;
+ return EOK;
+}
+
+struct sbus_method nss_dp_methods[] = {
+ { DP_CLI_METHOD_IDENTITY, nss_dp_identity },
+ { NULL, NULL }
+};
+
+int nss_dp_init(struct nss_ctx *nctx)
+{
+ int ret;
+
+ /* Set up SBUS connection to the data provider */
+ ret = dp_sbus_cli_init(nctx, nctx->ev, nctx->cdb,
+ nss_dp_methods, &nctx->dp_ctx);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ /* attach context to the connection */
+ sbus_conn_set_private_data(nctx->dp_ctx->scon_ctx, nctx);
+
+ return EOK;
+}
+
diff --git a/server/nss/nsssrv_ldb.c b/server/nss/nsssrv_ldb.c
index 8ad908a4..98fcb76c 100644
--- a/server/nss/nsssrv_ldb.c
+++ b/server/nss/nsssrv_ldb.c
@@ -40,15 +40,14 @@ static int nss_ldb_error_to_errno(int lerr)
return EIO;
}
-static int request_error(struct nss_ldb_search_ctx *sctx, int ldb_error)
+static void request_error(struct nss_ldb_search_ctx *sctx, int ldb_error)
{
sctx->callback(sctx->ptr, nss_ldb_error_to_errno(ldb_error), sctx->res);
- return ldb_error;
}
-static int request_done(struct nss_ldb_search_ctx *sctx)
+static void request_done(struct nss_ldb_search_ctx *sctx)
{
- return sctx->callback(sctx->ptr, EOK, sctx->res);
+ sctx->callback(sctx->ptr, EOK, sctx->res);
}
static int get_gen_callback(struct ldb_request *req,
@@ -62,10 +61,12 @@ static int get_gen_callback(struct ldb_request *req,
res = sctx->res;
if (!ares) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (ares->error != LDB_SUCCESS) {
- return request_error(sctx, ares->error);
+ request_error(sctx, ares->error);
+ return ares->error;
}
switch (ares->type) {
@@ -74,7 +75,8 @@ static int get_gen_callback(struct ldb_request *req,
struct ldb_message *,
res->count + 2);
if (!res->msgs) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
res->msgs[res->count + 1] = NULL;
@@ -92,7 +94,8 @@ static int get_gen_callback(struct ldb_request *req,
res->refs = talloc_realloc(res, res->refs, char *, n + 2);
if (! res->refs) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
res->refs[n] = talloc_steal(res->refs, ares->referral);
@@ -103,7 +106,8 @@ static int get_gen_callback(struct ldb_request *req,
res->controls = talloc_steal(res, ares->controls);
/* this is the last message, and means the request is done */
- return request_done(sctx);
+ request_done(sctx);
+ return LDB_SUCCESS;
}
talloc_free(ares);
@@ -230,8 +234,7 @@ struct get_mem_ctx {
int num_grps;
};
-static int get_members(void *ptr, int status,
- struct ldb_result *res)
+static void get_members(void *ptr, int status, struct ldb_result *res)
{
struct nss_ldb_ctx *ctx;
struct nss_ldb_search_ctx *sctx;
@@ -304,15 +307,13 @@ static int get_members(void *ptr, int status,
mem_sctx, get_gen_callback,
NULL);
if (ret != LDB_SUCCESS) {
- return request_error(gmctx->ret_sctx, ret);
+ return request_error(gmctx->ret_sctx, ret);
}
ret = ldb_request(ctx->ldb, req);
if (ret != LDB_SUCCESS) {
return request_error(gmctx->ret_sctx, ret);
}
-
- return LDB_SUCCESS;
}
static int get_grp_callback(struct ldb_request *req,
@@ -328,10 +329,12 @@ static int get_grp_callback(struct ldb_request *req,
res = sctx->res;
if (!ares) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (ares->error != LDB_SUCCESS) {
- return request_error(sctx, ares->error);
+ request_error(sctx, ares->error);
+ return ares->error;
}
switch (ares->type) {
@@ -340,7 +343,8 @@ static int get_grp_callback(struct ldb_request *req,
struct ldb_message *,
res->count + 2);
if (!res->msgs) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
res->msgs[res->count + 1] = NULL;
@@ -358,7 +362,8 @@ static int get_grp_callback(struct ldb_request *req,
res->refs = talloc_realloc(res, res->refs, char *, n + 2);
if (! res->refs) {
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
res->refs[n] = talloc_steal(res->refs, ares->referral);
@@ -370,7 +375,8 @@ static int get_grp_callback(struct ldb_request *req,
/* no results, return */
if (res->count == 0) {
- return request_done(sctx);
+ request_done(sctx);
+ return LDB_SUCCESS;
}
if (res->count > 0) {
struct get_mem_ctx *gmctx;
@@ -378,6 +384,7 @@ static int get_grp_callback(struct ldb_request *req,
gmctx = talloc_zero(req, struct get_mem_ctx);
if (!gmctx) {
request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
gmctx->ret_sctx = sctx;
gmctx->grps = talloc_steal(gmctx, res->msgs);
@@ -389,11 +396,13 @@ static int get_grp_callback(struct ldb_request *req,
* get_members() */
sctx = init_src_ctx(gmctx, ctx, get_members, gmctx);
- return get_members(sctx, LDB_SUCCESS, NULL);
+ get_members(sctx, LDB_SUCCESS, NULL);
+ return LDB_SUCCESS;
}
/* anything else is an error */
- return request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ request_error(sctx, LDB_ERR_OPERATIONS_ERROR);
+ return LDB_ERR_OPERATIONS_ERROR;
}
talloc_free(ares);
@@ -487,8 +496,8 @@ int nss_ldb_enumgrent(TALLOC_CTX *mem_ctx,
return grp_search(sctx, ctx, ctx->grent_filter);
}
-static int nss_ldb_initgr_search(void *ptr, int status,
- struct ldb_result *res)
+static void nss_ldb_initgr_search(void *ptr, int status,
+ struct ldb_result *res)
{
struct nss_ldb_ctx *ctx;
struct nss_ldb_search_ctx *sctx;
@@ -550,8 +559,6 @@ static int nss_ldb_initgr_search(void *ptr, int status,
if (ret != LDB_SUCCESS) {
return request_error(sctx, ret);
}
-
- return LDB_SUCCESS;
}
int nss_ldb_initgroups(TALLOC_CTX *mem_ctx,
diff --git a/server/nss/nsssrv_ldb.h b/server/nss/nsssrv_ldb.h
index c7a3c4d6..016f5a54 100644
--- a/server/nss/nsssrv_ldb.h
+++ b/server/nss/nsssrv_ldb.h
@@ -38,7 +38,7 @@ struct nss_ldb_ctx {
struct confdb_ctx;
-typedef int (*nss_ldb_callback_t)(void *, int, struct ldb_result *);
+typedef void (*nss_ldb_callback_t)(void *, int, struct ldb_result *);
int nss_ldb_init(TALLOC_CTX *mem_ctx,
struct event_context *ev,
diff --git a/server/nss/nsssrv_packet.c b/server/nss/nsssrv_packet.c
index 07cc2ff8..13e27f41 100644
--- a/server/nss/nsssrv_packet.c
+++ b/server/nss/nsssrv_packet.c
@@ -158,7 +158,7 @@ int nss_packet_recv(struct nss_packet *packet, int fd)
return EIO;
}
- if (packet->len > packet->memsize) {
+ if (*packet->len > packet->memsize) {
return EINVAL;
}