LCOV - code coverage report
Current view: top level - python - pysss_nss_idmap.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 136 0.0 %
Date: 2015-10-19 Functions: 0 14 0.0 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Sumit Bose <sbose@redhat.com>
       4             :         Alexander Bokovoy <abokovoy@redhat.com>
       5             : 
       6             :     Copyright (C) 2013 Red Hat
       7             : 
       8             :     This program is free software; you can redistribute it and/or modify
       9             :     it under the terms of the GNU General Public License as published by
      10             :     the Free Software Foundation; either version 3 of the License, or
      11             :     (at your option) any later version.
      12             : 
      13             :     This program is distributed in the hope that it will be useful,
      14             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :     GNU General Public License for more details.
      17             : 
      18             :     You should have received a copy of the GNU General Public License
      19             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include <Python.h>
      23             : #include "util/sss_python.h"
      24             : 
      25             : #include "sss_client/idmap/sss_nss_idmap.h"
      26             : 
      27             : #define SSS_NAME_KEY "name"
      28             : #define SSS_SID_KEY "sid"
      29             : #define SSS_ID_KEY "id"
      30             : #define SSS_TYPE_KEY "type"
      31             : 
      32             : enum lookup_type {
      33             :     SIDBYNAME,
      34             :     SIDBYID,
      35             :     NAMEBYSID,
      36             :     IDBYSID
      37             : };
      38             : 
      39           0 : static int add_dict(PyObject *py_result, PyObject *key, PyObject *res_type,
      40             :                     PyObject *res, PyObject *id_type)
      41             : {
      42             :     int ret;
      43             :     PyObject *py_dict;
      44             : 
      45           0 :     py_dict =  PyDict_New();
      46           0 :     if (py_dict == NULL) {
      47           0 :         return ENOMEM;
      48             :     }
      49             : 
      50           0 :     ret = PyDict_SetItem(py_dict, res_type, res);
      51           0 :     if (ret != 0) {
      52           0 :         Py_XDECREF(py_dict);
      53           0 :         return ret;
      54             :     }
      55             : 
      56           0 :     ret = PyDict_SetItem(py_dict, PyBytes_FromString(SSS_TYPE_KEY), id_type);
      57           0 :     if (ret != 0) {
      58           0 :         Py_XDECREF(py_dict);
      59           0 :         return ret;
      60             :     }
      61             : 
      62           0 :     ret = PyDict_SetItem(py_result, key, py_dict);
      63             : 
      64           0 :     return ret;
      65             : }
      66             : 
      67           0 : static char *py_string_or_unicode_as_string(PyObject *inp)
      68             : {
      69           0 :     PyObject *py_str = NULL;
      70             : 
      71           0 :     if (PyUnicode_Check(inp)) {
      72           0 :         py_str = PyUnicode_AsUTF8String(inp);
      73           0 :     } else if (PyBytes_Check(inp)) {
      74           0 :         py_str = inp;
      75             :     } else {
      76           0 :         PyErr_Format(PyExc_TypeError, "input must be unicode or a string");
      77           0 :         return NULL;
      78             :     }
      79             : 
      80           0 :     return PyBytes_AS_STRING(py_str);
      81             : }
      82             : 
      83           0 : static int do_getsidbyname(PyObject *py_result, PyObject *py_name)
      84             : {
      85             :     int ret;
      86             :     const char *name;
      87           0 :     char *sid = NULL;
      88             :     enum sss_id_type id_type;
      89             : 
      90           0 :     name = py_string_or_unicode_as_string(py_name);
      91           0 :     if (name == NULL) {
      92           0 :         return EINVAL;
      93             :     }
      94             : 
      95           0 :     ret = sss_nss_getsidbyname(name, &sid, &id_type);
      96           0 :     if (ret == 0) {
      97           0 :         ret = add_dict(py_result, py_name, PyBytes_FromString(SSS_SID_KEY),
      98             :                        PyUnicode_FromString(sid), PYNUMBER_FROMLONG(id_type));
      99             :     }
     100           0 :     free(sid);
     101             : 
     102           0 :     return ret;
     103             : }
     104             : 
     105           0 : static int do_getnamebysid(PyObject *py_result, PyObject *py_sid)
     106             : {
     107             :     int ret;
     108             :     const char *sid;
     109           0 :     char *name = NULL;
     110             :     enum sss_id_type id_type;
     111             : 
     112           0 :     sid = py_string_or_unicode_as_string(py_sid);
     113           0 :     if (sid == NULL) {
     114           0 :         return EINVAL;
     115             :     }
     116             : 
     117           0 :     ret = sss_nss_getnamebysid(sid, &name, &id_type);
     118           0 :     if (ret == 0) {
     119           0 :         ret = add_dict(py_result, py_sid, PyBytes_FromString(SSS_NAME_KEY),
     120             :                        PyUnicode_FromString(name), PYNUMBER_FROMLONG(id_type));
     121             :     }
     122           0 :     free(name);
     123             : 
     124           0 :     return ret;
     125             : }
     126             : 
     127           0 : static int do_getsidbyid(PyObject *py_result, PyObject *py_id)
     128             : {
     129             :     long id;
     130             :     const char *id_str;
     131             :     char *endptr;
     132           0 :     char *sid = NULL;
     133             :     int ret;
     134             :     enum sss_id_type id_type;
     135             : 
     136             : #ifndef IS_PY3K
     137           0 :     if (PyInt_Check(py_id)) {
     138           0 :         id = PyInt_AS_LONG(py_id);
     139             :     } else
     140             : #endif
     141           0 :     if (PyLong_Check(py_id)) {
     142           0 :         id = PyLong_AsLong(py_id);
     143             :     } else {
     144           0 :         id_str = py_string_or_unicode_as_string(py_id);
     145           0 :         if (id_str == NULL) {
     146           0 :             return EINVAL;
     147             :         }
     148           0 :         errno = 0;
     149           0 :         id = strtol(id_str, &endptr, 10);
     150           0 :         if (errno != 0 || *endptr != '\0') {
     151           0 :             return EINVAL;
     152             :         }
     153             :     }
     154             : 
     155           0 :     if (id < 0 || id > UINT32_MAX) {
     156           0 :         return EINVAL;
     157             :     }
     158             : 
     159           0 :     ret = sss_nss_getsidbyid((uint32_t) id, &sid, &id_type);
     160           0 :     if (ret == 0) {
     161           0 :         ret = add_dict(py_result, py_id, PyBytes_FromString(SSS_SID_KEY),
     162             :                        PyUnicode_FromString(sid), PYNUMBER_FROMLONG(id_type));
     163             :     }
     164           0 :     free(sid);
     165             : 
     166           0 :     return ret;
     167             : }
     168             : 
     169           0 : static int do_getidbysid(PyObject *py_result, PyObject *py_sid)
     170             : {
     171             :     const char *sid;
     172             :     uint32_t id;
     173             :     enum sss_id_type id_type;
     174             :     int ret;
     175             : 
     176           0 :     sid = py_string_or_unicode_as_string(py_sid);
     177           0 :     if (sid == NULL) {
     178           0 :         return EINVAL;
     179             :     }
     180             : 
     181           0 :     ret = sss_nss_getidbysid(sid, &id, &id_type);
     182           0 :     if (ret == 0) {
     183           0 :         ret = add_dict(py_result, py_sid, PyBytes_FromString(SSS_ID_KEY),
     184             :                        PYNUMBER_FROMLONG(id), PYNUMBER_FROMLONG(id_type));
     185             :     }
     186             : 
     187           0 :     return ret;
     188             : }
     189             : 
     190           0 : static int do_lookup(enum lookup_type type, PyObject *py_result,
     191             :                      PyObject *py_inp)
     192             : {
     193           0 :     switch(type) {
     194             :     case SIDBYNAME:
     195           0 :         return do_getsidbyname(py_result, py_inp);
     196             :         break;
     197             :     case NAMEBYSID:
     198           0 :         return do_getnamebysid(py_result, py_inp);
     199             :         break;
     200             :     case SIDBYID:
     201           0 :         return do_getsidbyid(py_result, py_inp);
     202             :         break;
     203             :     case IDBYSID:
     204           0 :         return do_getidbysid(py_result, py_inp);
     205             :         break;
     206             :     default:
     207           0 :         return ENOSYS;
     208             :     }
     209             : 
     210             :     return ENOSYS;
     211             : }
     212             : 
     213           0 : static PyObject *check_args(enum lookup_type type, PyObject *args)
     214             : {
     215             :     PyObject *obj, *py_value;
     216             :     int ret;
     217             :     Py_ssize_t len, i;
     218             :     PyObject *py_result;
     219             : 
     220           0 :     if (!PyArg_ParseTuple(args, sss_py_const_p(char, "O"), &obj)) {
     221           0 :         PyErr_Format(PyExc_ValueError, "Unable to retrieve argument\n");
     222           0 :         return NULL;
     223             :     }
     224             : 
     225           0 :     if (!(PyList_Check(obj) || PyTuple_Check(obj) ||
     226           0 :           PyBytes_Check(obj) || PyUnicode_Check(obj) ||
     227           0 :           (type == SIDBYID && (PYNUMBER_CHECK(obj))))) {
     228           0 :         PyErr_Format(PyExc_ValueError,
     229             :                      "Only string, long or list or tuples of them " \
     230             :                      "are accepted\n");
     231           0 :         return NULL;
     232             :     }
     233             : 
     234           0 :     py_result = PyDict_New();
     235           0 :     Py_XINCREF(py_result);
     236           0 :     if (py_result == NULL) {
     237           0 :         PyErr_Format(PyExc_MemoryError,
     238             :                      "Unable to allocate resulting dictionary\n");
     239           0 :         return NULL;
     240             :     }
     241             : 
     242           0 :     if (PyList_Check(obj) || PyTuple_Check(obj)) {
     243           0 :         len = PySequence_Size(obj);
     244           0 :         for(i=0; i < len; i++) {
     245           0 :             py_value = PySequence_GetItem(obj, i);
     246           0 :             if ((py_value != NULL) &&
     247           0 :                 (PyBytes_Check(py_value) || PyUnicode_Check(py_value) ||
     248           0 :                  (type == SIDBYID && PYNUMBER_CHECK(py_value)))) {
     249           0 :                 ret = do_lookup(type, py_result, py_value);
     250           0 :                 if (ret != 0) {
     251             :                     /* Skip this name */
     252           0 :                     continue;
     253             :                 }
     254             :             }
     255             :         }
     256             :     } else {
     257           0 :         ret = do_lookup(type, py_result, obj);
     258           0 :         switch (ret) {
     259             :         case 0:
     260             :         case ENOENT: /* nothing found, return empty dict */
     261           0 :             break;
     262             :         case EINVAL:
     263           0 :             PyErr_Format(PyExc_ValueError, "Unable to retrieve argument\n");
     264           0 :             Py_XDECREF(py_result);
     265           0 :             return NULL;
     266             :             break;
     267             :         default:
     268           0 :             PyErr_Format(PyExc_IOError, "Operation not supported\n");
     269           0 :             Py_XDECREF(py_result);
     270           0 :             return NULL;
     271             :         }
     272             :     }
     273             : 
     274           0 :     Py_XDECREF(py_result);
     275           0 :     return py_result;
     276             : 
     277             : }
     278             : 
     279             : PyDoc_STRVAR(getsidbyname_doc,
     280             : "getsidbyname(name or list/tuple of names) -> dict(name => dict(results))\n\
     281             : \n\
     282             : Returns a dictionary with a dictonary of results for each given name.\n\
     283             : The result dictonary contain the SID and the type of the object which can be\n\
     284             : accessed with the key constants SID_KEY and TYPE_KEY, respectively.\n\
     285             : \n\
     286             : The return type can be one of the following constants:\n\
     287             : - ID_NOT_SPECIFIED\n\
     288             : - ID_USER\n\
     289             : - ID_GROUP\n\
     290             : - ID_BOTH"
     291             : );
     292             : 
     293           0 : static PyObject * py_getsidbyname(PyObject *module, PyObject *args)
     294             : {
     295           0 :     return check_args(SIDBYNAME, args);
     296             : }
     297             : 
     298             : PyDoc_STRVAR(getsidbyid_doc,
     299             : "getsidbyid(id or list/tuple of id) -> dict(id => dict(results))\n\
     300             : \n\
     301             : Returns a dictionary with a dictonary of results for each given POSIX ID.\n\
     302             : The result dictonary contain the SID and the type of the object which can be\n\
     303             : accessed with the key constants SID_KEY and TYPE_KEY, respectively."
     304             : );
     305             : 
     306           0 : static PyObject * py_getsidbyid(PyObject *module, PyObject *args)
     307             : {
     308           0 :     return check_args(SIDBYID, args);
     309             : }
     310             : 
     311             : PyDoc_STRVAR(getnamebysid_doc,
     312             : "getnamebysid(sid or list/tuple of sid) -> dict(sid => dict(results))\n\
     313             : \n\
     314             : Returns a dictionary with a dictonary of results for each given SID.\n\
     315             : The result dictonary contain the name and the type of the object which can be\n\
     316             : accessed with the key constants NAME_KEY and TYPE_KEY, respectively.\n\
     317             : \n\
     318             : NOTE: getnamebysid currently works only with id_provider set as \"ad\" or \"ipa\""
     319             : );
     320             : 
     321           0 : static PyObject * py_getnamebysid(PyObject *module, PyObject *args)
     322             : {
     323           0 :     return check_args(NAMEBYSID, args);
     324             : }
     325             : 
     326             : PyDoc_STRVAR(getidbysid_doc,
     327             : "getidbysid(sid) -> POSIX ID\n\
     328             : \n\
     329             : Returns the POSIX ID of the object with the given SID."
     330             : "getidbysid(sid or list/tuple of sid) -> dict(sid => dict(results))\n\
     331             : \n\
     332             : Returns a dictionary with a dictonary of results for each given SID.\n\
     333             : The result dictonary contain the POSIX ID and the type of the object which\n\
     334             : can be accessed with the key constants ID_KEY and TYPE_KEY, respectively."
     335             : );
     336             : 
     337           0 : static PyObject * py_getidbysid(PyObject *module, PyObject *args)
     338             : {
     339           0 :     return check_args(IDBYSID, args);
     340             : }
     341             : 
     342             : static PyMethodDef methods[] = {
     343             :     { sss_py_const_p(char, "getsidbyname"), (PyCFunction) py_getsidbyname,
     344             :       METH_VARARGS, getsidbyname_doc },
     345             :     { sss_py_const_p(char, "getsidbyid"), (PyCFunction) py_getsidbyid,
     346             :       METH_VARARGS, getsidbyid_doc },
     347             :     { sss_py_const_p(char, "getnamebysid"), (PyCFunction) py_getnamebysid,
     348             :       METH_VARARGS, getnamebysid_doc },
     349             :     { sss_py_const_p(char, "getidbysid"), (PyCFunction) py_getidbysid,
     350             :       METH_VARARGS, getidbysid_doc },
     351             :     { NULL,NULL, 0, NULL }
     352             : };
     353             : 
     354             : #ifdef IS_PY3K
     355             : static struct PyModuleDef pysss_nss_idmap_def = {
     356             :     PyModuleDef_HEAD_INIT,
     357             :     "pysss_nss_idmap",
     358             :     NULL,
     359             :     -1,
     360             :     methods,
     361             :     NULL,
     362             :     NULL,
     363             :     NULL,
     364             :     NULL
     365             : };
     366             : 
     367             : PyMODINIT_FUNC
     368           0 : PyInit_pysss_nss_idmap(void)
     369             : #else
     370             : PyMODINIT_FUNC
     371           0 : initpysss_nss_idmap(void)
     372             : #endif
     373             : {
     374             :     PyObject *module;
     375             : 
     376             : #ifdef IS_PY3K
     377           0 :     module = PyModule_Create(&pysss_nss_idmap_def);
     378             : #else
     379           0 :     module = Py_InitModule3(sss_py_const_p(char, "pysss_nss_idmap"),
     380             :                             methods,
     381             :                             sss_py_const_p(char, "SSSD ID-mapping functions"));
     382             : #endif
     383           0 :     if (module == NULL)
     384           0 :         MODINITERROR;
     385             : 
     386           0 :     PyModule_AddIntConstant(module, "ID_NOT_SPECIFIED",
     387             :                             SSS_ID_TYPE_NOT_SPECIFIED);
     388           0 :     PyModule_AddIntConstant(module, "ID_USER", SSS_ID_TYPE_UID);
     389           0 :     PyModule_AddIntConstant(module, "ID_GROUP", SSS_ID_TYPE_GID);
     390           0 :     PyModule_AddIntConstant(module, "ID_BOTH", SSS_ID_TYPE_BOTH);
     391             : 
     392           0 :     PyModule_AddStringConstant(module, "SID_KEY", SSS_SID_KEY);
     393           0 :     PyModule_AddStringConstant(module, "NAME_KEY", SSS_NAME_KEY);
     394           0 :     PyModule_AddStringConstant(module, "ID_KEY", SSS_ID_KEY);
     395           0 :     PyModule_AddStringConstant(module, "TYPE_KEY", SSS_TYPE_KEY);
     396             : 
     397             : #ifdef IS_PY3K
     398           0 :     return module;
     399             : #endif
     400             : }

Generated by: LCOV version 1.10