>From f513734b61873fa9bbbaec78f1221d291a0c94a5 Mon Sep 17 00:00:00 2001
From: Simo Sorce <simo@redhat.com>
Date: Mon, 14 Oct 2013 16:20:11 -0400
Subject: [PATCH 1/2] Allow arbitrary users to connect to a service

The rpc.gssd daemon is changing to fork and change uid to the unprivileged
user it wants to authenticate, this means gssproxy needs to allow connection
from any euid. When this is done though, the trusted flag needs to be dropped,
if the connecting euid does not match the default trusted uid to prevent
improper impersonation.

Resolves: https://fedorahosted.org/gss-proxy/ticket/103
---
 proxy/examples/gssproxy.conf.in          |  1 +
 proxy/src/gp_config.c                    |  7 +++++++
 proxy/src/gp_creds.c                     | 27 ++++++++++++++++++---------
 proxy/src/gp_export.c                    |  8 ++++----
 proxy/src/gp_export.h                    |  6 +++---
 proxy/src/gp_proxy.h                     | 11 +++++++++--
 proxy/src/gp_rpc_accept_sec_context.c    | 11 +++++------
 proxy/src/gp_rpc_acquire_cred.c          | 13 ++++++-------
 proxy/src/gp_rpc_creds.h                 |  9 ++++-----
 proxy/src/gp_rpc_get_mic.c               |  3 +--
 proxy/src/gp_rpc_import_and_canon_name.c |  3 +--
 proxy/src/gp_rpc_indicate_mechs.c        |  3 +--
 proxy/src/gp_rpc_init_sec_context.c      | 12 +++++++-----
 proxy/src/gp_rpc_process.c               | 13 ++++++-------
 proxy/src/gp_rpc_process.h               |  3 +--
 proxy/src/gp_rpc_release_handle.c        |  3 +--
 proxy/src/gp_rpc_unwrap.c                |  3 +--
 proxy/src/gp_rpc_verify_mic.c            |  3 +--
 proxy/src/gp_rpc_wrap.c                  |  3 +--
 proxy/src/gp_rpc_wrap_size_limit.c       |  3 +--
 proxy/src/gp_socket.c                    |  5 +++++
 proxy/src/gp_workers.c                   | 10 ++++++----
 22 files changed, 90 insertions(+), 70 deletions(-)

diff --git a/proxy/examples/gssproxy.conf.in b/proxy/examples/gssproxy.conf.in
index 0f8339e805629cf6e2cb0cd5fc0fe73cbf10aa25..262125adf663c1943b8af10f2f476b4c526e7a21 100644
--- a/proxy/examples/gssproxy.conf.in
+++ b/proxy/examples/gssproxy.conf.in
@@ -13,5 +13,6 @@
   cred_store = keytab:/etc/krb5.keytab
   cred_store = ccache:FILE:@gpstatedir@/clients/krb5cc_%U
   cred_store = client_keytab:@gpstatedir@/clients/%U.keytab
+  allow_any_uid = yes
   trusted = yes
   euid = 0
diff --git a/proxy/src/gp_config.c b/proxy/src/gp_config.c
index ee218b4624a97d094101b91e86b470f14076b212..943906aca344ae8d11cec8b4b90cdd7e6b78a5eb 100644
--- a/proxy/src/gp_config.c
+++ b/proxy/src/gp_config.c
@@ -184,6 +184,13 @@ static int load_services(struct gp_config *cfg, struct gp_ini_context *ctx)
             }
             cfg->svcs[n]->euid = valnum;
 
