summaryrefslogtreecommitdiffstats
path: root/nsswitch/libwbclient/wbc_sid_sssd.c
diff options
context:
space:
mode:
Diffstat (limited to 'nsswitch/libwbclient/wbc_sid_sssd.c')
-rw-r--r--nsswitch/libwbclient/wbc_sid_sssd.c171
1 files changed, 168 insertions, 3 deletions
diff --git a/nsswitch/libwbclient/wbc_sid_sssd.c b/nsswitch/libwbclient/wbc_sid_sssd.c
index 4826f295fb7..28d181c5664 100644
--- a/nsswitch/libwbclient/wbc_sid_sssd.c
+++ b/nsswitch/libwbclient/wbc_sid_sssd.c
@@ -21,18 +21,69 @@
/* Required Headers */
+#include <sss_nss_idmap.h>
+
#include "replace.h"
#include "libwbclient.h"
#include "../winbind_client.h"
#include "wbc_sssd_internal.h"
+static int sss_id_type_to_wbcSidType(enum sss_id_type sss_type,
+ enum wbcSidType *name_type)
+{
+ switch (sss_type) {
+ case SSS_ID_TYPE_NOT_SPECIFIED:
+ *name_type = WBC_SID_NAME_USE_NONE;
+ break;
+ case SSS_ID_TYPE_UID:
+ case SSS_ID_TYPE_BOTH:
+ *name_type = WBC_SID_NAME_USER;
+ break;
+ case SSS_ID_TYPE_GID:
+ *name_type = WBC_SID_NAME_DOM_GRP;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+};
+
/* Convert a domain and name to SID */
wbcErr wbcLookupName(const char *domain,
const char *name,
struct wbcDomainSid *sid,
enum wbcSidType *name_type)
{
- WBC_SSSD_NOT_IMPLEMENTED;
+ char *fq_name = NULL;
+ char *str_sid;
+ enum sss_id_type type;
+ int ret;
+ wbcErr wbc_status;
+
+ ret = asprintf(&fq_name, "%s@%s", name, domain);
+ if (ret == -1) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ ret = sss_nss_getsidbyname(fq_name, &str_sid, &type);
+ free(fq_name);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ ret = sss_id_type_to_wbcSidType(type, name_type);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ wbc_status = wbcStringToSid(str_sid, sid);
+ free(str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ return WBC_ERR_SUCCESS;
}
@@ -42,7 +93,55 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
char **pname,
enum wbcSidType *pname_type)
{
- WBC_SSSD_NOT_IMPLEMENTED;
+ char *str_sid;
+ char *fq_name = NULL;
+ enum sss_id_type type;
+ int ret;
+ char *p;
+ wbcErr wbc_status;
+
+ wbc_status = wbcSidToString(sid, &str_sid);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ ret = sss_nss_getnamebysid(str_sid, &fq_name, &type);
+ wbcFreeMemory(str_sid);
+ if (ret != 0) {
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ ret = sss_id_type_to_wbcSidType(type, pname_type);
+ if (ret != 0) {
+ wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ goto done;
+ }
+
+ /* FIXME: it would be nice to have a sss_nss_getnamebysid() call which
+ * return name and domain separately. */
+ p = strchr(fq_name, '@');
+ if (p == NULL) {
+ wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ goto done;
+ }
+
+ *p = '\0';
+ *pname = wbcStrDup(fq_name);
+ if (*pname == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ *pdomain = wbcStrDup(p + 1);
+ if (*pdomain == NULL) {
+ wbc_status = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ wbc_status = WBC_ERR_SUCCESS;
+done:
+ free(fq_name);
+ return wbc_status;
}
wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
@@ -61,7 +160,73 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
const char ***pnames,
enum wbcSidType **ptypes)
{
- WBC_SSSD_NOT_IMPLEMENTED;
+ struct wbcDomainSid obj_sid;
+ size_t c;
+ wbcErr err;
+ char *domain;
+ char *name;
+ enum wbcSidType type;
+ const char **names = NULL;
+ enum wbcSidType *types = NULL;
+
+ memset(&obj_sid, 0, sizeof(obj_sid));
+
+ obj_sid.sid_rev_num = dom_sid->sid_rev_num;
+ obj_sid.num_auths = dom_sid->num_auths + 1;
+ for (c = 0; c < 6; c++) {
+ obj_sid.id_auth[c] = dom_sid->id_auth[c];
+ }
+ for (c = 0; c < WBC_MAXSUBAUTHS; c++) {
+ obj_sid.sub_auths[c] = dom_sid->sub_auths[c];
+ }
+
+ names = wbcAllocateStringArray(num_rids + 1);
+ if (names == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ types = wbcAllocateMemory(num_rids + 1, sizeof(enum wbcSidType), NULL);
+ if (types == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+
+ for (c = 0; c < num_rids; c++) {
+ obj_sid.sub_auths[obj_sid.num_auths - 1] = rids[c];
+
+ err = wbcLookupSid(&obj_sid, &domain, &name, &type);
+ if (err != WBC_ERR_SUCCESS) {
+ goto done;
+ }
+
+ names[c] = strdup(name);
+ wbcFreeMemory(name);
+ if (names[c] == NULL) {
+ err = WBC_ERR_NO_MEMORY;
+ goto done;
+ }
+ types[c] = type;
+
+ if (c == 0) {
+ *pp_domain_name = domain;
+ } else {
+ wbcFreeMemory(domain);
+ }
+ }
+
+ *pnames = names;
+ *ptypes = types;
+
+ err = WBC_ERR_SUCCESS;
+
+done:
+ if (err != WBC_ERR_SUCCESS) {
+ wbcFreeMemory(types);
+ wbcFreeMemory(names);
+ }
+
+ return err;
}
/* Get the groups a user belongs to */