libwbclient: Add wbcSidsToUnixIds
authorVolker Lendecke <vl@samba.org>
Wed, 23 Mar 2011 17:30:32 +0000 (18:30 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 13 Apr 2011 21:13:25 +0000 (14:13 -0700)
Signed-off-by: Jeremy Allison <jra@samba.org>
nsswitch/libwbclient/wbc_idmap.c
nsswitch/libwbclient/wbclient.h

index a77e7c09d44455963bec974b60e45ebbfd205a3a..ad3cfe67709adcc5cca120c5dc66030d76bb3a59 100644 (file)
@@ -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;
+}
index f1298878744cbc4ad07a27c68ce1d8a98a43a7dd..c5f3b77ed8cc21643f67ef4d0bc9bafb62d9f58b 100644 (file)
@@ -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
  *