From 9d1397219374531e7f2a3188ea6aa9f86ca35f9e Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Feb 21 2018 09:14:38 +0000 Subject: nss-idmap: add sss_nss_getnamebycert() Reviewed-by: Jakub Hrozek Reviewed-by: Lukáš Slebodník (cherry picked from commit 9c88f837ffacf6548c13825589b327de1a5525f3) --- diff --git a/Makefile.am b/Makefile.am index 4e48886..9f54517 100644 --- a/Makefile.am +++ b/Makefile.am @@ -979,7 +979,7 @@ libsss_nss_idmap_la_LIBADD = \ $(CLIENT_LIBS) libsss_nss_idmap_la_LDFLAGS = \ -Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.exports \ - -version-info 1:0:1 + -version-info 2:0:2 dist_noinst_DATA += src/sss_client/idmap/sss_nss_idmap.exports diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 58431fb..a739998 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -454,23 +454,23 @@ used by Python applications. %endif %package -n libsss_nss_idmap -Summary: Library for SID based lookups +Summary: Library for SID and certificate based lookups Group: Development/Libraries License: LGPLv3+ Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig %description -n libsss_nss_idmap -Utility library for SID based lookups +Utility library for SID and certificate based lookups %package -n libsss_nss_idmap-devel -Summary: Library for SID based lookups +Summary: Library for SID and certificate based lookups Group: Development/Libraries License: LGPLv3+ Requires: libsss_nss_idmap = %{version}-%{release} %description -n libsss_nss_idmap-devel -Utility library for SID based lookups +Utility library for SID and certificate based lookups %package -n python-libsss_nss_idmap Summary: Python2 bindings for libsss_nss_idmap diff --git a/src/python/pysss_nss_idmap.c b/src/python/pysss_nss_idmap.c index a0561a0..aa290f6 100644 --- a/src/python/pysss_nss_idmap.c +++ b/src/python/pysss_nss_idmap.c @@ -33,7 +33,8 @@ enum lookup_type { SIDBYNAME, SIDBYID, NAMEBYSID, - IDBYSID + IDBYSID, + NAMEBYCERT }; static int add_dict(PyObject *py_result, PyObject *key, PyObject *res_type, @@ -166,6 +167,28 @@ static int do_getsidbyid(PyObject *py_result, PyObject *py_id) return ret; } +static int do_getnamebycert(PyObject *py_result, PyObject *py_cert) +{ + int ret; + const char *cert; + char *name = NULL; + enum sss_id_type id_type; + + cert = py_string_or_unicode_as_string(py_cert); + if (cert == NULL) { + return EINVAL; + } + + ret = sss_nss_getnamebycert(cert, &name, &id_type); + if (ret == 0) { + ret = add_dict(py_result, py_cert, PyBytes_FromString(SSS_NAME_KEY), + PyUnicode_FromString(name), PYNUMBER_FROMLONG(id_type)); + } + free(name); + + return ret; +} + static int do_getidbysid(PyObject *py_result, PyObject *py_sid) { const char *sid; @@ -203,6 +226,9 @@ static int do_lookup(enum lookup_type type, PyObject *py_result, case IDBYSID: return do_getidbysid(py_result, py_inp); break; + case NAMEBYCERT: + return do_getnamebycert(py_result, py_inp); + break; default: return ENOSYS; } @@ -260,7 +286,7 @@ static PyObject *check_args(enum lookup_type type, PyObject *args) case ENOENT: /* nothing found, return empty dict */ break; case EINVAL: - PyErr_Format(PyExc_ValueError, "Unable to retrieve argument\n"); + PyErr_Format(PyExc_ValueError, "Unable to retrieve result\n"); Py_XDECREF(py_result); return NULL; break; @@ -339,6 +365,21 @@ static PyObject * py_getidbysid(PyObject *module, PyObject *args) return check_args(IDBYSID, args); } +PyDoc_STRVAR(getnamebycert_doc, +"getnamebycert(sid or list/tuple of certificates) -> dict(sid => dict(results))\n\ +\n\ +Returns a dictionary with a dictonary of results for each given certificates.\n\ +The result dictonary contain the name and the type of the object which can be\n\ +accessed with the key constants NAME_KEY and TYPE_KEY, respectively.\n\ +\n\ +NOTE: getnamebycert currently works only with id_provider set as \"ad\" or \"ipa\"" +); + +static PyObject * py_getnamebycert(PyObject *module, PyObject *args) +{ + return check_args(NAMEBYCERT, args); +} + static PyMethodDef methods[] = { { sss_py_const_p(char, "getsidbyname"), (PyCFunction) py_getsidbyname, METH_VARARGS, getsidbyname_doc }, @@ -348,6 +389,8 @@ static PyMethodDef methods[] = { METH_VARARGS, getnamebysid_doc }, { sss_py_const_p(char, "getidbysid"), (PyCFunction) py_getidbysid, METH_VARARGS, getidbysid_doc }, + { sss_py_const_p(char, "getnamebycert"), (PyCFunction) py_getnamebycert, + METH_VARARGS, getnamebycert_doc }, { NULL,NULL, 0, NULL } }; diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 5b438fb..ef6f061 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -5556,6 +5556,7 @@ static int nss_cmd_getbycert(enum sss_cli_command cmd, struct cli_ctx *cctx) } derb64 = (const char *)body; + DEBUG(SSSDBG_TRACE_ALL, "cert [%s]\n", derb64); /* check input */ ret = sss_cert_derb64_to_pem(cctx, derb64, &pem_cert, &pem_size); diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c index 55d8043..fa5a499 100644 --- a/src/sss_client/idmap/sss_nss_idmap.c +++ b/src/sss_client/idmap/sss_nss_idmap.c @@ -159,7 +159,8 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: case SSS_NSS_GETORIGBYNAME: - ret = sss_strnlen(inp.str, SSS_NAME_MAX, &inp_len); + case SSS_NSS_GETNAMEBYCERT: + ret = sss_strnlen(inp.str, 2048, &inp_len); if (ret != EOK) { return EINVAL; } @@ -209,6 +210,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , case SSS_NSS_GETSIDBYID: case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETNAMEBYSID: + case SSS_NSS_GETNAMEBYCERT: if (data_len <= 1 || repbuf[replen - 1] != '\0') { ret = EBADMSG; goto done; @@ -368,3 +370,25 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, return ret; } + +int sss_nss_getnamebycert(const char *cert, char **fq_name, + enum sss_id_type *type) +{ + int ret; + union input inp; + struct output out; + + if (fq_name == NULL || cert == NULL || *cert == '\0') { + return EINVAL; + } + + inp.str = cert; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, &out); + if (ret == EOK) { + *fq_name = out.d.str; + *type = out.type; + } + + return ret; +} diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports index 8aa4702..bd5d802 100644 --- a/src/sss_client/idmap/sss_nss_idmap.exports +++ b/src/sss_client/idmap/sss_nss_idmap.exports @@ -19,3 +19,9 @@ SSS_NSS_IDMAP_0.1.0 { sss_nss_getorigbyname; sss_nss_free_kv; } SSS_NSS_IDMAP_0.0.1; + +SSS_NSS_IDMAP_0.2.0 { + # public functions + global: + sss_nss_getnamebycert; +} SSS_NSS_IDMAP_0.1.0; diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h index 78a8a11..8a62991 100644 --- a/src/sss_client/idmap/sss_nss_idmap.h +++ b/src/sss_client/idmap/sss_nss_idmap.h @@ -124,6 +124,21 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, enum sss_id_type *type); /** + * @brief Return the fully qualified name for the given base64 encoded + * X.509 certificate in DER format + * + * @param[in] cert base64 encoded certificate + * @param[out] fq_name Fully qualified name of a user or a group, + * must be freed by the caller + * @param[out] type Type of the object related to the SID + * + * @return + * - see #sss_nss_getsidbyname + */ +int sss_nss_getnamebycert(const char *cert, char **fq_name, + enum sss_id_type *type); + +/** * @brief Free key-value list returned by sss_nss_getorigbyname() * * @param[in] kv_list Key-value list returned by sss_nss_getorigbyname().