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

Generated by: LCOV version 1.14