summaryrefslogtreecommitdiffstats
path: root/server/responder/nss/nsssrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/responder/nss/nsssrv.c')
-rw-r--r--server/responder/nss/nsssrv.c373
1 files changed, 18 insertions, 355 deletions
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 979bd9688..f5afc22f0 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -49,7 +49,6 @@
static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn);
static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn);
static int service_reload(DBusMessage *message, struct sbus_conn_ctx *sconn);
-static int nss_init_domains(struct nss_ctx *nctx);
struct sbus_method nss_sbus_methods[] = {
{SERVICE_METHOD_IDENTITY, service_identity},
@@ -58,176 +57,6 @@ struct sbus_method nss_sbus_methods[] = {
{NULL, NULL}
};
-static void set_nonblocking(int fd)
-{
- unsigned v;
- v = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, v | O_NONBLOCK);
-}
-
-static void set_close_on_exec(int fd)
-{
- unsigned v;
- v = fcntl(fd, F_GETFD, 0);
- fcntl(fd, F_SETFD, v | FD_CLOEXEC);
-}
-
-static int client_destructor(struct cli_ctx *ctx)
-{
- if (ctx->cfd > 0) close(ctx->cfd);
- return 0;
-}
-
-static void client_send(struct tevent_context *ev, struct cli_ctx *cctx)
-{
- int ret;
-
- ret = sss_packet_send(cctx->creq->out, cctx->cfd);
- if (ret == EAGAIN) {
- /* not all data was sent, loop again */
- return;
- }
- if (ret != EOK) {
- DEBUG(0, ("Failed to read request, aborting client!\n"));
- talloc_free(cctx);
- return;
- }
-
- /* ok all sent */
- TEVENT_FD_NOT_WRITEABLE(cctx->cfde);
- TEVENT_FD_READABLE(cctx->cfde);
- talloc_free(cctx->creq);
- cctx->creq = NULL;
- return;
-}
-
-static void client_recv(struct tevent_context *ev, struct cli_ctx *cctx)
-{
- int ret;
-
- if (!cctx->creq) {
- cctx->creq = talloc_zero(cctx, struct cli_request);
- if (!cctx->creq) {
- DEBUG(0, ("Failed to alloc request, aborting client!\n"));
- talloc_free(cctx);
- return;
- }
- }
-
- if (!cctx->creq->in) {
- ret = sss_packet_new(cctx->creq, NSS_PACKET_MAX_RECV_SIZE,
- 0, &cctx->creq->in);
- if (ret != EOK) {
- DEBUG(0, ("Failed to alloc request, aborting client!\n"));
- talloc_free(cctx);
- return;
- }
- }
-
- ret = sss_packet_recv(cctx->creq->in, cctx->cfd);
- switch (ret) {
- case EOK:
- /* do not read anymore */
- TEVENT_FD_NOT_READABLE(cctx->cfde);
- /* execute command */
- ret = nss_cmd_execute(cctx);
- if (ret != EOK) {
- DEBUG(0, ("Failed to execute request, aborting client!\n"));
- talloc_free(cctx);
- }
- /* 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 */
- break;
-
- case EINVAL:
- DEBUG(6, ("Invalid data from client, closing connection!\n"));
- talloc_free(cctx);
- break;
-
- case ENODATA:
- DEBUG(5, ("Client disconnected!\n"));
- talloc_free(cctx);
- break;
-
- default:
- DEBUG(6, ("Failed to read request, aborting client!\n"));
- talloc_free(cctx);
- }
-
- return;
-}
-
-static void client_fd_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *ptr)
-{
- struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx);
-
- if (flags & TEVENT_FD_READ) {
- client_recv(ev, cctx);
- return;
- }
- if (flags & TEVENT_FD_WRITE) {
- client_send(ev, cctx);
- return;
- }
-}
-
-static void accept_fd_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags, void *ptr)
-{
- /* accept and attach new event handler */
- struct nss_ctx *nctx = talloc_get_type(ptr, struct nss_ctx);
- struct cli_ctx *cctx;
- socklen_t len;
-
- cctx = talloc_zero(nctx, struct cli_ctx);
- if (!cctx) {
- struct sockaddr_un addr;
- int fd;
- DEBUG(0, ("Out of memory trying to setup client context!\n"));
- /* accept and close to signal the client we have a problem */
- memset(&addr, 0, sizeof(addr));
- len = sizeof(addr);
- fd = accept(nctx->lfd, (struct sockaddr *)&addr, &len);
- if (fd == -1) {
- return;
- }
- close(fd);
- return;
- }
-
- len = sizeof(cctx->addr);
- cctx->cfd = accept(nctx->lfd, (struct sockaddr *)&cctx->addr, &len);
- if (cctx->cfd == -1) {
- DEBUG(1, ("Accept failed [%s]", strerror(errno)));
- talloc_free(cctx);
- return;
- }
-
- cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd,
- TEVENT_FD_READ, client_fd_handler, cctx);
- if (!cctx->cfde) {
- close(cctx->cfd);
- talloc_free(cctx);
- DEBUG(2, ("Failed to queue client handler\n"));
- }
-
- cctx->ev = ev;
- cctx->nctx = nctx;
-
- talloc_set_destructor(cctx, client_destructor);
-
- DEBUG(4, ("Client connected!\n"));
-
- return;
-}
-
static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn)
{
dbus_uint16_t version = NSS_SBUS_SERVICE_VERSION;
@@ -289,175 +118,25 @@ static int service_reload(DBusMessage *message, struct sbus_conn_ctx *sconn)
return service_pong(message, sconn);
}
-static int nss_sbus_init(struct nss_ctx *nctx)
+static int nss_get_config(struct nss_ctx *nctx, struct confdb_ctx *cdb)
{
int ret;
- char *sbus_address;
- struct service_sbus_ctx *ss_ctx;
- struct sbus_method_ctx *sm_ctx;
- /* Set up SBUS connection to the monitor */
- ret = monitor_get_sbus_address(nctx, nctx->cdb, &sbus_address);
- if (ret != EOK) {
- DEBUG(0, ("Could not locate monitor address.\n"));
- return ret;
- }
-
- ret = monitor_init_sbus_methods(nctx, nss_sbus_methods, &sm_ctx);
- if (ret != EOK) {
- DEBUG(0, ("Could not initialize SBUS methods.\n"));
- return ret;
- }
-
- ret = sbus_client_init(nctx, nctx->ev,
- sbus_address, sm_ctx,
- NULL /* Private Data */,
- NULL /* Destructor */,
- &ss_ctx);
- if (ret != EOK) {
- DEBUG(0, ("Failed to connect to monitor services.\n"));
- return ret;
- }
-
- /* Set up NSS-specific listeners */
- /* None currently used */
-
- nctx->ss_ctx = ss_ctx;
-
- return EOK;
-}
-
-/* create a unix socket and listen to it */
-static int set_unix_socket(struct nss_ctx *nctx)
-{
- struct sockaddr_un addr;
-
-/* for future use */
-#if 0
- char *default_pipe;
- int ret;
-
- default_pipe = talloc_asprintf(nctx, "%s/%s", PIPE_PATH, SSS_NSS_PIPE_NAME);
- if (!default_pipe) {
- return ENOMEM;
- }
-
- ret = confdb_get_string(nctx->cdb, nctx,
- "config/services/nss", "unixSocket",
- default_pipe, &nctx->sock_name);
- if (ret != EOK) {
- talloc_free(default_pipe);
- return ret;
- }
- talloc_free(default_pipe);
-#endif
- nctx->sock_name = SSS_NSS_SOCKET_NAME;
-
- nctx->lfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (nctx->lfd == -1) {
- return EIO;
- }
-
- /* Set the umask so that permissions are set right on the socket.
- * It must be readable and writable by anybody on the system. */
- umask(0111);
-
- set_nonblocking(nctx->lfd);
- set_close_on_exec(nctx->lfd);
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, nctx->sock_name, sizeof(addr.sun_path));
-
- /* make sure we have no old sockets around */
- unlink(nctx->sock_name);
-
- if (bind(nctx->lfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
- DEBUG(0,("Unable to bind on socket '%s'\n", nctx->sock_name));
- goto failed;
- }
- if (listen(nctx->lfd, 10) != 0) {
- DEBUG(0,("Unable to listen on socket '%s'\n", nctx->sock_name));
- goto failed;
- }
-
- nctx->lfde = tevent_add_fd(nctx->ev, nctx, nctx->lfd,
- TEVENT_FD_READ, accept_fd_handler, nctx);
-
- /* we want default permissions on created files to be very strict,
- so set our umask to 0177 */
- umask(0177);
- return EOK;
-
-failed:
- /* we want default permissions on created files to be very strict,
- so set our umask to 0177 */
- umask(0177);
- close(nctx->lfd);
- return EIO;
-}
-
-static int nss_init_domains(struct nss_ctx *nctx)
-{
- int ret;
- int retval;
-
- ret = confdb_get_domains(nctx->cdb, nctx, &nctx->domain_map);
- if (ret != EOK) {
- retval = ret;
- goto done;
- }
-
- if (nctx->domain_map == NULL) {
- /* No domains configured!
- * Note: this should never happen, since LOCAL should
- * always be configured */
- DEBUG(0, ("No domains configured on this client!\n"));
- retval = EINVAL;
- goto done;
- }
-
- ret = confdb_get_string(nctx->cdb, nctx,
- "config/domains", "default",
- NULL, &nctx->default_domain);
- if (ret != EOK) {
- retval = ret;
- goto done;
- }
-
- retval = EOK;
-
-done:
- return retval;
-}
-
-static int nss_get_config(struct nss_ctx *nctx)
-{
- int ret;
-
- ret = confdb_get_int(nctx->cdb, nctx, NSS_SRV_CONFIG,
+ ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG,
"EnumCacheTimeout", 120,
&nctx->enum_cache_timeout);
if (ret != EOK) goto done;
- ret = confdb_get_int(nctx->cdb, nctx, NSS_SRV_CONFIG,
+ ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG,
"EntryCacheTimeout", 600,
&nctx->enum_cache_timeout);
if (ret != EOK) goto done;
- ret = confdb_get_int(nctx->cdb, nctx, NSS_SRV_CONFIG,
+ ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG,
"EntryNegativeTimeout", 15,
&nctx->enum_cache_timeout);
if (ret != EOK) goto done;
- ret = confdb_get_param(nctx->cdb, nctx, NSS_SRV_CONFIG,
- "filterUsers", &nctx->filter_users);
- if (ret != EOK) goto done;
-
- ret = confdb_get_param(nctx->cdb, nctx, NSS_SRV_CONFIG,
- "filterGroups", &nctx->filter_groups);
- if (ret != EOK) goto done;
-
done:
return ret;
}
@@ -466,6 +145,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb)
{
+ struct sbus_method *nss_dp_methods;
+ struct sss_cmd_table *nss_cmds;
struct nss_ctx *nctx;
int ret;
@@ -474,34 +155,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
DEBUG(0, ("fatal error initializing nss_ctx\n"));
return ENOMEM;
}
- nctx->ev = ev;
- nctx->cdb = cdb;
-
- ret = nss_init_domains(nctx);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up domain map\n"));
- return ret;
- }
-
- ret = nss_sbus_init(nctx);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up message bus\n"));
- return ret;
- }
-
- ret = nss_dp_init(nctx);
- if (ret != EOK) {
- DEBUG(0, ("fatal error setting up backend connector\n"));
- return ret;
- }
-
- ret = sysdb_init(nctx, ev, cdb, NULL, &nctx->sysdb);
- if (ret != EOK) {
- DEBUG(0, ("fatal error initializing nss_ctx\n"));
- return ret;
- }
- ret = nss_get_config(nctx);
+ ret = nss_get_config(nctx, cdb);
if (ret != EOK) {
DEBUG(0, ("fatal error getting nss config\n"));
return ret;
@@ -513,12 +168,20 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- /* after all initializations we are ready to listen on our socket */
- ret = set_unix_socket(nctx);
+ nss_dp_methods = get_nss_dp_methods();
+ nss_cmds = get_nss_cmds();
+
+ ret = sss_process_init(nctx, ev, cdb,
+ nss_sbus_methods,
+ nss_cmds,
+ SSS_NSS_SOCKET_NAME, NULL,
+ NSS_SRV_CONFIG,
+ nss_dp_methods,
+ &nctx->rctx);
if (ret != EOK) {
- DEBUG(0, ("fatal error initializing socket\n"));
return ret;
}
+ nctx->rctx->pvt_ctx = nctx;
DEBUG(1, ("NSS Initialization complete\n"));