summaryrefslogtreecommitdiffstats
path: root/src/sss_client/idmap/sss_nss_idmap.c
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-10-09 21:05:34 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-14 18:29:11 +0200
commit0d01e4f6cc21d8ca0e4fafe59c7cbfa1459fa47e (patch)
treefb81c6e36a8565cf5d9d311036e6395c6a0f84d1 /src/sss_client/idmap/sss_nss_idmap.c
parent229c292143dcd4120acb022682b5b7d0aca622dd (diff)
downloadsssd-0d01e4f6cc21d8ca0e4fafe59c7cbfa1459fa47e.tar.gz
sssd-0d01e4f6cc21d8ca0e4fafe59c7cbfa1459fa47e.tar.xz
sssd-0d01e4f6cc21d8ca0e4fafe59c7cbfa1459fa47e.zip
sss_nss_idmap: add sss_nss_getorigbyname()
This patch adds an interface to the new SSS_NSS_GETORIGBYNAME request of the nss responder to libsss_nss_idmap. The main use case for this new call is to replace sss_nss_getsidbyname() in the extdom plugin on the FreeIPA server to get more information about the given object than just the SID which is not available with the default POSIX interfaces. Reviewed-by: Pavel Březina <pbrezina@redhat.com> Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src/sss_client/idmap/sss_nss_idmap.c')
-rw-r--r--src/sss_client/idmap/sss_nss_idmap.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c
index adb588975..55d8043bd 100644
--- a/src/sss_client/idmap/sss_nss_idmap.c
+++ b/src/sss_client/idmap/sss_nss_idmap.c
@@ -41,6 +41,7 @@ struct output {
union {
char *str;
uint32_t id;
+ struct sss_nss_kv *kv_list;
} d;
};
@@ -58,6 +59,85 @@ int nss_status_to_errno(enum nss_status nret) {
return EINVAL;
}
+void sss_nss_free_kv(struct sss_nss_kv *kv_list)
+{
+ size_t c;
+
+ if (kv_list != NULL) {
+ for (c = 0; kv_list[c].key != NULL; c++) {
+ free(kv_list[c].key);
+ free(kv_list[c].value);
+ }
+ free(kv_list);
+ }
+}
+
+static int buf_to_kv_list(uint8_t *buf, size_t buf_len,
+ struct sss_nss_kv **kv_list)
+{
+ size_t c;
+ size_t count = 0;
+ struct sss_nss_kv *list;
+ uint8_t *p;
+ int ret;
+
+ for (c = 0; c < buf_len; c++) {
+ if (buf[c] == '\0') {
+ count++;
+ }
+ }
+
+ if ((count % 2) != 0) {
+ return EINVAL;
+ }
+ count /= 2;
+
+ list = calloc((count + 1), sizeof(struct sss_nss_kv));
+ if (list == NULL) {
+ return ENOMEM;
+ }
+
+ p = buf;
+ for (c = 0; c < count; c++) {
+ list[c].key = strdup((char *) p);
+ if (list[c].key == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ p = memchr(p, '\0', buf_len - (p - buf));
+ if (p == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+ p++;
+
+ list[c].value = strdup((char *) p);
+ if (list[c].value == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ p = memchr(p, '\0', buf_len - (p - buf));
+ if (p == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+ p++;
+ }
+
+ *kv_list = list;
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ sss_nss_free_kv(list);
+ }
+
+ return ret;
+}
+
static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
struct output *out)
{
@@ -72,11 +152,13 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
char *str = NULL;
size_t data_len;
uint32_t c;
+ struct sss_nss_kv *kv_list;
switch (cmd) {
case SSS_NSS_GETSIDBYNAME:
case SSS_NSS_GETNAMEBYSID:
case SSS_NSS_GETIDBYSID:
+ case SSS_NSS_GETORIGBYNAME:
ret = sss_strnlen(inp.str, SSS_NAME_MAX, &inp_len);
if (ret != EOK) {
return EINVAL;
@@ -153,6 +235,15 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd ,
out->d.id = c;
break;
+ case SSS_NSS_GETORIGBYNAME:
+ ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ out->d.kv_list = kv_list;
+
+ break;
default:
ret = EINVAL;
goto done;
@@ -255,3 +346,25 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type)
return ret;
}
+
+int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list,
+ enum sss_id_type *type)
+{
+ int ret;
+ union input inp;
+ struct output out;
+
+ if (kv_list == NULL || fq_name == NULL || *fq_name == '\0') {
+ return EINVAL;
+ }
+
+ inp.str = fq_name;
+
+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out);
+ if (ret == EOK) {
+ *kv_list = out.d.kv_list;
+ *type = out.type;
+ }
+
+ return ret;
+}