LCOV - code coverage report
Current view: top level - source4/librpc/ndr - py_security.c (source / functions) Hit Total Coverage
Test: coverage report for smb2.twrp.listdir_fix f886ca1c Lines: 250 356 70.2 %
Date: 2023-11-07 19:11:32 Functions: 30 35 85.7 %

          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             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : #include <Python.h>
      21             : #include "py3compat.h"
      22             : #include "libcli/security/sddl.h"
      23             : #include "libcli/security/security.h"
      24             : 
      25             : 
      26             : /* Set up in py_mod_security_patch() */
      27             : static PyObject *PyExc_SDDLValueError = NULL;
      28             : 
      29             : 
      30       29476 : static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods)
      31             : {
      32         764 :         PyObject *dict;
      33         764 :         int i;
      34       29476 :         if (type->tp_dict == NULL)
      35           0 :                 type->tp_dict = PyDict_New();
      36       29476 :         dict = type->tp_dict;
      37      162118 :         for (i = 0; methods[i].ml_name; i++) {
      38        3438 :                 PyObject *descr;
      39      132642 :                 if (methods[i].ml_flags & METH_CLASS) 
      40        7369 :                         descr = PyCFunction_New(&methods[i], (PyObject *)type);
      41             :                 else 
      42      125273 :                         descr = PyDescr_NewMethod(type, &methods[i]);
      43      132642 :                 PyDict_SetItemString(dict, methods[i].ml_name, 
      44             :                                      descr);
      45      132642 :                 Py_CLEAR(descr);
      46             :         }
      47       29476 : }
      48             : 
      49        8619 : static PyObject *py_dom_sid_split(PyObject *py_self, PyObject *args)
      50             : {
      51        8619 :         struct dom_sid *self = pytalloc_get_ptr(py_self);
      52          71 :         struct dom_sid *domain_sid;
      53          71 :         TALLOC_CTX *mem_ctx;
      54          71 :         uint32_t rid;
      55          71 :         NTSTATUS status;
      56          71 :         PyObject *py_domain_sid;
      57             : 
      58        8619 :         mem_ctx = talloc_new(NULL);
      59        8619 :         if (mem_ctx == NULL) {
      60           0 :                 PyErr_NoMemory();
      61           0 :                 return NULL;
      62             :         }
      63             : 
      64        8619 :         status = dom_sid_split_rid(mem_ctx, self, &domain_sid, &rid);
      65        8619 :         if (!NT_STATUS_IS_OK(status)) {
      66           0 :                 PyErr_SetString(PyExc_RuntimeError, "dom_sid_split_rid failed");
      67           0 :                 talloc_free(mem_ctx);
      68           0 :                 return NULL;
      69             :         }
      70             : 
      71        8619 :         py_domain_sid = pytalloc_steal(&dom_sid_Type, domain_sid);
      72        8619 :         talloc_free(mem_ctx);
      73        8619 :         return Py_BuildValue("(OI)", py_domain_sid, rid);
      74             : }
      75             : 
      76        4693 : static PyObject *py_dom_sid_richcmp(PyObject *py_self, PyObject *py_other, int op)
      77             : {
      78        4693 :         struct dom_sid *self = pytalloc_get_ptr(py_self), *other;
      79         121 :         int val;
      80             : 
      81        4693 :         other = pytalloc_get_ptr(py_other);
      82        4693 :         if (other == NULL) {
      83           0 :                 Py_INCREF(Py_NotImplemented);
      84           0 :                 return Py_NotImplemented;
      85             :         }
      86             : 
      87        4693 :         val =  dom_sid_compare(self, other);
      88             : 
      89        4693 :         switch (op) {
      90        4453 :                         case Py_EQ: if (val == 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      91         240 :                         case Py_NE: if (val != 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      92           0 :                         case Py_LT: if (val <  0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      93           0 :                         case Py_GT: if (val >  0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      94           0 :                         case Py_LE: if (val <= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      95           0 :                         case Py_GE: if (val >= 0) Py_RETURN_TRUE; else Py_RETURN_FALSE;
      96             :         }
      97           0 :         Py_INCREF(Py_NotImplemented);
      98           0 :         return Py_NotImplemented;
      99             : }
     100             : 
     101       63014 : static PyObject *py_dom_sid_str(PyObject *py_self)
     102             : {
     103       63014 :         struct dom_sid *self = pytalloc_get_ptr(py_self);
     104        1572 :         struct dom_sid_buf buf;
     105       63014 :         PyObject *ret = PyUnicode_FromString(dom_sid_str_buf(self, &buf));
     106       63014 :         return ret;
     107             : }
     108             : 
     109           1 : static PyObject *py_dom_sid_repr(PyObject *py_self)
     110             : {
     111           1 :         struct dom_sid *self = pytalloc_get_ptr(py_self);
     112           1 :         struct dom_sid_buf buf;
     113           1 :         PyObject *ret = PyUnicode_FromFormat(
     114             :                 "dom_sid('%s')", dom_sid_str_buf(self, &buf));
     115           1 :         return ret;
     116             : }
     117             : 
     118      122903 : static int py_dom_sid_init(PyObject *self, PyObject *args, PyObject *kwargs)
     119             : {
     120      122903 :         char *str = NULL;
     121      122903 :         struct dom_sid *sid = pytalloc_get_ptr(self);
     122      122903 :         const char *kwnames[] = { "str", NULL };
     123             : 
     124      122903 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &str))
     125           0 :                 return -1;
     126             : 
     127      122903 :         if (str != NULL && !dom_sid_parse(str, sid)) {
     128        6721 :                 PyErr_Format(PyExc_ValueError,
     129             :                              "Unable to parse string: '%s'", str);
     130        6721 :                 return -1;
     131             :         }
     132             : 
     133       49072 :         return 0;
     134             : }
     135             : 
     136             : static PyMethodDef py_dom_sid_extra_methods[] = {
     137             :         { "split", (PyCFunction)py_dom_sid_split, METH_NOARGS,
     138             :                 "S.split() -> (domain_sid, rid)\n"
     139             :                 "Split a domain sid" },
     140             :         {0}
     141             : };
     142             : 
     143             : 
     144        7369 : static void py_dom_sid_patch(PyTypeObject *type)
     145             : {
     146        7369 :         type->tp_init = py_dom_sid_init;
     147        7369 :         type->tp_str = py_dom_sid_str;
     148        7369 :         type->tp_repr = py_dom_sid_repr;
     149        7369 :         type->tp_richcompare = py_dom_sid_richcmp;
     150        7369 :         PyType_AddMethods(type, py_dom_sid_extra_methods);
     151        7178 : }
     152             : 
     153             : #define PY_DOM_SID_PATCH py_dom_sid_patch
     154             : 
     155        7335 : static PyObject *py_descriptor_sacl_add(PyObject *self, PyObject *args)
     156             : {
     157        7335 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     158        1495 :         NTSTATUS status;
     159        1495 :         struct security_ace *ace;
     160        1495 :         PyObject *py_ace;
     161        7335 :         Py_ssize_t idx = -1;
     162             : 
     163        7335 :         if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
     164           0 :                 return NULL;
     165             : 
     166        7335 :         ace = pytalloc_get_ptr(py_ace);
     167        7335 :         status = security_descriptor_sacl_insert(desc, ace, idx);
     168        7335 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     169        7335 :         Py_RETURN_NONE;
     170             : }
     171             : 
     172      861842 : static PyObject *py_descriptor_dacl_add(PyObject *self, PyObject *args)
     173             : {
     174      861842 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     175      144092 :         NTSTATUS status;
     176      144092 :         struct security_ace *ace;
     177      144092 :         PyObject *py_ace;
     178      861842 :         Py_ssize_t idx = -1;
     179             : 
     180      861842 :         if (!PyArg_ParseTuple(args, "O|n", &py_ace, &idx))
     181           0 :                 return NULL;
     182             : 
     183      861842 :         ace = pytalloc_get_ptr(py_ace);
     184             : 
     185      861842 :         status = security_descriptor_dacl_insert(desc, ace, idx);
     186      861842 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     187      861842 :         Py_RETURN_NONE;
     188             : }
     189             : 
     190           0 : static PyObject *py_descriptor_dacl_del(PyObject *self, PyObject *args)
     191             : {
     192           0 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     193           0 :         NTSTATUS status;
     194           0 :         struct dom_sid *sid;
     195           0 :         PyObject *py_sid;
     196             : 
     197           0 :         if (!PyArg_ParseTuple(args, "O", &py_sid))
     198           0 :                 return NULL;
     199             : 
     200           0 :         sid = pytalloc_get_ptr(py_sid);
     201           0 :         status = security_descriptor_dacl_del(desc, sid);
     202           0 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     203           0 :         Py_RETURN_NONE;
     204             : }
     205             : 
     206           0 : static PyObject *py_descriptor_sacl_del(PyObject *self, PyObject *args)
     207             : {
     208           0 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     209           0 :         NTSTATUS status;
     210           0 :         struct dom_sid *sid;
     211           0 :         PyObject *py_sid;
     212             : 
     213           0 :         if (!PyArg_ParseTuple(args, "O", &py_sid))
     214           0 :                 return NULL;
     215             : 
     216           0 :         sid = pytalloc_get_ptr(py_sid);
     217           0 :         status = security_descriptor_sacl_del(desc, sid);
     218           0 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     219           0 :         Py_RETURN_NONE;
     220             : }
     221             : 
     222      110779 : static PyObject *py_descriptor_dacl_del_ace(PyObject *self, PyObject *args)
     223             : {
     224      110779 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     225         594 :         NTSTATUS status;
     226      110779 :         struct security_ace *ace = NULL;
     227      110779 :         PyObject *py_ace = Py_None;
     228             : 
     229      110779 :         if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
     230           0 :                 return NULL;
     231             : 
     232      110779 :         if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
     233           0 :                 PyErr_SetString(PyExc_TypeError,
     234             :                                 "expected security.security_ace "
     235             :                                 "for first argument to .dacl_del_ace");
     236           0 :                 return NULL;
     237             :         }
     238             : 
     239      110779 :         ace = pytalloc_get_ptr(py_ace);
     240      110779 :         status = security_descriptor_dacl_del_ace(desc, ace);
     241      110779 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     242      110770 :         Py_RETURN_NONE;
     243             : }
     244             : 
     245           0 : static PyObject *py_descriptor_sacl_del_ace(PyObject *self, PyObject *args)
     246             : {
     247           0 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     248           0 :         NTSTATUS status;
     249           0 :         struct security_ace *ace = NULL;
     250           0 :         PyObject *py_ace = Py_None;
     251             : 
     252           0 :         if (!PyArg_ParseTuple(args, "O!", &security_ace_Type, &py_ace))
     253           0 :                 return NULL;
     254             : 
     255           0 :         if (!PyObject_TypeCheck(py_ace, &security_ace_Type)) {
     256           0 :                 PyErr_SetString(PyExc_TypeError,
     257             :                                 "expected security.security_ace "
     258             :                                 "for first argument to .sacl_del_ace");
     259           0 :                 return NULL;
     260             :         }
     261             : 
     262           0 :         ace = pytalloc_get_ptr(py_ace);
     263           0 :         status = security_descriptor_sacl_del_ace(desc, ace);
     264           0 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     265           0 :         Py_RETURN_NONE;
     266             : }
     267             : 
     268     1025139 : static PyObject *py_descriptor_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
     269             : {
     270     1025139 :         return pytalloc_steal(self, security_descriptor_initialise(NULL));
     271             : }
     272             : 
     273       49450 : static PyObject *py_descriptor_from_sddl(PyObject *self, PyObject *args)
     274             : {
     275       10076 :         struct security_descriptor *secdesc;
     276       10076 :         char *sddl;
     277       10076 :         PyObject *py_sid;
     278       10076 :         struct dom_sid *sid;
     279       49450 :         const char *err_msg = NULL;
     280       49450 :         size_t err_msg_offset = 0;
     281             : 
     282       49450 :         if (!PyArg_ParseTuple(args, "sO!", &sddl, &dom_sid_Type, &py_sid))
     283           0 :                 return NULL;
     284             : 
     285       49448 :         if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
     286           0 :                 PyErr_SetString(PyExc_TypeError,
     287             :                                 "expected security.dom_sid "
     288             :                                 "for second argument to .from_sddl");
     289           0 :                 return NULL;
     290             :         }
     291             : 
     292       49448 :         sid = pytalloc_get_ptr(py_sid);
     293             : 
     294       49448 :         secdesc = sddl_decode_err_msg(NULL, sddl, sid,
     295             :                                       &err_msg, &err_msg_offset);
     296       49448 :         if (secdesc == NULL) {
     297         214 :                 PyObject *exc = NULL;
     298         214 :                 if (err_msg == NULL) {
     299         197 :                         err_msg = "unknown error";
     300             :                 }
     301             :                 /*
     302             :                  * Some notes about this exception value:
     303             :                  *
     304             :                  * We don't want to add the offset first, so as not to
     305             :                  * confuse those who are used to the integer error
     306             :                  * code coming first.
     307             :                  *
     308             :                  * The errant sddl is added so that the exception can
     309             :                  * be caught some distance away from the call and we
     310             :                  * still know what the messages refer to.
     311             :                  */
     312         214 :                 exc = Py_BuildValue("(s, s, i, s)",
     313             :                                     "Unable to parse SDDL",
     314             :                                     err_msg,
     315             :                                     err_msg_offset,
     316             :                                     sddl);
     317         214 :                 if (exc == NULL) {
     318             :                         /* an exception was set by Py_BuildValue() */
     319           0 :                         return NULL;
     320             :                 }
     321         214 :                 PyErr_SetObject(PyExc_SDDLValueError, exc);
     322         214 :                 Py_DECREF(exc);
     323         214 :                 return NULL;
     324             :         }
     325             : 
     326       49234 :         return pytalloc_steal((PyTypeObject *)self, secdesc);
     327             : }
     328             : 
     329       77504 : static PyObject *py_descriptor_as_sddl(PyObject *self, PyObject *args)
     330             : {
     331         944 :         struct dom_sid *sid;
     332       77504 :         PyObject *py_sid = Py_None;
     333       77504 :         struct security_descriptor *desc = pytalloc_get_ptr(self);
     334         944 :         char *text;
     335         944 :         PyObject *ret;
     336             : 
     337       77504 :         if (!PyArg_ParseTuple(args, "|O!", &dom_sid_Type, &py_sid))
     338           0 :                 return NULL;
     339             : 
     340       77503 :         if (py_sid != Py_None)
     341       75837 :                 sid = pytalloc_get_ptr(py_sid);
     342             :         else
     343        1624 :                 sid = NULL;
     344             : 
     345       77503 :         text = sddl_encode(NULL, desc, sid);
     346       77503 :         if (text == NULL) {
     347           0 :                 PyErr_SetString(PyExc_ValueError, "Unable to encode SDDL");
     348           0 :                 return NULL;
     349             :         }
     350             : 
     351       77503 :         ret = PyUnicode_FromString(text);
     352             : 
     353       77503 :         talloc_free(text);
     354             : 
     355       77503 :         return ret;
     356             : }
     357             : 
     358             : static PyMethodDef py_descriptor_extra_methods[] = {
     359             :         { "sacl_add", (PyCFunction)py_descriptor_sacl_add, METH_VARARGS,
     360             :                 "S.sacl_add(ace) -> None\n"
     361             :                 "Add a security ace to this security descriptor" },
     362             :         { "dacl_add", (PyCFunction)py_descriptor_dacl_add, METH_VARARGS,
     363             :                 NULL },
     364             :         { "dacl_del", (PyCFunction)py_descriptor_dacl_del, METH_VARARGS,
     365             :                 NULL },
     366             :         { "sacl_del", (PyCFunction)py_descriptor_sacl_del, METH_VARARGS,
     367             :                 NULL },
     368             :         { "dacl_del_ace", (PyCFunction)py_descriptor_dacl_del_ace, METH_VARARGS,
     369             :                 NULL },
     370             :         { "sacl_del_ace", (PyCFunction)py_descriptor_sacl_del_ace, METH_VARARGS,
     371             :                 NULL },
     372             :         { "from_sddl", (PyCFunction)py_descriptor_from_sddl, METH_VARARGS|METH_CLASS,
     373             :                 NULL },
     374             :         { "as_sddl", (PyCFunction)py_descriptor_as_sddl, METH_VARARGS,
     375             :                 NULL },
     376             :         {0}
     377             : };
     378             : 
     379        7828 : static PyObject *py_descriptor_richcmp(
     380             :         PyObject *py_self, PyObject *py_other, int op)
     381             : {
     382        7828 :         struct security_descriptor *self = pytalloc_get_ptr(py_self);
     383        7828 :         struct security_descriptor *other = pytalloc_get_ptr(py_other);
     384        7828 :         bool eq;
     385             : 
     386        7828 :         if (other == NULL) {
     387           0 :                 Py_INCREF(Py_NotImplemented);
     388           0 :                 return Py_NotImplemented;
     389             :         }
     390             : 
     391        7828 :         eq = security_descriptor_equal(self, other);
     392             : 
     393        7828 :         switch(op) {
     394         143 :         case Py_EQ:
     395         143 :                 if (eq) {
     396         143 :                         Py_RETURN_TRUE;
     397             :                 } else {
     398           0 :                         Py_RETURN_FALSE;
     399             :                 }
     400        7685 :                 break;
     401        7685 :         case Py_NE:
     402        7685 :                 if (eq) {
     403        7568 :                         Py_RETURN_FALSE;
     404             :                 } else {
     405         117 :                         Py_RETURN_TRUE;
     406             :                 }
     407           0 :                 break;
     408           0 :         default:
     409           0 :                 break;
     410             :         }
     411             : 
     412           0 :         Py_RETURN_NOTIMPLEMENTED;
     413             : }
     414             : 
     415        7369 : static void py_descriptor_patch(PyTypeObject *type)
     416             : {
     417        7369 :         type->tp_new = py_descriptor_new;
     418        7369 :         type->tp_richcompare = py_descriptor_richcmp;
     419        7369 :         PyType_AddMethods(type, py_descriptor_extra_methods);
     420        7178 : }
     421             : 
     422             : #define PY_DESCRIPTOR_PATCH py_descriptor_patch
     423             : 
     424           0 : static PyObject *py_token_is_sid(PyObject *self, PyObject *args)
     425             : {
     426           0 :         PyObject *py_sid;
     427           0 :         struct dom_sid *sid;
     428           0 :         struct security_token *token = pytalloc_get_ptr(self);
     429           0 :         if (!PyArg_ParseTuple(args, "O", &py_sid))
     430           0 :                 return NULL;
     431             : 
     432           0 :         sid = pytalloc_get_ptr(py_sid);
     433             : 
     434           0 :         return PyBool_FromLong(security_token_is_sid(token, sid));
     435             : }
     436             : 
     437           0 : static PyObject *py_token_has_sid(PyObject *self, PyObject *args)
     438             : {
     439           0 :         PyObject *py_sid;
     440           0 :         struct dom_sid *sid;
     441           0 :         struct security_token *token = pytalloc_get_ptr(self);
     442           0 :         if (!PyArg_ParseTuple(args, "O", &py_sid))
     443           0 :                 return NULL;
     444             : 
     445           0 :         sid = pytalloc_get_ptr(py_sid);
     446             : 
     447           0 :         return PyBool_FromLong(security_token_has_sid(token, sid));
     448             : }
     449             : 
     450           3 : static PyObject *py_token_is_anonymous(PyObject *self,
     451             :         PyObject *Py_UNUSED(ignored))
     452             : {
     453           3 :         struct security_token *token = pytalloc_get_ptr(self);
     454             :         
     455           3 :         return PyBool_FromLong(security_token_is_anonymous(token));
     456             : }
     457             : 
     458          27 : static PyObject *py_token_is_system(PyObject *self,
     459             :         PyObject *Py_UNUSED(ignored))
     460             : {
     461          27 :         struct security_token *token = pytalloc_get_ptr(self);
     462             :         
     463          27 :         return PyBool_FromLong(security_token_is_system(token));
     464             : }
     465             : 
     466           2 : static PyObject *py_token_has_builtin_administrators(PyObject *self,
     467             :         PyObject *Py_UNUSED(ignored))
     468             : {
     469           2 :         struct security_token *token = pytalloc_get_ptr(self);
     470             :         
     471           2 :         return PyBool_FromLong(security_token_has_builtin_administrators(token));
     472             : }
     473             : 
     474           1 : static PyObject *py_token_has_nt_authenticated_users(PyObject *self,
     475             :         PyObject *Py_UNUSED(ignored))
     476             : {
     477           1 :         struct security_token *token = pytalloc_get_ptr(self);
     478             :         
     479           1 :         return PyBool_FromLong(security_token_has_nt_authenticated_users(token));
     480             : }
     481             : 
     482           3 : static PyObject *py_token_has_privilege(PyObject *self, PyObject *args)
     483             : {
     484           3 :         int priv;
     485           3 :         struct security_token *token = pytalloc_get_ptr(self);
     486             : 
     487           3 :         if (!PyArg_ParseTuple(args, "i", &priv))
     488           0 :                 return NULL;
     489             : 
     490           3 :         return PyBool_FromLong(security_token_has_privilege(token, priv));
     491             : }
     492             : 
     493           1 : static PyObject *py_token_set_privilege(PyObject *self, PyObject *args)
     494             : {
     495           1 :         int priv;
     496           1 :         struct security_token *token = pytalloc_get_ptr(self);
     497             : 
     498           1 :         if (!PyArg_ParseTuple(args, "i", &priv))
     499           0 :                 return NULL;
     500             : 
     501           1 :         security_token_set_privilege(token, priv);
     502           1 :         Py_RETURN_NONE;
     503             : }
     504             : 
     505          54 : static PyObject *py_token_new(PyTypeObject *self, PyObject *args, PyObject *kwargs)
     506             : {
     507          54 :         int evaluate_claims = CLAIMS_EVALUATION_INVALID_STATE;
     508          54 :         const char *kwnames[] = { "evaluate_claims", NULL };
     509             : 
     510          54 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i",
     511             :                                          discard_const_p(char *, kwnames),
     512             :                                          &evaluate_claims)) {
     513           0 :                 return NULL;
     514             :         }
     515             : 
     516          54 :         return pytalloc_steal(self, security_token_initialise(NULL, evaluate_claims));
     517             : }
     518             : 
     519             : static PyMethodDef py_token_extra_methods[] = {
     520             :         { "is_sid", (PyCFunction)py_token_is_sid, METH_VARARGS,
     521             :                 "S.is_sid(sid) -> bool\n"
     522             :                 "Check whether this token is of the specified SID." },
     523             :         { "has_sid", (PyCFunction)py_token_has_sid, METH_VARARGS,
     524             :                 NULL },
     525             :         { "is_anonymous", (PyCFunction)py_token_is_anonymous, METH_NOARGS,
     526             :                 "S.is_anonymous() -> bool\n"
     527             :                 "Check whether this is an anonymous token." },
     528             :         { "is_system", (PyCFunction)py_token_is_system, METH_NOARGS,
     529             :                 NULL },
     530             :         { "has_builtin_administrators", (PyCFunction)py_token_has_builtin_administrators, METH_NOARGS,
     531             :                 NULL },
     532             :         { "has_nt_authenticated_users", (PyCFunction)py_token_has_nt_authenticated_users, METH_NOARGS,
     533             :                 NULL },
     534             :         { "has_privilege", (PyCFunction)py_token_has_privilege, METH_VARARGS,
     535             :                 NULL },
     536             :         { "set_privilege", (PyCFunction)py_token_set_privilege, METH_VARARGS,
     537             :                 NULL },
     538             :         {0}
     539             : };
     540             : 
     541             : #define PY_TOKEN_PATCH py_token_patch
     542        7369 : static void py_token_patch(PyTypeObject *type)
     543             : {
     544        7369 :         type->tp_new = py_token_new;
     545        7369 :         PyType_AddMethods(type, py_token_extra_methods);
     546        7178 : }
     547             : 
     548           1 : static PyObject *py_privilege_name(PyObject *self, PyObject *args)
     549             : {
     550           1 :         int priv;
     551           1 :         const char *name = NULL;
     552           1 :         if (!PyArg_ParseTuple(args, "i", &priv)) {
     553           0 :                 return NULL;
     554             :         }
     555           1 :         name = sec_privilege_name(priv);
     556           1 :         if (name == NULL) {
     557           0 :                 PyErr_Format(PyExc_ValueError,
     558             :                              "Invalid privilege LUID: %d", priv);
     559           0 :                 return NULL;
     560             :         }
     561             : 
     562           1 :         return PyUnicode_FromString(name);
     563             : }
     564             : 
     565           1 : static PyObject *py_privilege_id(PyObject *self, PyObject *args)
     566             : {
     567           1 :         char *name;
     568             : 
     569           1 :         if (!PyArg_ParseTuple(args, "s", &name))
     570           0 :                 return NULL;
     571             : 
     572           1 :         return PyLong_FromLong(sec_privilege_id(name));
     573             : }
     574             : 
     575         143 : static PyObject *py_random_sid(PyObject *self,
     576             :         PyObject *Py_UNUSED(ignored))
     577             : {
     578          19 :         struct dom_sid *sid;
     579          19 :         PyObject *ret;
     580         143 :         char *str = talloc_asprintf(
     581             :                 NULL,
     582             :                 "S-1-5-21-%"PRIu32"-%"PRIu32"-%"PRIu32,
     583             :                 generate_random(),
     584             :                 generate_random(),
     585             :                 generate_random());
     586             : 
     587         143 :         sid = dom_sid_parse_talloc(NULL, str);
     588         143 :         talloc_free(str);
     589         143 :         ret = pytalloc_steal(&dom_sid_Type, sid);
     590         143 :         return ret;
     591             : }
     592             : 
     593             : static PyMethodDef py_mod_security_extra_methods[] = {
     594             :         { "random_sid", (PyCFunction)py_random_sid, METH_NOARGS, NULL },
     595             :         { "privilege_id", (PyCFunction)py_privilege_id, METH_VARARGS, NULL },
     596             :         { "privilege_name", (PyCFunction)py_privilege_name, METH_VARARGS, NULL },
     597             :         {0}
     598             : };
     599             : 
     600        7369 : static bool py_mod_security_patch(PyObject *m)
     601             : {
     602         191 :         int ret;
     603         191 :         int i;
     604       29476 :         for (i = 0; py_mod_security_extra_methods[i].ml_name; i++) {
     605       22107 :                 PyObject *descr = PyCFunction_New(&py_mod_security_extra_methods[i], NULL);
     606       22107 :                 ret = PyModule_AddObject(m, py_mod_security_extra_methods[i].ml_name,
     607             :                                          descr);
     608       22107 :                 if (ret != 0) {
     609           0 :                         return false;
     610             :                 }
     611             :         }
     612             :         /*
     613             :          * I wanted to make this a subclass of ValueError, but it
     614             :          * seems there isn't an easy way to do that using the API.
     615             :          * (c.f. SimpleExtendsException in cpython:Objects/exceptions.c)
     616             :          */
     617        7369 :         PyExc_SDDLValueError = PyErr_NewException("security.SDDLValueError",
     618             :                                                   NULL, NULL);
     619             : 
     620        7369 :         if (PyExc_SDDLValueError == NULL) {
     621           0 :                 return false;
     622             :         }
     623        7369 :         ret = PyModule_AddObject(m, "SDDLValueError", PyExc_SDDLValueError);
     624        7369 :         if (ret != 0) {
     625           0 :                 return false;
     626             :         }
     627        7178 :         return true;
     628             : }
     629             : 
     630             : #define PY_MOD_SECURITY_PATCH(m)                        \
     631             :         do {                                            \
     632             :                 bool _ok = py_mod_security_patch(m);    \
     633             :                 if (! _ok) {                            \
     634             :                         Py_XDECREF(m);                  \
     635             :                         return NULL;                    \
     636             :                 }                                       \
     637             :         } while(0)
     638             : 
     639      159954 : static PyObject *py_security_ace_equal(PyObject *py_self, PyObject *py_other, int op)
     640             : {
     641      159954 :         struct security_ace *self = pytalloc_get_ptr(py_self);
     642      159954 :         struct security_ace *other = NULL;
     643       14702 :         bool eq;
     644             : 
     645      159954 :         if (!PyObject_TypeCheck(py_other, &security_ace_Type)) {
     646           0 :                 eq = false;
     647             :         } else {
     648      159954 :                 other = pytalloc_get_ptr(py_other);
     649      159954 :                 eq = security_ace_equal(self, other);
     650             :         }
     651             : 
     652      159954 :         switch(op) {
     653      159952 :         case Py_EQ:
     654      159952 :                 if (eq) {
     655        1453 :                         Py_RETURN_TRUE;
     656             :                 } else {
     657      158499 :                         Py_RETURN_FALSE;
     658             :                 }
     659           2 :                 break;
     660           2 :         case Py_NE:
     661           2 :                 if (eq) {
     662           0 :                         Py_RETURN_FALSE;
     663             :                 } else {
     664           2 :                         Py_RETURN_TRUE;
     665             :                 }
     666           0 :                 break;
     667           0 :         default:
     668           0 :                 break;
     669             :         }
     670             : 
     671           0 :         Py_RETURN_NOTIMPLEMENTED;
     672             : }
     673             : 
     674          13 : static PyObject *py_security_ace_as_sddl(PyObject *self, PyObject *args)
     675             : {
     676          13 :         struct security_ace *ace = pytalloc_get_ptr(self);
     677          13 :         PyObject *py_sid = Py_None;
     678          13 :         struct dom_sid *sid = NULL;
     679          13 :         char *text = NULL;
     680          13 :         PyObject *ret = Py_None;
     681             : 
     682          13 :         if (!PyArg_ParseTuple(args, "O!", &dom_sid_Type, &py_sid))
     683           0 :                 return NULL;
     684             : 
     685          13 :         if (!PyObject_TypeCheck(py_sid, &dom_sid_Type)) {
     686           0 :                 PyErr_SetString(PyExc_TypeError,
     687             :                                 "expected security.dom_sid "
     688             :                                 "for second argument to .sddl_encode_ace");
     689           0 :                 return NULL;
     690             :         }
     691             : 
     692          13 :         sid = pytalloc_get_ptr(py_sid);
     693             : 
     694          13 :         text = sddl_encode_ace(NULL, ace, sid);
     695          13 :         if (text == NULL) {
     696           0 :                 return NULL;
     697             :         }
     698          13 :         ret = PyUnicode_FromString(text);
     699          13 :         talloc_free(text);
     700             : 
     701          13 :         return ret;
     702             : }
     703             : 
     704             : static PyMethodDef py_security_ace_extra_methods[] = {
     705             :         { "as_sddl", (PyCFunction)py_security_ace_as_sddl, METH_VARARGS, NULL },
     706             :         {0}
     707             : };
     708             : 
     709             : #define PY_ACE_PATCH py_security_ace_patch
     710             : 
     711        7369 : static void py_security_ace_patch(PyTypeObject *type)
     712             : {
     713        7369 :         type->tp_richcompare = py_security_ace_equal;
     714        7369 :         PyType_AddMethods(type, py_security_ace_extra_methods);
     715        7178 : }

Generated by: LCOV version 1.14