Merge branch 'master' of ssh://git.samba.org/data/git/samba
[bbaumbach/samba-autobuild/.git] / source3 / nsswitch / libwbclient / wbc_sid.c
index deec8e57c97206c30e642b294c7007dbbc48fb70..e2157b960971bd9076e3813707cc8af0256d3e13 100644 (file)
 #include "libwbclient.h"
 
 
-/** @brief Convert a binary SID to a character string
- *
- * @param sid           Binary Security Identifier
- * @param **sid_string  Resulting character string
- *
- * @return #wbcErr
- **/
-
+/* Convert a binary SID to a character string */
 wbcErr wbcSidToString(const struct wbcDomainSid *sid,
                      char **sid_string)
 {
@@ -40,51 +33,40 @@ wbcErr wbcSidToString(const struct wbcDomainSid *sid,
        uint32_t id_auth;
        int i;
        char *tmp = NULL;
-       TALLOC_CTX *ctx = NULL;
 
        if (!sid) {
                wbc_status = WBC_ERR_INVALID_SID;
                BAIL_ON_WBC_ERROR(wbc_status);
        }
 
-       ctx = talloc_init("wbcSidToString");
-       BAIL_ON_PTR_ERROR(ctx, wbc_status);
-
        id_auth = sid->id_auth[5] +
                (sid->id_auth[4] << 8) +
                (sid->id_auth[3] << 16) +
                (sid->id_auth[2] << 24);
 
-       tmp = talloc_asprintf(ctx, "S-%d-%d", sid->sid_rev_num, id_auth);
+       tmp = talloc_asprintf(NULL, "S-%d-%d", sid->sid_rev_num, id_auth);
        BAIL_ON_PTR_ERROR(tmp, wbc_status);
 
        for (i=0; i<sid->num_auths; i++) {
-               char *tmp2 =
+               char *tmp2;
                tmp2 = talloc_asprintf_append(tmp, "-%u", sid->sub_auths[i]);
                BAIL_ON_PTR_ERROR(tmp2, wbc_status);
 
                tmp = tmp2;
        }
 
-       *sid_string=talloc_strdup(NULL, tmp);
-       BAIL_ON_PTR_ERROR((*sid_string), wbc_status);
+       *sid_string = tmp;
+       tmp = NULL;
 
        wbc_status = WBC_ERR_SUCCESS;
 
 done:
-       talloc_free(ctx);
+       talloc_free(tmp);
 
        return wbc_status;
 }
 
-/** @brief Convert a character string to a binary SID
- *
- * @param *str          Character string in the form of S-...
- * @param sid           Resulting binary SID
- *
- * @return #wbcErr
- **/
-
+/* Convert a character string to a binary SID */
 wbcErr wbcStringToSid(const char *str,
                      struct wbcDomainSid *sid)
 {
@@ -102,8 +84,7 @@ wbcErr wbcStringToSid(const char *str,
 
        if (!str
            || (str[0]!='S' && str[0]!='s')
-           || (str[1]!='-')
-           || (strlen(str)<2))
+           || (str[1]!='-'))
        {
                wbc_status = WBC_ERR_INVALID_PARAM;
                BAIL_ON_WBC_ERROR(wbc_status);
@@ -124,7 +105,7 @@ wbcErr wbcStringToSid(const char *str,
 
        p = q+1;
        x = (uint32_t)strtol(p, &q, 10);
-       if (x==0 || !q || *q!='-') {
+       if (!q || *q!='-') {
                wbc_status = WBC_ERR_INVALID_SID;
                BAIL_ON_WBC_ERROR(wbc_status);
        }
@@ -140,11 +121,16 @@ wbcErr wbcStringToSid(const char *str,
        p = q +1;
        sid->num_auths = 0;
        while (sid->num_auths < WBC_MAXSUBAUTHS) {
-               if ((x=(uint32_t)strtoul(p, &q, 10)) == 0)
+               x=(uint32_t)strtoul(p, &q, 10);
+               if (p == q)
                        break;
+               if (q == NULL) {
+                       wbc_status = WBC_ERR_INVALID_SID;
+                       BAIL_ON_WBC_ERROR(wbc_status);
+               }
                sid->sub_auths[sid->num_auths++] = x;
 
-               if (q && ((*q!='-') || (*q=='\0')))
+               if ((*q!='-') || (*q=='\0'))
                        break;
                p = q + 1;
        }
@@ -163,17 +149,7 @@ done:
 
 }
 
-/** @brief Convert a domain and name to SID
- *
- * @param domain      Domain name (possibly "")
- * @param name        User or group name
- * @param *sid        Pointer to the resolved domain SID
- * @param *name_type  Pointet to the SID type
- *
- * @return #wbcErr
- *
- **/
-
+/* Convert a domain and name to SID */
 wbcErr wbcLookupName(const char *domain,
                     const char *name,
                     struct wbcDomainSid *sid,
@@ -216,26 +192,19 @@ wbcErr wbcLookupName(const char *domain,
        return wbc_status;
 }
 
-/** @brief Convert a SID to a domain and name
- *
- * @param *sid        Pointer to the domain SID to be resolved
- * @param domain      Resolved Domain name (possibly "")
- * @param name        Resolved User or group name
- * @param *name_type  Pointet to the resolved SID type
- *
- * @return #wbcErr
- *
- **/
-
+/* Convert a SID to a domain and name */
 wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
-                   char **domain,
-                   char **name,
-                   enum wbcSidType *name_type)
+                   char **pdomain,
+                   char **pname,
+                   enum wbcSidType *pname_type)
 {
        struct winbindd_request request;
        struct winbindd_response response;
        wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
        char *sid_string = NULL;
+       char *domain = NULL;
+       char *name = NULL;
+       enum wbcSidType name_type = WBC_SID_NAME_USE_NONE;
 
        if (!sid) {
                wbc_status = WBC_ERR_INVALID_PARAM;
@@ -264,43 +233,57 @@ wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
 
        /* Copy out result */
 
-       if (domain != NULL) {
-               *domain = talloc_strdup(NULL, response.data.name.dom_name);
-               BAIL_ON_PTR_ERROR((*domain), wbc_status);
-       }
+       domain = talloc_strdup(NULL, response.data.name.dom_name);
+       BAIL_ON_PTR_ERROR(domain, wbc_status);
 
-       if (name != NULL) {
-               *name = talloc_strdup(NULL, response.data.name.name);
-               BAIL_ON_PTR_ERROR((*name), wbc_status);
-       }
+       name = talloc_strdup(NULL, response.data.name.name);
+       BAIL_ON_PTR_ERROR(name, wbc_status);
 
-       if (name_type) {
-               *name_type = (enum wbcSidType)response.data.name.type;
-       }
+       name_type = (enum wbcSidType)response.data.name.type;
 
        wbc_status = WBC_ERR_SUCCESS;
 
  done:
-       if (!WBC_ERROR_IS_OK(wbc_status)) {
-               if (*domain)
-                       talloc_free(*domain);
-               if (*name)
-                       talloc_free(*name);
+       if (WBC_ERROR_IS_OK(wbc_status)) {
+               if (pdomain != NULL) {
+                       *pdomain = domain;
+               }
+               if (pname != NULL) {
+                       *pname = name;
+               }
+               if (pname_type != NULL) {
+                       *pname_type = name_type;
+               }
+       }
+       else {
+#if 0
+               /*
+                * Found by Coverity: In this particular routine we can't end
+                * up here with a non-NULL name. Further up there are just two
+                * exit paths that lead here, neither of which leave an
+                * allocated name. If you add more paths up there, re-activate
+                * this.
+                */
+               if (name != NULL) {
+                       talloc_free(name);
+               }
+#endif
+               if (domain != NULL) {
+                       talloc_free(domain);
+               }
        }
 
        return wbc_status;
 }
 
-/** @brief Translate a collection of RIDs within a domain to names
- *
- **/
+/* 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 ***names,
-                    enum wbcSidType **types)
+                    const char ***pnames,
+                    enum wbcSidType **ptypes)
 {
        size_t i, len, ridbuf_size;
        char *ridlist;
@@ -309,6 +292,8 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
        struct winbindd_response response;
        char *sid_string = NULL;
        char *domain_name = NULL;
+       const char **names = NULL;
+       enum wbcSidType *types = NULL;
        wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 
        /* Initialise request */
@@ -360,11 +345,11 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
        domain_name = talloc_strdup(NULL, response.data.domain_name);
        BAIL_ON_PTR_ERROR(domain_name, wbc_status);
 
-       *names = talloc_array(NULL, const char*, num_rids);
-       BAIL_ON_PTR_ERROR((*names), wbc_status);
+       names = talloc_array(NULL, const char*, num_rids);
+       BAIL_ON_PTR_ERROR(names, wbc_status);
 
-       *types = talloc_array(NULL, enum wbcSidType, num_rids);
-       BAIL_ON_PTR_ERROR((*types), wbc_status);
+       types = talloc_array(NULL, enum wbcSidType, num_rids);
+       BAIL_ON_PTR_ERROR(types, wbc_status);
 
        p = (char *)response.extra_data.data;
 
@@ -376,7 +361,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
-               (*types)[i] = (enum wbcSidType)strtoul(p, &q, 10);
+               types[i] = (enum wbcSidType)strtoul(p, &q, 10);
 
                if (*q != ' ') {
                        wbc_status = WBC_ERR_INVALID_RESPONSE;
@@ -392,8 +377,8 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
 
                *q = '\0';
 
-               (*names)[i] = talloc_strdup((*names), p);
-               BAIL_ON_PTR_ERROR(((*names)[i]), wbc_status);
+               names[i] = talloc_strdup(names, p);
+               BAIL_ON_PTR_ERROR(names[i], wbc_status);
 
                p = q+1;
        }
@@ -410,24 +395,24 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
                free(response.extra_data.data);
        }
 
-       if (!WBC_ERROR_IS_OK(wbc_status)) {
+       if (WBC_ERROR_IS_OK(wbc_status)) {
+               *pp_domain_name = domain_name;
+               *pnames = names;
+               *ptypes = types;
+       }
+       else {
                if (domain_name)
                        talloc_free(domain_name);
-               if (*names)
-                       talloc_free(*names);
-               if (*types)
-                       talloc_free(*types);
-       } else {
-               *pp_domain_name = domain_name;
+               if (names)
+                       talloc_free(names);
+               if (types)
+                       talloc_free(types);
        }
 
        return wbc_status;
 }
 
-/** @brief Get the groups a user belongs to
- *
- **/
-
+/* Get the groups a user belongs to */
 wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
                         bool domain_groups_only,
                         uint32_t *num_sids,
@@ -506,10 +491,7 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
        return wbc_status;
 }
 
-/** @brief Lists Users
- *
- **/
-
+/* Lists Users */
 wbcErr wbcListUsers(const char *domain_name,
                    uint32_t *_num_users,
                    const char ***_users)
@@ -577,10 +559,7 @@ wbcErr wbcListUsers(const char *domain_name,
        return wbc_status;
 }
 
-/** @brief Lists Groups
- *
- **/
-
+/* Lists Groups */
 wbcErr wbcListGroups(const char *domain_name,
                     uint32_t *_num_groups,
                     const char ***_groups)
@@ -647,3 +626,47 @@ wbcErr wbcListGroups(const char *domain_name,
        }
        return wbc_status;
 }
+
+wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
+                        char **pdomain,
+                        char **pfullname,
+                        enum wbcSidType *pname_type)
+{
+       wbcErr wbc_status;
+       char *domain = NULL;
+       char *name = NULL;
+       enum wbcSidType name_type;
+
+       wbc_status = wbcLookupSid(sid, &domain, &name, &name_type);
+       BAIL_ON_WBC_ERROR(wbc_status);
+
+       if (name_type == WBC_SID_NAME_USER) {
+               uid_t uid;
+               struct passwd *pwd;
+
+               wbc_status = wbcSidToUid(sid, &uid);
+               BAIL_ON_WBC_ERROR(wbc_status);
+
+               wbc_status = wbcGetpwuid(uid, &pwd);
+               BAIL_ON_WBC_ERROR(wbc_status);
+
+               wbcFreeMemory(name);
+
+               name = talloc_strdup(NULL, pwd->pw_gecos);
+               BAIL_ON_PTR_ERROR(name, wbc_status);
+       }
+
+       wbc_status = WBC_ERR_SUCCESS;
+
+ done:
+       if (WBC_ERROR_IS_OK(wbc_status)) {
+               *pdomain = domain;
+               *pfullname = name;
+               *pname_type = name_type;
+       } else {
+               wbcFreeMemory(domain);
+               wbcFreeMemory(name);
+       }
+
+       return wbc_status;
+}