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

Generated by: LCOV version 1.13