/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include #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) { 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; } /* Convert a SID to a domain and name */ wbcErr wbcLookupSid(const struct wbcDomainSid *sid, char **pdomain, char **pname, enum wbcSidType *pname_type) { 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, struct wbcDomainInfo **pdomains, int *pnum_domains, struct wbcTranslatedName **pnames) { WBC_SSSD_NOT_IMPLEMENTED; } /* Translate a collection of RIDs within a domain to names */ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **pp_domain_name, const char ***pnames, enum wbcSidType **ptypes) { 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 */ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **_sids) { WBC_SSSD_NOT_IMPLEMENTED; } /* Get alias membership for sids */ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids) { WBC_SSSD_NOT_IMPLEMENTED; } /* Lists Users */ wbcErr wbcListUsers(const char *domain_name, uint32_t *_num_users, const char ***_users) { WBC_SSSD_NOT_IMPLEMENTED; } /* Lists Groups */ wbcErr wbcListGroups(const char *domain_name, uint32_t *_num_groups, const char ***_groups) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, char **pdomain, char **pfullname, enum wbcSidType *pname_type) { WBC_SSSD_NOT_IMPLEMENTED; }