LCOV - code coverage report
Current view: top level - sss_client/libwbclient - wbc_pwd_sssd.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 301 0.0 %
Date: 2016-06-29 Functions: 0 19 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind client API - SSSD version
       5             : 
       6             :    Copyright (C) Sumit Bose <sbose@redhat.com> 2014
       7             : 
       8             :    This library is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU Lesser General Public
      10             :    License as published by the Free Software Foundation; either
      11             :    version 3 of the License, or (at your option) any later version.
      12             : 
      13             :    This library is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    Library General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU Lesser General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : /* Required Headers */
      22             : 
      23             : #include <nss.h>
      24             : #include <dlfcn.h>
      25             : #include <errno.h>
      26             : 
      27             : #include "libwbclient.h"
      28             : #include "wbc_sssd_internal.h"
      29             : 
      30             : #define DEFAULT_BUFSIZE_HALF 2048
      31             : #define DEFAULT_BUFSIZE (2 * DEFAULT_BUFSIZE_HALF)
      32             : #define MAX_BUFSIZE (1024*1204)
      33             : 
      34             : struct nss_ops_ctx {
      35             :     void *dl_handle;
      36             : 
      37             :     enum nss_status (*getpwnam_r)(const char *name, struct passwd *result,
      38             :                       char *buffer, size_t buflen, int *errnop);
      39             :     enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result,
      40             :                       char *buffer, size_t buflen, int *errnop);
      41             :     enum nss_status (*setpwent)(void);
      42             :     enum nss_status (*getpwent_r)(struct passwd *result,
      43             :                       char *buffer, size_t buflen, int *errnop);
      44             :     enum nss_status (*endpwent)(void);
      45             : 
      46             :     enum nss_status (*getgrnam_r)(const char *name, struct group *result,
      47             :                       char *buffer, size_t buflen, int *errnop);
      48             :     enum nss_status (*getgrgid_r)(gid_t gid, struct group *result,
      49             :                       char *buffer, size_t buflen, int *errnop);
      50             :     enum nss_status (*setgrent)(void);
      51             :     enum nss_status (*getgrent_r)(struct group *result,
      52             :                       char *buffer, size_t buflen, int *errnop);
      53             :     enum nss_status (*endgrent)(void);
      54             : 
      55             :     enum nss_status (*initgroups_dyn)(const char *user, gid_t group,
      56             :                           long int *start, long int *size,
      57             :                           gid_t **groups, long int limit,
      58             :                           int *errnop);
      59             : };
      60             : 
      61             : struct nss_ops_ctx *ctx = NULL;
      62             : 
      63           0 : static bool open_libnss_sss(void)
      64             : {
      65           0 :     ctx = calloc(1, sizeof(struct nss_ops_ctx));
      66           0 :     if (ctx == NULL) {
      67           0 :         return false;
      68             :     }
      69             : 
      70           0 :     ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW);
      71           0 :     if (ctx->dl_handle == NULL) {
      72           0 :         goto fail;
      73             :     }
      74             : 
      75           0 :     ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r");
      76           0 :     if (ctx->getpwnam_r == NULL) {
      77           0 :         goto fail;
      78             :     }
      79             : 
      80           0 :     ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r");
      81           0 :     if (ctx->getpwuid_r == NULL) {
      82           0 :         goto fail;
      83             :     }
      84             : 
      85           0 :     ctx->setpwent = dlsym(ctx->dl_handle, "_nss_sss_setpwent");
      86           0 :     if (ctx->setpwent == NULL) {
      87           0 :         goto fail;
      88             :     }
      89             : 
      90           0 :     ctx->getpwent_r = dlsym(ctx->dl_handle, "_nss_sss_getpwent_r");
      91           0 :     if (ctx->getpwent_r == NULL) {
      92           0 :         goto fail;
      93             :     }
      94             : 
      95           0 :     ctx->endpwent = dlsym(ctx->dl_handle, "_nss_sss_endpwent");
      96           0 :     if (ctx->endpwent == NULL) {
      97           0 :         goto fail;
      98             :     }
      99             : 
     100           0 :     ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r");
     101           0 :     if (ctx->getgrnam_r == NULL) {
     102           0 :         goto fail;
     103             :     }
     104             : 
     105           0 :     ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r");
     106           0 :     if (ctx->getgrgid_r == NULL) {
     107           0 :         goto fail;
     108             :     }
     109             : 
     110           0 :     ctx->setgrent = dlsym(ctx->dl_handle, "_nss_sss_setgrent");
     111           0 :     if (ctx->setgrent == NULL) {
     112           0 :         goto fail;
     113             :     }
     114             : 
     115           0 :     ctx->getgrent_r = dlsym(ctx->dl_handle, "_nss_sss_getgrent_r");
     116           0 :     if (ctx->getgrent_r == NULL) {
     117           0 :         goto fail;
     118             :     }
     119             : 
     120           0 :     ctx->endgrent = dlsym(ctx->dl_handle, "_nss_sss_endgrent");
     121           0 :     if (ctx->endgrent == NULL) {
     122           0 :         goto fail;
     123             :     }
     124             : 
     125           0 :     ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn");
     126           0 :     if (ctx->initgroups_dyn == NULL) {
     127           0 :         goto fail;
     128             :     }
     129             : 
     130           0 :     return true;
     131             : 
     132             : fail:
     133           0 :     if (ctx->dl_handle != NULL) {
     134           0 :         dlclose(ctx->dl_handle);
     135             :     }
     136             : 
     137           0 :     free(ctx);
     138           0 :     ctx = NULL;
     139             : 
     140           0 :     return false;
     141             : }
     142             : 
     143           0 : static void wbcPasswdDestructor(void *ptr)
     144             : {
     145           0 :     struct passwd *pw = (struct passwd *)ptr;
     146           0 :     free(pw->pw_name);
     147           0 :     free(pw->pw_passwd);
     148           0 :     free(pw->pw_gecos);
     149           0 :     free(pw->pw_shell);
     150           0 :     free(pw->pw_dir);
     151           0 : }
     152             : 
     153           0 : static wbcErr copy_pwd(struct passwd *in, struct passwd **out)
     154             : {
     155             :     struct passwd *pw;
     156             : 
     157           0 :     pw = (struct passwd *)wbcAllocateMemory(1, sizeof(struct passwd),
     158             :                           wbcPasswdDestructor);
     159           0 :     if (pw == NULL) {
     160           0 :         return WBC_ERR_NO_MEMORY;
     161             :     }
     162             : 
     163           0 :     pw->pw_name = strdup(in->pw_name);
     164           0 :     if (pw->pw_name == NULL) {
     165           0 :         goto fail;
     166             :     }
     167             : 
     168           0 :     pw->pw_passwd = strdup(in->pw_passwd);
     169           0 :     if (pw->pw_passwd == NULL) {
     170           0 :         goto fail;
     171             :     }
     172             : 
     173           0 :     pw->pw_uid = in->pw_uid;
     174           0 :     pw->pw_gid = in->pw_gid;
     175             : 
     176           0 :     pw->pw_gecos = strdup(in->pw_gecos);
     177           0 :     if (pw->pw_gecos == NULL) {
     178           0 :         goto fail;
     179             :     }
     180             : 
     181           0 :     pw->pw_shell = strdup(in->pw_shell);
     182           0 :     if (pw->pw_shell == NULL) {
     183           0 :         goto fail;
     184             :     }
     185             : 
     186           0 :     pw->pw_dir = strdup(in->pw_dir);
     187           0 :     if (pw->pw_dir == NULL) {
     188           0 :         goto fail;
     189             :     }
     190             : 
     191           0 :     *out = pw;
     192           0 :     return WBC_ERR_SUCCESS;
     193             : fail:
     194           0 :     wbcFreeMemory(pw);
     195             : 
     196           0 :     return WBC_ERR_NO_MEMORY;
     197             : }
     198             : 
     199           0 : static wbcErr nss_to_wbc(enum nss_status status)
     200             : {
     201             :     wbcErr wbc_status;
     202             : 
     203           0 :     switch (status) {
     204             :     case NSS_STATUS_SUCCESS:
     205           0 :         wbc_status = WBC_ERR_SUCCESS;
     206           0 :         break;
     207             :     case NSS_STATUS_NOTFOUND:
     208           0 :         wbc_status = WBC_ERR_UNKNOWN_USER;
     209           0 :         break;
     210             :     case NSS_STATUS_UNAVAIL:
     211           0 :         wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
     212           0 :         break;
     213             :     default:
     214           0 :         wbc_status = WBC_ERR_UNKNOWN_FAILURE;
     215             :     }
     216             : 
     217           0 :     return wbc_status;
     218             : }
     219             : 
     220             : /* Fill in a struct passwd* for a domain user based on username */
     221           0 : wbcErr wbcGetpwnam(const char *name, struct passwd **pwd)
     222             : {
     223           0 :     struct passwd lpwd = {0};
     224             :     enum nss_status status;
     225           0 :     char *buffer = NULL;
     226             :     size_t buflen;
     227             :     wbcErr wbc_status;
     228             :     int nss_errno;
     229             : 
     230           0 :     if (ctx == NULL && !open_libnss_sss()) {
     231           0 :         return WBC_ERR_NSS_ERROR;
     232             :     }
     233             : 
     234           0 :     if (name == NULL || pwd == NULL) {
     235           0 :         return WBC_ERR_INVALID_PARAM;
     236             :     }
     237             : 
     238           0 :     buflen = DEFAULT_BUFSIZE;
     239           0 :     buffer = malloc(buflen);
     240           0 :     if (buffer == NULL) {
     241           0 :         return WBC_ERR_NO_MEMORY;
     242             :     }
     243             : 
     244           0 :     status = ctx->getpwnam_r(name, &lpwd, buffer, buflen, &nss_errno);
     245           0 :     wbc_status = nss_to_wbc(status);
     246           0 :     if (WBC_ERROR_IS_OK(wbc_status) == true) {
     247           0 :         wbc_status = copy_pwd(&lpwd, pwd);
     248             :     }
     249             : 
     250           0 :     free(buffer);
     251             : 
     252           0 :     return wbc_status;
     253             : }
     254             : 
     255             : /* Fill in a struct passwd* for a domain user based on uid */
     256           0 : wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd)
     257             : {
     258           0 :     struct passwd lpwd = {0};
     259             :     enum nss_status status;
     260           0 :     char *buffer = NULL;
     261             :     size_t buflen;
     262             :     wbcErr wbc_status;
     263             :     int nss_errno;
     264             : 
     265           0 :     if (ctx == NULL && !open_libnss_sss()) {
     266           0 :         return WBC_ERR_NSS_ERROR;
     267             :     }
     268             : 
     269           0 :     if (pwd == NULL) {
     270           0 :         return WBC_ERR_INVALID_PARAM;
     271             :     }
     272             : 
     273           0 :     buflen = DEFAULT_BUFSIZE;
     274           0 :     buffer = malloc(buflen);
     275           0 :     if (buffer == NULL) {
     276           0 :         return WBC_ERR_NO_MEMORY;
     277             :     }
     278             : 
     279           0 :     status = ctx->getpwuid_r(uid, &lpwd, buffer, buflen, &nss_errno);
     280           0 :     wbc_status = nss_to_wbc(status);
     281           0 :     if (WBC_ERROR_IS_OK(wbc_status) == true) {
     282           0 :         wbc_status = copy_pwd(&lpwd, pwd);
     283             :     }
     284             : 
     285           0 :     free(buffer);
     286             : 
     287           0 :     return wbc_status;
     288             : }
     289             : 
     290             : /* Fill in a struct passwd* for a domain user based on sid */
     291           0 : wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd)
     292             : {
     293             :     wbcErr wbc_status;
     294             :     uid_t uid;
     295             : 
     296           0 :     wbc_status = wbcSidToUid(sid, &uid);
     297           0 :     if (!WBC_ERROR_IS_OK(wbc_status)) {
     298           0 :         return wbc_status;
     299             :     }
     300             : 
     301           0 :     wbc_status = wbcGetpwuid(uid, pwd);
     302             : 
     303           0 :     return wbc_status;
     304             : 
     305             : }
     306             : 
     307           0 : static void wbcGroupDestructor(void *ptr)
     308             : {
     309           0 :     struct group *gr = (struct group *)ptr;
     310             :     size_t c;
     311             : 
     312           0 :     free(gr->gr_name);
     313           0 :     free(gr->gr_passwd);
     314             : 
     315             :     /* if the array was partly created this can be NULL */
     316           0 :     if (gr->gr_mem == NULL) {
     317           0 :         return;
     318             :     }
     319             : 
     320           0 :     for (c=0; gr->gr_mem[c] != NULL; c++) {
     321           0 :         free(gr->gr_mem[c]);
     322             :     }
     323           0 :     free(gr->gr_mem);
     324             : }
     325             : 
     326           0 : static wbcErr copy_grp(struct group *in, struct group **out)
     327             : {
     328             :     struct group *gr;
     329             :     size_t members;
     330             :     size_t c;
     331             : 
     332           0 :     gr = (struct group *)wbcAllocateMemory(1, sizeof(struct group),
     333             :                           wbcGroupDestructor);
     334           0 :     if (gr == NULL) {
     335           0 :         return WBC_ERR_NO_MEMORY;
     336             :     }
     337             : 
     338           0 :     gr->gr_name = strdup(in->gr_name);
     339           0 :     if (gr->gr_name == NULL) {
     340           0 :         goto fail;
     341             :     }
     342             : 
     343           0 :     gr->gr_passwd = strdup(in->gr_passwd);
     344           0 :     if (gr->gr_passwd == NULL) {
     345           0 :         goto fail;
     346             :     }
     347             : 
     348           0 :     gr->gr_gid = in->gr_gid;
     349             : 
     350           0 :     for (members = 0; in->gr_mem[members] != NULL; members++);
     351             : 
     352           0 :     gr->gr_mem = (char **)calloc(members+1, sizeof(char *));
     353           0 :     if (gr->gr_mem == NULL) {
     354           0 :         goto fail;
     355             :     }
     356             : 
     357           0 :     for (c = 0; c < members; c++) {
     358           0 :         gr->gr_mem[c] = strdup(in->gr_mem[c]);
     359           0 :         if (gr->gr_mem[c] == NULL) {
     360           0 :             goto fail;
     361             :         }
     362             :     }
     363             : 
     364           0 :     *out = gr;
     365           0 :     return WBC_ERR_SUCCESS;
     366             : fail:
     367           0 :     wbcFreeMemory(gr);
     368             : 
     369           0 :     return WBC_ERR_NO_MEMORY;
     370             : }
     371             : /* Fill in a struct passwd* for a domain user based on username */
     372           0 : wbcErr wbcGetgrnam(const char *name, struct group **grp)
     373             : {
     374             :     struct group lgrp;
     375             :     enum nss_status status;
     376           0 :     char *newbuffer = NULL;
     377           0 :     char *buffer = NULL;
     378           0 :     size_t buflen = 0;
     379             :     wbcErr wbc_status;
     380             :     int nss_errno;
     381             : 
     382           0 :     if (ctx == NULL && !open_libnss_sss()) {
     383           0 :         return WBC_ERR_NSS_ERROR;
     384             :     }
     385             : 
     386           0 :     if (name == NULL || grp == NULL) {
     387           0 :         return WBC_ERR_INVALID_PARAM;
     388             :     }
     389             : 
     390           0 :     buflen = DEFAULT_BUFSIZE_HALF;
     391             :     do {
     392           0 :         buflen *= 2;
     393             : 
     394           0 :         newbuffer = realloc(buffer, buflen);
     395           0 :         if (newbuffer == NULL) {
     396           0 :             free(buffer);
     397           0 :             return WBC_ERR_NO_MEMORY;
     398             :         }
     399           0 :         buffer = newbuffer;
     400             : 
     401           0 :         memset(grp, 0, sizeof(struct group));
     402           0 :         status = ctx->getgrnam_r(name, &lgrp, buffer, buflen, &nss_errno);
     403           0 :         wbc_status = nss_to_wbc(status);
     404           0 :         if (WBC_ERROR_IS_OK(wbc_status) == true) {
     405           0 :             wbc_status = copy_grp(&lgrp, grp);
     406             :         }
     407           0 :     } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
     408           0 :          && buflen < MAX_BUFSIZE);
     409             : 
     410           0 :     free(buffer);
     411             : 
     412           0 :     return wbc_status;
     413             : }
     414             : 
     415             : /* Fill in a struct passwd* for a domain user based on uid */
     416           0 : wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
     417             : {
     418             :     struct group lgrp;
     419             :     enum nss_status status;
     420           0 :     char *newbuffer = NULL;
     421           0 :     char *buffer = NULL;
     422           0 :     size_t buflen = 0;
     423             :     wbcErr wbc_status;
     424             :     int nss_errno;
     425             : 
     426           0 :     if (ctx == NULL && !open_libnss_sss()) {
     427           0 :         return WBC_ERR_NSS_ERROR;
     428             :     }
     429             : 
     430           0 :     if (grp == NULL) {
     431           0 :         return WBC_ERR_INVALID_PARAM;
     432             :     }
     433             : 
     434           0 :     buflen = DEFAULT_BUFSIZE_HALF;
     435             :     do {
     436           0 :         buflen *= 2;
     437             : 
     438           0 :         newbuffer = realloc(buffer, buflen);
     439           0 :         if (newbuffer == NULL) {
     440           0 :             free(buffer);
     441           0 :             return WBC_ERR_NO_MEMORY;
     442             :         }
     443           0 :         buffer = newbuffer;
     444             : 
     445           0 :         memset(grp, 0, sizeof(struct group));
     446           0 :         status = ctx->getgrgid_r(gid, &lgrp, buffer, buflen, &nss_errno);
     447           0 :         wbc_status = nss_to_wbc(status);
     448           0 :         if (WBC_ERROR_IS_OK(wbc_status) == true) {
     449           0 :             wbc_status = copy_grp(&lgrp, grp);
     450             :         }
     451           0 :     } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
     452           0 :          && buflen < MAX_BUFSIZE);
     453             : 
     454           0 :     free(buffer);
     455             : 
     456           0 :     return wbc_status;
     457             : }
     458             : 
     459             : /* Reset the passwd iterator */
     460           0 : wbcErr wbcSetpwent(void)
     461             : {
     462             :     enum nss_status status;
     463             :     wbcErr wbc_status;
     464             : 
     465           0 :     if (ctx == NULL && !open_libnss_sss()) {
     466           0 :         return WBC_ERR_NSS_ERROR;
     467             :     }
     468             : 
     469           0 :     status = ctx->setpwent();
     470           0 :     wbc_status = nss_to_wbc(status);
     471             : 
     472           0 :     return wbc_status;
     473             : }
     474             : 
     475             : /* Close the passwd iterator */
     476           0 : wbcErr wbcEndpwent(void)
     477             : {
     478             :     enum nss_status status;
     479             :     wbcErr wbc_status;
     480             : 
     481           0 :     if (ctx == NULL && !open_libnss_sss()) {
     482           0 :         return WBC_ERR_NSS_ERROR;
     483             :     }
     484             : 
     485           0 :     status = ctx->endpwent();
     486           0 :     wbc_status = nss_to_wbc(status);
     487             : 
     488           0 :     return wbc_status;
     489             : }
     490             : 
     491             : /* Return the next struct passwd* entry from the pwent iterator */
     492           0 : wbcErr wbcGetpwent(struct passwd **pwd)
     493             : {
     494           0 :     struct passwd lpwd = {0};
     495             :     enum nss_status status;
     496           0 :     char *buffer = NULL;
     497             :     size_t buflen;
     498             :     wbcErr wbc_status;
     499             :     int nss_errno;
     500             : 
     501           0 :     if (ctx == NULL && !open_libnss_sss()) {
     502           0 :         return WBC_ERR_NSS_ERROR;
     503             :     }
     504             : 
     505           0 :     if (pwd == NULL) {
     506           0 :         return WBC_ERR_INVALID_PARAM;
     507             :     }
     508             : 
     509           0 :     buflen = DEFAULT_BUFSIZE;
     510           0 :     buffer = malloc(buflen);
     511           0 :     if (buffer == NULL) {
     512           0 :         return WBC_ERR_NO_MEMORY;
     513             :     }
     514             : 
     515           0 :     status = ctx->getpwent_r(&lpwd, buffer, buflen, &nss_errno);
     516           0 :     wbc_status = nss_to_wbc(status);
     517           0 :     if (WBC_ERROR_IS_OK(wbc_status) == true) {
     518           0 :         wbc_status = copy_pwd(&lpwd, pwd);
     519             :     }
     520             : 
     521           0 :     free(buffer);
     522             : 
     523           0 :     return wbc_status;
     524             : }
     525             : 
     526             : /* Reset the group iterator */
     527           0 : wbcErr wbcSetgrent(void)
     528             : {
     529             :     enum nss_status status;
     530             :     wbcErr wbc_status;
     531             : 
     532           0 :     if (ctx == NULL && !open_libnss_sss()) {
     533           0 :         return WBC_ERR_NSS_ERROR;
     534             :     }
     535             : 
     536           0 :     status = ctx->setgrent();
     537           0 :     wbc_status = nss_to_wbc(status);
     538             : 
     539           0 :     return wbc_status;
     540             : }
     541             : 
     542             : /* Close the group iterator */
     543           0 : wbcErr wbcEndgrent(void)
     544             : {
     545             :     enum nss_status status;
     546             :     wbcErr wbc_status;
     547             : 
     548           0 :     if (ctx == NULL && !open_libnss_sss()) {
     549           0 :         return WBC_ERR_NSS_ERROR;
     550             :     }
     551             : 
     552           0 :     status = ctx->endgrent();
     553           0 :     wbc_status = nss_to_wbc(status);
     554             : 
     555           0 :     return wbc_status;
     556             : }
     557             : 
     558             : /* Return the next struct group* entry from the pwent iterator */
     559           0 : wbcErr wbcGetgrent(struct group **grp)
     560             : {
     561             :     struct group lgrp;
     562             :     enum nss_status status;
     563           0 :     char *newbuffer = NULL;
     564           0 :     char *buffer = NULL;
     565           0 :     size_t buflen = 0;
     566             :     wbcErr wbc_status;
     567             :     int nss_errno;
     568             : 
     569           0 :     if (ctx == NULL && !open_libnss_sss()) {
     570           0 :         return WBC_ERR_NSS_ERROR;
     571             :     }
     572             : 
     573           0 :     if (grp == NULL) {
     574           0 :         return WBC_ERR_INVALID_PARAM;
     575             :     }
     576             : 
     577           0 :     buflen = DEFAULT_BUFSIZE_HALF;
     578             :     do {
     579           0 :         buflen *= 2;
     580             : 
     581           0 :         newbuffer = realloc(buffer, buflen);
     582           0 :         if (newbuffer == NULL) {
     583           0 :             free(buffer);
     584           0 :             return WBC_ERR_NO_MEMORY;
     585             :         }
     586           0 :         buffer = newbuffer;
     587             : 
     588           0 :         memset(grp, 0, sizeof(struct group));
     589           0 :         status = ctx->getgrent_r(&lgrp, buffer, buflen, &nss_errno);
     590           0 :         wbc_status = nss_to_wbc(status);
     591           0 :         if (WBC_ERROR_IS_OK(wbc_status) == true) {
     592           0 :             wbc_status = copy_grp(&lgrp, grp);
     593             :         }
     594           0 :     } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \
     595           0 :          && buflen < MAX_BUFSIZE);
     596             : 
     597           0 :     free(buffer);
     598             : 
     599           0 :     return wbc_status;
     600             : }
     601             : 
     602             : /* Return the next struct group* entry from the pwent iterator */
     603           0 : wbcErr wbcGetgrlist(struct group **grp)
     604             : {
     605             :     /* Not used anywhere */
     606           0 :     WBC_SSSD_NOT_IMPLEMENTED;
     607             : }
     608             : 
     609             : /* Return the unix group array belonging to the given user */
     610           0 : wbcErr wbcGetGroups(const char *account,
     611             :             uint32_t *num_groups,
     612             :             gid_t **_groups)
     613             : {
     614             :     wbcErr wbc_status;
     615             :     enum nss_status status;
     616             :     struct passwd *pwd;
     617           0 :     long int gr_size = 0;
     618           0 :     long int start = 0;
     619           0 :     gid_t *gids = NULL;
     620             :     int nss_errno;
     621             : 
     622           0 :     wbc_status = wbcGetpwnam(account, &pwd);
     623           0 :     if (!WBC_ERROR_IS_OK(wbc_status)) {
     624           0 :         return wbc_status;
     625             :     }
     626             : 
     627           0 :     gr_size = DEFAULT_BUFSIZE;
     628           0 :     gids = calloc(gr_size, sizeof(gid_t));
     629           0 :     if (gids == NULL) {
     630           0 :         wbc_status = WBC_ERR_NO_MEMORY;
     631           0 :         goto done;
     632             :     }
     633             : 
     634             :     /* nss modules may skip the primary group when we pass it in so always
     635             :      * add it in advance */
     636           0 :     gids[0] = pwd->pw_gid;
     637           0 :     start++;
     638             : 
     639           0 :     status = ctx->initgroups_dyn(pwd->pw_name, pwd->pw_gid, &start,
     640             :                      &gr_size, &gids, -1, &nss_errno);
     641           0 :     wbc_status = nss_to_wbc(status);
     642           0 :     if (!WBC_ERROR_IS_OK(wbc_status)) {
     643           0 :         goto done;
     644             :     }
     645             : 
     646           0 :     *_groups = gids;
     647           0 :     *num_groups = start;
     648             : 
     649           0 :     wbc_status = WBC_ERR_SUCCESS;
     650             : 
     651             : done:
     652           0 :     wbcFreeMemory(pwd);
     653             : 
     654           0 :     if (!WBC_ERROR_IS_OK(wbc_status)) {
     655           0 :         free(gids);
     656             :     }
     657             : 
     658           0 :     return wbc_status;
     659             : }

Generated by: LCOV version 1.10