LCOV - code coverage report
Current view: top level - nsswitch/libwbclient - wbclient.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 96 136 70.6 %
Date: 2024-04-21 15:09:00 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind client API
       5             : 
       6             :    Copyright (C) Gerald (Jerry) Carter 2007
       7             :    Copyright (C) Matthew Newton 2015
       8             : 
       9             : 
      10             :    This library is free software; you can redistribute it and/or
      11             :    modify it under the terms of the GNU Lesser General Public
      12             :    License as published by the Free Software Foundation; either
      13             :    version 3 of the License, or (at your option) any later version.
      14             : 
      15             :    This library is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :    Library General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : /* Required Headers */
      25             : 
      26             : #include "replace.h"
      27             : #include "libwbclient.h"
      28             : 
      29             : /* From wb_common.c */
      30             : 
      31             : struct winbindd_context;
      32             : 
      33             : NSS_STATUS winbindd_request_response(struct winbindd_context *wbctx,
      34             :                                      int req_type,
      35             :                                      struct winbindd_request *request,
      36             :                                      struct winbindd_response *response);
      37             : NSS_STATUS winbindd_priv_request_response(struct winbindd_context *wbctx,
      38             :                                           int req_type,
      39             :                                           struct winbindd_request *request,
      40             :                                           struct winbindd_response *response);
      41             : struct winbindd_context *winbindd_ctx_create(void);
      42             : void winbindd_ctx_free(struct winbindd_context *ctx);
      43             : 
      44             : /* Global context used for non-Ctx functions */
      45             : 
      46             : static struct wbcContext wbcGlobalCtx = {
      47             :         .winbindd_ctx = NULL,
      48             :         .pw_cache_size = 0,
      49             :         .pw_cache_idx = 0,
      50             :         .gr_cache_size = 0,
      51             :         .gr_cache_idx = 0
      52             : };
      53             : 
      54             : /*
      55             :  result == NSS_STATUS_UNAVAIL: winbind not around
      56             :  result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
      57             : 
      58             :  Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off
      59             :  and when winbind return WINBINDD_ERROR. So the semantics of this
      60             :  routine depends on winbind_on. Grepping for winbind_off I just
      61             :  found 3 places where winbind is turned off, and this does not conflict
      62             :  (as far as I have seen) with the callers of is_trusted_domains.
      63             : 
      64             :  --Volker
      65             : */
      66             : 
      67      901189 : static wbcErr wbcRequestResponseInt(
      68             :         struct winbindd_context *wbctx,
      69             :         int cmd,
      70             :         struct winbindd_request *request,
      71             :         struct winbindd_response *response,
      72             :         NSS_STATUS (*fn)(struct winbindd_context *wbctx, int req_type,
      73             :                          struct winbindd_request *request,
      74             :                          struct winbindd_response *response))
      75             : {
      76      901189 :         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
      77        4243 :         NSS_STATUS nss_status;
      78             : 
      79             :         /* for some calls the request and/or response can be NULL */
      80             : 
      81      905432 :         nss_status = fn(wbctx, cmd, request, response);
      82             : 
      83      901188 :         switch (nss_status) {
      84      433379 :         case NSS_STATUS_SUCCESS:
      85      433379 :                 wbc_status = WBC_ERR_SUCCESS;
      86      433379 :                 break;
      87      456634 :         case NSS_STATUS_UNAVAIL:
      88      456634 :                 wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
      89      456634 :                 break;
      90        6932 :         case NSS_STATUS_NOTFOUND:
      91        6932 :                 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
      92        6932 :                 break;
      93           0 :         default:
      94           0 :                 wbc_status = WBC_ERR_NSS_ERROR;
      95           0 :                 break;
      96             :         }
      97             : 
      98      901188 :         return wbc_status;
      99             : }
     100             : 
     101             : /**
     102             :  * @brief Wrapper around Winbind's send/receive API call
     103             :  *
     104             :  * @param ctx       Context
     105             :  * @param cmd       Winbind command operation to perform
     106             :  * @param request   Send structure
     107             :  * @param response  Receive structure
     108             :  *
     109             :  * @return #wbcErr
     110             :  */
     111             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     112      881225 : wbcErr wbcRequestResponse(struct wbcContext *ctx, int cmd,
     113             :                           struct winbindd_request *request,
     114             :                           struct winbindd_response *response)
     115             : {
     116      881225 :         struct winbindd_context *wbctx = NULL;
     117             : 
     118      881225 :         if (ctx) {
     119        1224 :                 wbctx = ctx->winbindd_ctx;
     120             :         }
     121             : 
     122      881225 :         return wbcRequestResponseInt(wbctx, cmd, request, response,
     123             :                                      winbindd_request_response);
     124             : }
     125             : 
     126             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     127       19964 : wbcErr wbcRequestResponsePriv(struct wbcContext *ctx, int cmd,
     128             :                               struct winbindd_request *request,
     129             :                               struct winbindd_response *response)
     130             : {
     131       19964 :         struct winbindd_context *wbctx = NULL;
     132             : 
     133       19964 :         if (ctx) {
     134           0 :                 wbctx = ctx->winbindd_ctx;
     135             :         }
     136             : 
     137       19964 :         return wbcRequestResponseInt(wbctx, cmd, request, response,
     138             :                                      winbindd_priv_request_response);
     139             : }
     140             : 
     141             : /** @brief Translate an error value into a string
     142             :  *
     143             :  * @param error
     144             :  *
     145             :  * @return a pointer to a static string
     146             :  **/
     147             : _PUBLIC_
     148         414 : const char *wbcErrorString(wbcErr error)
     149             : {
     150         414 :         switch (error) {
     151         220 :         case WBC_ERR_SUCCESS:
     152         220 :                 return "WBC_ERR_SUCCESS";
     153           0 :         case WBC_ERR_NOT_IMPLEMENTED:
     154           0 :                 return "WBC_ERR_NOT_IMPLEMENTED";
     155           0 :         case WBC_ERR_UNKNOWN_FAILURE:
     156           0 :                 return "WBC_ERR_UNKNOWN_FAILURE";
     157           0 :         case WBC_ERR_NO_MEMORY:
     158           0 :                 return "WBC_ERR_NO_MEMORY";
     159           0 :         case WBC_ERR_INVALID_SID:
     160           0 :                 return "WBC_ERR_INVALID_SID";
     161           0 :         case WBC_ERR_INVALID_PARAM:
     162           0 :                 return "WBC_ERR_INVALID_PARAM";
     163          12 :         case WBC_ERR_WINBIND_NOT_AVAILABLE:
     164          12 :                 return "WBC_ERR_WINBIND_NOT_AVAILABLE";
     165         106 :         case WBC_ERR_DOMAIN_NOT_FOUND:
     166         106 :                 return "WBC_ERR_DOMAIN_NOT_FOUND";
     167           0 :         case WBC_ERR_INVALID_RESPONSE:
     168           0 :                 return "WBC_ERR_INVALID_RESPONSE";
     169           0 :         case WBC_ERR_NSS_ERROR:
     170           0 :                 return "WBC_ERR_NSS_ERROR";
     171           0 :         case WBC_ERR_UNKNOWN_USER:
     172           0 :                 return "WBC_ERR_UNKNOWN_USER";
     173           0 :         case WBC_ERR_UNKNOWN_GROUP:
     174           0 :                 return "WBC_ERR_UNKNOWN_GROUP";
     175          76 :         case WBC_ERR_AUTH_ERROR:
     176          76 :                 return "WBC_ERR_AUTH_ERROR";
     177           0 :         case WBC_ERR_PWD_CHANGE_FAILED:
     178           0 :                 return "WBC_ERR_PWD_CHANGE_FAILED";
     179             :         }
     180             : 
     181           0 :         return "unknown wbcErr value";
     182             : }
     183             : 
     184             : #define WBC_MAGIC (0x7a2b0e1e)
     185             : #define WBC_MAGIC_FREE (0x875634fe)
     186             : 
     187             : struct wbcMemPrefix {
     188             :         uint32_t magic;
     189             :         void (*destructor)(void *ptr);
     190             : };
     191             : 
     192      463141 : static size_t wbcPrefixLen(void)
     193             : {
     194      463157 :         size_t result = sizeof(struct wbcMemPrefix);
     195      463141 :         return (result + 15) & ~15;
     196             : }
     197             : 
     198      153755 : static struct wbcMemPrefix *wbcMemToPrefix(void *ptr)
     199             : {
     200      153755 :         return (struct wbcMemPrefix *)(((char *)ptr) - wbcPrefixLen());
     201             : }
     202             : 
     203             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     204      154701 : void *wbcAllocateMemory(size_t nelem, size_t elsize,
     205             :                         void (*destructor)(void *ptr))
     206             : {
     207           6 :         struct wbcMemPrefix *result;
     208             : 
     209      154701 :         if (nelem >= (2<<24)/elsize) {
     210             :                 /* basic protection against integer wrap */
     211           0 :                 return NULL;
     212             :         }
     213             : 
     214      154701 :         result = (struct wbcMemPrefix *)calloc(
     215      154701 :                 1, nelem*elsize + wbcPrefixLen());
     216      154701 :         if (result == NULL) {
     217           0 :                 return NULL;
     218             :         }
     219      154701 :         result->magic = WBC_MAGIC;
     220      154701 :         result->destructor = destructor;
     221      154701 :         return ((char *)result) + wbcPrefixLen();
     222             : }
     223             : 
     224             : /* Free library allocated memory */
     225             : _PUBLIC_
     226      166161 : void wbcFreeMemory(void *p)
     227             : {
     228           8 :         struct wbcMemPrefix *wbcMem;
     229             : 
     230      166161 :         if (p == NULL) {
     231       12402 :                 return;
     232             :         }
     233      153755 :         wbcMem = wbcMemToPrefix(p);
     234      153755 :         if (wbcMem->magic != WBC_MAGIC) {
     235           0 :                 return;
     236             :         }
     237             : 
     238             :         /* paranoid check to ensure we don't double free */
     239      153755 :         wbcMem->magic = WBC_MAGIC_FREE;
     240             : 
     241      153755 :         if (wbcMem->destructor != NULL) {
     242      149211 :                 wbcMem->destructor(p);
     243             :         }
     244      153755 :         free(wbcMem);
     245      153755 :         return;
     246             : }
     247             : 
     248             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     249        1918 : char *wbcStrDup(const char *str)
     250             : {
     251           0 :         char *result;
     252           0 :         size_t len;
     253             : 
     254        1918 :         len = strlen(str);
     255        1918 :         result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL);
     256        1918 :         if (result == NULL) {
     257           0 :                 return NULL;
     258             :         }
     259        1918 :         memcpy(result, str, len+1);
     260        1918 :         return result;
     261             : }
     262             : 
     263          72 : static void wbcStringArrayDestructor(void *ptr)
     264             : {
     265          72 :         char **p = (char **)ptr;
     266        6560 :         while (*p != NULL) {
     267        6488 :                 free(*p);
     268        6488 :                 p += 1;
     269             :         }
     270          72 : }
     271             : 
     272             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     273          72 : const char **wbcAllocateStringArray(int num_strings)
     274             : {
     275         144 :         return (const char **)wbcAllocateMemory(
     276          72 :                 num_strings + 1, sizeof(const char *),
     277             :                 wbcStringArrayDestructor);
     278             : }
     279             : 
     280             : _PUBLIC_
     281           4 : wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details)
     282             : {
     283           0 :         struct wbcLibraryDetails *info;
     284             : 
     285           4 :         info = (struct wbcLibraryDetails *)wbcAllocateMemory(
     286             :                 1, sizeof(struct wbcLibraryDetails), NULL);
     287             : 
     288           4 :         if (info == NULL) {
     289           0 :                 return WBC_ERR_NO_MEMORY;
     290             :         }
     291             : 
     292           4 :         info->major_version = WBCLIENT_MAJOR_VERSION;
     293           4 :         info->minor_version = WBCLIENT_MINOR_VERSION;
     294           4 :         info->vendor_version = WBCLIENT_VENDOR_VERSION;
     295             : 
     296           4 :         *_details = info;
     297           4 :         return WBC_ERR_SUCCESS;
     298             : }
     299             : 
     300             : /* Context handling functions */
     301             : 
     302         266 : static void wbcContextDestructor(void *ptr)
     303             : {
     304         266 :         struct wbcContext *ctx = (struct wbcContext *)ptr;
     305             : 
     306         266 :         winbindd_ctx_free(ctx->winbindd_ctx);
     307         266 : }
     308             : 
     309             : _PUBLIC_
     310         266 : struct wbcContext *wbcCtxCreate(void)
     311             : {
     312           0 :         struct wbcContext *ctx;
     313           0 :         struct winbindd_context *wbctx;
     314             : 
     315         266 :         ctx = (struct wbcContext *)wbcAllocateMemory(
     316             :                 1, sizeof(struct wbcContext), wbcContextDestructor);
     317             : 
     318         266 :         if (!ctx) {
     319           0 :                 return NULL;
     320             :         }
     321             : 
     322         266 :         wbctx = winbindd_ctx_create();
     323             : 
     324         266 :         if (!wbctx) {
     325           0 :                 wbcFreeMemory(ctx);
     326           0 :                 return NULL;
     327             :         }
     328             : 
     329         266 :         ctx->winbindd_ctx = wbctx;
     330             : 
     331         266 :         return ctx;
     332             : }
     333             : 
     334             : _PUBLIC_
     335         266 : void wbcCtxFree(struct wbcContext *ctx)
     336             : {
     337         266 :         wbcFreeMemory(ctx);
     338         266 : }
     339             : 
     340             : _PUBLIC_ /* this is internal to wbclient_internal.h, but part of the ABI */
     341           0 : struct wbcContext *wbcGetGlobalCtx(void)
     342             : {
     343           0 :         return &wbcGlobalCtx;
     344             : }

Generated by: LCOV version 1.14