root/nsswitch/libwbclient/wbc_util.c

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

DEFINITIONS

This source file includes following definitions.
  1. wbcPing
  2. wbcInterfaceDetails
  3. wbcDomainInfo
  4. wbcResolveWinsByName
  5. wbcResolveWinsByIP
  6. process_domain_info_string
  7. wbcListTrusts
  8. wbcLookupDomainController
  9. wbc_create_domain_controller_info_ex
  10. wbcLookupDomainControllerEx
  11. wbcAddNamedBlob

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    Winbind client API
   5 
   6    Copyright (C) Gerald (Jerry) Carter 2007-2008
   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 
  29 /** @brief Ping winbindd to see if the daemon is running
  30  *
  31  * @return #wbcErr
  32  **/
  33 
  34 wbcErr wbcPing(void)
     /* [<][>][^][v][top][bottom][index][help] */
  35 {
  36         struct winbindd_request request;
  37         struct winbindd_response response;
  38 
  39         /* Initialize request */
  40 
  41         ZERO_STRUCT(request);
  42         ZERO_STRUCT(response);
  43 
  44         return wbcRequestResponse(WINBINDD_PING, &request, &response);
  45 }
  46 
  47 wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
  50         struct wbcInterfaceDetails *info;
  51         struct wbcDomainInfo *domain = NULL;
  52         struct winbindd_request request;
  53         struct winbindd_response response;
  54 
  55         /* Initialize request */
  56 
  57         ZERO_STRUCT(request);
  58         ZERO_STRUCT(response);
  59 
  60         info = talloc(NULL, struct wbcInterfaceDetails);
  61         BAIL_ON_PTR_ERROR(info, wbc_status);
  62 
  63         /* first the interface version */
  64         wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response);
  65         BAIL_ON_WBC_ERROR(wbc_status);
  66         info->interface_version = response.data.interface_version;
  67 
  68         /* then the samba version and the winbind separator */
  69         wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
  70         BAIL_ON_WBC_ERROR(wbc_status);
  71 
  72         info->winbind_version = talloc_strdup(info,
  73                                               response.data.info.samba_version);
  74         BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
  75         info->winbind_separator = response.data.info.winbind_separator;
  76 
  77         /* then the local netbios name */
  78         wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
  79         BAIL_ON_WBC_ERROR(wbc_status);
  80 
  81         info->netbios_name = talloc_strdup(info,
  82                                            response.data.netbios_name);
  83         BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
  84 
  85         /* then the local workgroup name */
  86         wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
  87         BAIL_ON_WBC_ERROR(wbc_status);
  88 
  89         info->netbios_domain = talloc_strdup(info,
  90                                         response.data.domain_name);
  91         BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
  92 
  93         wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
  94         if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
  95                 /* maybe it's a standalone server */
  96                 domain = NULL;
  97                 wbc_status = WBC_ERR_SUCCESS;
  98         } else {
  99                 BAIL_ON_WBC_ERROR(wbc_status);
 100         }
 101 
 102         if (domain) {
 103                 info->dns_domain = talloc_strdup(info,
 104                                                  domain->dns_name);
 105                 wbcFreeMemory(domain);
 106                 BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
 107         } else {
 108                 info->dns_domain = NULL;
 109         }
 110 
 111         *_details = info;
 112         info = NULL;
 113 
 114         wbc_status = WBC_ERR_SUCCESS;
 115 
 116 done:
 117         talloc_free(info);
 118         return wbc_status;
 119 }
 120 
 121 
 122 /* Lookup the current status of a trusted domain */
 123 wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
     /* [<][>][^][v][top][bottom][index][help] */
 124 {
 125         struct winbindd_request request;
 126         struct winbindd_response response;
 127         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 128         struct wbcDomainInfo *info = NULL;
 129 
 130         if (!domain || !dinfo) {
 131                 wbc_status = WBC_ERR_INVALID_PARAM;
 132                 BAIL_ON_WBC_ERROR(wbc_status);
 133         }
 134 
 135         /* Initialize request */
 136 
 137         ZERO_STRUCT(request);
 138         ZERO_STRUCT(response);
 139 
 140         strncpy(request.domain_name, domain,
 141                 sizeof(request.domain_name)-1);
 142 
 143         wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
 144                                         &request,
 145                                         &response);
 146         BAIL_ON_WBC_ERROR(wbc_status);
 147 
 148         info = talloc(NULL, struct wbcDomainInfo);
 149         BAIL_ON_PTR_ERROR(info, wbc_status);
 150 
 151         info->short_name = talloc_strdup(info,
 152                                          response.data.domain_info.name);
 153         BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
 154 
 155         info->dns_name = talloc_strdup(info,
 156                                        response.data.domain_info.alt_name);
 157         BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
 158 
 159         wbc_status = wbcStringToSid(response.data.domain_info.sid,
 160                                     &info->sid);
 161         BAIL_ON_WBC_ERROR(wbc_status);
 162 
 163         if (response.data.domain_info.native_mode)
 164                 info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
 165         if (response.data.domain_info.active_directory)
 166                 info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
 167         if (response.data.domain_info.primary)
 168                 info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
 169 
 170         *dinfo = info;
 171 
 172         wbc_status = WBC_ERR_SUCCESS;
 173 
 174  done:
 175         if (!WBC_ERROR_IS_OK(wbc_status)) {
 176                 talloc_free(info);
 177         }
 178 
 179         return wbc_status;
 180 }
 181 
 182 
 183 /* Resolve a NetbiosName via WINS */
 184 wbcErr wbcResolveWinsByName(const char *name, char **ip)
     /* [<][>][^][v][top][bottom][index][help] */
 185 {
 186         struct winbindd_request request;
 187         struct winbindd_response response;
 188         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 189         char *ipaddr;
 190 
 191         ZERO_STRUCT(request);
 192         ZERO_STRUCT(response);
 193 
 194         /* Send request */
 195 
 196         strncpy(request.data.winsreq, name,
 197                 sizeof(request.data.winsreq)-1);
 198 
 199         wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME,
 200                                         &request,
 201                                         &response);
 202         BAIL_ON_WBC_ERROR(wbc_status);
 203 
 204         /* Display response */
 205 
 206         ipaddr = talloc_strdup(NULL, response.data.winsresp);
 207         BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
 208 
 209         *ip = ipaddr;
 210         wbc_status = WBC_ERR_SUCCESS;
 211 
 212  done:
 213         return wbc_status;
 214 }
 215 
 216 /* Resolve an IP address via WINS into a NetbiosName */
 217 wbcErr wbcResolveWinsByIP(const char *ip, char **name)
     /* [<][>][^][v][top][bottom][index][help] */
 218 {
 219         struct winbindd_request request;
 220         struct winbindd_response response;
 221         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 222         char *name_str;
 223 
 224         ZERO_STRUCT(request);
 225         ZERO_STRUCT(response);
 226 
 227         /* Send request */
 228 
 229         strncpy(request.data.winsreq, ip,
 230                 sizeof(request.data.winsreq)-1);
 231 
 232         wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP,
 233                                         &request,
 234                                         &response);
 235         BAIL_ON_WBC_ERROR(wbc_status);
 236 
 237         /* Display response */
 238 
 239         name_str = talloc_strdup(NULL, response.data.winsresp);
 240         BAIL_ON_PTR_ERROR(name_str, wbc_status);
 241 
 242         *name = name_str;
 243         wbc_status = WBC_ERR_SUCCESS;
 244 
 245  done:
 246         return wbc_status;
 247 }
 248 
 249 /**
 250  */
 251 
 252 static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 253                                          struct wbcDomainInfo *info,
 254                                          char *info_string)
 255 {
 256         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 257         char *r = NULL;
 258         char *s = NULL;
 259 
 260         if (!info || !info_string) {
 261                 wbc_status = WBC_ERR_INVALID_PARAM;
 262                 BAIL_ON_WBC_ERROR(wbc_status);
 263         }
 264 
 265         ZERO_STRUCTP(info);
 266 
 267         r = info_string;
 268 
 269         /* Short Name */
 270         if ((s = strchr(r, '\\')) == NULL) {
 271                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 272                 BAIL_ON_WBC_ERROR(wbc_status);
 273         }
 274         *s = '\0';
 275         s++;
 276 
 277         info->short_name = talloc_strdup(ctx, r);
 278         BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
 279 
 280 
 281         /* DNS Name */
 282         r = s;
 283         if ((s = strchr(r, '\\')) == NULL) {
 284                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 285                 BAIL_ON_WBC_ERROR(wbc_status);
 286         }
 287         *s = '\0';
 288         s++;
 289 
 290         info->dns_name = talloc_strdup(ctx, r);
 291         BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
 292 
 293         /* SID */
 294         r = s;
 295         if ((s = strchr(r, '\\')) == NULL) {
 296                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 297                 BAIL_ON_WBC_ERROR(wbc_status);
 298         }
 299         *s = '\0';
 300         s++;
 301 
 302         wbc_status = wbcStringToSid(r, &info->sid);
 303         BAIL_ON_WBC_ERROR(wbc_status);
 304 
 305         /* Trust type */
 306         r = s;
 307         if ((s = strchr(r, '\\')) == NULL) {
 308                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 309                 BAIL_ON_WBC_ERROR(wbc_status);
 310         }
 311         *s = '\0';
 312         s++;
 313 
 314         if (strcmp(r, "None") == 0) {
 315                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
 316         } else if (strcmp(r, "External") == 0) {
 317                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
 318         } else if (strcmp(r, "Forest") == 0) {
 319                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
 320         } else if (strcmp(r, "In Forest") == 0) {
 321                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
 322         } else {
 323                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 324                 BAIL_ON_WBC_ERROR(wbc_status);
 325         }
 326 
 327         /* Transitive */
 328         r = s;
 329         if ((s = strchr(r, '\\')) == NULL) {
 330                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 331                 BAIL_ON_WBC_ERROR(wbc_status);
 332         }
 333         *s = '\0';
 334         s++;
 335 
 336         if (strcmp(r, "Yes") == 0) {
 337                 info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
 338         }
 339 
 340         /* Incoming */
 341         r = s;
 342         if ((s = strchr(r, '\\')) == NULL) {
 343                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 344                 BAIL_ON_WBC_ERROR(wbc_status);
 345         }
 346         *s = '\0';
 347         s++;
 348 
 349         if (strcmp(r, "Yes") == 0) {
 350                 info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
 351         }
 352 
 353         /* Outgoing */
 354         r = s;
 355         if ((s = strchr(r, '\\')) == NULL) {
 356                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 357                 BAIL_ON_WBC_ERROR(wbc_status);
 358         }
 359         *s = '\0';
 360         s++;
 361 
 362         if (strcmp(r, "Yes") == 0) {
 363                 info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
 364         }
 365 
 366         /* Online/Offline status */
 367 
 368         r = s;
 369         if (r == NULL) {
 370                 wbc_status = WBC_ERR_INVALID_RESPONSE;
 371                 BAIL_ON_WBC_ERROR(wbc_status);
 372         }
 373         if ( strcmp(r, "Offline") == 0) {
 374                 info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE;
 375         }
 376 
 377         wbc_status = WBC_ERR_SUCCESS;
 378 
 379  done:
 380         return wbc_status;
 381 }
 382 
 383 /* Enumerate the domain trusts known by Winbind */
 384 wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
     /* [<][>][^][v][top][bottom][index][help] */
 385 {
 386         struct winbindd_response response;
 387         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 388         char *p = NULL;
 389         char *q = NULL;
 390         char *extra_data = NULL;
 391         int count = 0;
 392         struct wbcDomainInfo *d_list = NULL;
 393         int i = 0;
 394 
 395         *domains = NULL;
 396         *num_domains = 0;
 397 
 398         ZERO_STRUCT(response);
 399 
 400         /* Send request */
 401 
 402         wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
 403                                         NULL,
 404                                         &response);
 405         BAIL_ON_WBC_ERROR(wbc_status);
 406 
 407         /* Decode the response */
 408 
 409         p = (char *)response.extra_data.data;
 410 
 411         if (strlen(p) == 0) {
 412                 /* We should always at least get back our
 413                    own SAM domain */
 414 
 415                 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
 416                 BAIL_ON_WBC_ERROR(wbc_status);
 417         }
 418 
 419         /* Count number of domains */
 420 
 421         count = 0;
 422         while (p) {
 423                 count++;
 424 
 425                 if ((q = strchr(p, '\n')) != NULL)
 426                         q++;
 427                 p = q;
 428         }
 429 
 430         d_list = talloc_array(NULL, struct wbcDomainInfo, count);
 431         BAIL_ON_PTR_ERROR(d_list, wbc_status);
 432 
 433         extra_data = strdup((char*)response.extra_data.data);
 434         BAIL_ON_PTR_ERROR(extra_data, wbc_status);
 435 
 436         p = extra_data;
 437 
 438         /* Outer loop processes the list of domain information */
 439 
 440         for (i=0; i<count && p; i++) {
 441                 char *next = strchr(p, '\n');
 442 
 443                 if (next) {
 444                         *next = '\0';
 445                         next++;
 446                 }
 447 
 448                 wbc_status = process_domain_info_string(d_list, &d_list[i], p);
 449                 BAIL_ON_WBC_ERROR(wbc_status);
 450 
 451                 p = next;
 452         }
 453 
 454         *domains = d_list;
 455         *num_domains = i;
 456 
 457  done:
 458         if (!WBC_ERROR_IS_OK(wbc_status)) {
 459                 if (d_list)
 460                         talloc_free(d_list);
 461                 if (extra_data)
 462                         free(extra_data);
 463         }
 464 
 465         return wbc_status;
 466 }
 467 
 468 /* Enumerate the domain trusts known by Winbind */
 469 wbcErr wbcLookupDomainController(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 470                                  uint32_t flags,
 471                                 struct wbcDomainControllerInfo **dc_info)
 472 {
 473         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 474         struct winbindd_request request;
 475         struct winbindd_response response;
 476         struct wbcDomainControllerInfo *dc = NULL;
 477 
 478         /* validate input params */
 479 
 480         if (!domain || !dc_info) {
 481                 wbc_status = WBC_ERR_INVALID_PARAM;
 482                 BAIL_ON_WBC_ERROR(wbc_status);
 483         }
 484 
 485         ZERO_STRUCT(request);
 486         ZERO_STRUCT(response);
 487 
 488         strncpy(request.domain_name, domain, sizeof(request.domain_name)-1);
 489 
 490         request.flags = flags;
 491 
 492         dc = talloc(NULL, struct wbcDomainControllerInfo);
 493         BAIL_ON_PTR_ERROR(dc, wbc_status);
 494 
 495         /* Send request */
 496 
 497         wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
 498                                         &request,
 499                                         &response);
 500         BAIL_ON_WBC_ERROR(wbc_status);
 501 
 502         dc->dc_name = talloc_strdup(dc, response.data.dc_name);
 503         BAIL_ON_PTR_ERROR(dc->dc_name, wbc_status);
 504 
 505         *dc_info = dc;
 506 
 507 done:
 508         if (!WBC_ERROR_IS_OK(wbc_status)) {
 509                 talloc_free(dc);
 510         }
 511 
 512         return wbc_status;
 513 }
 514 
 515 static wbcErr wbc_create_domain_controller_info_ex(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 516                                                    const struct winbindd_response *resp,
 517                                                    struct wbcDomainControllerInfoEx **_i)
 518 {
 519         wbcErr wbc_status = WBC_ERR_SUCCESS;
 520         struct wbcDomainControllerInfoEx *i;
 521         struct wbcGuid guid;
 522 
 523         i = talloc(mem_ctx, struct wbcDomainControllerInfoEx);
 524         BAIL_ON_PTR_ERROR(i, wbc_status);
 525 
 526         i->dc_unc = talloc_strdup(i, resp->data.dsgetdcname.dc_unc);
 527         BAIL_ON_PTR_ERROR(i->dc_unc, wbc_status);
 528 
 529         i->dc_address = talloc_strdup(i, resp->data.dsgetdcname.dc_address);
 530         BAIL_ON_PTR_ERROR(i->dc_address, wbc_status);
 531 
 532         i->dc_address_type = resp->data.dsgetdcname.dc_address_type;
 533 
 534         wbc_status = wbcStringToGuid(resp->data.dsgetdcname.domain_guid, &guid);
 535         if (WBC_ERROR_IS_OK(wbc_status)) {
 536                 i->domain_guid = talloc(i, struct wbcGuid);
 537                 BAIL_ON_PTR_ERROR(i->domain_guid, wbc_status);
 538 
 539                 *i->domain_guid = guid;
 540         } else {
 541                 i->domain_guid = NULL;
 542         }
 543 
 544         i->domain_name = talloc_strdup(i, resp->data.dsgetdcname.domain_name);
 545         BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
 546 
 547         if (resp->data.dsgetdcname.forest_name[0] != '\0') {
 548                 i->forest_name = talloc_strdup(i,
 549                         resp->data.dsgetdcname.forest_name);
 550                 BAIL_ON_PTR_ERROR(i->forest_name, wbc_status);
 551         } else {
 552                 i->forest_name = NULL;
 553         }
 554 
 555         i->dc_flags = resp->data.dsgetdcname.dc_flags;
 556 
 557         if (resp->data.dsgetdcname.dc_site_name[0] != '\0') {
 558                 i->dc_site_name = talloc_strdup(i,
 559                         resp->data.dsgetdcname.dc_site_name);
 560                 BAIL_ON_PTR_ERROR(i->dc_site_name, wbc_status);
 561         } else {
 562                 i->dc_site_name = NULL;
 563         }
 564 
 565         if (resp->data.dsgetdcname.client_site_name[0] != '\0') {
 566                 i->client_site_name = talloc_strdup(i,
 567                         resp->data.dsgetdcname.client_site_name);
 568                 BAIL_ON_PTR_ERROR(i->client_site_name, wbc_status);
 569         } else {
 570                 i->client_site_name = NULL;
 571         }
 572 
 573         *_i = i;
 574         i = NULL;
 575 
 576 done:
 577         talloc_free(i);
 578         return wbc_status;
 579 }
 580 
 581 /* Get extended domain controller information */
 582 wbcErr wbcLookupDomainControllerEx(const char *domain,
     /* [<][>][^][v][top][bottom][index][help] */
 583                                    struct wbcGuid *guid,
 584                                    const char *site,
 585                                    uint32_t flags,
 586                                    struct wbcDomainControllerInfoEx **dc_info)
 587 {
 588         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 589         struct winbindd_request request;
 590         struct winbindd_response response;
 591 
 592         /* validate input params */
 593 
 594         if (!domain || !dc_info) {
 595                 wbc_status = WBC_ERR_INVALID_PARAM;
 596                 BAIL_ON_WBC_ERROR(wbc_status);
 597         }
 598 
 599         ZERO_STRUCT(request);
 600         ZERO_STRUCT(response);
 601 
 602         request.data.dsgetdcname.flags = flags;
 603 
 604         strncpy(request.data.dsgetdcname.domain_name, domain,
 605                 sizeof(request.data.dsgetdcname.domain_name)-1);
 606 
 607         if (site) {
 608                 strncpy(request.data.dsgetdcname.site_name, site,
 609                         sizeof(request.data.dsgetdcname.site_name)-1);
 610         }
 611 
 612         if (guid) {
 613                 char *str = NULL;
 614 
 615                 wbc_status = wbcGuidToString(guid, &str);
 616                 BAIL_ON_WBC_ERROR(wbc_status);
 617 
 618                 strncpy(request.data.dsgetdcname.domain_guid, str,
 619                         sizeof(request.data.dsgetdcname.domain_guid)-1);
 620 
 621                 wbcFreeMemory(str);
 622         }
 623 
 624         /* Send request */
 625 
 626         wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
 627                                         &request,
 628                                         &response);
 629         BAIL_ON_WBC_ERROR(wbc_status);
 630 
 631         if (dc_info) {
 632                 wbc_status = wbc_create_domain_controller_info_ex(NULL,
 633                                                                   &response,
 634                                                                   dc_info);
 635                 BAIL_ON_WBC_ERROR(wbc_status);
 636         }
 637 
 638         wbc_status = WBC_ERR_SUCCESS;
 639 done:
 640         return wbc_status;
 641 }
 642 
 643 /* Initialize a named blob and add to list of blobs */
 644 wbcErr wbcAddNamedBlob(size_t *num_blobs,
     /* [<][>][^][v][top][bottom][index][help] */
 645                        struct wbcNamedBlob **blobs,
 646                        const char *name,
 647                        uint32_t flags,
 648                        uint8_t *data,
 649                        size_t length)
 650 {
 651         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
 652         struct wbcNamedBlob blob;
 653 
 654         *blobs = talloc_realloc(NULL, *blobs, struct wbcNamedBlob,
 655                                 *(num_blobs)+1);
 656         BAIL_ON_PTR_ERROR(*blobs, wbc_status);
 657 
 658         blob.name               = talloc_strdup(*blobs, name);
 659         BAIL_ON_PTR_ERROR(blob.name, wbc_status);
 660         blob.flags              = flags;
 661         blob.blob.length        = length;
 662         blob.blob.data          = (uint8_t *)talloc_memdup(*blobs, data, length);
 663         BAIL_ON_PTR_ERROR(blob.blob.data, wbc_status);
 664 
 665         (*(blobs))[*num_blobs] = blob;
 666         *(num_blobs) += 1;
 667 
 668         wbc_status = WBC_ERR_SUCCESS;
 669 done:
 670         if (!WBC_ERROR_IS_OK(wbc_status) && blobs) {
 671                 wbcFreeMemory(*blobs);
 672         }
 673         return wbc_status;
 674 }

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