LCOV - code coverage report
Current view: top level - source4/libnet - py_net_dckeytab.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 40 49 81.6 %
Date: 2024-05-31 13:13:24 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             : 
       5             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
       6             :    Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
       7             :    Copyright (C) Alexander Bokovoy <ab@samba.org> 2012
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "lib/replace/system/python.h"
      24             : #include "includes.h"
      25             : #include "python/py3compat.h"
      26             : #include "python/modules.h"
      27             : #include "py_net.h"
      28             : #include "libnet_export_keytab.h"
      29             : #include "pyldb.h"
      30             : #include "libcli/util/pyerrors.h"
      31             : 
      32          64 : static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObject *kwargs)
      33             : {
      34          64 :         struct libnet_export_keytab r = { .in = { .principal = NULL, }};
      35          64 :         PyObject *py_samdb = NULL;
      36           0 :         TALLOC_CTX *mem_ctx;
      37          64 :         const char *kwnames[] = { "keytab",
      38             :                                   "samdb",
      39             :                                   "principal",
      40             :                                   "keep_stale_entries",
      41             :                                   "only_current_keys",
      42             :                                   "as_for_AS_REQ",
      43             :                                   NULL };
      44           0 :         NTSTATUS status;
      45             :         /*
      46             :          * int, with values true or false, to match expectation of
      47             :          * PyArg_ParseTupleAndKeywords()
      48             :          */
      49          64 :         int keep_stale_entries = false;
      50          64 :         int only_current_keys = false;
      51          64 :         int as_for_AS_REQ = false;
      52             : 
      53          64 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Ozppp:export_keytab", discard_const_p(char *, kwnames),
      54             :                                          &r.in.keytab_name,
      55             :                                          &py_samdb,
      56             :                                          &r.in.principal,
      57             :                                          &keep_stale_entries,
      58             :                                          &only_current_keys,
      59             :                                          &as_for_AS_REQ)) {
      60           0 :                 return NULL;
      61             :         }
      62             : 
      63          64 :         r.in.keep_stale_entries = keep_stale_entries;
      64          64 :         r.in.only_current_keys = only_current_keys;
      65          64 :         r.in.as_for_AS_REQ = as_for_AS_REQ;
      66             : 
      67          64 :         if (py_samdb == NULL) {
      68          40 :                 r.in.samdb = NULL;
      69             :         } else {
      70          24 :                 PyErr_LDB_OR_RAISE(py_samdb, r.in.samdb);
      71             :         }
      72             : 
      73          64 :         mem_ctx = talloc_new(self->mem_ctx);
      74          64 :         if (mem_ctx == NULL) {
      75           0 :                 PyErr_NoMemory();
      76           0 :                 return NULL;
      77             :         }
      78             : 
      79          64 :         status = libnet_export_keytab(self->libnet_ctx, mem_ctx, &r);
      80             : 
      81          64 :         if (!NT_STATUS_IS_OK(status)) {
      82           4 :                 PyErr_SetNTSTATUS_and_string(status,
      83             :                                              r.out.error_string
      84             :                                              ? r.out.error_string
      85             :                                              : nt_errstr(status));
      86           4 :                 talloc_free(mem_ctx);
      87           4 :                 return NULL;
      88             :         }
      89             : 
      90          60 :         talloc_free(mem_ctx);
      91             : 
      92          60 :         Py_RETURN_NONE;
      93             : }
      94             : 
      95             : static const char py_net_export_keytab_doc[] =
      96             :         "export_keytab(keytab, samdb=None, principal=None, "
      97             :         "keep_stale_entries=False, only_current_keys=False, "
      98             :         "as_for_AS_REQ=False)\n\n"
      99             :         "Export the DC keytab to a keytab file.\n\n"
     100             :         "Pass as_for_AS_REQ=True to simulate the combination of flags normally "
     101             :         "utilized for an AS‐REQ. Samba’s testsuite uses this to verify which "
     102             :         "keys the KDC would see — some combination of previous and current "
     103             :         "keys — for a Group Managed Service Account performing an AS‐REQ.";
     104             : 
     105             : static PyMethodDef export_keytab_method_table[] = {
     106             :         {"export_keytab", PY_DISCARD_FUNC_SIG(PyCFunction,
     107             :                                               py_net_export_keytab),
     108             :                 METH_VARARGS|METH_KEYWORDS, py_net_export_keytab_doc},
     109             :         { NULL, NULL, 0, NULL }
     110             : };
     111             : 
     112             : /*
     113             :  * A fake Python module to inject export_keytab() method into existing samba.net.Net class.
     114             :  * Python enforces that every loaded module actually creates Python module record in
     115             :  * the global module table even if we don't really need that record. Thus, we initialize
     116             :  * dckeytab module but never use it.
     117             :  * */
     118             : static struct PyModuleDef moduledef = {
     119             :     PyModuleDef_HEAD_INIT,
     120             :     .m_name = "dckeytab",
     121             :     .m_doc = "dckeytab",
     122             :     .m_size = -1,
     123             :     .m_methods = NULL
     124             : };
     125             : 
     126         746 : MODULE_INIT_FUNC(dckeytab)
     127             : {
     128         746 :         PyObject *m = NULL;
     129          34 :         PyObject *Net;
     130          34 :         PyObject *descr;
     131          34 :         int ret;
     132             : 
     133         746 :         m = PyModule_Create(&moduledef);
     134         746 :         if (m == NULL)
     135           0 :                 return m;
     136             : 
     137         746 :         m = PyImport_ImportModule("samba.net");
     138         746 :         if (m == NULL)
     139           0 :                 return m;
     140             : 
     141         746 :         Net = (PyObject *)PyObject_GetAttrString(m, "Net");
     142         746 :         if (Net == NULL)
     143           0 :                 return m;
     144             : 
     145         746 :         descr = PyDescr_NewMethod((PyTypeObject*)Net, &export_keytab_method_table[0]);
     146         746 :         if (descr == NULL)
     147           0 :                 return m;
     148             : 
     149         746 :         ret = PyDict_SetItemString(((PyTypeObject*)Net)->tp_dict,
     150             :                                      export_keytab_method_table[0].ml_name,
     151             :                                      descr);
     152         746 :         if (ret != -1) {
     153         549 :                 Py_DECREF(descr);
     154             :         }
     155             : 
     156         712 :         return m;
     157             : }

Generated by: LCOV version 1.14