gensec: Add gensec_{get,set}_target_service_description()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 20 Feb 2017 00:32:47 +0000 (13:32 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 29 Mar 2017 00:37:25 +0000 (02:37 +0200)
This allows a free text description of what the server-side service is for logging
purposes where the various services may be using the same Kerberos service or not
use Kerberos.

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Pair-Programmed-by: Gary Lockyer <gary@catalyst.net.nz>
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
auth/gensec/gensec.c
auth/gensec/gensec.h
source4/auth/gensec/pygensec.c
source4/rpc_server/dcesrv_auth.c

index d623613769174d5a920feb225572ce2750023f02..e413fbdfd6fdbd26b0121ea8459d4a84a2bae2aa 100644 (file)
@@ -574,6 +574,7 @@ _PUBLIC_ struct cli_credentials *gensec_get_credentials(struct gensec_security *
 /**
  * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed
  *
+ * This is used for Kerberos service principal name resolution.
  */
 
 _PUBLIC_ NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service)
@@ -594,6 +595,34 @@ _PUBLIC_ const char *gensec_get_target_service(struct gensec_security *gensec_se
        return "host";
 }
 
+/**
+ * Set the target service (such as 'samr') on an GENSEC context - ensures it is talloc()ed.
+ *
+ * This is not the Kerberos service principal, instead this is a
+ * constant value that can be logged as part of authentication and
+ * authorization logging
+ */
+_PUBLIC_ NTSTATUS gensec_set_target_service_description(struct gensec_security *gensec_security,
+                                                       const char *service)
+{
+       gensec_security->target.service_description = talloc_strdup(gensec_security, service);
+       if (!gensec_security->target.service_description) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+_PUBLIC_ const char *gensec_get_target_service_description(struct gensec_security *gensec_security)
+{
+       if (gensec_security->target.service_description) {
+               return gensec_security->target.service_description;
+       } else if (gensec_security->target.service) {
+               return gensec_security->target.service;
+       }
+
+       return NULL;
+}
+
 /**
  * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed
  *
index e8bd7b1f22a78f0effb4b06ec6012f6afc72a41c..0c9fa2661a84f49a43b0b2716ce2f0b68ad44881 100644 (file)
@@ -50,6 +50,7 @@ struct gensec_target {
        const char *principal;
        const char *hostname;
        const char *service;
+       const char *service_description;
 };
 
 #define GENSEC_FEATURE_SESSION_KEY     0x00000001
@@ -145,10 +146,26 @@ bool gensec_have_feature(struct gensec_security *gensec_security,
                         uint32_t feature);
 NTTIME gensec_expire_time(struct gensec_security *gensec_security);
 NTSTATUS gensec_set_credentials(struct gensec_security *gensec_security, struct cli_credentials *credentials);
+/**
+ * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed
+ *
+ * This is used for Kerberos service principal name resolution.
+ */
+
 NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service);
 const char *gensec_get_target_service(struct gensec_security *gensec_security);
 NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname);
 const char *gensec_get_target_hostname(struct gensec_security *gensec_security);
+/**
+ * Set the target service (such as 'samr') on an GENSEC context - ensures it is talloc()ed.
+ *
+ * This is not the Kerberos service principal, instead this is a
+ * constant value that can be logged as part of authentication and
+ * authorization logging
+ */
+const char *gensec_get_target_service_description(struct gensec_security *gensec_security);
+NTSTATUS gensec_set_target_service_description(struct gensec_security *gensec_security,
+                                              const char *service);
 NTSTATUS gensec_session_key(struct gensec_security *gensec_security,
                            TALLOC_CTX *mem_ctx,
                            DATA_BLOB *session_key);
index 946a0827eb8d946cd4b9148614aa476ec63ab9c4..d27fe28648a807bfe9e6f8fc4aca7974041b3f6c 100644 (file)
@@ -241,6 +241,25 @@ static PyObject *py_gensec_set_target_service(PyObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
+static PyObject *py_gensec_set_target_service_description(PyObject *self, PyObject *args)
+{
+       struct gensec_security *security = pytalloc_get_type(self, struct gensec_security);
+       char *target_service_description;
+       NTSTATUS status;
+
+       if (!PyArg_ParseTuple(args, "s", &target_service_description))
+               return NULL;
+
+       status = gensec_set_target_service_description(security,
+                                                      target_service_description);
+       if (!NT_STATUS_IS_OK(status)) {
+               PyErr_SetNTSTATUS(status);
+               return NULL;
+       }
+
+       Py_RETURN_NONE;
+}
+
 static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args)
 {
        PyObject *py_creds = Py_None;
@@ -617,9 +636,11 @@ static PyMethodDef py_gensec_security_methods[] = {
        { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 
                "S.start_client(credentials)" },
        { "set_target_hostname", (PyCFunction)py_gensec_set_target_hostname, METH_VARARGS, 
-               "S.start_target_hostname(target_hostname)" },
+               "S.start_target_hostname(target_hostname) \n This sets the Kerberos target hostname to obtain a ticket for." },
        { "set_target_service", (PyCFunction)py_gensec_set_target_service, METH_VARARGS, 
-               "S.start_target_service(target_service)" },
+               "S.start_target_service(target_service) \n This sets the Kerberos target service to obtain a ticket for.  The default value is 'host'" },
+       { "set_target_service_description", (PyCFunction)py_gensec_set_target_service_description, METH_VARARGS,
+               "S.start_target_service_description(target_service_description) \n This description is set server-side and used in authentication and authorization logs.  The default value is that provided to set_target_service() or None."},
        { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
                "S.session_info() -> info" },
        { "session_key", (PyCFunction)py_gensec_session_key, METH_NOARGS,
index af0079beabb95e817fec819d6415994cf1baa529..769b52bd00aac4979f99b94961e865307b83b18b 100644 (file)
@@ -125,6 +125,20 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call)
                return false;
        }
 
+       /*
+        * We have to call this because we set the target_service for
+        * Kerberos to NULL above, and in any case we wish to log a
+        * more specific service target.
+        *
+        */
+       status = gensec_set_target_service_description(auth->gensec_security,
+                                                      "DCE/RPC");
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(1, ("Failed to call gensec_set_target_service_description %s\n",
+                         nt_errstr(status)));
+               return false;
+       }
+
        if (call->conn->remote_address != NULL) {
                status = gensec_set_remote_address(auth->gensec_security,
                                                call->conn->remote_address);