root/source4/lib/ldb/nssldb/ldb-grp.c

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

DEFINITIONS

This source file includes following definitions.
  1. _nss_ldb_setgrent
  2. _nss_ldb_endgrent
  3. _nss_ldb_getgrent_r
  4. _nss_ldb_getgrnam_r
  5. _nss_ldb_getgrgid_r
  6. _nss_ldb_initgroups_dyn

   1 /* 
   2    LDB nsswitch module
   3 
   4    Copyright (C) Simo Sorce 2006
   5    
   6    This library is free software; you can redistribute it and/or
   7    modify it under the terms of the GNU Lesser General Public
   8    License as published by the Free Software Foundation; either
   9    version 3 of the License, or (at your option) any later version.
  10    
  11    This library is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14    Library General Public License for more details.
  15    
  16    You should have received a copy of the GNU Lesser General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "ldb-nss.h"
  21 
  22 extern struct _ldb_nss_context *_ldb_nss_ctx;
  23 
  24 const char *_ldb_nss_gr_attrs[] = {
  25         "cn",
  26         "userPassword",
  27         "gidNumber",
  28         NULL
  29 };
  30 
  31 const char *_ldb_nss_mem_attrs[] = {
  32         "uid",
  33         NULL
  34 };
  35 
  36 #define _NSS_LDB_ENOMEM(amem) \
  37         do { \
  38                 if ( ! amem) { \
  39                         errno = ENOMEM; \
  40                         talloc_free(memctx); \
  41                         return NSS_STATUS_UNAVAIL; \
  42                 } \
  43         } while(0)
  44 
  45 /* This setgrent, getgrent, endgrent is not very efficient */
  46 
  47 NSS_STATUS _nss_ldb_setgrent(void)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49         int ret;
  50 
  51         ret = _ldb_nss_init();
  52         if (ret != NSS_STATUS_SUCCESS) {
  53                 return ret;
  54         }
  55 
  56         _ldb_nss_ctx->gr_cur = 0;
  57         if (_ldb_nss_ctx->gr_res != NULL) {
  58                 talloc_free(_ldb_nss_ctx->gr_res);
  59                 _ldb_nss_ctx->gr_res = NULL;
  60         }
  61 
  62         ret = ldb_search(_ldb_nss_ctx->ldb,
  63                          _ldb_nss_ctx->ldb,
  64                          &_ldb_nss_ctx->gr_res,
  65                          _ldb_nss_ctx->base,
  66                          LDB_SCOPE_SUBTREE,
  67                          _ldb_nss_gr_attrs,
  68                          _LDB_NSS_GRENT_FILTER);
  69         if (ret != LDB_SUCCESS) {
  70                 return NSS_STATUS_UNAVAIL;
  71         }
  72 
  73         return NSS_STATUS_SUCCESS;
  74 }
  75 
  76 NSS_STATUS _nss_ldb_endgrent(void)
     /* [<][>][^][v][top][bottom][index][help] */
  77 {
  78         int ret;
  79 
  80         ret = _ldb_nss_init();
  81         if (ret != NSS_STATUS_SUCCESS) {
  82                 return ret;
  83         }
  84 
  85         _ldb_nss_ctx->gr_cur = 0;
  86         if (_ldb_nss_ctx->gr_res) {
  87                 talloc_free(_ldb_nss_ctx->gr_res);
  88                 _ldb_nss_ctx->gr_res = NULL;
  89         }
  90 
  91         return NSS_STATUS_SUCCESS;
  92 }
  93 
  94 NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
     /* [<][>][^][v][top][bottom][index][help] */
  95 {
  96         int ret;
  97         struct ldb_result *res;
  98 
  99         ret = _ldb_nss_init();
 100         if (ret != NSS_STATUS_SUCCESS) {
 101                 return ret;
 102         }
 103 
 104         *errnop = 0;
 105 
 106         if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
 107                 /* already returned all entries */
 108                 return NSS_STATUS_NOTFOUND;
 109         }
 110 
 111         res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result);
 112         if ( ! res) {
 113                 errno = *errnop = ENOMEM;
 114                 _ldb_nss_ctx->gr_cur++; /* skip this entry */
 115                 return NSS_STATUS_UNAVAIL;
 116         }
 117 
 118         ret = _ldb_nss_group_request(&res,
 119                                 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn, 
 120                                 _ldb_nss_mem_attrs,
 121                                 "member");
 122 
 123         if (ret != NSS_STATUS_SUCCESS) {
 124                 *errnop = errno;
 125                 talloc_free(res);
 126                 _ldb_nss_ctx->gr_cur++; /* skip this entry */
 127                 return ret;
 128         }
 129 
 130         ret = _ldb_nss_fill_group(result_buf,
 131                                 buffer,
 132                                 buflen,
 133                                 errnop,
 134                                 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
 135                                 res);
 136 
 137         talloc_free(res);
 138 
 139         if (ret != NSS_STATUS_SUCCESS) {
 140                 if (ret != NSS_STATUS_TRYAGAIN) {
 141                         _ldb_nss_ctx->gr_cur++; /* skip this entry */
 142                 }
 143                 return ret;
 144         }
 145 
 146         /* this entry is ok, increment counter to nex entry */
 147         _ldb_nss_ctx->gr_cur++;
 148 
 149         return NSS_STATUS_SUCCESS;
 150 }
 151 
 152 NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
     /* [<][>][^][v][top][bottom][index][help] */
 153 {
 154         int ret;
 155         char *filter;
 156         TALLOC_CTX *ctx;
 157         struct ldb_result *gr_res;
 158         struct ldb_result *mem_res;
 159 
 160         ret = _ldb_nss_init();
 161         if (ret != NSS_STATUS_SUCCESS) {
 162                 return ret;
 163         }
 164 
 165         ctx = talloc_new(_ldb_nss_ctx->ldb);
 166         if ( ! ctx) {
 167                 *errnop = errno = ENOMEM;
 168                 return NSS_STATUS_UNAVAIL;
 169         }
 170 
 171         /* build the filter for this uid */
 172         filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name);
 173         if (filter == NULL) {
 174                 /* this is a fatal error */
 175                 *errnop = errno = ENOMEM;
 176                 ret = NSS_STATUS_UNAVAIL;
 177                 goto done;
 178         }
 179 
 180         /* search the entry */
 181         ret = ldb_search(_ldb_nss_ctx->ldb,
 182                          _ldb_nss_ctx->ldb,
 183                          &gr_res,
 184                          _ldb_nss_ctx->base,
 185                          LDB_SCOPE_SUBTREE,
 186                          _ldb_nss_gr_attrs,
 187                          filter);
 188         if (ret != LDB_SUCCESS) {
 189                 /* this is a fatal error */
 190                 *errnop = errno = ENOENT;
 191                 ret = NSS_STATUS_UNAVAIL;
 192                 goto done;
 193         }
 194 
 195         talloc_steal(ctx, gr_res);
 196 
 197         /* if none found return */
 198         if (gr_res->count == 0) {
 199                 *errnop = errno = ENOENT;
 200                 ret = NSS_STATUS_NOTFOUND;
 201                 goto done;
 202         }
 203 
 204         if (gr_res->count != 1) {
 205                 /* this is a fatal error */
 206                 *errnop = errno = ENOENT;
 207                 ret = NSS_STATUS_UNAVAIL;
 208                 goto done;
 209         }
 210 
 211         mem_res = talloc_zero(ctx, struct ldb_result);
 212         if ( ! mem_res) {
 213                 errno = *errnop = ENOMEM;
 214                 ret = NSS_STATUS_UNAVAIL;
 215                 goto done;
 216         }
 217 
 218         ret = _ldb_nss_group_request(&mem_res,
 219                                         gr_res->msgs[0]->dn,
 220                                         _ldb_nss_mem_attrs,
 221                                         "member");
 222 
 223         if (ret != NSS_STATUS_SUCCESS) {
 224                 *errnop = errno;
 225                 goto done;
 226         }
 227 
 228         ret = _ldb_nss_fill_group(result_buf,
 229                                 buffer,
 230                                 buflen,
 231                                 errnop,
 232                                 gr_res->msgs[0],
 233                                 mem_res);
 234 
 235         if (ret != NSS_STATUS_SUCCESS) {
 236                 goto done;
 237         }
 238 
 239         ret = NSS_STATUS_SUCCESS;
 240 done:
 241         talloc_free(ctx);
 242         return ret;
 243 }
 244 
 245 NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
     /* [<][>][^][v][top][bottom][index][help] */
 246 {
 247         int ret;
 248         char *filter;
 249         TALLOC_CTX *ctx;
 250         struct ldb_result *gr_res;
 251         struct ldb_result *mem_res;
 252 
 253         if (gid == 0) { /* we don't serve root gid by policy */
 254                 *errnop = errno = ENOENT;
 255                 return NSS_STATUS_NOTFOUND;
 256         }
 257 
 258         ret = _ldb_nss_init();
 259         if (ret != NSS_STATUS_SUCCESS) {
 260                 return ret;
 261         }
 262 
 263         ctx = talloc_new(_ldb_nss_ctx->ldb);
 264         if ( ! ctx) {
 265                 *errnop = errno = ENOMEM;
 266                 return NSS_STATUS_UNAVAIL;
 267         }
 268 
 269         /* build the filter for this uid */
 270         filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid);
 271         if (filter == NULL) {
 272                 /* this is a fatal error */
 273                 *errnop = errno = ENOMEM;
 274                 ret = NSS_STATUS_UNAVAIL;
 275                 goto done;
 276         }
 277 
 278         /* search the entry */
 279         ret = ldb_search(_ldb_nss_ctx->ldb,
 280                          _ldb_nss_ctx->ldb,
 281                          &gr_res,
 282                          _ldb_nss_ctx->base,
 283                          LDB_SCOPE_SUBTREE,
 284                          _ldb_nss_gr_attrs,
 285                          filter);
 286         if (ret != LDB_SUCCESS) {
 287                 /* this is a fatal error */
 288                 *errnop = errno = ENOENT;
 289                 ret = NSS_STATUS_UNAVAIL;
 290                 goto done;
 291         }
 292 
 293         talloc_steal(ctx, gr_res);
 294 
 295         /* if none found return */
 296         if (gr_res->count == 0) {
 297                 *errnop = errno = ENOENT;
 298                 ret = NSS_STATUS_NOTFOUND;
 299                 goto done;
 300         }
 301 
 302         if (gr_res->count != 1) {
 303                 /* this is a fatal error */
 304                 *errnop = errno = ENOENT;
 305                 ret = NSS_STATUS_UNAVAIL;
 306                 goto done;
 307         }
 308 
 309         mem_res = talloc_zero(ctx, struct ldb_result);
 310         if ( ! mem_res) {
 311                 errno = *errnop = ENOMEM;
 312                 ret = NSS_STATUS_UNAVAIL;
 313                 goto done;
 314         }
 315 
 316         ret = _ldb_nss_group_request(&mem_res,
 317                                         gr_res->msgs[0]->dn,
 318                                         _ldb_nss_mem_attrs,
 319                                         "member");
 320 
 321         if (ret != NSS_STATUS_SUCCESS) {
 322                 *errnop = errno;
 323                 goto done;
 324         }
 325 
 326         ret = _ldb_nss_fill_group(result_buf,
 327                                 buffer,
 328                                 buflen,
 329                                 errnop,
 330                                 gr_res->msgs[0],
 331                                 mem_res);
 332 
 333         if (ret != NSS_STATUS_SUCCESS) {
 334                 goto done;
 335         }
 336 
 337         ret = NSS_STATUS_SUCCESS;
 338 done:
 339         talloc_free(ctx);
 340         return ret;
 341 }
 342 
 343 NSS_STATUS _nss_ldb_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop)
     /* [<][>][^][v][top][bottom][index][help] */
 344 {
 345         int ret;
 346         char *filter;
 347         const char * attrs[] = { "uidNumber", "gidNumber", NULL };
 348         struct ldb_result *uid_res;
 349         struct ldb_result *mem_res;
 350 
 351         ret = _ldb_nss_init();
 352         if (ret != NSS_STATUS_SUCCESS) {
 353                 return ret;
 354         }
 355 
 356         mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
 357         if ( ! mem_res) {
 358                 errno = *errnop = ENOMEM;
 359                 return NSS_STATUS_UNAVAIL;
 360         }
 361 
 362         /* build the filter for this name */
 363         filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
 364         if (filter == NULL) {
 365                 /* this is a fatal error */
 366                 *errnop = errno = ENOENT;
 367                 ret = NSS_STATUS_UNAVAIL;
 368                 goto done;
 369         }
 370 
 371         /* search the entry */
 372         ret = ldb_search(_ldb_nss_ctx->ldb,
 373                          _ldb_nss_ctx->ldb,
 374                          &uid_res,
 375                          _ldb_nss_ctx->base,
 376                          LDB_SCOPE_SUBTREE,
 377                          attrs,
 378                          filter);
 379         if (ret != LDB_SUCCESS) {
 380                 /* this is a fatal error */
 381                 *errnop = errno = ENOENT;
 382                 ret = NSS_STATUS_UNAVAIL;
 383                 goto done;
 384         }
 385 
 386         talloc_steal(mem_res, uid_res);
 387 
 388         /* if none found return */
 389         if (uid_res->count == 0) {
 390                 *errnop = errno = ENOENT;
 391                 ret = NSS_STATUS_NOTFOUND;
 392                 goto done;
 393         }
 394 
 395         if (uid_res->count != 1) {
 396                 /* this is a fatal error */
 397                 *errnop = errno = ENOENT;
 398                 ret = NSS_STATUS_UNAVAIL;
 399                 goto done;
 400         }
 401 
 402         ret = _ldb_nss_group_request(&mem_res,
 403                                         uid_res->msgs[0]->dn,
 404                                         attrs,
 405                                         "memberOf");
 406 
 407         if (ret != NSS_STATUS_SUCCESS) {
 408                 *errnop = errno;
 409                 goto done;
 410         }
 411 
 412         ret = _ldb_nss_fill_initgr(group,
 413                                 limit,
 414                                 start,
 415                                 size,
 416                                 groups,
 417                                 errnop,
 418                                 mem_res);
 419 
 420         if (ret != NSS_STATUS_SUCCESS) {
 421                 goto done;
 422         }
 423 
 424         ret = NSS_STATUS_SUCCESS;
 425 
 426 done:
 427         talloc_free(mem_res);
 428         return ret;
 429 }

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