root/source3/torture/nsstest.c

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

DEFINITIONS

This source file includes following definitions.
  1. find_fn
  2. report_nss_error
  3. nss_getpwent
  4. nss_getpwnam
  5. nss_getpwuid
  6. nss_setpwent
  7. nss_endpwent
  8. nss_getgrent
  9. nss_getgrnam
  10. nss_getgrgid
  11. nss_setgrent
  12. nss_endgrent
  13. nss_initgroups
  14. print_passwd
  15. print_group
  16. nss_test_initgroups
  17. nss_test_users
  18. nss_test_groups
  19. nss_test_errors
  20. main

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    nss tester for winbindd
   4    Copyright (C) Andrew Tridgell 2001
   5    Copyright (C) Tim Potter 2003
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 
  23 static const char *so_path = "/lib/libnss_winbind.so";
  24 static const char *nss_name = "winbind";
  25 static int nss_errno;
  26 static NSS_STATUS last_error;
  27 static int total_errors;
  28 
  29 static void *find_fn(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  30 {
  31         char *s;
  32         static void *h;
  33         void *res;
  34 
  35         if (asprintf(&s, "_nss_%s_%s", nss_name, name) < 0) {
  36                 exit(1);
  37         }
  38 
  39         if (!h) {
  40                 h = dlopen(so_path, RTLD_LAZY);
  41         }
  42         if (!h) {
  43                 printf("Can't open shared library %s\n", so_path);
  44                 exit(1);
  45         }
  46         res = dlsym(h, s);
  47         if (!res) {
  48                 printf("Can't find function %s\n", s);
  49                 total_errors++;
  50                 SAFE_FREE(s);
  51                 return NULL;
  52         }
  53         SAFE_FREE(s);
  54         return res;
  55 }
  56 
  57 static void report_nss_error(const char *who, NSS_STATUS status)
     /* [<][>][^][v][top][bottom][index][help] */
  58 {
  59         last_error = status;
  60         total_errors++;
  61         printf("ERROR %s: NSS_STATUS=%d  %d (nss_errno=%d)\n", 
  62                who, status, NSS_STATUS_SUCCESS, nss_errno);
  63 }
  64 
  65 static struct passwd *nss_getpwent(void)
     /* [<][>][^][v][top][bottom][index][help] */
  66 {
  67         NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, 
  68                                       size_t , int *) =
  69                 (NSS_STATUS (*)(struct passwd *, char *,
  70                                 size_t, int *))find_fn("getpwent_r");
  71         static struct passwd pwd;
  72         static char buf[1000];
  73         NSS_STATUS status;
  74 
  75         if (!_nss_getpwent_r)
  76                 return NULL;
  77 
  78         status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
  79         if (status == NSS_STATUS_NOTFOUND) {
  80                 return NULL;
  81         }
  82         if (status != NSS_STATUS_SUCCESS) {
  83                 report_nss_error("getpwent", status);
  84                 return NULL;
  85         }
  86         return &pwd;
  87 }
  88 
  89 static struct passwd *nss_getpwnam(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  90 {
  91         NSS_STATUS (*_nss_getpwnam_r)(const char *, struct passwd *, char *, 
  92                                       size_t , int *) =
  93                 (NSS_STATUS (*)(const char *, struct passwd *, char *,
  94                                 size_t, int *))find_fn("getpwnam_r");
  95         static struct passwd pwd;
  96         static char buf[1000];
  97         NSS_STATUS status;
  98 
  99         if (!_nss_getpwnam_r)
 100                 return NULL;
 101         
 102         status = _nss_getpwnam_r(name, &pwd, buf, sizeof(buf), &nss_errno);
 103         if (status == NSS_STATUS_NOTFOUND) {
 104                 return NULL;
 105         }
 106         if (status != NSS_STATUS_SUCCESS) {
 107                 report_nss_error("getpwnam", status);
 108                 return NULL;
 109         }
 110         return &pwd;
 111 }
 112 
 113 static struct passwd *nss_getpwuid(uid_t uid)
     /* [<][>][^][v][top][bottom][index][help] */
 114 {
 115         NSS_STATUS (*_nss_getpwuid_r)(uid_t , struct passwd *, char *, 
 116                                       size_t , int *) =
 117                 (NSS_STATUS (*)(uid_t, struct passwd *, char *,
 118                                 size_t, int *))find_fn("getpwuid_r");
 119         static struct passwd pwd;
 120         static char buf[1000];
 121         NSS_STATUS status;
 122 
 123         if (!_nss_getpwuid_r)
 124                 return NULL;
 125         
 126         status = _nss_getpwuid_r(uid, &pwd, buf, sizeof(buf), &nss_errno);
 127         if (status == NSS_STATUS_NOTFOUND) {
 128                 return NULL;
 129         }
 130         if (status != NSS_STATUS_SUCCESS) {
 131                 report_nss_error("getpwuid", status);
 132                 return NULL;
 133         }
 134         return &pwd;
 135 }
 136 
 137 static void nss_setpwent(void)
     /* [<][>][^][v][top][bottom][index][help] */
 138 {
 139         NSS_STATUS (*_nss_setpwent)(void) =
 140                 (NSS_STATUS(*)(void))find_fn("setpwent");
 141         NSS_STATUS status;
 142         
 143         if (!_nss_setpwent)
 144                 return;
 145 
 146         status = _nss_setpwent();
 147         if (status != NSS_STATUS_SUCCESS) {
 148                 report_nss_error("setpwent", status);
 149         }
 150 }
 151 
 152 static void nss_endpwent(void)
     /* [<][>][^][v][top][bottom][index][help] */
 153 {
 154         NSS_STATUS (*_nss_endpwent)(void) =
 155                 (NSS_STATUS (*)(void))find_fn("endpwent");
 156         NSS_STATUS status;
 157 
 158         if (!_nss_endpwent)
 159                 return;
 160 
 161         status = _nss_endpwent();
 162         if (status != NSS_STATUS_SUCCESS) {
 163                 report_nss_error("endpwent", status);
 164         }
 165 }
 166 
 167 
 168 static struct group *nss_getgrent(void)
     /* [<][>][^][v][top][bottom][index][help] */
 169 {
 170         NSS_STATUS (*_nss_getgrent_r)(struct group *, char *, 
 171                                       size_t , int *) =
 172                 (NSS_STATUS (*)(struct group *, char *,
 173                                 size_t, int *))find_fn("getgrent_r");
 174         static struct group grp;
 175         static char *buf;
 176         static int buflen = 1024;
 177         NSS_STATUS status;
 178 
 179         if (!_nss_getgrent_r)
 180                 return NULL;
 181 
 182         if (!buf) 
 183                 buf = SMB_MALLOC_ARRAY(char, buflen);
 184 
 185 again:  
 186         status = _nss_getgrent_r(&grp, buf, buflen, &nss_errno);
 187         if (status == NSS_STATUS_TRYAGAIN) {
 188                 buflen *= 2;
 189                 buf = SMB_REALLOC_ARRAY(buf, char, buflen);
 190                 if (!buf) {
 191                         return NULL;
 192                 }
 193                 goto again;
 194         }
 195         if (status == NSS_STATUS_NOTFOUND) {
 196                 SAFE_FREE(buf);
 197                 return NULL;
 198         }
 199         if (status != NSS_STATUS_SUCCESS) {
 200                 report_nss_error("getgrent", status);
 201                 SAFE_FREE(buf);
 202                 return NULL;
 203         }
 204         return &grp;
 205 }
 206 
 207 static struct group *nss_getgrnam(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 208 {
 209         NSS_STATUS (*_nss_getgrnam_r)(const char *, struct group *, char *, 
 210                                       size_t , int *) =
 211                 (NSS_STATUS (*)(const char *, struct group *, char *,
 212                                 size_t, int *))find_fn("getgrnam_r");
 213         static struct group grp;
 214         static char *buf;
 215         static int buflen = 1000;
 216         NSS_STATUS status;
 217 
 218         if (!_nss_getgrnam_r)
 219                 return NULL;
 220 
 221         if (!buf) 
 222                 buf = SMB_MALLOC_ARRAY(char, buflen);
 223 again:  
 224         status = _nss_getgrnam_r(name, &grp, buf, buflen, &nss_errno);
 225         if (status == NSS_STATUS_TRYAGAIN) {
 226                 buflen *= 2;
 227                 buf = SMB_REALLOC_ARRAY(buf, char, buflen);
 228                 if (!buf) {
 229                         return NULL;
 230                 }
 231                 goto again;
 232         }
 233         if (status == NSS_STATUS_NOTFOUND) {
 234                 SAFE_FREE(buf);
 235                 return NULL;
 236         }
 237         if (status != NSS_STATUS_SUCCESS) {
 238                 report_nss_error("getgrnam", status);
 239                 SAFE_FREE(buf);
 240                 return NULL;
 241         }
 242         return &grp;
 243 }
 244 
 245 static struct group *nss_getgrgid(gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
 246 {
 247         NSS_STATUS (*_nss_getgrgid_r)(gid_t , struct group *, char *, 
 248                                       size_t , int *) =
 249                 (NSS_STATUS (*)(gid_t, struct group *, char *,
 250                                 size_t, int *))find_fn("getgrgid_r");
 251         static struct group grp;
 252         static char *buf;
 253         static int buflen = 1000;
 254         NSS_STATUS status;
 255         
 256         if (!_nss_getgrgid_r)
 257                 return NULL;
 258 
 259         if (!buf) 
 260                 buf = SMB_MALLOC_ARRAY(char, buflen);
 261 
 262 again:  
 263         status = _nss_getgrgid_r(gid, &grp, buf, buflen, &nss_errno);
 264         if (status == NSS_STATUS_TRYAGAIN) {
 265                 buflen *= 2;
 266                 buf = SMB_REALLOC_ARRAY(buf, char, buflen);
 267                 if (!buf) {
 268                         return NULL;
 269                 }
 270                 goto again;
 271         }
 272         if (status == NSS_STATUS_NOTFOUND) {
 273                 SAFE_FREE(buf);
 274                 return NULL;
 275         }
 276         if (status != NSS_STATUS_SUCCESS) {
 277                 report_nss_error("getgrgid", status);
 278                 SAFE_FREE(buf);
 279                 return NULL;
 280         }
 281         return &grp;
 282 }
 283 
 284 static void nss_setgrent(void)
     /* [<][>][^][v][top][bottom][index][help] */
 285 {
 286         NSS_STATUS (*_nss_setgrent)(void) =
 287                 (NSS_STATUS (*)(void))find_fn("setgrent");
 288         NSS_STATUS status;
 289 
 290         if (!_nss_setgrent)
 291                 return;
 292 
 293         status = _nss_setgrent();
 294         if (status != NSS_STATUS_SUCCESS) {
 295                 report_nss_error("setgrent", status);
 296         }
 297 }
 298 
 299 static void nss_endgrent(void)
     /* [<][>][^][v][top][bottom][index][help] */
 300 {
 301         NSS_STATUS (*_nss_endgrent)(void) =
 302                 (NSS_STATUS (*)(void))find_fn("endgrent");
 303         NSS_STATUS status;
 304 
 305         if (!_nss_endgrent)
 306                 return;
 307 
 308         status = _nss_endgrent();
 309         if (status != NSS_STATUS_SUCCESS) {
 310                 report_nss_error("endgrent", status);
 311         }
 312 }
 313 
 314 static int nss_initgroups(char *user, gid_t group, gid_t **groups, long int *start, long int *size)
     /* [<][>][^][v][top][bottom][index][help] */
 315 {
 316         NSS_STATUS (*_nss_initgroups)(char *, gid_t , long int *,
 317                                       long int *, gid_t **, long int , int *) = 
 318                 (NSS_STATUS (*)(char *, gid_t, long int *,
 319                                 long int *, gid_t **,
 320                                 long int, int *))find_fn("initgroups_dyn");
 321         NSS_STATUS status;
 322 
 323         if (!_nss_initgroups) 
 324                 return NSS_STATUS_UNAVAIL;
 325 
 326         status = _nss_initgroups(user, group, start, size, groups, 0, &nss_errno);
 327         if (status != NSS_STATUS_SUCCESS) {
 328                 report_nss_error("initgroups", status);
 329         }
 330         return status;
 331 }
 332 
 333 static void print_passwd(struct passwd *pwd)
     /* [<][>][^][v][top][bottom][index][help] */
 334 {
 335         printf("%s:%s:%lu:%lu:%s:%s:%s\n", 
 336                pwd->pw_name,
 337                pwd->pw_passwd,
 338                (unsigned long)pwd->pw_uid,
 339                (unsigned long)pwd->pw_gid,
 340                pwd->pw_gecos,
 341                pwd->pw_dir,
 342                pwd->pw_shell);
 343 }
 344 
 345 static void print_group(struct group *grp)
     /* [<][>][^][v][top][bottom][index][help] */
 346 {
 347         int i;
 348         printf("%s:%s:%lu: ", 
 349                grp->gr_name,
 350                grp->gr_passwd,
 351                (unsigned long)grp->gr_gid);
 352         
 353         if (!grp->gr_mem[0]) {
 354                 printf("\n");
 355                 return;
 356         }
 357         
 358         for (i=0; grp->gr_mem[i+1]; i++) {
 359                 printf("%s, ", grp->gr_mem[i]);
 360         }
 361         printf("%s\n", grp->gr_mem[i]);
 362 }
 363 
 364 static void nss_test_initgroups(char *name, gid_t gid)
     /* [<][>][^][v][top][bottom][index][help] */
 365 {
 366         long int size = 16;
 367         long int start = 1;
 368         gid_t *groups = NULL;
 369         int i;
 370         NSS_STATUS status;
 371 
 372         groups = SMB_MALLOC_ARRAY(gid_t, size);
 373         groups[0] = gid;
 374 
 375         status = nss_initgroups(name, gid, &groups, &start, &size);
 376         if (status == NSS_STATUS_UNAVAIL) {
 377                 printf("No initgroups fn\n");
 378                 return;
 379         }
 380 
 381         for (i=0; i<start-1; i++) {
 382                 printf("%lu, ", (unsigned long)groups[i]);
 383         }
 384         printf("%lu\n", (unsigned long)groups[i]);
 385 }
 386 
 387 
 388 static void nss_test_users(void)
     /* [<][>][^][v][top][bottom][index][help] */
 389 {
 390         struct passwd *pwd;
 391 
 392         nss_setpwent();
 393         /* loop over all users */
 394         while ((pwd = nss_getpwent())) {
 395                 printf("Testing user %s\n", pwd->pw_name);
 396                 printf("getpwent:   "); print_passwd(pwd);
 397                 pwd = nss_getpwuid(pwd->pw_uid);
 398                 if (!pwd) {
 399                         total_errors++;
 400                         printf("ERROR: can't getpwuid\n");
 401                         continue;
 402                 }
 403                 printf("getpwuid:   "); print_passwd(pwd);
 404                 pwd = nss_getpwnam(pwd->pw_name);
 405                 if (!pwd) {
 406                         total_errors++;
 407                         printf("ERROR: can't getpwnam\n");
 408                         continue;
 409                 }
 410                 printf("getpwnam:   "); print_passwd(pwd);
 411                 printf("initgroups: "); nss_test_initgroups(pwd->pw_name, pwd->pw_gid);
 412                 printf("\n");
 413         }
 414         nss_endpwent();
 415 }
 416 
 417 static void nss_test_groups(void)
     /* [<][>][^][v][top][bottom][index][help] */
 418 {
 419         struct group *grp;
 420 
 421         nss_setgrent();
 422         /* loop over all groups */
 423         while ((grp = nss_getgrent())) {
 424                 printf("Testing group %s\n", grp->gr_name);
 425                 printf("getgrent: "); print_group(grp);
 426                 grp = nss_getgrnam(grp->gr_name);
 427                 if (!grp) {
 428                         total_errors++;
 429                         printf("ERROR: can't getgrnam\n");
 430                         continue;
 431                 }
 432                 printf("getgrnam: "); print_group(grp);
 433                 grp = nss_getgrgid(grp->gr_gid);
 434                 if (!grp) {
 435                         total_errors++;
 436                         printf("ERROR: can't getgrgid\n");
 437                         continue;
 438                 }
 439                 printf("getgrgid: "); print_group(grp);
 440                 printf("\n");
 441         }
 442         nss_endgrent();
 443 }
 444 
 445 static void nss_test_errors(void)
     /* [<][>][^][v][top][bottom][index][help] */
 446 {
 447         struct passwd *pwd;
 448         struct group *grp;
 449 
 450         pwd = getpwnam("nosuchname");
 451         if (pwd || last_error != NSS_STATUS_NOTFOUND) {
 452                 total_errors++;
 453                 printf("ERROR Non existant user gave error %d\n", last_error);
 454         }
 455 
 456         pwd = getpwuid(0xFFF0);
 457         if (pwd || last_error != NSS_STATUS_NOTFOUND) {
 458                 total_errors++;
 459                 printf("ERROR Non existant uid gave error %d\n", last_error);
 460         }
 461 
 462         grp = getgrnam("nosuchgroup");
 463         if (grp || last_error != NSS_STATUS_NOTFOUND) {
 464                 total_errors++;
 465                 printf("ERROR Non existant group gave error %d\n", last_error);
 466         }
 467 
 468         grp = getgrgid(0xFFF0);
 469         if (grp || last_error != NSS_STATUS_NOTFOUND) {
 470                 total_errors++;
 471                 printf("ERROR Non existant gid gave error %d\n", last_error);
 472         }
 473 }
 474 
 475  int main(int argc, char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 476 {       
 477         if (argc > 1) so_path = argv[1];
 478         if (argc > 2) nss_name = argv[2];
 479 
 480         nss_test_users();
 481         nss_test_groups();
 482         nss_test_errors();
 483 
 484         printf("total_errors=%d\n", total_errors);
 485 
 486         return total_errors;
 487 }

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