From 2a9af1f71887f02935e2fb6ad5023afba5b6d43e Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 27 Feb 2013 13:38:57 +0100 Subject: Add client library for SID related lookups This patch add a library for client side lookups for a SID or with a SID through the calls: - sss_nss_getsidbyname - sss_nss_getsidbyid - sss_nss_getnamebysid - sss_nss_getidbysid The library is called libsss_nss_idmap and the contributed spec file will create two new packages libsss_nss_idmap and libsss_nss_idmap-devel. --- src/sss_client/idmap/sss_nss_idmap.c | 255 +++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 src/sss_client/idmap/sss_nss_idmap.c (limited to 'src/sss_client/idmap/sss_nss_idmap.c') diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c new file mode 100644 index 00000000..e0faf6e7 --- /dev/null +++ b/src/sss_client/idmap/sss_nss_idmap.c @@ -0,0 +1,255 @@ +/* + SSSD + + NSS Responder Interface for ID-SID mappings + + Authors: + Sumit Bose + + Copyright (C) 2013 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include + +#include "sss_client/sss_cli.h" +#include "sss_client/idmap/sss_nss_idmap.h" +#include "util/strtonum.h" + +#define DATA_START (3 * sizeof(uint32_t)) +union input { + const char *str; + uint32_t id; +}; + +struct output { + enum sss_id_type type; + union { + char *str; + uint32_t id; + } d; +}; + +int nss_status_to_errno(enum nss_status nret) { + switch (nret) { + case NSS_STATUS_TRYAGAIN: + return EAGAIN; + case NSS_STATUS_SUCCESS: + return EOK; + case NSS_STATUS_UNAVAIL: + default: + return ENOENT; + } + + return EINVAL; +} + +static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , + struct output *out) +{ + int ret; + size_t inp_len; + struct sss_cli_req_data rd; + uint8_t *repbuf = NULL; + size_t replen; + int errnop; + enum nss_status nret; + uint32_t num_results; + char *str = NULL; + size_t data_len; + uint32_t c; + + switch (cmd) { + case SSS_NSS_GETSIDBYNAME: + case SSS_NSS_GETNAMEBYSID: + case SSS_NSS_GETIDBYSID: + ret = sss_strnlen(inp.str, SSS_NAME_MAX, &inp_len); + if (ret != EOK) { + return EINVAL; + } + + rd.len = inp_len + 1; + rd.data = inp.str; + + break; + case SSS_NSS_GETSIDBYID: + rd.len = sizeof(uint32_t); + rd.data = &inp.id; + + break; + default: + return EINVAL; + } + + sss_nss_lock(); + + nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop); + if (nret != NSS_STATUS_SUCCESS) { + ret = nss_status_to_errno(nret); + goto done; + } + + if (replen < 8) { + ret = EBADMSG; + goto done; + } + + num_results = ((uint32_t *)repbuf)[0]; + if (num_results == 0) { + ret = ENOENT; + goto done; + } else if (num_results > 1) { + ret = EBADMSG; + goto done; + } + + out->type = ((uint32_t *)repbuf)[2]; + + data_len = replen - DATA_START; + + switch(cmd) { + case SSS_NSS_GETSIDBYID: + case SSS_NSS_GETSIDBYNAME: + case SSS_NSS_GETNAMEBYSID: + if (data_len <= 1 || repbuf[replen - 1] != '\0') { + ret = EBADMSG; + goto done; + } + + str = malloc(sizeof(char) * data_len); + if (str == NULL) { + ret = ENOMEM; + goto done; + } + + strncpy(str, (char *) repbuf + DATA_START, data_len); + + out->d.str = str; + + break; + case SSS_NSS_GETIDBYSID: + if (data_len != sizeof(uint32_t)) { + ret = EBADMSG; + goto done; + } + + SAFEALIGN_COPY_UINT32(&c, repbuf + DATA_START, NULL); + out->d.id = c; + + break; + default: + ret = EINVAL; + goto done; + } + + ret = EOK; + +done: + sss_nss_unlock(); + free(repbuf); + if (ret != EOK) { + free(str); + } + + return ret; +} + +int sss_nss_getsidbyname(const char *fq_name, char **sid, + enum sss_id_type *type) +{ + int ret; + union input inp; + struct output out; + + if (sid == NULL || fq_name == NULL || *fq_name == '\0') { + return EINVAL; + } + + inp.str = fq_name; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out); + if (ret == EOK) { + *sid = out.d.str; + *type = out.type; + } + + return ret; +} + +int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) +{ + int ret; + union input inp; + struct output out; + + if (sid == NULL) { + return EINVAL; + } + + inp.id = id; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out); + if (ret == EOK) { + *sid = out.d.str; + *type = out.type; + } + + return ret; +} + +int sss_nss_getnamebysid(const char *sid, char **fq_name, + enum sss_id_type *type) +{ + int ret; + union input inp; + struct output out; + + if (fq_name == NULL || sid == NULL || *sid == '\0') { + return EINVAL; + } + + inp.str = sid; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out); + if (ret == EOK) { + *fq_name = out.d.str; + *type = out.type; + } + + return ret; +} + +int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) +{ + int ret; + union input inp; + struct output out; + + if (id == NULL || id_type == NULL || sid == NULL || *sid == '\0') { + return EINVAL; + } + + inp.str = sid; + + ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out); + if (ret == EOK) { + *id = out.d.id; + *id_type = out.type; + } + + return ret; +} -- cgit