LCOV - code coverage report
Current view: top level - nsswitch/libwbclient - wbc_sid.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 364 595 61.2 %
Date: 2024-04-21 15:09:00 Functions: 21 25 84.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind client API
       5             : 
       6             :    Copyright (C) Gerald (Jerry) Carter 2007
       7             :    Copyright (C) Volker Lendecke 2010
       8             : 
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Library General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : /* Required Headers */
      25             : 
      26             : #include "replace.h"
      27             : #include "libwbclient.h"
      28             : #include "../winbind_client.h"
      29             : #include "lib/util/smb_strtox.h"
      30             : 
      31             : /* Convert a sid to a string into a buffer. Return the string
      32             :  * length. If buflen is too small, return the string length that would
      33             :  * result if it was long enough. */
      34             : _PUBLIC_
      35      476032 : int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen)
      36             : {
      37       15746 :         uint64_t id_auth;
      38       15746 :         int i, ofs;
      39             : 
      40      476032 :         if (!sid) {
      41           0 :                 strlcpy(buf, "(NULL SID)", buflen);
      42           0 :                 return 10;      /* strlen("(NULL SID)") */
      43             :         }
      44             : 
      45      476032 :         id_auth = (uint64_t)sid->id_auth[5] +
      46      476032 :                 ((uint64_t)sid->id_auth[4] << 8) +
      47      476032 :                 ((uint64_t)sid->id_auth[3] << 16) +
      48      476032 :                 ((uint64_t)sid->id_auth[2] << 24) +
      49      476032 :                 ((uint64_t)sid->id_auth[1] << 32) +
      50      476032 :                 ((uint64_t)sid->id_auth[0] << 40);
      51             : 
      52      476032 :         ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num);
      53      476032 :         if (id_auth >= UINT32_MAX) {
      54           0 :                 ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx",
      55             :                                 (unsigned long long)id_auth);
      56             :         } else {
      57      476032 :                 ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu",
      58             :                                 (unsigned long long)id_auth);
      59             :         }
      60             : 
      61     1649622 :         for (i = 0; i < sid->num_auths; i++) {
      62     1173590 :                 ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u",
      63     1173590 :                                 (unsigned int)sid->sub_auths[i]);
      64             :         }
      65      460286 :         return ofs;
      66             : }
      67             : 
      68             : /* Convert a binary SID to a character string */
      69             : _PUBLIC_
      70         468 : wbcErr wbcSidToString(const struct wbcDomainSid *sid,
      71             :                       char **sid_string)
      72             : {
      73           0 :         char buf[WBC_SID_STRING_BUFLEN];
      74           0 :         char *result;
      75           0 :         int len;
      76             : 
      77         468 :         if (!sid) {
      78           0 :                 return WBC_ERR_INVALID_SID;
      79             :         }
      80             : 
      81         468 :         len = wbcSidToStringBuf(sid, buf, sizeof(buf));
      82             : 
      83         468 :         if (len >= WBC_SID_STRING_BUFLEN) {
      84           0 :                 return WBC_ERR_INVALID_SID;
      85             :         }
      86             : 
      87         468 :         result = (char *)wbcAllocateMemory(len+1, 1, NULL);
      88         468 :         if (result == NULL) {
      89           0 :                 return WBC_ERR_NO_MEMORY;
      90             :         }
      91         468 :         memcpy(result, buf, len+1);
      92             : 
      93         468 :         *sid_string = result;
      94         468 :         return WBC_ERR_SUCCESS;
      95             : }
      96             : 
      97             : #define AUTHORITY_MASK  (~(0xffffffffffffULL))
      98             : 
      99             : /* Convert a character string to a binary SID */
     100             : _PUBLIC_
     101       44248 : wbcErr wbcStringToSid(const char *str,
     102             :                       struct wbcDomainSid *sid)
     103             : {
     104           2 :         const char *p;
     105           2 :         char *q;
     106       44248 :         int error = 0;
     107           2 :         uint64_t x;
     108       44248 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     109             : 
     110       44248 :         if (!sid) {
     111           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     112           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     113             :         }
     114             : 
     115             :         /* Sanity check for either "S-" or "s-" */
     116             : 
     117       44248 :         if (!str
     118       44248 :             || (str[0]!='S' && str[0]!='s')
     119       30000 :             || (str[1]!='-'))
     120             :         {
     121       14252 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     122       14252 :                 BAIL_ON_WBC_ERROR(wbc_status);
     123             :         }
     124             : 
     125             :         /* Get the SID revision number */
     126             : 
     127       29996 :         p = str+2;
     128       29996 :         x = (uint64_t)smb_strtoul(p, &q, 10, &error, SMB_STR_STANDARD);
     129       29996 :         if (x == 0 || x > UINT8_MAX || !q || *q != '-' || error != 0) {
     130           0 :                 wbc_status = WBC_ERR_INVALID_SID;
     131           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     132             :         }
     133       29996 :         sid->sid_rev_num = (uint8_t)x;
     134             : 
     135             :         /*
     136             :          * Next the Identifier Authority.  This is stored big-endian in a
     137             :          * 6 byte array. If the authority value is >= UINT_MAX, then it should
     138             :          * be expressed as a hex value, according to MS-DTYP.
     139             :          */
     140       29996 :         p = q+1;
     141       29996 :         x = smb_strtoull(p, &q, 0, &error, SMB_STR_STANDARD);
     142       29996 :         if (!q || *q != '-' || (x & AUTHORITY_MASK) || error != 0) {
     143           0 :                 wbc_status = WBC_ERR_INVALID_SID;
     144           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     145             :         }
     146       29996 :         sid->id_auth[5] = (x & 0x0000000000ffULL);
     147       29996 :         sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8;
     148       29996 :         sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16;
     149       29996 :         sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24;
     150       29996 :         sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32;
     151       29996 :         sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40;
     152             : 
     153             :         /* now read the the subauthorities */
     154       29996 :         p = q +1;
     155       29996 :         sid->num_auths = 0;
     156       99256 :         while (sid->num_auths < WBC_MAXSUBAUTHS) {
     157       99256 :                 x = smb_strtoull(p, &q, 10, &error, SMB_STR_ALLOW_NO_CONVERSION);
     158       99256 :                 if (p == q)
     159           0 :                         break;
     160       99256 :                 if (x > UINT32_MAX || error != 0) {
     161           0 :                         wbc_status = WBC_ERR_INVALID_SID;
     162           0 :                         BAIL_ON_WBC_ERROR(wbc_status);
     163             :                 }
     164       99256 :                 sid->sub_auths[sid->num_auths++] = x;
     165             : 
     166       99256 :                 if (*q != '-') {
     167       29994 :                         break;
     168             :                 }
     169       69260 :                 p = q + 1;
     170             :         }
     171             : 
     172             :         /* IF we ended early, then the SID could not be converted */
     173             : 
     174       29996 :         if (q && *q!='\0') {
     175           0 :                 wbc_status = WBC_ERR_INVALID_SID;
     176           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     177             :         }
     178             : 
     179       29994 :         wbc_status = WBC_ERR_SUCCESS;
     180             : 
     181       44248 : done:
     182       44248 :         return wbc_status;
     183             : 
     184             : }
     185             : 
     186             : 
     187             : /* Convert a domain and name to SID */
     188             : _PUBLIC_
     189        3228 : wbcErr wbcCtxLookupName(struct wbcContext *ctx,
     190             :                         const char *domain,
     191             :                         const char *name,
     192             :                         struct wbcDomainSid *sid,
     193             :                         enum wbcSidType *name_type)
     194             : {
     195           0 :         struct winbindd_request request;
     196           0 :         struct winbindd_response response;
     197        3228 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     198             : 
     199        3228 :         if (!sid || !name_type) {
     200           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     201           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     202             :         }
     203             : 
     204             :         /* Initialize request */
     205             : 
     206        3228 :         ZERO_STRUCT(request);
     207        3228 :         ZERO_STRUCT(response);
     208             : 
     209             :         /* dst is already null terminated from the memset above */
     210             : 
     211        3228 :         strncpy(request.data.name.dom_name, domain,
     212             :                 sizeof(request.data.name.dom_name)-1);
     213        3228 :         strncpy(request.data.name.name, name,
     214             :                 sizeof(request.data.name.name)-1);
     215             : 
     216        3228 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPNAME,
     217             :                                         &request,
     218             :                                         &response);
     219        3228 :         BAIL_ON_WBC_ERROR(wbc_status);
     220             : 
     221        2936 :         wbc_status = wbcStringToSid(response.data.sid.sid, sid);
     222        2936 :         BAIL_ON_WBC_ERROR(wbc_status);
     223             : 
     224        2936 :         *name_type = (enum wbcSidType)response.data.sid.type;
     225             : 
     226        2936 :         wbc_status = WBC_ERR_SUCCESS;
     227             : 
     228        3228 :  done:
     229        3228 :         return wbc_status;
     230             : }
     231             : 
     232             : _PUBLIC_
     233        3084 : wbcErr wbcLookupName(const char *domain,
     234             :                      const char *name,
     235             :                      struct wbcDomainSid *sid,
     236             :                      enum wbcSidType *name_type)
     237             : {
     238        3084 :         return wbcCtxLookupName(NULL, domain, name, sid, name_type);
     239             : }
     240             : 
     241             : 
     242             : /* Convert a SID to a domain and name */
     243             : _PUBLIC_
     244         838 : wbcErr wbcCtxLookupSid(struct wbcContext *ctx,
     245             :                        const struct wbcDomainSid *sid,
     246             :                        char **pdomain,
     247             :                        char **pname,
     248             :                        enum wbcSidType *pname_type)
     249             : {
     250           0 :         struct winbindd_request request;
     251           0 :         struct winbindd_response response;
     252         838 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     253           0 :         char *domain, *name;
     254             : 
     255         838 :         if (!sid) {
     256           0 :                 return WBC_ERR_INVALID_PARAM;
     257             :         }
     258             : 
     259             :         /* Initialize request */
     260             : 
     261         838 :         ZERO_STRUCT(request);
     262         838 :         ZERO_STRUCT(response);
     263             : 
     264         838 :         wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
     265             : 
     266             :         /* Make request */
     267             : 
     268         838 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPSID,
     269             :                                         &request,
     270             :                                         &response);
     271         838 :         if (!WBC_ERROR_IS_OK(wbc_status)) {
     272           6 :                 return wbc_status;
     273             :         }
     274             : 
     275             :         /* Copy out result */
     276             : 
     277         832 :         wbc_status = WBC_ERR_NO_MEMORY;
     278         832 :         domain = NULL;
     279         832 :         name = NULL;
     280             : 
     281         832 :         domain = wbcStrDup(response.data.name.dom_name);
     282         832 :         if (domain == NULL) {
     283           0 :                 goto done;
     284             :         }
     285         832 :         name = wbcStrDup(response.data.name.name);
     286         832 :         if (name == NULL) {
     287           0 :                 goto done;
     288             :         }
     289         832 :         if (pdomain != NULL) {
     290         832 :                 *pdomain = domain;
     291         832 :                 domain = NULL;
     292             :         }
     293         832 :         if (pname != NULL) {
     294         832 :                 *pname = name;
     295         832 :                 name = NULL;
     296             :         }
     297         832 :         if (pname_type != NULL) {
     298         832 :                 *pname_type = (enum wbcSidType)response.data.name.type;
     299             :         }
     300         832 :         wbc_status = WBC_ERR_SUCCESS;
     301         832 : done:
     302         832 :         wbcFreeMemory(name);
     303         832 :         wbcFreeMemory(domain);
     304         832 :         return wbc_status;
     305             : }
     306             : 
     307             : _PUBLIC_
     308         544 : wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
     309             :                     char **pdomain,
     310             :                     char **pname,
     311             :                     enum wbcSidType *pname_type)
     312             : {
     313         544 :         return wbcCtxLookupSid(NULL, sid, pdomain, pname, pname_type);
     314             : }
     315             : 
     316           0 : static void wbcDomainInfosDestructor(void *ptr)
     317             : {
     318           0 :         struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
     319             : 
     320           0 :         while (i->short_name != NULL) {
     321           0 :                 wbcFreeMemory(i->short_name);
     322           0 :                 wbcFreeMemory(i->dns_name);
     323           0 :                 i += 1;
     324             :         }
     325           0 : }
     326             : 
     327           0 : static void wbcTranslatedNamesDestructor(void *ptr)
     328             : {
     329           0 :         struct wbcTranslatedName *n = (struct wbcTranslatedName *)ptr;
     330             : 
     331           0 :         while (n->name != NULL) {
     332           0 :                 wbcFreeMemory(n->name);
     333           0 :                 n += 1;
     334             :         }
     335           0 : }
     336             : 
     337             : _PUBLIC_
     338           0 : wbcErr wbcCtxLookupSids(struct wbcContext *ctx,
     339             :                         const struct wbcDomainSid *sids, int num_sids,
     340             :                         struct wbcDomainInfo **pdomains, int *pnum_domains,
     341             :                         struct wbcTranslatedName **pnames)
     342             : {
     343           0 :         struct winbindd_request request;
     344           0 :         struct winbindd_response response;
     345           0 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     346           0 :         int buflen, i, extra_len, num_domains, num_names;
     347           0 :         char *sidlist, *p, *q, *extra_data;
     348           0 :         struct wbcDomainInfo *domains = NULL;
     349           0 :         struct wbcTranslatedName *names = NULL;
     350           0 :         int error = 0;
     351             : 
     352           0 :         buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1;
     353             : 
     354           0 :         sidlist = (char *)malloc(buflen);
     355           0 :         if (sidlist == NULL) {
     356           0 :                 return WBC_ERR_NO_MEMORY;
     357             :         }
     358             : 
     359           0 :         p = sidlist;
     360             : 
     361           0 :         for (i=0; i<num_sids; i++) {
     362           0 :                 int remaining;
     363           0 :                 int len;
     364             : 
     365           0 :                 remaining = buflen - (p - sidlist);
     366             : 
     367           0 :                 len = wbcSidToStringBuf(&sids[i], p, remaining);
     368           0 :                 if (len > remaining) {
     369           0 :                         free(sidlist);
     370           0 :                         return WBC_ERR_UNKNOWN_FAILURE;
     371             :                 }
     372             : 
     373           0 :                 p += len;
     374           0 :                 *p++ = '\n';
     375             :         }
     376           0 :         *p++ = '\0';
     377             : 
     378           0 :         ZERO_STRUCT(request);
     379           0 :         ZERO_STRUCT(response);
     380             : 
     381           0 :         request.extra_data.data = sidlist;
     382           0 :         request.extra_len = p - sidlist;
     383             : 
     384           0 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPSIDS,
     385             :                                         &request, &response);
     386           0 :         free(sidlist);
     387           0 :         if (!WBC_ERROR_IS_OK(wbc_status)) {
     388           0 :                 return wbc_status;
     389             :         }
     390             : 
     391           0 :         extra_len = response.length - sizeof(struct winbindd_response);
     392           0 :         extra_data = (char *)response.extra_data.data;
     393             : 
     394           0 :         if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) {
     395           0 :                 goto wbc_err_invalid;
     396             :         }
     397             : 
     398           0 :         p = extra_data;
     399             : 
     400           0 :         num_domains = smb_strtoul(p, &q, 10, &error, SMB_STR_STANDARD);
     401           0 :         if (*q != '\n' || error != 0) {
     402           0 :                 goto wbc_err_invalid;
     403             :         }
     404           0 :         p = q+1;
     405             : 
     406           0 :         domains = (struct wbcDomainInfo *)wbcAllocateMemory(
     407           0 :                 num_domains+1, sizeof(struct wbcDomainInfo),
     408             :                 wbcDomainInfosDestructor);
     409           0 :         if (domains == NULL) {
     410           0 :                 wbc_status = WBC_ERR_NO_MEMORY;
     411           0 :                 goto fail;
     412             :         }
     413             : 
     414           0 :         for (i=0; i<num_domains; i++) {
     415             : 
     416           0 :                 q = strchr(p, ' ');
     417           0 :                 if (q == NULL) {
     418           0 :                         goto wbc_err_invalid;
     419             :                 }
     420           0 :                 *q = '\0';
     421           0 :                 wbc_status = wbcStringToSid(p, &domains[i].sid);
     422           0 :                 if (!WBC_ERROR_IS_OK(wbc_status)) {
     423           0 :                         goto fail;
     424             :                 }
     425           0 :                 p = q+1;
     426             : 
     427           0 :                 q = strchr(p, '\n');
     428           0 :                 if (q == NULL) {
     429           0 :                         goto wbc_err_invalid;
     430             :                 }
     431           0 :                 *q = '\0';
     432           0 :                 domains[i].short_name = wbcStrDup(p);
     433           0 :                 if (domains[i].short_name == NULL) {
     434           0 :                         wbc_status = WBC_ERR_NO_MEMORY;
     435           0 :                         goto fail;
     436             :                 }
     437           0 :                 p = q+1;
     438             :         }
     439             : 
     440           0 :         num_names = smb_strtoul(p, &q, 10, &error, SMB_STR_STANDARD);
     441           0 :         if (*q != '\n' || error != 0) {
     442           0 :                 goto wbc_err_invalid;
     443             :         }
     444           0 :         p = q+1;
     445             : 
     446           0 :         if (num_names != num_sids) {
     447           0 :                 goto wbc_err_invalid;
     448             :         }
     449             : 
     450           0 :         names = (struct wbcTranslatedName *)wbcAllocateMemory(
     451           0 :                 num_names+1, sizeof(struct wbcTranslatedName),
     452             :                 wbcTranslatedNamesDestructor);
     453           0 :         if (names == NULL) {
     454           0 :                 wbc_status = WBC_ERR_NO_MEMORY;
     455           0 :                 goto fail;
     456             :         }
     457             : 
     458           0 :         for (i=0; i<num_names; i++) {
     459             : 
     460           0 :                 names[i].domain_index = smb_strtoul(p,
     461             :                                                     &q,
     462             :                                                     10,
     463             :                                                     &error,
     464             :                                                     SMB_STR_STANDARD);
     465           0 :                 if (names[i].domain_index < 0 || error != 0) {
     466           0 :                         goto wbc_err_invalid;
     467             :                 }
     468           0 :                 if (names[i].domain_index >= num_domains) {
     469           0 :                         goto wbc_err_invalid;
     470             :                 }
     471             : 
     472           0 :                 if (*q != ' ') {
     473           0 :                         goto wbc_err_invalid;
     474             :                 }
     475           0 :                 p = q+1;
     476             : 
     477           0 :                 names[i].type = smb_strtoul(p, &q, 10, &error, SMB_STR_STANDARD);
     478           0 :                 if (*q != ' ' || error != 0) {
     479           0 :                         goto wbc_err_invalid;
     480             :                 }
     481           0 :                 p = q+1;
     482             : 
     483           0 :                 q = strchr(p, '\n');
     484           0 :                 if (q == NULL) {
     485           0 :                         goto wbc_err_invalid;
     486             :                 }
     487           0 :                 *q = '\0';
     488           0 :                 names[i].name = wbcStrDup(p);
     489           0 :                 if (names[i].name == NULL) {
     490           0 :                         wbc_status = WBC_ERR_NO_MEMORY;
     491           0 :                         goto fail;
     492             :                 }
     493           0 :                 p = q+1;
     494             :         }
     495           0 :         if (*p != '\0') {
     496           0 :                 goto wbc_err_invalid;
     497             :         }
     498             : 
     499           0 :         *pdomains = domains;
     500           0 :         *pnames = names;
     501           0 :         winbindd_free_response(&response);
     502           0 :         return WBC_ERR_SUCCESS;
     503             : 
     504           0 : wbc_err_invalid:
     505           0 :         wbc_status = WBC_ERR_INVALID_RESPONSE;
     506           0 : fail:
     507           0 :         winbindd_free_response(&response);
     508           0 :         wbcFreeMemory(domains);
     509           0 :         wbcFreeMemory(names);
     510           0 :         return wbc_status;
     511             : }
     512             : 
     513             : _PUBLIC_
     514           0 : wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
     515             :                      struct wbcDomainInfo **pdomains, int *pnum_domains,
     516             :                      struct wbcTranslatedName **pnames)
     517             : {
     518           0 :         return wbcCtxLookupSids(NULL, sids, num_sids, pdomains,
     519             :                                 pnum_domains, pnames);
     520             : }
     521             : 
     522             : /* Translate a collection of RIDs within a domain to names */
     523             : 
     524             : _PUBLIC_
     525         158 : wbcErr wbcCtxLookupRids(struct wbcContext *ctx, struct wbcDomainSid *dom_sid,
     526             :                      int num_rids,
     527             :                      uint32_t *rids,
     528             :                      const char **pp_domain_name,
     529             :                      const char ***pnames,
     530             :                      enum wbcSidType **ptypes)
     531             : {
     532           0 :         int i;
     533           0 :         size_t  len, ridbuf_size;
     534           0 :         char *ridlist;
     535           0 :         char *p;
     536         158 :         int error = 0;
     537           0 :         struct winbindd_request request;
     538           0 :         struct winbindd_response response;
     539         158 :         char *domain_name = NULL;
     540         158 :         const char **names = NULL;
     541         158 :         enum wbcSidType *types = NULL;
     542         158 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     543             : 
     544             :         /* Initialise request */
     545             : 
     546         158 :         ZERO_STRUCT(request);
     547         158 :         ZERO_STRUCT(response);
     548             : 
     549         158 :         if (!dom_sid || (num_rids == 0)) {
     550           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     551           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     552             :         }
     553             : 
     554         158 :         wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid));
     555             : 
     556             :         /* Even if all the Rids were of maximum 32bit values,
     557             :            we would only have 11 bytes per rid in the final array
     558             :            ("4294967296" + \n).  Add one more byte for the
     559             :            terminating '\0' */
     560             : 
     561         158 :         ridbuf_size = (sizeof(char)*11) * num_rids + 1;
     562             : 
     563         158 :         ridlist = (char *)malloc(ridbuf_size);
     564         158 :         BAIL_ON_PTR_ERROR(ridlist, wbc_status);
     565             : 
     566         158 :         len = 0;
     567         324 :         for (i=0; i<num_rids; i++) {
     568         166 :                 len += snprintf(ridlist + len, ridbuf_size - len, "%u\n",
     569         166 :                                 rids[i]);
     570             :         }
     571         158 :         ridlist[len] = '\0';
     572         158 :         len += 1;
     573             : 
     574         158 :         request.extra_data.data = ridlist;
     575         158 :         request.extra_len = len;
     576             : 
     577         158 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LOOKUPRIDS,
     578             :                                         &request,
     579             :                                         &response);
     580         158 :         free(ridlist);
     581         158 :         BAIL_ON_WBC_ERROR(wbc_status);
     582             : 
     583           8 :         domain_name = wbcStrDup(response.data.domain_name);
     584           8 :         BAIL_ON_PTR_ERROR(domain_name, wbc_status);
     585             : 
     586           8 :         names = wbcAllocateStringArray(num_rids);
     587           8 :         BAIL_ON_PTR_ERROR(names, wbc_status);
     588             : 
     589           8 :         types = (enum wbcSidType *)wbcAllocateMemory(
     590             :                 num_rids, sizeof(enum wbcSidType), NULL);
     591           8 :         BAIL_ON_PTR_ERROR(types, wbc_status);
     592             : 
     593           8 :         p = (char *)response.extra_data.data;
     594             : 
     595          24 :         for (i=0; i<num_rids; i++) {
     596           0 :                 char *q;
     597             : 
     598          16 :                 if (*p == '\0') {
     599           0 :                         wbc_status = WBC_ERR_INVALID_RESPONSE;
     600           0 :                         goto done;
     601             :                 }
     602             : 
     603          16 :                 types[i] = (enum wbcSidType)smb_strtoul(p,
     604             :                                                         &q,
     605             :                                                         10,
     606             :                                                         &error,
     607             :                                                         SMB_STR_STANDARD);
     608             : 
     609          16 :                 if (*q != ' ' || error != 0) {
     610           0 :                         wbc_status = WBC_ERR_INVALID_RESPONSE;
     611           0 :                         goto done;
     612             :                 }
     613             : 
     614          16 :                 p = q+1;
     615             : 
     616          16 :                 if ((q = strchr(p, '\n')) == NULL) {
     617           0 :                         wbc_status = WBC_ERR_INVALID_RESPONSE;
     618           0 :                         goto done;
     619             :                 }
     620             : 
     621          16 :                 *q = '\0';
     622             : 
     623          16 :                 names[i] = strdup(p);
     624          16 :                 BAIL_ON_PTR_ERROR(names[i], wbc_status);
     625             : 
     626          16 :                 p = q+1;
     627             :         }
     628             : 
     629           8 :         if (*p != '\0') {
     630           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     631           0 :                 goto done;
     632             :         }
     633             : 
     634           8 :         wbc_status = WBC_ERR_SUCCESS;
     635             : 
     636         158 :  done:
     637         158 :         winbindd_free_response(&response);
     638             : 
     639         158 :         if (WBC_ERROR_IS_OK(wbc_status)) {
     640           8 :                 *pp_domain_name = domain_name;
     641           8 :                 *pnames = names;
     642           8 :                 *ptypes = types;
     643             :         }
     644             :         else {
     645         150 :                 wbcFreeMemory(domain_name);
     646         150 :                 wbcFreeMemory(names);
     647         150 :                 wbcFreeMemory(types);
     648             :         }
     649             : 
     650         158 :         return wbc_status;
     651             : }
     652             : 
     653             : _PUBLIC_
     654         158 : wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
     655             :                      int num_rids,
     656             :                      uint32_t *rids,
     657             :                      const char **pp_domain_name,
     658             :                      const char ***pnames,
     659             :                      enum wbcSidType **ptypes)
     660             : {
     661         158 :         return wbcCtxLookupRids(NULL, dom_sid, num_rids, rids,
     662             :                                 pp_domain_name, pnames, ptypes);
     663             : }
     664             : 
     665             : /* Get the groups a user belongs to */
     666             : _PUBLIC_
     667         494 : wbcErr wbcCtxLookupUserSids(struct wbcContext *ctx,
     668             :                             const struct wbcDomainSid *user_sid,
     669             :                             bool domain_groups_only,
     670             :                             uint32_t *num_sids,
     671             :                             struct wbcDomainSid **_sids)
     672             : {
     673           0 :         uint32_t i;
     674           0 :         const char *s;
     675           0 :         struct winbindd_request request;
     676           0 :         struct winbindd_response response;
     677         494 :         struct wbcDomainSid *sids = NULL;
     678         494 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     679           0 :         int cmd;
     680             : 
     681             :         /* Initialise request */
     682             : 
     683         494 :         ZERO_STRUCT(request);
     684         494 :         ZERO_STRUCT(response);
     685             : 
     686         494 :         if (!user_sid) {
     687           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     688           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     689             :         }
     690             : 
     691         494 :         wbcSidToStringBuf(user_sid, request.data.sid, sizeof(request.data.sid));
     692             : 
     693         494 :         if (domain_groups_only) {
     694         230 :                 cmd = WINBINDD_GETUSERDOMGROUPS;
     695             :         } else {
     696         264 :                 cmd = WINBINDD_GETUSERSIDS;
     697             :         }
     698             : 
     699         494 :         wbc_status = wbcRequestResponse(ctx, cmd,
     700             :                                         &request,
     701             :                                         &response);
     702         494 :         BAIL_ON_WBC_ERROR(wbc_status);
     703             : 
     704         376 :         if (response.data.num_entries &&
     705         376 :             !response.extra_data.data) {
     706           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     707           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     708             :         }
     709             : 
     710         376 :         sids = (struct wbcDomainSid *)wbcAllocateMemory(
     711         376 :                 response.data.num_entries, sizeof(struct wbcDomainSid),
     712             :                 NULL);
     713         376 :         BAIL_ON_PTR_ERROR(sids, wbc_status);
     714             : 
     715         376 :         s = (const char *)response.extra_data.data;
     716        1259 :         for (i = 0; i < response.data.num_entries; i++) {
     717         883 :                 char *n = strchr(s, '\n');
     718         883 :                 if (n) {
     719         883 :                         *n = '\0';
     720             :                 }
     721         883 :                 wbc_status = wbcStringToSid(s, &sids[i]);
     722         883 :                 BAIL_ON_WBC_ERROR(wbc_status);
     723         883 :                 s += strlen(s) + 1;
     724             :         }
     725             : 
     726         376 :         *num_sids = response.data.num_entries;
     727         376 :         *_sids = sids;
     728         376 :         sids = NULL;
     729         376 :         wbc_status = WBC_ERR_SUCCESS;
     730             : 
     731         494 :  done:
     732         494 :         winbindd_free_response(&response);
     733         494 :         if (sids) {
     734           0 :                 wbcFreeMemory(sids);
     735             :         }
     736             : 
     737         494 :         return wbc_status;
     738             : }
     739             : 
     740             : _PUBLIC_
     741         494 : wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
     742             :                          bool domain_groups_only,
     743             :                          uint32_t *num_sids,
     744             :                          struct wbcDomainSid **_sids)
     745             : {
     746         494 :         return wbcCtxLookupUserSids(NULL, user_sid, domain_groups_only,
     747             :                                     num_sids, _sids);
     748             : }
     749             : 
     750             : static inline
     751           4 : wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid)
     752             : {
     753           4 :         if (sid->num_auths < 1) {
     754           0 :                 return WBC_ERR_INVALID_RESPONSE;
     755             :         }
     756           4 :         *rid = sid->sub_auths[sid->num_auths - 1];
     757             : 
     758           4 :         return WBC_ERR_SUCCESS;
     759             : }
     760             : 
     761             : /* Get alias membership for sids */
     762             : _PUBLIC_
     763           4 : wbcErr wbcCtxGetSidAliases(struct wbcContext *ctx,
     764             :                            const struct wbcDomainSid *dom_sid,
     765             :                            struct wbcDomainSid *sids,
     766             :                            uint32_t num_sids,
     767             :                            uint32_t **alias_rids,
     768             :                            uint32_t *num_alias_rids)
     769             : {
     770           0 :         uint32_t i;
     771           0 :         const char *s;
     772           0 :         struct winbindd_request request;
     773           0 :         struct winbindd_response response;
     774           4 :         ssize_t extra_data_len = 0;
     775           4 :         char * extra_data = NULL;
     776           4 :         ssize_t buflen = 0;
     777           0 :         struct wbcDomainSid sid;
     778           4 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     779           4 :         uint32_t * rids = NULL;
     780             : 
     781             :         /* Initialise request */
     782             : 
     783           4 :         ZERO_STRUCT(request);
     784           4 :         ZERO_STRUCT(response);
     785             : 
     786           4 :         if (!dom_sid) {
     787           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     788           0 :                 goto done;
     789             :         }
     790             : 
     791           4 :         wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid));
     792             : 
     793             :         /* Lets assume each sid is around 57 characters
     794             :          * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
     795           4 :         buflen = 57 * num_sids;
     796           4 :         extra_data = (char *)malloc(buflen);
     797           4 :         if (!extra_data) {
     798           0 :                 wbc_status = WBC_ERR_NO_MEMORY;
     799           0 :                 goto done;
     800             :         }
     801             : 
     802             :         /* Build the sid list */
     803          12 :         for (i=0; i<num_sids; i++) {
     804           0 :                 char sid_str[WBC_SID_STRING_BUFLEN];
     805           0 :                 size_t sid_len;
     806             : 
     807           8 :                 sid_len = wbcSidToStringBuf(&sids[i], sid_str, sizeof(sid_str));
     808             : 
     809           8 :                 if (buflen < extra_data_len + sid_len + 2) {
     810           0 :                         char * tmp_data = NULL;
     811           0 :                         buflen *= 2;
     812           0 :                         tmp_data = (char *)realloc(extra_data, buflen);
     813           0 :                         if (!tmp_data) {
     814           0 :                                 wbc_status = WBC_ERR_NO_MEMORY;
     815           0 :                                 BAIL_ON_WBC_ERROR(wbc_status);
     816             :                         }
     817           0 :                         extra_data = tmp_data;
     818             :                 }
     819             : 
     820           8 :                 strncpy(&extra_data[extra_data_len], sid_str,
     821           8 :                         buflen - extra_data_len);
     822           8 :                 extra_data_len += sid_len;
     823           8 :                 extra_data[extra_data_len++] = '\n';
     824           8 :                 extra_data[extra_data_len] = '\0';
     825             :         }
     826           4 :         extra_data_len += 1;
     827             : 
     828           4 :         request.extra_data.data = extra_data;
     829           4 :         request.extra_len = extra_data_len;
     830             : 
     831           4 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_GETSIDALIASES,
     832             :                                         &request,
     833             :                                         &response);
     834           4 :         BAIL_ON_WBC_ERROR(wbc_status);
     835             : 
     836           4 :         if (response.data.num_entries &&
     837           4 :             !response.extra_data.data) {
     838           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     839           0 :                 goto done;
     840             :         }
     841             : 
     842           4 :         rids = (uint32_t *)wbcAllocateMemory(response.data.num_entries,
     843             :                                              sizeof(uint32_t), NULL);
     844           4 :         BAIL_ON_PTR_ERROR(rids, wbc_status);
     845             : 
     846           4 :         s = (const char *)response.extra_data.data;
     847           8 :         for (i = 0; i < response.data.num_entries; i++) {
     848           4 :                 char *n = strchr(s, '\n');
     849           4 :                 if (n) {
     850           4 :                         *n = '\0';
     851             :                 }
     852           4 :                 wbc_status = wbcStringToSid(s, &sid);
     853           4 :                 BAIL_ON_WBC_ERROR(wbc_status);
     854           4 :                 wbc_status = _sid_to_rid(&sid, &rids[i]);
     855           4 :                 BAIL_ON_WBC_ERROR(wbc_status);
     856           4 :                 s += strlen(s) + 1;
     857             :         }
     858             : 
     859           4 :         *num_alias_rids = response.data.num_entries;
     860           4 :         *alias_rids = rids;
     861           4 :         rids = NULL;
     862           4 :         wbc_status = WBC_ERR_SUCCESS;
     863             : 
     864           4 :  done:
     865           4 :         free(extra_data);
     866           4 :         winbindd_free_response(&response);
     867           4 :         wbcFreeMemory(rids);
     868           4 :         return wbc_status;
     869             : }
     870             : 
     871             : _PUBLIC_
     872           4 : wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
     873             :                         struct wbcDomainSid *sids,
     874             :                         uint32_t num_sids,
     875             :                         uint32_t **alias_rids,
     876             :                         uint32_t *num_alias_rids)
     877             : {
     878           4 :         return wbcCtxGetSidAliases(NULL, dom_sid, sids, num_sids,
     879             :                                    alias_rids, num_alias_rids);
     880             : }
     881             : 
     882             : 
     883             : /* Lists Users */
     884             : _PUBLIC_
     885          34 : wbcErr wbcCtxListUsers(struct wbcContext *ctx,
     886             :                        const char *domain_name,
     887             :                        uint32_t *_num_users,
     888             :                        const char ***_users)
     889             : {
     890          34 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     891           0 :         struct winbindd_request request;
     892           0 :         struct winbindd_response response;
     893          34 :         uint32_t num_users = 0;
     894          34 :         const char **users = NULL;
     895           0 :         const char *next;
     896             : 
     897             :         /* Initialise request */
     898             : 
     899          34 :         ZERO_STRUCT(request);
     900          34 :         ZERO_STRUCT(response);
     901             : 
     902          34 :         if (domain_name) {
     903          24 :                 strncpy(request.domain_name, domain_name,
     904             :                         sizeof(request.domain_name)-1);
     905             :         }
     906             : 
     907          34 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_USERS,
     908             :                                         &request,
     909             :                                         &response);
     910          34 :         BAIL_ON_WBC_ERROR(wbc_status);
     911             : 
     912          34 :         users = wbcAllocateStringArray(response.data.num_entries);
     913          34 :         if (users == NULL) {
     914           0 :                 return WBC_ERR_NO_MEMORY;
     915             :         }
     916             : 
     917             :         /* Look through extra data */
     918             : 
     919          34 :         next = (const char *)response.extra_data.data;
     920        5296 :         while (next) {
     921           0 :                 const char *current;
     922           0 :                 char *k;
     923             : 
     924        5262 :                 if (num_users >= response.data.num_entries) {
     925           0 :                         wbc_status = WBC_ERR_INVALID_RESPONSE;
     926           0 :                         goto done;
     927             :                 }
     928             : 
     929        5262 :                 current = next;
     930        5262 :                 k = strchr(next, ',');
     931             : 
     932        5262 :                 if (k) {
     933        5228 :                         k[0] = '\0';
     934        5228 :                         next = k+1;
     935             :                 } else {
     936          34 :                         next = NULL;
     937             :                 }
     938             : 
     939        5262 :                 users[num_users] = strdup(current);
     940        5262 :                 BAIL_ON_PTR_ERROR(users[num_users], wbc_status);
     941        5262 :                 num_users += 1;
     942             :         }
     943          34 :         if (num_users != response.data.num_entries) {
     944           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     945           0 :                 goto done;
     946             :         }
     947             : 
     948          34 :         *_num_users = response.data.num_entries;
     949          34 :         *_users = users;
     950          34 :         users = NULL;
     951          34 :         wbc_status = WBC_ERR_SUCCESS;
     952             : 
     953          34 :  done:
     954          34 :         winbindd_free_response(&response);
     955          34 :         wbcFreeMemory(users);
     956          34 :         return wbc_status;
     957             : }
     958             : 
     959             : _PUBLIC_
     960          34 : wbcErr wbcListUsers(const char *domain_name,
     961             :                     uint32_t *_num_users,
     962             :                     const char ***_users)
     963             : {
     964          34 :         return wbcCtxListUsers(NULL, domain_name, _num_users, _users);
     965             : }
     966             : 
     967             : /* Lists Groups */
     968             : _PUBLIC_
     969          22 : wbcErr wbcCtxListGroups(struct wbcContext *ctx,
     970             :                         const char *domain_name,
     971             :                         uint32_t *_num_groups,
     972             :                         const char ***_groups)
     973             : {
     974          22 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     975           0 :         struct winbindd_request request;
     976           0 :         struct winbindd_response response;
     977          22 :         uint32_t num_groups = 0;
     978          22 :         const char **groups = NULL;
     979           0 :         const char *next;
     980             : 
     981             :         /* Initialise request */
     982             : 
     983          22 :         ZERO_STRUCT(request);
     984          22 :         ZERO_STRUCT(response);
     985             : 
     986          22 :         if (domain_name) {
     987          22 :                 strncpy(request.domain_name, domain_name,
     988             :                         sizeof(request.domain_name)-1);
     989             :         }
     990             : 
     991          22 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_GROUPS,
     992             :                                         &request,
     993             :                                         &response);
     994          22 :         BAIL_ON_WBC_ERROR(wbc_status);
     995             : 
     996          22 :         groups = wbcAllocateStringArray(response.data.num_entries);
     997          22 :         if (groups == NULL) {
     998           0 :                 return WBC_ERR_NO_MEMORY;
     999             :         }
    1000             : 
    1001             :         /* Look through extra data */
    1002             : 
    1003          22 :         next = (const char *)response.extra_data.data;
    1004        1224 :         while (next) {
    1005           0 :                 const char *current;
    1006           0 :                 char *k;
    1007             : 
    1008        1202 :                 if (num_groups >= response.data.num_entries) {
    1009           0 :                         wbc_status = WBC_ERR_INVALID_RESPONSE;
    1010           0 :                         goto done;
    1011             :                 }
    1012             : 
    1013        1202 :                 current = next;
    1014        1202 :                 k = strchr(next, ',');
    1015             : 
    1016        1202 :                 if (k) {
    1017        1180 :                         k[0] = '\0';
    1018        1180 :                         next = k+1;
    1019             :                 } else {
    1020          22 :                         next = NULL;
    1021             :                 }
    1022             : 
    1023        1202 :                 groups[num_groups] = strdup(current);
    1024        1202 :                 BAIL_ON_PTR_ERROR(groups[num_groups], wbc_status);
    1025        1202 :                 num_groups += 1;
    1026             :         }
    1027          22 :         if (num_groups != response.data.num_entries) {
    1028           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
    1029           0 :                 goto done;
    1030             :         }
    1031             : 
    1032          22 :         *_num_groups = response.data.num_entries;
    1033          22 :         *_groups = groups;
    1034          22 :         groups = NULL;
    1035          22 :         wbc_status = WBC_ERR_SUCCESS;
    1036             : 
    1037          22 :  done:
    1038          22 :         winbindd_free_response(&response);
    1039          22 :         wbcFreeMemory(groups);
    1040          22 :         return wbc_status;
    1041             : }
    1042             : 
    1043             : _PUBLIC_
    1044          22 : wbcErr wbcListGroups(const char *domain_name,
    1045             :                      uint32_t *_num_groups,
    1046             :                      const char ***_groups)
    1047             : {
    1048          22 :         return wbcCtxListGroups(NULL, domain_name, _num_groups, _groups);
    1049             : }
    1050             : 
    1051             : _PUBLIC_
    1052         222 : wbcErr wbcCtxGetDisplayName(struct wbcContext *ctx,
    1053             :                             const struct wbcDomainSid *sid,
    1054             :                             char **pdomain,
    1055             :                             char **pfullname,
    1056             :                             enum wbcSidType *pname_type)
    1057             : {
    1058           0 :         wbcErr wbc_status;
    1059         222 :         char *domain = NULL;
    1060         222 :         char *name = NULL;
    1061           0 :         enum wbcSidType name_type;
    1062             : 
    1063         222 :         wbc_status = wbcCtxLookupSid(ctx, sid, &domain, &name, &name_type);
    1064         222 :         BAIL_ON_WBC_ERROR(wbc_status);
    1065             : 
    1066         222 :         if (name_type == WBC_SID_NAME_USER) {
    1067           0 :                 uid_t uid;
    1068           0 :                 struct passwd *pwd;
    1069             : 
    1070         222 :                 wbc_status = wbcCtxSidToUid(ctx, sid, &uid);
    1071         222 :                 BAIL_ON_WBC_ERROR(wbc_status);
    1072             : 
    1073         222 :                 wbc_status = wbcCtxGetpwuid(ctx, uid, &pwd);
    1074         222 :                 BAIL_ON_WBC_ERROR(wbc_status);
    1075             : 
    1076         222 :                 wbcFreeMemory(name);
    1077             : 
    1078         222 :                 name = wbcStrDup(pwd->pw_gecos);
    1079         222 :                 wbcFreeMemory(pwd);
    1080         222 :                 BAIL_ON_PTR_ERROR(name, wbc_status);
    1081             :         }
    1082             : 
    1083         222 :         wbc_status = WBC_ERR_SUCCESS;
    1084             : 
    1085         222 :  done:
    1086         222 :         if (WBC_ERROR_IS_OK(wbc_status)) {
    1087         222 :                 *pdomain = domain;
    1088         222 :                 *pfullname = name;
    1089         222 :                 *pname_type = name_type;
    1090             :         } else {
    1091           0 :                 wbcFreeMemory(domain);
    1092           0 :                 wbcFreeMemory(name);
    1093             :         }
    1094             : 
    1095         222 :         return wbc_status;
    1096             : }
    1097             : 
    1098             : _PUBLIC_
    1099         222 : wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
    1100             :                          char **pdomain,
    1101             :                          char **pfullname,
    1102             :                          enum wbcSidType *pname_type)
    1103             : {
    1104         222 :         return wbcCtxGetDisplayName(NULL, sid, pdomain, pfullname, pname_type);
    1105             : }
    1106             : 
    1107             : _PUBLIC_
    1108         376 : const char* wbcSidTypeString(enum wbcSidType type)
    1109             : {
    1110         376 :         switch (type) {
    1111           4 :         case WBC_SID_NAME_USE_NONE: return "SID_NONE";
    1112         284 :         case WBC_SID_NAME_USER:     return "SID_USER";
    1113          14 :         case WBC_SID_NAME_DOM_GRP:  return "SID_DOM_GROUP";
    1114          30 :         case WBC_SID_NAME_DOMAIN:   return "SID_DOMAIN";
    1115           8 :         case WBC_SID_NAME_ALIAS:    return "SID_ALIAS";
    1116          12 :         case WBC_SID_NAME_WKN_GRP:  return "SID_WKN_GROUP";
    1117           4 :         case WBC_SID_NAME_DELETED:  return "SID_DELETED";
    1118           4 :         case WBC_SID_NAME_INVALID:  return "SID_INVALID";
    1119           8 :         case WBC_SID_NAME_UNKNOWN:  return "SID_UNKNOWN";
    1120           4 :         case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER";
    1121           4 :         case WBC_SID_NAME_LABEL:    return "SID_LABEL";
    1122           0 :         default:                    return "Unknown type";
    1123             :         }
    1124             : }

Generated by: LCOV version 1.14