]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
pynet: Add a hook to decrypt one attribute
authorAndrew Bartlett <abartlet@samba.org>
Wed, 17 May 2017 05:05:13 +0000 (17:05 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 25 May 2017 00:25:12 +0000 (02:25 +0200)
This will help with testing GetNCChanges and supplementalCredentials against Windows in Python

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
source4/libnet/py_net.c

index 35869358de20ae617dd5ca2e95126e95a08afe48..78e60f6d6a6d2d1bc50892b9cc96bb00991aba4c 100644 (file)
@@ -36,6 +36,7 @@
 #include "dsdb/samdb/samdb.h"
 #include "py_net.h"
 #include "librpc/rpc/pyrpc_util.h"
+#include "libcli/drsuapi/drsuapi.h"
 
 static void PyErr_SetDsExtendedError(enum drsuapi_DsExtendedError ext_err, const char *error_description)
 {
@@ -607,6 +608,75 @@ static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyO
 }
 
 
+/*
+  just do the decryption of a DRS replicated attribute
+ */
+static PyObject *py_net_replicate_decrypt(py_net_Object *self, PyObject *args, PyObject *kwargs)
+{
+       const char *kwnames[] = { "drspipe", "attribute", "rid", NULL };
+       PyObject *py_drspipe, *py_attribute;
+       NTSTATUS status;
+        dcerpc_InterfaceObject *drs_pipe;
+       TALLOC_CTX *frame;
+       TALLOC_CTX *context;
+       DATA_BLOB gensec_skey;
+       unsigned int rid;
+       struct drsuapi_DsReplicaAttribute *attribute;
+       WERROR werr;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOI",
+                                        discard_const_p(char *, kwnames),
+                                        &py_drspipe,
+                                        &py_attribute, &rid)) {
+               return NULL;
+       }
+
+       frame = talloc_stackframe();
+
+       if (!py_check_dcerpc_type(py_drspipe,
+                                 "samba.dcerpc.base",
+                                 "ClientConnection")) {
+               return NULL;
+       }
+       drs_pipe = (dcerpc_InterfaceObject *)(py_drspipe);
+
+       status = gensec_session_key(drs_pipe->pipe->conn->security_state.generic_state,
+                                   frame,
+                                   &gensec_skey);
+       if (!NT_STATUS_IS_OK(status)) {
+               char *error_string
+                       = talloc_asprintf(frame,
+                                         "Unable to get session key from drspipe: %s",
+                                         nt_errstr(status));
+               PyErr_SetNTSTATUS_and_string(status, error_string);
+               talloc_free(frame);
+               return NULL;
+       }
+
+       if (!py_check_dcerpc_type(py_attribute, "samba.dcerpc.drsuapi",
+                                 "DsReplicaAttribute")) {
+               return NULL;
+       }
+
+       attribute = pytalloc_get_ptr(py_attribute);
+       context   = pytalloc_get_mem_ctx(py_attribute);
+       werr = drsuapi_decrypt_attribute(context, &gensec_skey,
+                                        rid, 0, attribute);
+       if (!W_ERROR_IS_OK(werr)) {
+               char *error_string = talloc_asprintf(frame,
+                                                    "Unable to get decrypt attribute: %s",
+                                                    win_errstr(werr));
+               PyErr_SetWERROR_and_string(werr, error_string);
+               talloc_free(frame);
+               return NULL;
+       }
+
+       talloc_free(frame);
+
+       Py_RETURN_NONE;
+
+}
+
 /*
   find a DC given a domain name and server type
  */
@@ -659,6 +729,9 @@ static const char py_net_replicate_init_doc[] = "replicate_init(samdb, lp, drspi
 static const char py_net_replicate_chunk_doc[] = "replicate_chunk(state, level, ctr, schema)\n"
                                         "Process replication for one chunk";
 
+static const char py_net_replicate_decrypt_doc[] = "replicate_decrypt(drs, attribute, rid)\n"
+                                        "Decrypt (in place) a DsReplicaAttribute replicated with drs.GetNCChanges()";
+
 static const char py_net_finddc_doc[] = "finddc(flags=server_type, domain=None, address=None)\n"
                                         "Find a DC with the specified 'server_type' bits. The 'domain' and/or 'address' have to be used as additional search criteria. Returns the whole netlogon struct";
 
@@ -671,6 +744,7 @@ static PyMethodDef net_obj_methods[] = {
        {"delete_user", (PyCFunction)py_net_user_delete, METH_VARARGS|METH_KEYWORDS, py_net_delete_user_doc},
        {"replicate_init", (PyCFunction)py_net_replicate_init, METH_VARARGS|METH_KEYWORDS, py_net_replicate_init_doc},
        {"replicate_chunk", (PyCFunction)py_net_replicate_chunk, METH_VARARGS|METH_KEYWORDS, py_net_replicate_chunk_doc},
+       {"replicate_decrypt", (PyCFunction)py_net_replicate_decrypt, METH_VARARGS|METH_KEYWORDS, py_net_replicate_decrypt_doc},
        {"finddc", (PyCFunction)py_net_finddc, METH_KEYWORDS, py_net_finddc_doc},
        { NULL }
 };