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

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