+            ret = gp_config_get_string(ctx, secname, "allow_any_uid", &value);
+            if (ret == 0) {
+                if (gp_boolean_is_true(value)) {
+                    cfg->svcs[n]->any_uid = true;
+                }
+            }
+
             ret = gp_config_get_string(ctx, secname, "trusted", &value);
             if (ret == 0) {
                 if (gp_boolean_is_true(value)) {
diff --git a/proxy/src/gp_creds.c b/proxy/src/gp_creds.c
index 4d68afb6fbe812eb1810ab23af07e6288df9968c..b047d8f65fe2169ce71d62229405c61bc2e23d1e 100644
--- a/proxy/src/gp_creds.c
+++ b/proxy/src/gp_creds.c
@@ -49,12 +49,12 @@ struct supported_mechs_map {
     { 0, NULL }
 };
 
-bool gp_creds_allowed_mech(struct gp_service *svc, gss_OID desired_mech)
+bool gp_creds_allowed_mech(struct gp_call_ctx *gpcall, gss_OID desired_mech)
 {
     int i;
 
     for (i = 0; supported_mechs_map[i].internal_id != 0; i++) {
-        if (svc->mechs & supported_mechs_map[i].internal_id) {
+        if (gpcall->service->mechs & supported_mechs_map[i].internal_id) {
             if (gss_oid_equal(desired_mech, supported_mechs_map[i].mech)) {
                 return true;
             }
@@ -64,8 +64,7 @@ bool gp_creds_allowed_mech(struct gp_service *svc, gss_OID desired_mech)
     return false;
 }
 
-uint32_t gp_get_supported_mechs(uint32_t *min,
-                                struct gp_service *svc, gss_OID_set *set)
+uint32_t gp_get_supported_mechs(uint32_t *min, gss_OID_set *set)
 {
     uint32_t ret_maj;
     uint32_t ret_min;
@@ -102,7 +101,8 @@ struct gp_service *gp_creds_match_conn(struct gssproxy_ctx *gpctx,
     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]->any_uid ||
+            gpctx->config->svcs[i]->euid == gcs->ucred.uid) {
             if (gpctx->config->svcs[i]->socket) {
                 if (!gp_same(socket, gpctx->config->svcs[i]->socket)) {
                     continue;
@@ -202,12 +202,13 @@ static void free_cred_store_elements(gss_key_value_set_desc *cs)
     safefree(cs->elements);
 }
 
-static int gp_get_cred_environment(struct gp_service *svc,
+static int gp_get_cred_environment(struct gp_call_ctx *gpcall,
                                    gssx_name *desired_name,
                                    gss_name_t *requested_name,
                                    gss_cred_usage_t cred_usage,
                                    gss_key_value_set_desc *cs)
 {
+    struct gp_service *svc;
     gss_name_t name = GSS_C_NO_NAME;
     gss_OID_desc name_type;
     uint32_t ret_maj = 0;
@@ -222,17 +223,25 @@ static int gp_get_cred_environment(struct gp_service *svc,
     int ck_num = -1;
     int c, s;
 
-    target_uid = svc->euid;
+    target_uid = gp_conn_get_uid(gpcall->connection);
+    svc = gpcall->service;
 
     if (desired_name) {
         gp_conv_gssx_to_oid(&desired_name->name_type, &name_type);
 
+        /* A service retains the trusted flag only if the current uid matches
+         * the configured euid */
         if (svc->trusted &&
+            (svc->euid == target_uid) &&
             (gss_oid_equal(&name_type, GSS_C_NT_STRING_UID_NAME) ||
              gss_oid_equal(&name_type, GSS_C_NT_MACHINE_UID_NAME))) {
             target_uid = atol(desired_name->display_name.octet_string_val);
             user_requested = true;
         } else {
+            /* it's a user request if it comes from an arbitrary uid */
+            if (svc->euid != target_uid) {
+                user_requested = true;
+            }
             ret_maj = gp_conv_gssx_to_name(&ret_min, desired_name, &name);
             if (ret_maj) {
                 goto done;
@@ -333,7 +342,7 @@ done:
 }
 
 uint32_t gp_add_krb5_creds(uint32_t *min,
-                           struct gp_service *svc,
+                           struct gp_call_ctx *gpcall,
                            gss_cred_id_t in_cred,
                            gssx_name *desired_name,
                            gss_cred_usage_t cred_usage,
@@ -369,7 +378,7 @@ uint32_t gp_add_krb5_creds(uint32_t *min,
         return GSS_S_CRED_UNAVAIL;
     }
 
-    ret_min = gp_get_cred_environment(svc, desired_name, &req_name,
+    ret_min = gp_get_cred_environment(gpcall, desired_name, &req_name,
                                       cred_usage, &cred_store);
     if (ret_min) {
         ret_maj = GSS_S_CRED_UNAVAIL;
diff --git a/proxy/src/gp_export.c b/proxy/src/gp_export.c
index 2710589d881431aeba443cc367017f331357c6a7..51dd686ce5aacf3835d2890a24ff3ad25885ee5e 100644
--- a/proxy/src/gp_export.c
+++ b/proxy/src/gp_export.c
@@ -187,7 +187,7 @@ static int gp_decrypt_buffer(krb5_context context, krb5_keyblock *key,
     return 0;
 }
 
-uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_service *svc,
+uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
                              gss_cred_id_t *in, gssx_cred *out)
 {
     uint32_t ret_maj;
@@ -268,7 +268,7 @@ uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_service *svc,
         el->acceptor_time_rec = acceptor_lifetime;
     }
 
-    handle = gp_service_get_creds_handle(svc);
+    handle = gp_service_get_creds_handle(gpcall->service);
     if (!handle) {
         ret_maj = GSS_S_FAILURE;
         ret_min = EINVAL;
@@ -340,7 +340,7 @@ static void gp_set_cred_options(gssx_cred *cred, gss_cred_id_t gss_cred)
     }
 }
 
-uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_service *svc,
+uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
                              gssx_cred *cred, gss_cred_id_t *out)
 {
     gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
@@ -349,7 +349,7 @@ uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_service *svc,
     uint32_t ret_min;
     int ret;
 
-    handle = gp_service_get_creds_handle(svc);
+    handle = gp_service_get_creds_handle(gpcall->service);
     if (!handle) {
         ret_maj = GSS_S_FAILURE;
         ret_min = EINVAL;
diff --git a/proxy/src/gp_export.h b/proxy/src/gp_export.h
index 28d2229df5e9ccf14e303fe0bdfa2b45aa1903a1..58c00407c6a0a5e7040288575dd5ad0152eda710 100644
--- a/proxy/src/gp_export.h
+++ b/proxy/src/gp_export.h
@@ -29,11 +29,11 @@
 #include <gssapi/gssapi.h>
 #include "rpcgen/gss_proxy.h"
 
-struct gp_service;
+struct gp_call_ctx;
 
-uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_service *svc,
+uint32_t gp_export_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
                              gss_cred_id_t *in, gssx_cred *out);
-uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_service *svc,
+uint32_t gp_import_gssx_cred(uint32_t *min, struct gp_call_ctx *gpcall,
                              gssx_cred *cred, gss_cred_id_t *out);
 
 int gp_get_exported_context_type(struct gssx_call_ctx *ctx);
diff --git a/proxy/src/gp_proxy.h b/proxy/src/gp_proxy.h
index 835fcf5669ab34c18e8e74ae81a306a5600ec495..a5b3a28887f91e37f36cdd5d7d9c578ef44ce78d 100644
--- a/proxy/src/gp_proxy.h
+++ b/proxy/src/gp_proxy.h
@@ -50,6 +50,7 @@ struct gp_creds_handle;
 struct gp_service {
     char *name;
     uid_t euid;
+    bool any_uid;
     bool trusted;
     bool kernel_nfsd;
     char *socket;
@@ -87,6 +88,12 @@ struct gp_sock_ctx {
 
 struct gp_conn;
 
+struct gp_call_ctx {
+    struct gssproxy_ctx *gpctx;
+    struct gp_service *service;
+    struct gp_conn *connection;
+};
+
 /* from gp_config.c */
 struct gp_config *read_config(char *config_file, int opt_daemonize);
 struct gp_creds_handle *gp_service_get_creds_handle(struct gp_service *svc);
@@ -107,6 +114,7 @@ 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);
+uid_t gp_conn_get_uid(struct gp_conn *conn);
 const char *gp_conn_get_socket(struct gp_conn *conn);
 bool gp_conn_check_selinux(struct gp_conn *conn, SELINUX_CTX ctx);
 
@@ -117,8 +125,7 @@ int gp_query_new(struct gp_workers *w, struct gp_conn *conn,
                  uint8_t *buffer, size_t buflen);
 
 /* from gp_rpc.c */
-int gp_rpc_process_call(struct gssproxy_ctx *gpctx,
-                        struct gp_service *gpsvc,
+int gp_rpc_process_call(struct gp_call_ctx *gpcall,
                         uint8_t *inbuf, size_t inlen,
                         uint8_t **outbuf, size_t *outlen);
 
diff --git a/proxy/src/gp_rpc_accept_sec_context.c b/proxy/src/gp_rpc_accept_sec_context.c
index e43b72ab29e744aff173505f3f99421a82ddd0e0..40370aa0d0da3bae9f5826bd4219d90b877fb0f7 100644
--- a/proxy/src/gp_rpc_accept_sec_context.c
+++ b/proxy/src/gp_rpc_accept_sec_context.c
@@ -25,8 +25,7 @@
 
 #include "gp_rpc_process.h"
 
-int gp_accept_sec_context(struct gssproxy_ctx *gpctx,
-                          struct gp_service *gpsvc,
+int gp_accept_sec_context(struct gp_call_ctx *gpcall,
                           union gp_rpc_arg *arg,
                           union gp_rpc_res *res)
 {
@@ -67,14 +66,15 @@ int gp_accept_sec_context(struct gssproxy_ctx *gpctx,
     }
 
     if (asca->cred_handle) {
-        ret_maj = gp_import_gssx_cred(&ret_min, gpsvc, asca->cred_handle, &ach);
+        ret_maj = gp_import_gssx_cred(&ret_min, gpcall,
+                                      asca->cred_handle, &ach);
         if (ret_maj) {
             goto done;
         }
     }
 
     if (ach == GSS_C_NO_CREDENTIAL) {
-        ret_maj = gp_add_krb5_creds(&ret_min, gpsvc,
+        ret_maj = gp_add_krb5_creds(&ret_min, gpcall,
                                     NULL, NULL,
                                     GSS_C_ACCEPT,
                                     0, 0,
@@ -145,8 +145,7 @@ int gp_accept_sec_context(struct gssproxy_ctx *gpctx,
             ret_min = ENOMEM;
             goto done;
         }
-        ret_maj = gp_export_gssx_cred(&ret_min,
-                                      gpsvc,
+        ret_maj = gp_export_gssx_cred(&ret_min, gpcall,
                                       &dch, ascr->delegated_cred_handle);
         if (ret_maj) {
             goto done;
diff --git a/proxy/src/gp_rpc_acquire_cred.c b/proxy/src/gp_rpc_acquire_cred.c
index c5bf1a28f0fd6fc3aeaf516fb64cd3be18558d09..0f53989e95896601d277c5c074c798bdd048b8cf 100644
--- a/proxy/src/gp_rpc_acquire_cred.c
+++ b/proxy/src/gp_rpc_acquire_cred.c
@@ -26,8 +26,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi_krb5.h>
 
-int gp_acquire_cred(struct gssproxy_ctx *gpctx,
-                    struct gp_service *gpsvc,
+int gp_acquire_cred(struct gp_call_ctx *gpcall,
                     union gp_rpc_arg *arg,
                     union gp_rpc_res *res)
 {
@@ -49,7 +48,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx,
     acr = &res->acquire_cred;
 
     if (aca->input_cred_handle) {
-        ret_maj = gp_import_gssx_cred(&ret_min, gpsvc,
+        ret_maj = gp_import_gssx_cred(&ret_min, gpcall,
                                       aca->input_cred_handle, &in_cred);
         if (ret_maj) {
             goto done;
@@ -80,7 +79,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx,
         for (i = 0; i < desired_mechs->count; i++) {
             desired_mech = &desired_mechs->elements[i];
 
-            if (!gp_creds_allowed_mech(gpsvc, desired_mech)) {
+            if (!gp_creds_allowed_mech(gpcall, desired_mech)) {
                 continue;
             }
 
@@ -99,7 +98,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx,
             goto done;
         }
     } else {
-        ret_maj = gp_get_supported_mechs(&ret_min, gpsvc, &use_mechs);
+        ret_maj = gp_get_supported_mechs(&ret_min, &use_mechs);
         if (ret_maj) {
             goto done;
         }
@@ -114,7 +113,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx,
          * that define keytabs and ccaches and principals */
         if (gss_oid_equal(desired_mech, gss_mech_krb5)) {
             ret_maj = gp_add_krb5_creds(&ret_min,
-                                        gpsvc,
+                                        gpcall,
                                         in_cred,
                                         aca->desired_name,
                                         cred_usage,
@@ -150,7 +149,7 @@ int gp_acquire_cred(struct gssproxy_ctx *gpctx,
         ret_min = ENOMEM;
         goto done;
     }
-    ret_maj = gp_export_gssx_cred(&ret_min, gpsvc,
+    ret_maj = gp_export_gssx_cred(&ret_min, gpcall,
                                   &out_cred, acr->output_cred_handle);
     if (ret_maj) {
         goto done;
diff --git a/proxy/src/gp_rpc_creds.h b/proxy/src/gp_rpc_creds.h
index 50e339296f78de5804dd9f510477e6cc6f6783e5..6389ebe568271fe8a3ad419467c224b6ba1c593f 100644
--- a/proxy/src/gp_rpc_creds.h
+++ b/proxy/src/gp_rpc_creds.h
@@ -30,14 +30,13 @@
 #include <stdint.h>
 #include <gssapi/gssapi.h>
 
-struct gp_service;
+struct gp_call_ctx;
 
-bool gp_creds_allowed_mech(struct gp_service *svc, gss_OID desired_mech);
-uint32_t gp_get_supported_mechs(uint32_t *min,
-                                struct gp_service *svc, gss_OID_set *set);
+bool gp_creds_allowed_mech(struct gp_call_ctx *gpcall, gss_OID desired_mech);
+uint32_t gp_get_supported_mechs(uint32_t *min, gss_OID_set *set);
 
 uint32_t gp_add_krb5_creds(uint32_t *min,
-                           struct gp_service *svc,
+                           struct gp_call_ctx *gpcall,
                            gss_cred_id_t in_cred,
                            gssx_name *desired_name,
                            gss_cred_usage_t cred_usage,
diff --git a/proxy/src/gp_rpc_get_mic.c b/proxy/src/gp_rpc_get_mic.c
index 9f3773137a628c1bb004090c887ecf5b7cfad4ec..ca60fe407be39720024734e8c59d5c2738f198a3 100644
--- a/proxy/src/gp_rpc_get_mic.c
+++ b/proxy/src/gp_rpc_get_mic.c
@@ -27,8 +27,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi.h>
 
-int gp_get_mic(struct gssproxy_ctx *gpctx,
-               struct gp_service *gpsvc,
+int gp_get_mic(struct gp_call_ctx *gpcall,
                union gp_rpc_arg *arg,
                union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_import_and_canon_name.c b/proxy/src/gp_rpc_import_and_canon_name.c
index ba2bc06dcf169f3369c786c96faf67719f594301..1988a8bd99fb2129fc5fd54f5e32f777da121c70 100644
--- a/proxy/src/gp_rpc_import_and_canon_name.c
+++ b/proxy/src/gp_rpc_import_and_canon_name.c
@@ -31,8 +31,7 @@
  * I am not kidding, if you hav not read it, go back and do it now, or do not
  * touch this function */
 
-int gp_import_and_canon_name(struct gssproxy_ctx *gpctx,
-                             struct gp_service *gpsvc,
+int gp_import_and_canon_name(struct gp_call_ctx *gpcall,
                              union gp_rpc_arg *arg,
                              union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_indicate_mechs.c b/proxy/src/gp_rpc_indicate_mechs.c
index c85243b26762a192b72e0db95efe57bf65e2e2f3..e2318283c9fa52ffc7df435006519bda80228fb1 100644
--- a/proxy/src/gp_rpc_indicate_mechs.c
+++ b/proxy/src/gp_rpc_indicate_mechs.c
@@ -26,8 +26,7 @@
 #include "gp_rpc_process.h"
 #include "gp_debug.h"
 
-int gp_indicate_mechs(struct gssproxy_ctx *gpctx,
-                      struct gp_service *gpsvc,
+int gp_indicate_mechs(struct gp_call_ctx *gpcall,
                       union gp_rpc_arg *arg,
                       union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_init_sec_context.c b/proxy/src/gp_rpc_init_sec_context.c
index fa87b15addbf62f12675f91758319379def8429c..944389c6f08c0c8e238adf300b383401329fb9da 100644
--- a/proxy/src/gp_rpc_init_sec_context.c
+++ b/proxy/src/gp_rpc_init_sec_context.c
@@ -25,8 +25,7 @@
 
 #include "gp_rpc_process.h"
 
-int gp_init_sec_context(struct gssproxy_ctx *gpctx,
-                        struct gp_service *gpsvc,
+int gp_init_sec_context(struct gp_call_ctx *gpcall,
                         union gp_rpc_arg *arg,
                         union gp_rpc_res *res)
 {
@@ -68,15 +67,18 @@ int gp_init_sec_context(struct gssproxy_ctx *gpctx,
     }
 
     if (isca->cred_handle) {
-        ret_maj = gp_import_gssx_cred(&ret_min, gpsvc,
+        ret_maj = gp_import_gssx_cred(&ret_min, gpcall,
                                       isca->cred_handle, &ich);
         if (ret_maj) {
             goto done;
         }
+    } else {
+        /* FIXME: get ccache from gpsvc ? */
+        ret_maj = GSS_S_CRED_UNAVAIL;
+        ret_min = 0;
+        goto done;
     }
 
-    /* FIXME: gett ccache from gpsvc */
-
     ret_maj = gp_conv_gssx_to_name(&ret_min, isca->target_name, &target_name);
     if (ret_maj) {
         goto done;
diff --git a/proxy/src/gp_rpc_process.c b/proxy/src/gp_rpc_process.c
index 18f8dc6052beb8b6e9a5b2599166e0d9d2fc4d20..74dada187a3bd64d64df704eff6693035ce3e603 100644
--- a/proxy/src/gp_rpc_process.c
+++ b/proxy/src/gp_rpc_process.c
@@ -333,14 +333,14 @@ static const char *gp_rpc_procname(uint32_t proc)
     return gp_xdr_set[proc].proc_name;
 }
 
-static int gp_rpc_execute(struct gssproxy_ctx *gpctx,
-                          struct gp_service *gpsvc, uint32_t proc,
+static int gp_rpc_execute(struct gp_call_ctx *gpcall, uint32_t proc,
                           union gp_rpc_arg *arg, union gp_rpc_res *res)
 {
     GPDEBUG("gp_rpc_execute: executing %d (%s) for service \"%s\", euid: %d, socket: %s\n",
-        proc, gp_rpc_procname(proc), gpsvc->name, gpsvc->euid, gpsvc->socket);
+        proc, gp_rpc_procname(proc), gpcall->service->name,
+        gp_conn_get_uid(gpcall->connection), gpcall->service->socket);
 
-    return gp_xdr_set[proc].exec_fn(gpctx, gpsvc, arg, res);
+    return gp_xdr_set[proc].exec_fn(gpcall, arg, res);
 }
 
 static int gp_rpc_return_buffer(XDR *xdr_reply_ctx, char *reply_buffer,
@@ -371,8 +371,7 @@ static void gp_rpc_free_xdrs(int proc,
     xdr_free(gp_xdr_set[proc].res_fn, (char *)res);
 }
 
-int gp_rpc_process_call(struct gssproxy_ctx *gpctx,
-                        struct gp_service *gpsvc,
+int gp_rpc_process_call(struct gp_call_ctx *gpcall,
                         uint8_t *inbuf, size_t inlen,
                         uint8_t **outbuf, size_t *outlen)
 {
@@ -398,7 +397,7 @@ int gp_rpc_process_call(struct gssproxy_ctx *gpctx,
     ret = gp_rpc_decode_call(&xdr_call_ctx, &xid, &proc, &arg, &acc, &rej);
     if (!ret) {
         /* execute request */
-        ret = gp_rpc_execute(gpctx, gpsvc, proc, &arg, &res);
+        ret = gp_rpc_execute(gpcall, proc, &arg, &res);
         if (ret) {
             acc = GP_RPC_SYSTEM_ERR;
             ret = EINVAL;
diff --git a/proxy/src/gp_rpc_process.h b/proxy/src/gp_rpc_process.h
index a0e8102b36e50bf83c988d0c8b7c4d5311784250..0a9b426b5430dfc4b2823e73f3537ff2eb01c0ac 100644
--- a/proxy/src/gp_rpc_process.h
+++ b/proxy/src/gp_rpc_process.h
@@ -42,8 +42,7 @@
 struct gssproxy_ctx;
 struct gp_service;
 
-#define gp_exec_std_args struct gssproxy_ctx *gpctx, \
-                         struct gp_service *gpsvc, \
+#define gp_exec_std_args struct gp_call_ctx *gpcall, \
                          union gp_rpc_arg *arg, \
                          union gp_rpc_res *res
 
diff --git a/proxy/src/gp_rpc_release_handle.c b/proxy/src/gp_rpc_release_handle.c
index a9f5ee24cb4d1762c2d13144668479301c9f55bc..97fc896044722ccdbd2d93087f0a2baf7d33ec09 100644
--- a/proxy/src/gp_rpc_release_handle.c
+++ b/proxy/src/gp_rpc_release_handle.c
@@ -25,8 +25,7 @@
 
 #include "gp_rpc_process.h"
 
-int gp_release_handle(struct gssproxy_ctx *gpctx,
-                      struct gp_service *gpsvc,
+int gp_release_handle(struct gp_call_ctx *gpcall,
                       union gp_rpc_arg *arg,
                       union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_unwrap.c b/proxy/src/gp_rpc_unwrap.c
index a1f5404ffce8fc0935594bfe66bd3e69f6c734c1..a20b8ea785808c3b34ebbfafaaf56b668a415108 100644
--- a/proxy/src/gp_rpc_unwrap.c
+++ b/proxy/src/gp_rpc_unwrap.c
@@ -27,8 +27,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi.h>
 
-int gp_unwrap(struct gssproxy_ctx *gpctx,
-              struct gp_service *gpsvc,
+int gp_unwrap(struct gp_call_ctx *gpcall,
               union gp_rpc_arg *arg,
               union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_verify_mic.c b/proxy/src/gp_rpc_verify_mic.c
index b2032debdd4ad7f47d1d2e976f3082bab8765790..68369a05e4991f5b2aa30ffa05587e792b187134 100644
--- a/proxy/src/gp_rpc_verify_mic.c
+++ b/proxy/src/gp_rpc_verify_mic.c
@@ -27,8 +27,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi.h>
 
-int gp_verify_mic(struct gssproxy_ctx *gpctx,
-                  struct gp_service *gpsvc,
+int gp_verify_mic(struct gp_call_ctx *gpcall,
                   union gp_rpc_arg *arg,
                   union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_wrap.c b/proxy/src/gp_rpc_wrap.c
index e8ef530be5aed612cbc61339df75ef51717fb01d..d17c2928412a2a6ff89f0a799a4435f7e62dcb5b 100644
--- a/proxy/src/gp_rpc_wrap.c
+++ b/proxy/src/gp_rpc_wrap.c
@@ -27,8 +27,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi.h>
 
-int gp_wrap(struct gssproxy_ctx *gpctx,
-            struct gp_service *gpsvc,
+int gp_wrap(struct gp_call_ctx *gpcall,
             union gp_rpc_arg *arg,
             union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_rpc_wrap_size_limit.c b/proxy/src/gp_rpc_wrap_size_limit.c
index 90f989dbd03dc9bb951d3206cd149bc52686c88d..481d04a73b7b2645d04463aeb44e53e10ab8170a 100644
--- a/proxy/src/gp_rpc_wrap_size_limit.c
+++ b/proxy/src/gp_rpc_wrap_size_limit.c
@@ -27,8 +27,7 @@
 #include "gp_rpc_process.h"
 #include <gssapi/gssapi.h>
 
-int gp_wrap_size_limit(struct gssproxy_ctx *gpctx,
-                       struct gp_service *gpsvc,
+int gp_wrap_size_limit(struct gp_call_ctx *gpcall,
                        union gp_rpc_arg *arg,
                        union gp_rpc_res *res)
 {
diff --git a/proxy/src/gp_socket.c b/proxy/src/gp_socket.c
index 521a2ee951c1fd8e465b2469759c5952c3ee3125..b1851a21b85809bb7e054fd510f02c006689bd4e 100644
--- a/proxy/src/gp_socket.c
+++ b/proxy/src/gp_socket.c
@@ -101,6 +101,11 @@ struct gp_creds *gp_conn_get_creds(struct gp_conn *conn)
     return &conn->creds;
 }
 
+uid_t gp_conn_get_uid(struct gp_conn *conn)
+{
+    return conn->creds.ucred.uid;
+}
+
 const char *gp_conn_get_socket(struct gp_conn *conn)
 {
     return conn->sock_ctx->socket;
diff --git a/proxy/src/gp_workers.c b/proxy/src/gp_workers.c
index 6d650c6906eaca1c98e0559d5e548216bf6fa984..bca2cc8b82fc55a3f5c1a36212f6c5478e96ca78 100644
--- a/proxy/src/gp_workers.c
+++ b/proxy/src/gp_workers.c
@@ -430,19 +430,21 @@ static void *gp_worker_main(void *pvt)
 
 static void gp_handle_query(struct gp_workers *w, struct gp_query *q)
 {
-    struct gp_service *gpsvc;
+    struct gp_call_ctx gpcall;
     uint8_t *buffer;
     size_t buflen;
     int ret;
 
     /* find service */
-    gpsvc = gp_creds_match_conn(w->gpctx, q->conn);
-    if (!gpsvc) {
+    gpcall.gpctx = w->gpctx;
+    gpcall.service = gp_creds_match_conn(w->gpctx, q->conn);
+    if (!gpcall.service) {
         q->status = GP_QUERY_ERR;
         return;
     }
+    gpcall.connection = q->conn;
 
-    ret = gp_rpc_process_call(w->gpctx, gpsvc,
+    ret = gp_rpc_process_call(&gpcall,
                               q->buffer, q->buflen,
                               &buffer, &buflen);
     if (ret) {
-- 
1.8.3.1

