LCOV - code coverage report
Current view: top level - nsswitch/libwbclient - wbc_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 397 468 84.8 %
Date: 2024-02-28 12:06:22 Functions: 28 28 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind client asynchronous API, utility functions
       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 "replace.h"
      26             : #include "libwbclient.h"
      27             : #include "../winbind_client.h"
      28             : 
      29             : /** @brief Ping winbindd to see if the daemon is running
      30             :  *
      31             :  * @param *ctx       wbclient Context
      32             :  *
      33             :  * @return #wbcErr
      34             :  **/
      35             : _PUBLIC_
      36      184018 : wbcErr wbcCtxPing(struct wbcContext *ctx)
      37             : {
      38           0 :         struct winbindd_request request;
      39           0 :         struct winbindd_response response;
      40             : 
      41             :         /* Initialize request */
      42             : 
      43      184018 :         ZERO_STRUCT(request);
      44      184018 :         ZERO_STRUCT(response);
      45             : 
      46      184018 :         return wbcRequestResponse(ctx, WINBINDD_PING, &request, &response);
      47             : }
      48             : 
      49             : _PUBLIC_
      50      184018 : wbcErr wbcPing(void)
      51             : {
      52      184018 :         return wbcCtxPing(NULL);
      53             : }
      54             : 
      55         492 : static void wbcInterfaceDetailsDestructor(void *ptr)
      56             : {
      57         492 :         struct wbcInterfaceDetails *i = (struct wbcInterfaceDetails *)ptr;
      58         492 :         free(i->winbind_version);
      59         492 :         free(i->netbios_name);
      60         492 :         free(i->netbios_domain);
      61         492 :         free(i->dns_domain);
      62         492 : }
      63             : 
      64             : /**
      65             :  * @brief Query useful information about the winbind service
      66             :  *
      67             :  * @param *_details     pointer to hold the struct wbcInterfaceDetails
      68             :  *
      69             :  * @return #wbcErr
      70             :  */
      71             : 
      72             : _PUBLIC_
      73        1260 : wbcErr wbcCtxInterfaceDetails(struct wbcContext *ctx,
      74             :                               struct wbcInterfaceDetails **_details)
      75             : {
      76        1260 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
      77           2 :         struct wbcInterfaceDetails *info;
      78        1260 :         struct wbcDomainInfo *domain = NULL;
      79           2 :         struct winbindd_request request;
      80           2 :         struct winbindd_response response;
      81             : 
      82             :         /* Initialize request */
      83             : 
      84        1260 :         ZERO_STRUCT(request);
      85        1260 :         ZERO_STRUCT(response);
      86             : 
      87        1260 :         info = (struct wbcInterfaceDetails *)wbcAllocateMemory(
      88             :                 1, sizeof(struct wbcInterfaceDetails),
      89             :                 wbcInterfaceDetailsDestructor);
      90        1260 :         BAIL_ON_PTR_ERROR(info, wbc_status);
      91             : 
      92             :         /* first the interface version */
      93        1260 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_INTERFACE_VERSION,
      94             :                                         NULL, &response);
      95        1260 :         BAIL_ON_WBC_ERROR(wbc_status);
      96        1254 :         info->interface_version = response.data.interface_version;
      97             : 
      98             :         /* then the samba version and the winbind separator */
      99        1254 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_INFO, NULL, &response);
     100        1254 :         BAIL_ON_WBC_ERROR(wbc_status);
     101             : 
     102        1254 :         info->winbind_version = strdup(response.data.info.samba_version);
     103        1254 :         BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
     104        1254 :         info->winbind_separator = response.data.info.winbind_separator;
     105             : 
     106             :         /* then the local netbios name */
     107        1254 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_NETBIOS_NAME,
     108             :                                         NULL, &response);
     109        1254 :         BAIL_ON_WBC_ERROR(wbc_status);
     110             : 
     111        1254 :         info->netbios_name = strdup(response.data.netbios_name);
     112        1254 :         BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
     113             : 
     114             :         /* then the local workgroup name */
     115        1254 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_DOMAIN_NAME,
     116             :                                         NULL, &response);
     117        1254 :         BAIL_ON_WBC_ERROR(wbc_status);
     118             : 
     119        1254 :         info->netbios_domain = strdup(response.data.domain_name);
     120        1254 :         BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
     121             : 
     122        1254 :         wbc_status = wbcCtxDomainInfo(ctx, info->netbios_domain, &domain);
     123        1254 :         if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
     124             :                 /* maybe it's a standalone server */
     125           0 :                 domain = NULL;
     126             :         } else {
     127        1254 :                 BAIL_ON_WBC_ERROR(wbc_status);
     128             :         }
     129             : 
     130        1254 :         if (domain) {
     131        1254 :                 info->dns_domain = strdup(domain->dns_name);
     132        1254 :                 wbcFreeMemory(domain);
     133        1254 :                 BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
     134             :         } else {
     135           0 :                 info->dns_domain = NULL;
     136             :         }
     137             : 
     138        1254 :         *_details = info;
     139        1254 :         info = NULL;
     140             : 
     141        1254 :         wbc_status = WBC_ERR_SUCCESS;
     142             : 
     143        1260 : done:
     144        1260 :         wbcFreeMemory(info);
     145        1260 :         return wbc_status;
     146             : }
     147             : 
     148             : _PUBLIC_
     149        1116 : wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
     150             : {
     151        1116 :         return wbcCtxInterfaceDetails(NULL, _details);
     152             : }
     153             : 
     154        1296 : static void wbcDomainInfoDestructor(void *ptr)
     155             : {
     156        1296 :         struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
     157        1296 :         free(i->short_name);
     158        1296 :         free(i->dns_name);
     159        1296 : }
     160             : 
     161             : /** @brief Lookup the current status of a trusted domain, sync wrapper
     162             :  *
     163             :  * @param domain      Domain to query
     164             :  * @param *dinfo       Pointer to returned struct wbcDomainInfo
     165             :  *
     166             :  * @return #wbcErr
     167             :  */
     168             : 
     169             : _PUBLIC_
     170        1296 : wbcErr wbcCtxDomainInfo(struct wbcContext *ctx,
     171             :                         const char *domain,
     172             :                         struct wbcDomainInfo **dinfo)
     173             : {
     174           2 :         struct winbindd_request request;
     175           2 :         struct winbindd_response response;
     176        1296 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     177        1296 :         struct wbcDomainInfo *info = NULL;
     178             : 
     179        1296 :         if (!domain || !dinfo) {
     180           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     181           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     182             :         }
     183             : 
     184             :         /* Initialize request */
     185             : 
     186        1296 :         ZERO_STRUCT(request);
     187        1296 :         ZERO_STRUCT(response);
     188             : 
     189        1296 :         strncpy(request.domain_name, domain,
     190             :                 sizeof(request.domain_name)-1);
     191             : 
     192        1296 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_DOMAIN_INFO,
     193             :                                         &request,
     194             :                                         &response);
     195        1296 :         BAIL_ON_WBC_ERROR(wbc_status);
     196             : 
     197        1296 :         info = (struct wbcDomainInfo *)wbcAllocateMemory(
     198             :                 1, sizeof(struct wbcDomainInfo), wbcDomainInfoDestructor);
     199        1296 :         BAIL_ON_PTR_ERROR(info, wbc_status);
     200             : 
     201        1296 :         info->short_name = strdup(response.data.domain_info.name);
     202        1296 :         BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
     203             : 
     204        1296 :         info->dns_name = strdup(response.data.domain_info.alt_name);
     205        1296 :         BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
     206             : 
     207        1296 :         wbc_status = wbcStringToSid(response.data.domain_info.sid,
     208             :                                     &info->sid);
     209        1296 :         BAIL_ON_WBC_ERROR(wbc_status);
     210             : 
     211        1296 :         if (response.data.domain_info.native_mode)
     212         476 :                 info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
     213        1296 :         if (response.data.domain_info.active_directory)
     214        1005 :                 info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
     215        1296 :         if (response.data.domain_info.primary)
     216        1286 :                 info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
     217             : 
     218        1296 :         *dinfo = info;
     219        1296 :         info = NULL;
     220             : 
     221        1296 :         wbc_status = WBC_ERR_SUCCESS;
     222             : 
     223        1296 :  done:
     224        1296 :         wbcFreeMemory(info);
     225        1296 :         return wbc_status;
     226             : }
     227             : 
     228             : _PUBLIC_
     229          42 : wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
     230             : {
     231          42 :         return wbcCtxDomainInfo(NULL, domain, dinfo);
     232             : }
     233             : 
     234             : /* Get the list of current DCs */
     235             : _PUBLIC_
     236           4 : wbcErr wbcCtxDcInfo(struct wbcContext *ctx,
     237             :                     const char *domain, size_t *num_dcs,
     238             :                     const char ***dc_names, const char ***dc_ips)
     239             : {
     240           0 :         struct winbindd_request request;
     241           0 :         struct winbindd_response response;
     242           4 :         const char **names = NULL;
     243           4 :         const char **ips = NULL;
     244           4 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     245           0 :         size_t extra_len;
     246           0 :         int i;
     247           0 :         char *p;
     248             : 
     249             :         /* Initialise request */
     250             : 
     251           4 :         ZERO_STRUCT(request);
     252           4 :         ZERO_STRUCT(response);
     253             : 
     254           4 :         if (domain != NULL) {
     255           4 :                 strncpy(request.domain_name, domain,
     256             :                         sizeof(request.domain_name) - 1);
     257             :         }
     258             : 
     259           4 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_DC_INFO,
     260             :                                         &request, &response);
     261           4 :         BAIL_ON_WBC_ERROR(wbc_status);
     262             : 
     263           4 :         names = wbcAllocateStringArray(response.data.num_entries);
     264           4 :         BAIL_ON_PTR_ERROR(names, wbc_status);
     265             : 
     266           4 :         ips = wbcAllocateStringArray(response.data.num_entries);
     267           4 :         BAIL_ON_PTR_ERROR(ips, wbc_status);
     268             : 
     269           4 :         wbc_status = WBC_ERR_INVALID_RESPONSE;
     270             : 
     271           4 :         p = (char *)response.extra_data.data;
     272             : 
     273           4 :         if (response.length < (sizeof(struct winbindd_response)+1)) {
     274           0 :                 goto done;
     275             :         }
     276             : 
     277           4 :         extra_len = response.length - sizeof(struct winbindd_response);
     278             : 
     279           4 :         if (p[extra_len-1] != '\0') {
     280           0 :                 goto done;
     281             :         }
     282             : 
     283           8 :         for (i=0; i<response.data.num_entries; i++) {
     284           0 :                 char *q;
     285             : 
     286           4 :                 q = strchr(p, '\n');
     287           4 :                 if (q == NULL) {
     288           0 :                         goto done;
     289             :                 }
     290           4 :                 names[i] = strndup(p, q-p);
     291           4 :                 BAIL_ON_PTR_ERROR(names[i], wbc_status);
     292           4 :                 p = q+1;
     293             : 
     294           4 :                 q = strchr(p, '\n');
     295           4 :                 if (q == NULL) {
     296           0 :                         goto done;
     297             :                 }
     298           4 :                 ips[i] = strndup(p, q-p);
     299           4 :                 BAIL_ON_PTR_ERROR(ips[i], wbc_status);
     300           4 :                 p = q+1;
     301             :         }
     302           4 :         if (p[0] != '\0') {
     303           0 :                 goto done;
     304             :         }
     305             : 
     306           4 :         wbc_status = WBC_ERR_SUCCESS;
     307           4 : done:
     308           4 :         if (response.extra_data.data)
     309           4 :                 free(response.extra_data.data);
     310             : 
     311           4 :         if (WBC_ERROR_IS_OK(wbc_status)) {
     312           4 :                 *num_dcs = response.data.num_entries;
     313           4 :                 *dc_names = names;
     314           4 :                 names = NULL;
     315           4 :                 *dc_ips = ips;
     316           4 :                 ips = NULL;
     317             :         }
     318           4 :         wbcFreeMemory(names);
     319           4 :         wbcFreeMemory(ips);
     320           4 :         return wbc_status;
     321             : }
     322             : 
     323             : _PUBLIC_
     324           4 : wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
     325             :                  const char ***dc_names, const char ***dc_ips)
     326             : {
     327           4 :         return wbcCtxDcInfo(NULL, domain, num_dcs, dc_names, dc_ips);
     328             : }
     329             : 
     330             : /* Resolve a NetbiosName via WINS */
     331             : _PUBLIC_
     332          12 : wbcErr wbcCtxResolveWinsByName(struct wbcContext *ctx,
     333             :                                const char *name, char **ip)
     334             : {
     335           0 :         struct winbindd_request request;
     336           0 :         struct winbindd_response response;
     337          12 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     338           0 :         char *ipaddr;
     339             : 
     340          12 :         ZERO_STRUCT(request);
     341          12 :         ZERO_STRUCT(response);
     342             : 
     343             :         /* Send request */
     344             : 
     345          12 :         strncpy(request.data.winsreq, name,
     346             :                 sizeof(request.data.winsreq)-1);
     347             : 
     348          12 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_WINS_BYNAME,
     349             :                                         &request,
     350             :                                         &response);
     351          12 :         BAIL_ON_WBC_ERROR(wbc_status);
     352             : 
     353             :         /* Display response */
     354             : 
     355          12 :         ipaddr = wbcStrDup(response.data.winsresp);
     356          12 :         BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
     357             : 
     358          12 :         *ip = ipaddr;
     359          12 :         wbc_status = WBC_ERR_SUCCESS;
     360             : 
     361          12 :  done:
     362          12 :         return wbc_status;
     363             : }
     364             : 
     365             : _PUBLIC_
     366          12 : wbcErr wbcResolveWinsByName(const char *name, char **ip)
     367             : {
     368          12 :         return wbcCtxResolveWinsByName(NULL, name, ip);
     369             : }
     370             : 
     371             : /* Resolve an IP address via WINS into a NetbiosName */
     372             : _PUBLIC_
     373          12 : wbcErr wbcCtxResolveWinsByIP(struct wbcContext *ctx,
     374             :                              const char *ip, char **name)
     375             : {
     376           0 :         struct winbindd_request request;
     377           0 :         struct winbindd_response response;
     378          12 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     379           0 :         char *name_str;
     380             : 
     381          12 :         ZERO_STRUCT(request);
     382          12 :         ZERO_STRUCT(response);
     383             : 
     384             :         /* Send request */
     385             : 
     386          12 :         strncpy(request.data.winsreq, ip,
     387             :                 sizeof(request.data.winsreq)-1);
     388             : 
     389          12 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_WINS_BYIP,
     390             :                                         &request,
     391             :                                         &response);
     392          12 :         BAIL_ON_WBC_ERROR(wbc_status);
     393             : 
     394             :         /* Display response */
     395             : 
     396          12 :         name_str = wbcStrDup(response.data.winsresp);
     397          12 :         BAIL_ON_PTR_ERROR(name_str, wbc_status);
     398             : 
     399          12 :         *name = name_str;
     400          12 :         wbc_status = WBC_ERR_SUCCESS;
     401             : 
     402          12 :  done:
     403          12 :         return wbc_status;
     404             : }
     405             : 
     406             : _PUBLIC_
     407          12 : wbcErr wbcResolveWinsByIP(const char *ip, char **name)
     408             : {
     409          12 :         return wbcCtxResolveWinsByIP(NULL, ip, name);
     410             : }
     411             : 
     412             : /**
     413             :  */
     414             : 
     415         246 : static wbcErr process_domain_info_string(struct wbcDomainInfo *info,
     416             :                                          char *info_string)
     417             : {
     418         246 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     419         246 :         char *r = NULL;
     420         246 :         char *s = NULL;
     421             : 
     422         246 :         r = info_string;
     423             : 
     424             :         /* Short Name */
     425         246 :         if ((s = strchr(r, '\\')) == NULL) {
     426           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     427           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     428             :         }
     429         246 :         *s = '\0';
     430         246 :         s++;
     431             : 
     432         246 :         info->short_name = strdup(r);
     433         246 :         BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
     434             : 
     435             : 
     436             :         /* DNS Name */
     437         246 :         r = s;
     438         246 :         if ((s = strchr(r, '\\')) == NULL) {
     439           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     440           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     441             :         }
     442         246 :         *s = '\0';
     443         246 :         s++;
     444             : 
     445         246 :         info->dns_name = strdup(r);
     446         246 :         BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
     447             : 
     448             :         /* SID */
     449         246 :         r = s;
     450         246 :         if ((s = strchr(r, '\\')) == NULL) {
     451           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     452           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     453             :         }
     454         246 :         *s = '\0';
     455         246 :         s++;
     456             : 
     457         246 :         wbc_status = wbcStringToSid(r, &info->sid);
     458         246 :         BAIL_ON_WBC_ERROR(wbc_status);
     459             : 
     460             :         /* Trust type */
     461         246 :         r = s;
     462         246 :         if ((s = strchr(r, '\\')) == NULL) {
     463           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     464           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     465             :         }
     466         246 :         *s = '\0';
     467         246 :         s++;
     468             : 
     469         246 :         if (strncmp(r, "Routed", strlen("Routed")) == 0) {
     470          36 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
     471          36 :                 info->trust_routing = strdup(r);
     472          36 :                 BAIL_ON_PTR_ERROR(info->trust_routing, wbc_status);
     473         210 :         } else if (strcmp(r, "Local") == 0) {
     474         118 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_LOCAL;
     475          92 :         } else if (strcmp(r, "Workstation") == 0) {
     476          34 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_WKSTA;
     477          58 :         } else if (strcmp(r, "RWDC") == 0) {
     478          28 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_RWDC;
     479          30 :         } else if (strcmp(r, "RODC") == 0) {
     480           8 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_RODC;
     481          22 :         } else if (strcmp(r, "PDC") == 0) {
     482          14 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_PDC;
     483           8 :         } else if (strcmp(r, "External") == 0) {
     484           2 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
     485           6 :         } else if (strcmp(r, "Forest") == 0) {
     486           6 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
     487           0 :         } else if (strcmp(r, "In Forest") == 0) {
     488           0 :                 info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
     489             :         } else {
     490           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     491           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     492             :         }
     493             : 
     494             :         /* Transitive */
     495         246 :         r = s;
     496         246 :         if ((s = strchr(r, '\\')) == NULL) {
     497           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     498           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     499             :         }
     500         246 :         *s = '\0';
     501         246 :         s++;
     502             : 
     503         246 :         if (strcmp(r, "Yes") == 0) {
     504          94 :                 info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
     505             :         }
     506             : 
     507             :         /* Incoming */
     508         246 :         r = s;
     509         246 :         if ((s = strchr(r, '\\')) == NULL) {
     510           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     511           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     512             :         }
     513         246 :         *s = '\0';
     514         246 :         s++;
     515             : 
     516         246 :         if (strcmp(r, "Yes") == 0) {
     517          12 :                 info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
     518             :         }
     519             : 
     520             :         /* Outgoing */
     521         246 :         r = s;
     522         246 :         if ((s = strchr(r, '\\')) == NULL) {
     523           0 :                 wbc_status = WBC_ERR_INVALID_RESPONSE;
     524           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     525             :         }
     526         246 :         *s = '\0';
     527         246 :         s++;
     528             : 
     529         246 :         if (strcmp(r, "Yes") == 0) {
     530         160 :                 info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
     531             :         }
     532             : 
     533             :         /* Online/Offline status */
     534         246 :         r = s;
     535         246 :         if ( strcmp(r, "Offline") == 0) {
     536           6 :                 info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE;
     537             :         }
     538             : 
     539         246 :         wbc_status = WBC_ERR_SUCCESS;
     540             : 
     541         246 :  done:
     542         246 :         return wbc_status;
     543             : }
     544             : 
     545          84 : static void wbcDomainInfoListDestructor(void *ptr)
     546             : {
     547          84 :         struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
     548             : 
     549         330 :         while (i->short_name != NULL) {
     550         246 :                 free(i->short_name);
     551         246 :                 free(i->dns_name);
     552         246 :                 i += 1;
     553             :         }
     554          84 : }
     555             : 
     556             : /* Enumerate the domain trusts known by Winbind */
     557             : _PUBLIC_
     558          84 : wbcErr wbcCtxListTrusts(struct wbcContext *ctx,
     559             :                         struct wbcDomainInfo **domains, size_t *num_domains)
     560             : {
     561           0 :         struct winbindd_response response;
     562          84 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     563          84 :         char *p = NULL;
     564          84 :         char *extra_data = NULL;
     565          84 :         struct wbcDomainInfo *d_list = NULL;
     566          84 :         int i = 0;
     567             : 
     568          84 :         *domains = NULL;
     569          84 :         *num_domains = 0;
     570             : 
     571          84 :         ZERO_STRUCT(response);
     572             : 
     573             :         /* Send request */
     574             : 
     575          84 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_LIST_TRUSTDOM,
     576             :                                         NULL,
     577             :                                         &response);
     578          84 :         BAIL_ON_WBC_ERROR(wbc_status);
     579             : 
     580             :         /* Decode the response */
     581             : 
     582          84 :         p = (char *)response.extra_data.data;
     583             : 
     584          84 :         if ((p == NULL) || (strlen(p) == 0)) {
     585             :                 /* We should always at least get back our
     586             :                    own SAM domain */
     587             : 
     588           0 :                 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
     589           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     590             :         }
     591             : 
     592          84 :         d_list = (struct wbcDomainInfo *)wbcAllocateMemory(
     593          84 :                 response.data.num_entries + 1,sizeof(struct wbcDomainInfo),
     594             :                 wbcDomainInfoListDestructor);
     595          84 :         BAIL_ON_PTR_ERROR(d_list, wbc_status);
     596             : 
     597          84 :         extra_data = strdup((char*)response.extra_data.data);
     598          84 :         BAIL_ON_PTR_ERROR(extra_data, wbc_status);
     599             : 
     600          84 :         p = extra_data;
     601             : 
     602             :         /* Outer loop processes the list of domain information */
     603             : 
     604         330 :         for (i=0; i<response.data.num_entries && p; i++) {
     605         246 :                 char *next = strchr(p, '\n');
     606             : 
     607         246 :                 if (next) {
     608         162 :                         *next = '\0';
     609         162 :                         next++;
     610             :                 }
     611             : 
     612         246 :                 wbc_status = process_domain_info_string(&d_list[i], p);
     613         246 :                 BAIL_ON_WBC_ERROR(wbc_status);
     614             : 
     615         246 :                 p = next;
     616             :         }
     617             : 
     618          84 :         *domains = d_list;
     619          84 :         d_list = NULL;
     620          84 :         *num_domains = i;
     621             : 
     622          84 :  done:
     623          84 :         winbindd_free_response(&response);
     624          84 :         wbcFreeMemory(d_list);
     625          84 :         free(extra_data);
     626          84 :         return wbc_status;
     627             : }
     628             : 
     629             : _PUBLIC_
     630          84 : wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
     631             : {
     632          84 :         return wbcCtxListTrusts(NULL, domains, num_domains);
     633             : }
     634             : 
     635           4 : static void wbcDomainControllerInfoDestructor(void *ptr)
     636             : {
     637           4 :         struct wbcDomainControllerInfo *i =
     638             :                 (struct wbcDomainControllerInfo *)ptr;
     639           4 :         free(i->dc_name);
     640           4 : }
     641             : 
     642             : /* Enumerate the domain trusts known by Winbind */
     643             : _PUBLIC_
     644           4 : wbcErr wbcCtxLookupDomainController(struct wbcContext *ctx,
     645             :                                     const char *domain, uint32_t flags,
     646             :                                     struct wbcDomainControllerInfo **dc_info)
     647             : {
     648           4 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     649           0 :         struct winbindd_request request;
     650           0 :         struct winbindd_response response;
     651           4 :         struct wbcDomainControllerInfo *dc = NULL;
     652             : 
     653             :         /* validate input params */
     654             : 
     655           4 :         if (!domain || !dc_info) {
     656           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     657           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     658             :         }
     659             : 
     660           4 :         ZERO_STRUCT(request);
     661           4 :         ZERO_STRUCT(response);
     662             : 
     663           4 :         strncpy(request.data.dsgetdcname.domain_name, domain,
     664             :                 sizeof(request.data.dsgetdcname.domain_name)-1);
     665             : 
     666           4 :         request.flags = flags;
     667             : 
     668           4 :         dc = (struct wbcDomainControllerInfo *)wbcAllocateMemory(
     669             :                  1, sizeof(struct wbcDomainControllerInfo),
     670             :                 wbcDomainControllerInfoDestructor);
     671           4 :         BAIL_ON_PTR_ERROR(dc, wbc_status);
     672             : 
     673             :         /* Send request */
     674             : 
     675           4 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_DSGETDCNAME,
     676             :                                         &request,
     677             :                                         &response);
     678           4 :         BAIL_ON_WBC_ERROR(wbc_status);
     679             : 
     680           4 :         dc->dc_name = strdup(response.data.dsgetdcname.dc_unc);
     681           4 :         BAIL_ON_PTR_ERROR(dc->dc_name, wbc_status);
     682             : 
     683           4 :         *dc_info = dc;
     684           4 :         dc = NULL;
     685             : 
     686           4 : done:
     687           4 :         wbcFreeMemory(dc);
     688           4 :         return wbc_status;
     689             : }
     690             : 
     691             : _PUBLIC_
     692           4 : wbcErr wbcLookupDomainController(const char *domain, uint32_t flags,
     693             :                                  struct wbcDomainControllerInfo **dc_info)
     694             : {
     695           4 :         return wbcCtxLookupDomainController(NULL, domain, flags, dc_info);
     696             : }
     697             : 
     698           4 : static void wbcDomainControllerInfoExDestructor(void *ptr)
     699             : {
     700           4 :         struct wbcDomainControllerInfoEx *i =
     701             :                 (struct wbcDomainControllerInfoEx *)ptr;
     702           4 :         free(discard_const_p(char, i->dc_unc));
     703           4 :         free(discard_const_p(char, i->dc_address));
     704           4 :         free(discard_const_p(char, i->domain_guid));
     705           4 :         free(discard_const_p(char, i->domain_name));
     706           4 :         free(discard_const_p(char, i->forest_name));
     707           4 :         free(discard_const_p(char, i->dc_site_name));
     708           4 :         free(discard_const_p(char, i->client_site_name));
     709           4 : }
     710             : 
     711           4 : static wbcErr wbc_create_domain_controller_info_ex(const struct winbindd_response *resp,
     712             :                                                    struct wbcDomainControllerInfoEx **_i)
     713             : {
     714           4 :         wbcErr wbc_status = WBC_ERR_SUCCESS;
     715           0 :         struct wbcDomainControllerInfoEx *i;
     716           0 :         struct wbcGuid guid;
     717             : 
     718           4 :         i = (struct wbcDomainControllerInfoEx *)wbcAllocateMemory(
     719             :                 1, sizeof(struct wbcDomainControllerInfoEx),
     720             :                 wbcDomainControllerInfoExDestructor);
     721           4 :         BAIL_ON_PTR_ERROR(i, wbc_status);
     722             : 
     723           4 :         i->dc_unc = strdup(resp->data.dsgetdcname.dc_unc);
     724           4 :         BAIL_ON_PTR_ERROR(i->dc_unc, wbc_status);
     725             : 
     726           4 :         i->dc_address = strdup(resp->data.dsgetdcname.dc_address);
     727           4 :         BAIL_ON_PTR_ERROR(i->dc_address, wbc_status);
     728             : 
     729           4 :         i->dc_address_type = resp->data.dsgetdcname.dc_address_type;
     730             : 
     731           4 :         wbc_status = wbcStringToGuid(resp->data.dsgetdcname.domain_guid, &guid);
     732           4 :         if (WBC_ERROR_IS_OK(wbc_status)) {
     733           4 :                 i->domain_guid = (struct wbcGuid *)malloc(
     734             :                         sizeof(struct wbcGuid));
     735           4 :                 BAIL_ON_PTR_ERROR(i->domain_guid, wbc_status);
     736             : 
     737           4 :                 *i->domain_guid = guid;
     738             :         }
     739             : 
     740           4 :         i->domain_name = strdup(resp->data.dsgetdcname.domain_name);
     741           4 :         BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
     742             : 
     743           4 :         if (resp->data.dsgetdcname.forest_name[0] != '\0') {
     744           0 :                 i->forest_name = strdup(resp->data.dsgetdcname.forest_name);
     745           0 :                 BAIL_ON_PTR_ERROR(i->forest_name, wbc_status);
     746             :         }
     747             : 
     748           4 :         i->dc_flags = resp->data.dsgetdcname.dc_flags;
     749             : 
     750           4 :         if (resp->data.dsgetdcname.dc_site_name[0] != '\0') {
     751           0 :                 i->dc_site_name = strdup(resp->data.dsgetdcname.dc_site_name);
     752           0 :                 BAIL_ON_PTR_ERROR(i->dc_site_name, wbc_status);
     753             :         }
     754             : 
     755           4 :         if (resp->data.dsgetdcname.client_site_name[0] != '\0') {
     756           0 :                 i->client_site_name = strdup(
     757           0 :                         resp->data.dsgetdcname.client_site_name);
     758           0 :                 BAIL_ON_PTR_ERROR(i->client_site_name, wbc_status);
     759             :         }
     760             : 
     761           4 :         *_i = i;
     762           4 :         i = NULL;
     763             : 
     764           4 : done:
     765           4 :         if (i != NULL) {
     766           0 :                 wbcFreeMemory(i);
     767             :         }
     768           4 :         return wbc_status;
     769             : }
     770             : 
     771             : /* Get extended domain controller information */
     772             : _PUBLIC_
     773           4 : wbcErr wbcCtxLookupDomainControllerEx(struct wbcContext *ctx,
     774             :                                       const char *domain,
     775             :                                       struct wbcGuid *guid,
     776             :                                       const char *site,
     777             :                                       uint32_t flags,
     778             :                                       struct wbcDomainControllerInfoEx **dc_info)
     779             : {
     780           4 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     781           0 :         struct winbindd_request request;
     782           0 :         struct winbindd_response response;
     783             : 
     784             :         /* validate input params */
     785             : 
     786           4 :         if (!domain || !dc_info) {
     787           0 :                 wbc_status = WBC_ERR_INVALID_PARAM;
     788           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     789             :         }
     790             : 
     791           4 :         ZERO_STRUCT(request);
     792           4 :         ZERO_STRUCT(response);
     793             : 
     794           4 :         request.data.dsgetdcname.flags = flags;
     795             : 
     796           4 :         strncpy(request.data.dsgetdcname.domain_name, domain,
     797             :                 sizeof(request.data.dsgetdcname.domain_name)-1);
     798             : 
     799           4 :         if (site) {
     800           0 :                 strncpy(request.data.dsgetdcname.site_name, site,
     801             :                         sizeof(request.data.dsgetdcname.site_name)-1);
     802             :         }
     803             : 
     804           4 :         if (guid) {
     805           0 :                 char *str = NULL;
     806             : 
     807           0 :                 wbc_status = wbcGuidToString(guid, &str);
     808           0 :                 BAIL_ON_WBC_ERROR(wbc_status);
     809             : 
     810           0 :                 strncpy(request.data.dsgetdcname.domain_guid, str,
     811             :                         sizeof(request.data.dsgetdcname.domain_guid)-1);
     812             : 
     813           0 :                 wbcFreeMemory(str);
     814             :         }
     815             : 
     816             :         /* Send request */
     817             : 
     818           4 :         wbc_status = wbcRequestResponse(ctx, WINBINDD_DSGETDCNAME,
     819             :                                         &request,
     820             :                                         &response);
     821           4 :         BAIL_ON_WBC_ERROR(wbc_status);
     822             : 
     823           4 :         if (dc_info) {
     824           4 :                 wbc_status = wbc_create_domain_controller_info_ex(&response,
     825             :                                                                   dc_info);
     826           4 :                 BAIL_ON_WBC_ERROR(wbc_status);
     827             :         }
     828             : 
     829           4 :         wbc_status = WBC_ERR_SUCCESS;
     830           4 : done:
     831           4 :         return wbc_status;
     832             : }
     833             : 
     834             : _PUBLIC_
     835           4 : wbcErr wbcLookupDomainControllerEx(const char *domain,
     836             :                                    struct wbcGuid *guid,
     837             :                                    const char *site,
     838             :                                    uint32_t flags,
     839             :                                    struct wbcDomainControllerInfoEx **dc_info)
     840             : {
     841           4 :         return wbcCtxLookupDomainControllerEx(NULL, domain, guid, site,
     842             :                                               flags, dc_info);
     843             : }
     844             : 
     845        1194 : static void wbcNamedBlobDestructor(void *ptr)
     846             : {
     847        1194 :         struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr;
     848             : 
     849        2388 :         while (b->name != NULL) {
     850        1194 :                 free(discard_const_p(char, b->name));
     851        1194 :                 free(b->blob.data);
     852        1194 :                 b += 1;
     853             :         }
     854        1194 : }
     855             : 
     856             : /* Initialize a named blob and add to list of blobs */
     857             : _PUBLIC_
     858        1202 : wbcErr wbcAddNamedBlob(size_t *num_blobs,
     859             :                        struct wbcNamedBlob **pblobs,
     860             :                        const char *name,
     861             :                        uint32_t flags,
     862             :                        uint8_t *data,
     863             :                        size_t length)
     864             : {
     865        1202 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     866           0 :         struct wbcNamedBlob *blobs, *blob;
     867             : 
     868        1202 :         if (name == NULL) {
     869           0 :                 return WBC_ERR_INVALID_PARAM;
     870             :         }
     871             : 
     872             :         /*
     873             :          * Overallocate the b->name==NULL terminator for
     874             :          * wbcNamedBlobDestructor
     875             :          */
     876        1202 :         blobs = (struct wbcNamedBlob *)wbcAllocateMemory(
     877        1202 :                 *num_blobs + 2, sizeof(struct wbcNamedBlob),
     878             :                 wbcNamedBlobDestructor);
     879             : 
     880        1202 :         if (blobs == NULL) {
     881           0 :                 return WBC_ERR_NO_MEMORY;
     882             :         }
     883             : 
     884        1202 :         if (*pblobs != NULL) {
     885         630 :                 struct wbcNamedBlob *old = *pblobs;
     886         630 :                 memcpy(blobs, old, sizeof(struct wbcNamedBlob) * (*num_blobs));
     887         630 :                 if (*num_blobs != 0) {
     888             :                         /* end indicator for wbcNamedBlobDestructor */
     889         630 :                         old[0].name = NULL;
     890             :                 }
     891         630 :                 wbcFreeMemory(old);
     892             :         }
     893        1202 :         *pblobs = blobs;
     894             : 
     895        1202 :         blob = &blobs[*num_blobs];
     896             : 
     897        1202 :         blob->name = strdup(name);
     898        1202 :         BAIL_ON_PTR_ERROR(blob->name, wbc_status);
     899        1202 :         blob->flags = flags;
     900             : 
     901        1202 :         blob->blob.length = length;
     902        1202 :         blob->blob.data      = (uint8_t *)malloc(length);
     903        1202 :         BAIL_ON_PTR_ERROR(blob->blob.data, wbc_status);
     904        1202 :         memcpy(blob->blob.data, data, length);
     905             : 
     906        1202 :         *num_blobs += 1;
     907        1202 :         *pblobs = blobs;
     908        1202 :         blobs = NULL;
     909             : 
     910        1202 :         wbc_status = WBC_ERR_SUCCESS;
     911        1202 : done:
     912        1202 :         wbcFreeMemory(blobs);
     913        1202 :         return wbc_status;
     914             : }
     915             : 
     916             : _PUBLIC_
     917         266 : void wbcSetClientProcessName(const char *name)
     918             : {
     919         266 :         winbind_set_client_name(name);
     920         266 : }

Generated by: LCOV version 1.14