root/nsswitch/libwbclient/wbc_sid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wbcSidToString
  2. wbcStringToSid
  3. wbcLookupName
  4. wbcLookupSid
  5. wbcLookupRids
  6. wbcLookupUserSids
  7. _sid_to_rid
  8. wbcGetSidAliases
  9. wbcListUsers
  10. wbcListGroups
  11. wbcGetDisplayName

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    Winbind client API
   5 
   6    Copyright (C) Gerald (Jerry) Carter 2007
   7 
   8 
   9    This library is free software; you can redistribute it and/or
  10    modify it under the terms of the GNU Lesser General Public
  11    License as published by the Free Software Foundation; either
  12    version 3 of the License, or (at your option) any later version.
  13 
  14    This library is distributed in the hope that it will be useful,
  15    but WITHOUT ANY WARRANTY; without even the implied warranty of
  16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17    Library General Public License for more details.
  18 
  19    You should have received a copy of the GNU Lesser General Public License
  20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  21 */
  22 
  23 /* Required Headers */
  24 
  25 #include "libwbclient.h"
  26 
  27 
  28 /* Convert a binary SID to a character string */
  29 wbcErr wbcSidToString(const struct wbcDomainSid *sid,
     /* [<][>][^][v][top][bottom][index][help] */
  30                       char **sid_string)
  31 {
  32         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
  33         uint32_t id_auth;
  34         int i;
  35         char *tmp = NULL;
  36 
  37         if (!sid) {
  38                 wbc_status = WBC_ERR_INVALID_SID;
  39                 BAIL_ON_WBC_ERROR(wbc_status);
  40         }
  41 
  42         id_auth = sid->id_auth[5] +
  43                 (sid->id_auth[4] << 8) +
  44                 (sid->id_auth[3] << 16) +
  45                 (sid->id_auth[2] << 24);
  46 
  47         tmp = talloc_asprintf(NULL, "S-%d-%d", sid->sid_rev_num, id_auth);
  48         BAIL_ON_PTR_ERROR(tmp, wbc_status);
  49 
  50         for (i=0; i<sid->num_auths; i++) {
  51                 char *tmp2;
  52                 tmp2 = talloc_asprintf_append(tmp, "-%u", sid->sub_auths[i]);
  53                 BAIL_ON_PTR_ERROR(tmp2, wbc_status);
  54 
  55                 tmp = tmp2;
  56         }
  57 
  58         *sid_string = tmp;
  59         tmp = NULL;
  60 
  61         wbc_status = WBC_ERR_SUCCESS;
  62 
  63 done:
  64         talloc_free(tmp);
  65 
  66         return wbc_status;
  67 }
  68 
  69 /* Convert a character string to a binary SID */
  70 wbcErr wbcStringToSid(const char *str,
     /* [<][>][^][v][top][bottom][index][help] */
  71                       struct wbcDomainSid *sid)
  72 {
  73         const char *p;
  74         char *q;
  75         uint32_t x;
  76         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
  77 
  78         if (!sid) {
  79                 wbc_status = WBC_ERR_INVALID_PARAM;
  80                 BAIL_ON_WBC_ERROR(wbc_status);
  81         }
  82 
  83         /* Sanity check for either "S-" or "s-" */
  84 
  85         if (!str
  86             || (str[0]!='S' && str[0]!='s')
  87             || (str[1]!='-'))
  88         {
  89                 wbc_status = WBC_ERR_INVALID_PARAM;
  90                 BAIL_ON_WBC_ERROR(wbc_status);
  91         }
  92 
  93         /* Get the SID revision number */
  94 
  95         p = str+2;
  96         x = (uint32_t)strtol(p, &q, 10);
  97         if (x==0 || !q || *q!='-') {
  98                 wbc_status = WBC_ERR_INVALID_SID;
  99                 BAIL_ON_WBC_ERROR(wbc_status);
 100         }
 101         sid->sid_rev_num = (uint8_t)x;
 102 
 103         /* Next the Identifier Authority.  This is stored in big-endian
 104            in a 6 byte array. */
 105 
 106         p = q+1;
 107         x = (uint32_t)strtol(p, &q, 10);
 108         if (!q || *q!='-') {
 109                 wbc_status = WBC_ERR_INVALID_SID;
 110                 BAIL_ON_WBC_ERROR(wbc_status);
 111         }
 112         sid->id_auth[5] = (x & 0x000000ff);
 113         sid->id_auth[4] = (x & 0x0000ff00) >> 8;
 114         sid->id_auth[3] = (x & 0x00ff0000) >> 16;
 115         sid->id_auth[2] = (x & 0xff000000) >> 24;
 116         sid->id_auth[1] = 0;
 117         sid->id_auth[0] = 0;
 118 
 119         /* now read the the subauthorities */
 120 
 121         p = q +1;
 122         sid->num_auths = 0;
 123         while (sid->num_auths < WBC_MAXSUBAUTHS) {
 124                 x=(uint32_t)strtoul(p, &q, 10);
 125                 if (p == q)
 126                         break;
 127                 if (q == NULL) {
 128                         wbc_status = WBC_ERR_INVALID_SID;
 129                         BAIL_ON_WBC_ERROR(wbc_status);
 130                 }
 131                 sid->sub_auths[sid->num_auths++] = x;
 132 
 133                 if ((*q!='-') || (*q=='\0'))
 134                         break;
 135                 p = q + 1;
 136         }
 137 
 138         /* IF we ended early, then the SID could not be converted */
 139 
 140         if (q && *q!='\0') {
 141                 wbc_status = WBC_ERR_INVALID_SID;
 142                 BAIL_ON_WBC_ERROR(wbc_status);
 143         }
 144 
 145         wbc_status = WBC_ERR_SUCCESS;
 146 
 147 done:
 148         return wbc_status;
 149 
 150 }
 151 
 152 /* Convert a domain and name to SID */
 153 wbcErr wbcLookupName(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 154                      const char *name,
 155                      struct wbcDomainSid *sid,
 156                      enum wbcSidType *name_type)
 157 {
 158         struct winbindd_request request;
 159         struct winbindd_response response;
 160         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 161 
 162         if (!sid || !name_type) {
 163                 wbc_status = WBC_ERR_INVALID_PARAM;
 164                 BAIL_ON_WBC_ERROR(wbc_status);
 165         }
 166 
 167         /* Initialize request */
 168 
 169         ZERO_STRUCT(request);
 170         ZERO_STRUCT(response);
 171 
 172         /* dst is already null terminated from the memset above */
 173 
 174         strncpy(request.data.name.dom_name, domain,
 175                 sizeof(request.data.name.dom_name)-1);
 176         strncpy(request.data.name.name, name,
 177                 sizeof(request.data.name.name)-1);
 178 
 179         wbc_status = wbcRequestResponse(WINBINDD_LOOKUPNAME,
 180                                         &request,
 181                                         &response);
 182         BAIL_ON_WBC_ERROR(wbc_status);
 183 
 184         wbc_status = wbcStringToSid(response.data.sid.sid, sid);
 185         BAIL_ON_WBC_ERROR(wbc_status);
 186 
 187         *name_type = (enum wbcSidType)response.data.sid.type;
 188 
 189         wbc_status = WBC_ERR_SUCCESS;
 190 
 191  done:
 192         return wbc_status;
 193 }
 194 
 195 /* Convert a SID to a domain and name */
 196 wbcErr wbcLookupSid(const struct wbcDomainSid *sid,
     /* [<][>][^][v][top][bottom][index][help] */
 197                     char **pdomain,
 198                     char **pname,
 199                     enum wbcSidType *pname_type)
 200 {
 201         struct winbindd_request request;
 202         struct winbindd_response response;
 203         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 204         char *sid_string = NULL;
 205         char *domain = NULL;
 206         char *name = NULL;
 207         enum wbcSidType name_type = WBC_SID_NAME_USE_NONE;
 208 
 209         if (!sid) {
 210                 wbc_status = WBC_ERR_INVALID_PARAM;
 211                 BAIL_ON_WBC_ERROR(wbc_status);
 212         }
 213 
 214         /* Initialize request */
 215 
 216         ZERO_STRUCT(request);
 217         ZERO_STRUCT(response);
 218 
 219         /* dst is already null terminated from the memset above */
 220 
 221         wbc_status = wbcSidToString(sid, &sid_string);
 222         BAIL_ON_WBC_ERROR(wbc_status);
 223 
 224         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
 225         wbcFreeMemory(sid_string);
 226 
 227         /* Make request */
 228 
 229         wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSID,
 230                                            &request,
 231                                            &response);
 232         BAIL_ON_WBC_ERROR(wbc_status);
 233 
 234         /* Copy out result */
 235 
 236         domain = talloc_strdup(NULL, response.data.name.dom_name);
 237         BAIL_ON_PTR_ERROR(domain, wbc_status);
 238 
 239         name = talloc_strdup(NULL, response.data.name.name);
 240         BAIL_ON_PTR_ERROR(name, wbc_status);
 241 
 242         name_type = (enum wbcSidType)response.data.name.type;
 243 
 244         wbc_status = WBC_ERR_SUCCESS;
 245 
 246  done:
 247         if (WBC_ERROR_IS_OK(wbc_status)) {
 248                 if (pdomain != NULL) {
 249                         *pdomain = domain;
 250                 } else {
 251                         TALLOC_FREE(domain);
 252                 }
 253                 if (pname != NULL) {
 254                         *pname = name;
 255                 } else {
 256                         TALLOC_FREE(name);
 257                 }
 258                 if (pname_type != NULL) {
 259                         *pname_type = name_type;
 260                 }
 261         }
 262         else {
 263 #if 0
 264                 /*
 265                  * Found by Coverity: In this particular routine we can't end
 266                  * up here with a non-NULL name. Further up there are just two
 267                  * exit paths that lead here, neither of which leave an
 268                  * allocated name. If you add more paths up there, re-activate
 269                  * this.
 270                  */
 271                 if (name != NULL) {
 272                         talloc_free(name);
 273                 }
 274 #endif
 275                 if (domain != NULL) {
 276                         talloc_free(domain);
 277                 }
 278         }
 279 
 280         return wbc_status;
 281 }
 282 
 283 /* Translate a collection of RIDs within a domain to names */
 284 
 285 wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 286                      int num_rids,
 287                      uint32_t *rids,
 288                      const char **pp_domain_name,
 289                      const char ***pnames,
 290                      enum wbcSidType **ptypes)
 291 {
 292         size_t i, len, ridbuf_size;
 293         char *ridlist;
 294         char *p;
 295         struct winbindd_request request;
 296         struct winbindd_response response;
 297         char *sid_string = NULL;
 298         char *domain_name = NULL;
 299         const char **names = NULL;
 300         enum wbcSidType *types = NULL;
 301         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 302 
 303         /* Initialise request */
 304 
 305         ZERO_STRUCT(request);
 306         ZERO_STRUCT(response);
 307 
 308         if (!dom_sid || (num_rids == 0)) {
 309                 wbc_status = WBC_ERR_INVALID_PARAM;
 310                 BAIL_ON_WBC_ERROR(wbc_status);
 311         }
 312 
 313         wbc_status = wbcSidToString(dom_sid, &sid_string);
 314         BAIL_ON_WBC_ERROR(wbc_status);
 315 
 316         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
 317         wbcFreeMemory(sid_string);
 318 
 319         /* Even if all the Rids were of maximum 32bit values,
 320            we would only have 11 bytes per rid in the final array
 321            ("4294967296" + \n).  Add one more byte for the
 322            terminating '\0' */
 323 
 324         ridbuf_size = (sizeof(char)*11) * num_rids + 1;
 325 
 326         ridlist = talloc_zero_array(NULL, char, ridbuf_size);
 327         BAIL_ON_PTR_ERROR(ridlist, wbc_status);
 328 
 329         len = 0;
 330         for (i=0; i<num_rids && (len-1)>0; i++) {
 331                 char ridstr[12];
 332 
 333                 len = strlen(ridlist);
 334                 p = ridlist + len;
 335 
 336                 snprintf( ridstr, sizeof(ridstr)-1, "%u\n", rids[i]);
 337                 strncat(p, ridstr, ridbuf_size-len-1);
 338         }
 339 
 340         request.extra_data.data = ridlist;
 341         request.extra_len = strlen(ridlist)+1;
 342 
 343         wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS,
 344                                         &request,
 345                                         &response);
 346         talloc_free(ridlist);
 347         BAIL_ON_WBC_ERROR(wbc_status);
 348 
 349         domain_name = talloc_strdup(NULL, response.data.domain_name);
 350         BAIL_ON_PTR_ERROR(domain_name, wbc_status);
 351 
 352         names = talloc_array(NULL, const char*, num_rids);
 353         BAIL_ON_PTR_ERROR(names, wbc_status);
 354 
 355         types = talloc_array(NULL, enum wbcSidType, num_rids);
 356         BAIL_ON_PTR_ERROR(types, wbc_status);
 357 
 358         p = (char *)response.extra_data.data;
 359 
 360         for (i=0; i<num_rids; i++) {
 361                 char *q;
 362 
 363                 if (*p == '\0') {
 364                         wbc_status = WBC_ERR_INVALID_RESPONSE;
 365                         BAIL_ON_WBC_ERROR(wbc_status);
 366                 }
 367 
 368                 types[i] = (enum wbcSidType)strtoul(p, &q, 10);
 369 
 370                 if (*q != ' ') {
 371                         wbc_status = WBC_ERR_INVALID_RESPONSE;
 372                         BAIL_ON_WBC_ERROR(wbc_status);
 373                 }
 374 
 375                 p = q+1;
 376 
 377                 if ((q = strchr(p, '\n')) == NULL) {
 378                         wbc_status = WBC_ERR_INVALID_RESPONSE;
 379                         BAIL_ON_WBC_ERROR(wbc_status);
 380                 }
 381 
 382                 *q = '\0';
 383 
 384                 names[i] = talloc_strdup(names, p);
 385                 BAIL_ON_PTR_ERROR(names[i], wbc_status);
 386 
 387                 p = q+1;
 388         }
 389 
 390         if (*p != '\0') {
 391                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 392                 BAIL_ON_WBC_ERROR(wbc_status);
 393         }
 394 
 395         wbc_status = WBC_ERR_SUCCESS;
 396 
 397  done:
 398         if (response.extra_data.data) {
 399                 free(response.extra_data.data);
 400         }
 401 
 402         if (WBC_ERROR_IS_OK(wbc_status)) {
 403                 *pp_domain_name = domain_name;
 404                 *pnames = names;
 405                 *ptypes = types;
 406         }
 407         else {
 408                 if (domain_name)
 409                         talloc_free(domain_name);
 410                 if (names)
 411                         talloc_free(names);
 412                 if (types)
 413                         talloc_free(types);
 414         }
 415 
 416         return wbc_status;
 417 }
 418 
 419 /* Get the groups a user belongs to */
 420 wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 421                          bool domain_groups_only,
 422                          uint32_t *num_sids,
 423                          struct wbcDomainSid **_sids)
 424 {
 425         uint32_t i;
 426         const char *s;
 427         struct winbindd_request request;
 428         struct winbindd_response response;
 429         char *sid_string = NULL;
 430         struct wbcDomainSid *sids = NULL;
 431         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 432         int cmd;
 433 
 434         /* Initialise request */
 435 
 436         ZERO_STRUCT(request);
 437         ZERO_STRUCT(response);
 438 
 439         if (!user_sid) {
 440                 wbc_status = WBC_ERR_INVALID_PARAM;
 441                 BAIL_ON_WBC_ERROR(wbc_status);
 442         }
 443 
 444         wbc_status = wbcSidToString(user_sid, &sid_string);
 445         BAIL_ON_WBC_ERROR(wbc_status);
 446 
 447         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
 448         wbcFreeMemory(sid_string);
 449 
 450         if (domain_groups_only) {
 451                 cmd = WINBINDD_GETUSERDOMGROUPS;
 452         } else {
 453                 cmd = WINBINDD_GETUSERSIDS;
 454         }
 455 
 456         wbc_status = wbcRequestResponse(cmd,
 457                                         &request,
 458                                         &response);
 459         BAIL_ON_WBC_ERROR(wbc_status);
 460 
 461         if (response.data.num_entries &&
 462             !response.extra_data.data) {
 463                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 464                 BAIL_ON_WBC_ERROR(wbc_status);
 465         }
 466 
 467         sids = talloc_array(NULL, struct wbcDomainSid,
 468                             response.data.num_entries);
 469         BAIL_ON_PTR_ERROR(sids, wbc_status);
 470 
 471         s = (const char *)response.extra_data.data;
 472         for (i = 0; i < response.data.num_entries; i++) {
 473                 char *n = strchr(s, '\n');
 474                 if (n) {
 475                         *n = '\0';
 476                 }
 477                 wbc_status = wbcStringToSid(s, &sids[i]);
 478                 BAIL_ON_WBC_ERROR(wbc_status);
 479                 s += strlen(s) + 1;
 480         }
 481 
 482         *num_sids = response.data.num_entries;
 483         *_sids = sids;
 484         sids = NULL;
 485         wbc_status = WBC_ERR_SUCCESS;
 486 
 487  done:
 488         if (response.extra_data.data) {
 489                 free(response.extra_data.data);
 490         }
 491         if (sids) {
 492                 talloc_free(sids);
 493         }
 494 
 495         return wbc_status;
 496 }
 497 
 498 static inline
 499 wbcErr _sid_to_rid(struct wbcDomainSid *sid, uint32_t *rid)
     /* [<][>][^][v][top][bottom][index][help] */
 500 {
 501         if (sid->num_auths < 1) {
 502                 return WBC_ERR_INVALID_RESPONSE;
 503         }
 504         *rid = sid->sub_auths[sid->num_auths - 1];
 505 
 506         return WBC_ERR_SUCCESS;
 507 }
 508 
 509 /* Get alias membership for sids */
 510 wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid,
     /* [<][>][^][v][top][bottom][index][help] */
 511                         struct wbcDomainSid *sids,
 512                         uint32_t num_sids,
 513                         uint32_t **alias_rids,
 514                         uint32_t *num_alias_rids)
 515 {
 516         uint32_t i;
 517         const char *s;
 518         struct winbindd_request request;
 519         struct winbindd_response response;
 520         char *sid_string = NULL;
 521         ssize_t sid_len;
 522         ssize_t extra_data_len = 0;
 523         char * extra_data = NULL;
 524         ssize_t buflen = 0;
 525         struct wbcDomainSid sid;
 526         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 527         uint32_t * rids = NULL;
 528 
 529         /* Initialise request */
 530 
 531         ZERO_STRUCT(request);
 532         ZERO_STRUCT(response);
 533 
 534         if (!dom_sid) {
 535                 wbc_status = WBC_ERR_INVALID_PARAM;
 536                 BAIL_ON_WBC_ERROR(wbc_status);
 537         }
 538 
 539         wbc_status = wbcSidToString(dom_sid, &sid_string);
 540         BAIL_ON_WBC_ERROR(wbc_status);
 541 
 542         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
 543         wbcFreeMemory(sid_string);
 544         sid_string = NULL;
 545 
 546         /* Lets assume each sid is around 54 characters
 547          * S-1-5-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
 548         buflen = 54 * num_sids;
 549         extra_data = talloc_array(NULL, char, buflen);
 550         if (!extra_data) {
 551                 wbc_status = WBC_ERR_NO_MEMORY;
 552                 BAIL_ON_WBC_ERROR(wbc_status);
 553         }
 554 
 555         /* Build the sid list */
 556         for (i=0; i<num_sids; i++) {
 557                 if (sid_string) {
 558                         wbcFreeMemory(sid_string);
 559                         sid_string = NULL;
 560                 }
 561                 wbc_status = wbcSidToString(&sids[i], &sid_string);
 562                 BAIL_ON_WBC_ERROR(wbc_status);
 563 
 564                 sid_len = strlen(sid_string);
 565 
 566                 if (buflen < extra_data_len + sid_len + 2) {
 567                         buflen *= 2;
 568                         extra_data = talloc_realloc(NULL, extra_data,
 569                             char, buflen);
 570                         if (!extra_data) {
 571                                 wbc_status = WBC_ERR_NO_MEMORY;
 572                                 BAIL_ON_WBC_ERROR(wbc_status);
 573                         }
 574                 }
 575 
 576                 strncpy(&extra_data[extra_data_len], sid_string,
 577                         buflen - extra_data_len);
 578                 extra_data_len += sid_len;
 579                 extra_data[extra_data_len++] = '\n';
 580                 extra_data[extra_data_len] = '\0';
 581         }
 582 
 583         request.extra_data.data = extra_data;
 584         request.extra_len = extra_data_len;
 585 
 586         wbc_status = wbcRequestResponse(WINBINDD_GETSIDALIASES,
 587                                         &request,
 588                                         &response);
 589         BAIL_ON_WBC_ERROR(wbc_status);
 590 
 591         if (response.data.num_entries &&
 592             !response.extra_data.data) {
 593                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 594                 BAIL_ON_WBC_ERROR(wbc_status);
 595         }
 596 
 597         rids = talloc_array(NULL, uint32_t,
 598                             response.data.num_entries);
 599         BAIL_ON_PTR_ERROR(sids, wbc_status);
 600 
 601         s = (const char *)response.extra_data.data;
 602         for (i = 0; i < response.data.num_entries; i++) {
 603                 char *n = strchr(s, '\n');
 604                 if (n) {
 605                         *n = '\0';
 606                 }
 607                 wbc_status = wbcStringToSid(s, &sid);
 608                 BAIL_ON_WBC_ERROR(wbc_status);
 609                 wbc_status = _sid_to_rid(&sid, &rids[i]);
 610                 BAIL_ON_WBC_ERROR(wbc_status);
 611                 s += strlen(s) + 1;
 612         }
 613 
 614         *num_alias_rids = response.data.num_entries;
 615         *alias_rids = rids;
 616         rids = NULL;
 617         wbc_status = WBC_ERR_SUCCESS;
 618 
 619  done:
 620         if (sid_string) {
 621                 wbcFreeMemory(sid_string);
 622         }
 623         if (extra_data) {
 624                 talloc_free(extra_data);
 625         }
 626         if (response.extra_data.data) {
 627                 free(response.extra_data.data);
 628         }
 629         if (rids) {
 630                 talloc_free(rids);
 631         }
 632 
 633         return wbc_status;
 634 }
 635 
 636 
 637 /* Lists Users */
 638 wbcErr wbcListUsers(const char *domain_name,
     /* [<][>][^][v][top][bottom][index][help] */
 639                     uint32_t *_num_users,
 640                     const char ***_users)
 641 {
 642         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 643         struct winbindd_request request;
 644         struct winbindd_response response;
 645         uint32_t num_users = 0;
 646         const char **users = NULL;
 647         const char *next;
 648 
 649         /* Initialise request */
 650 
 651         ZERO_STRUCT(request);
 652         ZERO_STRUCT(response);
 653 
 654         if (domain_name) {
 655                 strncpy(request.domain_name, domain_name,
 656                         sizeof(request.domain_name)-1);
 657         }
 658 
 659         wbc_status = wbcRequestResponse(WINBINDD_LIST_USERS,
 660                                         &request,
 661                                         &response);
 662         BAIL_ON_WBC_ERROR(wbc_status);
 663 
 664         /* Look through extra data */
 665 
 666         next = (const char *)response.extra_data.data;
 667         while (next) {
 668                 const char **tmp;
 669                 const char *current = next;
 670                 char *k = strchr(next, ',');
 671                 if (k) {
 672                         k[0] = '\0';
 673                         next = k+1;
 674                 } else {
 675                         next = NULL;
 676                 }
 677 
 678                 tmp = talloc_realloc(NULL, users,
 679                                      const char *,
 680                                      num_users+1);
 681                 BAIL_ON_PTR_ERROR(tmp, wbc_status);
 682                 users = tmp;
 683 
 684                 users[num_users] = talloc_strdup(users, current);
 685                 BAIL_ON_PTR_ERROR(users[num_users], wbc_status);
 686 
 687                 num_users++;
 688         }
 689 
 690         *_num_users = num_users;
 691         *_users = users;
 692         users = NULL;
 693         wbc_status = WBC_ERR_SUCCESS;
 694 
 695  done:
 696         if (response.extra_data.data) {
 697                 free(response.extra_data.data);
 698         }
 699         if (users) {
 700                 talloc_free(users);
 701         }
 702         return wbc_status;
 703 }
 704 
 705 /* Lists Groups */
 706 wbcErr wbcListGroups(const char *domain_name,
     /* [<][>][^][v][top][bottom][index][help] */
 707                      uint32_t *_num_groups,
 708                      const char ***_groups)
 709 {
 710         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 711         struct winbindd_request request;
 712         struct winbindd_response response;
 713         uint32_t num_groups = 0;
 714         const char **groups = NULL;
 715         const char *next;
 716 
 717         /* Initialise request */
 718 
 719         ZERO_STRUCT(request);
 720         ZERO_STRUCT(response);
 721 
 722         if (domain_name) {
 723                 strncpy(request.domain_name, domain_name,
 724                         sizeof(request.domain_name)-1);
 725         }
 726 
 727         wbc_status = wbcRequestResponse(WINBINDD_LIST_GROUPS,
 728                                         &request,
 729                                         &response);
 730         BAIL_ON_WBC_ERROR(wbc_status);
 731 
 732         /* Look through extra data */
 733 
 734         next = (const char *)response.extra_data.data;
 735         while (next) {
 736                 const char **tmp;
 737                 const char *current = next;
 738                 char *k = strchr(next, ',');
 739                 if (k) {
 740                         k[0] = '\0';
 741                         next = k+1;
 742                 } else {
 743                         next = NULL;
 744                 }
 745 
 746                 tmp = talloc_realloc(NULL, groups,
 747                                      const char *,
 748                                      num_groups+1);
 749                 BAIL_ON_PTR_ERROR(tmp, wbc_status);
 750                 groups = tmp;
 751 
 752                 groups[num_groups] = talloc_strdup(groups, current);
 753                 BAIL_ON_PTR_ERROR(groups[num_groups], wbc_status);
 754 
 755                 num_groups++;
 756         }
 757 
 758         *_num_groups = num_groups;
 759         *_groups = groups;
 760         groups = NULL;
 761         wbc_status = WBC_ERR_SUCCESS;
 762 
 763  done:
 764         if (response.extra_data.data) {
 765                 free(response.extra_data.data);
 766         }
 767         if (groups) {
 768                 talloc_free(groups);
 769         }
 770         return wbc_status;
 771 }
 772 
 773 wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid,
     /* [<][>][^][v][top][bottom][index][help] */
 774                          char **pdomain,
 775                          char **pfullname,
 776                          enum wbcSidType *pname_type)
 777 {
 778         wbcErr wbc_status;
 779         char *domain = NULL;
 780         char *name = NULL;
 781         enum wbcSidType name_type;
 782 
 783         wbc_status = wbcLookupSid(sid, &domain, &name, &name_type);
 784         BAIL_ON_WBC_ERROR(wbc_status);
 785 
 786         if (name_type == WBC_SID_NAME_USER) {
 787                 uid_t uid;
 788                 struct passwd *pwd;
 789 
 790                 wbc_status = wbcSidToUid(sid, &uid);
 791                 BAIL_ON_WBC_ERROR(wbc_status);
 792 
 793                 wbc_status = wbcGetpwuid(uid, &pwd);
 794                 BAIL_ON_WBC_ERROR(wbc_status);
 795 
 796                 wbcFreeMemory(name);
 797 
 798                 name = talloc_strdup(NULL, pwd->pw_gecos);
 799                 BAIL_ON_PTR_ERROR(name, wbc_status);
 800         }
 801 
 802         wbc_status = WBC_ERR_SUCCESS;
 803 
 804  done:
 805         if (WBC_ERROR_IS_OK(wbc_status)) {
 806                 *pdomain = domain;
 807                 *pfullname = name;
 808                 *pname_type = name_type;
 809         } else {
 810                 wbcFreeMemory(domain);
 811                 wbcFreeMemory(name);
 812         }
 813 
 814         return wbc_status;
 815 }

/* [<][>][^][v][top][bottom][index][help] */