summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-04-12 17:09:06 -0400
committerSimo Sorce <simo@redhat.com>2013-04-23 12:02:50 -0700
commitedf939632c9a1dbab4e769f0c23fe393d7fc8a6a (patch)
treeb6fabfe341663ee072ef6cbe5be7f62e956991fd
parent7f8078e906b138dcd34f84e0260cba87b63ca62f (diff)
downloadgss-proxy-edf939632c9a1dbab4e769f0c23fe393d7fc8a6a.tar.gz
gss-proxy-edf939632c9a1dbab4e769f0c23fe393d7fc8a6a.tar.xz
gss-proxy-edf939632c9a1dbab4e769f0c23fe393d7fc8a6a.zip
Add support for per-service sockets
This way different processes running as the same user can be configured as different servervices Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Günther Deschner <gdeschner@redhat.com>
-rw-r--r--proxy/Makefile.am1
-rw-r--r--proxy/conf_macros.m46
-rw-r--r--proxy/src/client/gpm_common.c8
-rw-r--r--proxy/src/gp_common.c37
-rw-r--r--proxy/src/gp_common.h2
-rw-r--r--proxy/src/gp_config.c9
-rw-r--r--proxy/src/gp_creds.c6
-rw-r--r--proxy/src/gp_proxy.h11
-rw-r--r--proxy/src/gp_socket.c28
-rw-r--r--proxy/src/gssproxy.c41
10 files changed, 128 insertions, 21 deletions
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index c814ab8..04027d6 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -154,6 +154,7 @@ gssproxy_SOURCES = \
src/gp_export.c \
src/gp_debug.c \
src/gp_log.c \
+ src/gp_common.c \
src/gp_rpc_accept_sec_context.c \
src/gp_rpc_release_handle.c \
src/gp_rpc_acquire_cred.c \
diff --git a/proxy/conf_macros.m4 b/proxy/conf_macros.m4
index f2d3755..a92c24a 100644
--- a/proxy/conf_macros.m4
+++ b/proxy/conf_macros.m4
@@ -46,12 +46,12 @@ AC_DEFUN([WITH_PUBCONF_PATH],
AC_DEFUN([WITH_SOCKET_NAME],
[ AC_ARG_WITH([socket-name],
[AC_HELP_STRING([--with-socket-name=PATH],
- [Name of the GSS Proxy socket file [/var/run/gssproxy.sock]]
+ [Name of the GSS Proxy socket file [/var/lib/gssproxy/default.sock]]
)
]
)
- gp_socket_name="\"VARDIR\"/run/gssproxy.sock"
- socketname="${localstatedir}/run/gssproxy.sock"
+ gp_socket_name="\"VARDIR\"/lib/gssproxy/default.sock"
+ socketname="${localstatedir}/lib/gssproxy/default.sock"
if test x"$with_socket_name" != x; then
gp_socket_name=$with_socket_name
socketname=$with_socket_name
diff --git a/proxy/src/client/gpm_common.c b/proxy/src/client/gpm_common.c
index d9015f6..8ac1a2a 100644
--- a/proxy/src/client/gpm_common.c
+++ b/proxy/src/client/gpm_common.c
@@ -65,9 +65,15 @@ static void gpm_init_once(void)
static int get_pipe_name(struct gpm_ctx *gpmctx, char *name)
{
+ const char *socket;
int ret;
- ret = snprintf(name, PATH_MAX, "%s", GP_SOCKET_NAME);
+ socket = getenv("GSSPROXY_SOCKET");
+ if (!socket) {
+ socket = GP_SOCKET_NAME;
+ }
+
+ ret = snprintf(name, PATH_MAX, "%s", socket);
if (ret < 0 || ret >= PATH_MAX) {
return ENAMETOOLONG;
}
diff --git a/proxy/src/gp_common.c b/proxy/src/gp_common.c
new file mode 100644
index 0000000..f4ebc5e
--- /dev/null
+++ b/proxy/src/gp_common.c
@@ -0,0 +1,37 @@
+/*
+ GSS-PROXY
+
+ Copyright (C) 2013 Red Hat, Inc.
+ Copyright (C) 2013 Simo Sorce <simo.sorce@redhat.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#include <stdbool.h>
+#include <string.h>
+#include "gp_common.h"
+
+bool gp_same(const char *a, const char *b)
+{
+ if ((a == b) || strcmp(a, b) == 0) {
+ return true;
+ }
+
+ return false;
+}
diff --git a/proxy/src/gp_common.h b/proxy/src/gp_common.h
index f4a8a58..25cd278 100644
--- a/proxy/src/gp_common.h
+++ b/proxy/src/gp_common.h
@@ -65,6 +65,8 @@
/* max out at 1MB for now */
#define MAX_RPC_SIZE 1024*1024
+bool gp_same(const char *a, const char *b);
+
#include "rpcgen/gss_proxy.h"
union gp_rpc_arg {
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
index 012094a..630f56d 100644
--- a/proxy/src/gp_config.c
+++ b/proxy/src/gp_config.c
@@ -184,6 +184,15 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
}
}
+ value = gp_config_get_string(ctx, secname, "socket");
+ if (value != NULL) {
+ cfg->svcs[n]->socket = strdup(value);
+ if (!cfg->svcs[n]->socket) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
ret = setup_service_creds_handle(cfg->svcs[n]);
if (ret) {
goto done;
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index 4a731b0..e6c12a5 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -95,12 +95,18 @@ struct gp_service *gp_creds_match_conn(struct gssproxy_ctx *gpctx,
struct gp_conn *conn)
{
struct gp_creds *gcs;
+ const char *socket;
int i;
gcs = gp_conn_get_creds(conn);
+ socket = gp_conn_get_socket(conn);
for (i = 0; i < gpctx->config->num_svcs; i++) {
if (gpctx->config->svcs[i]->euid == gcs->ucred.uid) {
+ if (gpctx->config->svcs[i]->socket &&
+ gp_same(socket, gpctx->config->svcs[i]->socket)) {
+ continue;
+ }
return gpctx->config->svcs[i];
}
}
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index 8f5a059..6764f6a 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -51,6 +51,7 @@ struct gp_service {
uid_t euid;
bool trusted;
bool kernel_nfsd;
+ char *socket;
uint32_t mechs;
struct gp_cred_krb5 krb5;
@@ -76,6 +77,12 @@ struct gssproxy_ctx {
verto_ctx *vctx;
};
+struct gp_sock_ctx {
+ struct gssproxy_ctx *gpctx;
+ const char *socket;
+ int fd;
+};
+
struct gp_conn;
/* from gp_config.c */
@@ -91,12 +98,14 @@ void init_proc_nfsd(struct gp_config *cfg);
void write_pid(void);
/* from gp_socket.c */
-int init_unix_socket(const char *file_name);
+struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
+ const char *file_name);
void accept_sock_conn(verto_ctx *vctx, verto_ev *ev);
void gp_conn_free(struct gp_conn *conn);
void gp_socket_send_data(verto_ctx *vctx, struct gp_conn *conn,
uint8_t *buffer, size_t buflen);
struct gp_creds *gp_conn_get_creds(struct gp_conn *conn);
+const char *gp_conn_get_socket(struct gp_conn *conn);
/* from gp_workers.c */
int gp_workers_init(struct gssproxy_ctx *gpctx);
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c
index 20a13c5..02bc882 100644
--- a/proxy/src/gp_socket.c
+++ b/proxy/src/gp_socket.c
@@ -55,7 +55,7 @@ struct unix_sock_conn {
};
struct gp_conn {
- struct gssproxy_ctx *gpctx;
+ struct gp_sock_ctx *sock_ctx;
struct unix_sock_conn us;
struct gp_creds creds;
SEC_CTX secctx;
@@ -73,6 +73,11 @@ struct gp_creds *gp_conn_get_creds(struct gp_conn *conn)
return &conn->creds;
}
+const char *gp_conn_get_socket(struct gp_conn *conn)
+{
+ return conn->sock_ctx->socket;
+}
+
void gp_conn_free(struct gp_conn *conn)
{
if (!conn) return;
@@ -118,13 +123,20 @@ static int set_fd_flags(int fd, int flags)
return 0;
}
-int init_unix_socket(const char *file_name)
+struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
+ const char *file_name)
{
struct sockaddr_un addr = {0};
+ struct gp_sock_ctx *sock_ctx;
mode_t old_mode;
int ret = 0;
int fd = -1;
+ sock_ctx = calloc(1, sizeof(struct gp_sock_ctx));
+ if (!sock_ctx) {
+ return NULL;
+ }
+
/* can't bind if an old socket is around */
unlink(file_name);
@@ -177,9 +189,15 @@ done:
close(fd);
fd = -1;
}
+ safefree(sock_ctx);
+ } else {
+ sock_ctx->gpctx = gpctx;
+ sock_ctx->socket = file_name;
+ sock_ctx->fd = fd;
}
umask(old_mode);
- return fd;
+
+ return sock_ctx;
}
static int get_peercred(int fd, struct gp_conn *conn)
@@ -334,7 +352,7 @@ static void gp_socket_read(verto_ctx *vctx, verto_ev *ev)
if (rbuf->pos == rbuf->size) {
/* got all data, hand over packet */
- ret = gp_query_new(rbuf->conn->gpctx->workers, rbuf->conn,
+ ret = gp_query_new(rbuf->conn->sock_ctx->gpctx->workers, rbuf->conn,
rbuf->data, rbuf->size);
if (ret != 0) {
/* internal error, not much we can do */
@@ -472,7 +490,7 @@ void accept_sock_conn(verto_ctx *vctx, verto_ev *ev)
ret = ENOMEM;
goto done;
}
- conn->gpctx = verto_get_private(ev);
+ conn->sock_ctx = verto_get_private(ev);
conn->us.sd = -1;
listen_fd = verto_get_fd(ev);
diff --git a/proxy/src/gssproxy.c b/proxy/src/gssproxy.c
index 8c143e5..0936407 100644
--- a/proxy/src/gssproxy.c
+++ b/proxy/src/gssproxy.c
@@ -40,9 +40,10 @@ int main(int argc, const char *argv[])
verto_ctx *vctx;
verto_ev *ev;
int vflags;
- int fd;
struct gssproxy_ctx *gpctx;
+ struct gp_sock_ctx *sock_ctx;
int ret;
+ int i;
struct poptOption long_options[] = {
POPT_AUTOHELP
@@ -98,14 +99,6 @@ int main(int argc, const char *argv[])
init_server(gpctx->config->daemonize);
- fd = init_unix_socket(gpctx->config->socket_name);
- if (fd == -1) {
- return 1;
- }
-
- /* special call to tell the Linux kernel gss-proxy is available */
- init_proc_nfsd(gpctx->config);
-
write_pid();
vctx = init_event_loop();
@@ -114,12 +107,38 @@ int main(int argc, const char *argv[])
}
gpctx->vctx = vctx;
+ /* init main socket */
+ sock_ctx = init_unix_socket(gpctx, gpctx->config->socket_name);
+ if (!sock_ctx) {
+ return 1;
+ }
+
vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ;
- ev = verto_add_io(vctx, vflags, accept_sock_conn, fd);
+ ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd);
if (!ev) {
return 1;
}
- verto_set_private(ev, gpctx, NULL);
+ verto_set_private(ev, sock_ctx, NULL);
+
+ /* init secondary sockets */
+ for (i = 0; i < gpctx->config->num_svcs; i++) {
+ if (gpctx->config->svcs[i]->socket != NULL) {
+ sock_ctx = init_unix_socket(gpctx, gpctx->config->svcs[i]->socket);
+ if (!sock_ctx) {
+ return 1;
+ }
+
+ vflags = VERTO_EV_FLAG_PERSIST | VERTO_EV_FLAG_IO_READ;
+ ev = verto_add_io(vctx, vflags, accept_sock_conn, sock_ctx->fd);
+ if (!ev) {
+ return 1;
+ }
+ verto_set_private(ev, sock_ctx, NULL);
+ }
+ }
+
+ /* special call to tell the Linux kernel gss-proxy is available */
+ init_proc_nfsd(gpctx->config);
ret = gp_workers_init(gpctx);
if (ret) {