summaryrefslogtreecommitdiff
path: root/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'nsswitch')
-rw-r--r--nsswitch/libwbclient/wbc_idmap.c93
-rw-r--r--nsswitch/libwbclient/wbclient.h32
2 files changed, 124 insertions, 1 deletions
diff --git a/nsswitch/libwbclient/wbc_idmap.c b/nsswitch/libwbclient/wbc_idmap.c
index a77e7c09d4..ad3cfe6770 100644
--- a/nsswitch/libwbclient/wbc_idmap.c
+++ b/nsswitch/libwbclient/wbc_idmap.c
@@ -23,6 +23,7 @@
#include "replace.h"
#include "libwbclient.h"
+#include "../winbind_client.h"
/* Convert a Windows SID to a Unix uid, allocating an uid if needed */
wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
@@ -296,3 +297,95 @@ wbcErr wbcSetGidHwm(gid_t gid_hwm)
{
return WBC_ERR_NOT_IMPLEMENTED;
}
+
+/* Convert a list of SIDs */
+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
+ struct wbcUnixId *ids)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ int buflen, extra_len;
+ uint32_t i;
+ char *sidlist, *p, *extra_data;
+
+ buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1;
+
+ sidlist = (char *)malloc(buflen);
+ if (sidlist == NULL) {
+ return WBC_ERR_NO_MEMORY;
+ }
+
+ p = sidlist;
+
+ for (i=0; i<num_sids; i++) {
+ int remaining;
+ int len;
+
+ remaining = buflen - (p - sidlist);
+
+ len = wbcSidToStringBuf(&sids[i], p, remaining);
+ if (len > remaining) {
+ free(sidlist);
+ return WBC_ERR_UNKNOWN_FAILURE;
+ }
+
+ p += len;
+ *p++ = '\n';
+ }
+ *p++ = '\0';
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ request.extra_data.data = sidlist;
+ request.extra_len = p - sidlist;
+
+ wbc_status = wbcRequestResponse(WINBINDD_SIDS_TO_XIDS,
+ &request, &response);
+ free(sidlist);
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ return wbc_status;
+ }
+
+ extra_len = response.length - sizeof(struct winbindd_response);
+ extra_data = (char *)response.extra_data.data;
+
+ if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) {
+ goto wbc_err_invalid;
+ }
+
+ p = extra_data;
+
+ for (i=0; i<num_sids; i++) {
+ struct wbcUnixId *id = &ids[i];
+ char *q;
+
+ switch (p[0]) {
+ case 'U':
+ id->type = WBC_ID_TYPE_UID;
+ id->id.uid = strtoul(p+1, &q, 10);
+ break;
+ case 'G':
+ id->type = WBC_ID_TYPE_GID;
+ id->id.gid = strtoul(p+1, &q, 10);
+ break;
+ default:
+ id->type = WBC_ID_TYPE_NOT_SPECIFIED;
+ q = p;
+ break;
+ };
+ if (q[0] != '\n') {
+ goto wbc_err_invalid;
+ }
+ p = q+1;
+ }
+ wbc_status = WBC_ERR_SUCCESS;
+ goto done;
+
+wbc_err_invalid:
+ wbc_status = WBC_ERR_INVALID_RESPONSE;
+done:
+ winbindd_free_response(&response);
+ return wbc_status;
+}
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index f129887874..c5f3b77ed8 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -67,9 +67,10 @@ const char *wbcErrorString(wbcErr error);
* 0.5: Added wbcChangeTrustCredentials()
* 0.6: Made struct wbcInterfaceDetails char* members non-const
* 0.7: Added wbcSidToStringBuf()
+ * 0.8: Added wbcSidsToUnixIds() and wbcLookupSids()
**/
#define WBCLIENT_MAJOR_VERSION 0
-#define WBCLIENT_MINOR_VERSION 7
+#define WBCLIENT_MINOR_VERSION 8
#define WBCLIENT_VENDOR_VERSION "Samba libwbclient"
struct wbcLibraryDetails {
uint16_t major_version;
@@ -792,6 +793,35 @@ wbcErr wbcGidToSid(gid_t gid,
wbcErr wbcQueryGidToSid(gid_t gid,
struct wbcDomainSid *sid);
+enum wbcIdType {
+ WBC_ID_TYPE_NOT_SPECIFIED,
+ WBC_ID_TYPE_UID,
+ WBC_ID_TYPE_GID
+};
+
+union wbcUnixIdContainer {
+ uid_t uid;
+ gid_t gid;
+};
+
+struct wbcUnixId {
+ enum wbcIdType type;
+ union wbcUnixIdContainer id;
+};
+
+/**
+ * @brief Convert a list of sids to unix ids
+ *
+ * @param sids Pointer to an array of SIDs to convert
+ * @param num_sids Number of SIDs
+ * @param ids Preallocated output array for translated IDs
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
+ struct wbcUnixId *ids);
+
/**
* @brief Obtain a new uid from Winbind
*