Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / pam / pam_modules / unix / switch_utils.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: switch_utils.c /main/5 1996/05/09 04:32:20 drk $ */
24
25 /*
26  * Copyright (c) 1992-1995, by Sun Microsystems, Inc.
27  * All rights reserved.
28  */
29
30 #ident  "@(#)switch_utils.c 1.31     96/02/02 SMI"
31
32 #include "unix_headers.h"
33
34 /*
35  * XXX
36  * This file relies on the fact that you are using NSS_SWITCH.
37  * If PAM_NIS or PAM_NISPLUS is defined, then the
38  * include files for nss_switch are included.
39  * Otherwise, the repository is assumed to be FILES,
40  * and NSS_SWITCH is not used.
41  */
42
43 static void     pr_config();
44
45 /*
46  * The following is similar to getpwnam() except that it specifies
47  * where to get the information. This is modeled after getpwnam_r().
48  */
49 #ifdef PAM_NIS
50 static void
51 nss_nis_passwd(p)
52         nss_db_params_t *p;
53 {
54         p->name = NSS_DBNAM_PASSWD;
55         p->flags |= NSS_USE_DEFAULT_CONFIG;
56         p->default_config = "nis";
57 }
58
59 static void
60 nss_nis_shadow(p)
61         nss_db_params_t *p;
62 {
63         p->name = NSS_DBNAM_SHADOW;
64         p->config_name    = NSS_DBNAM_PASSWD;   /* Use config for "passwd" */
65         p->flags |= NSS_USE_DEFAULT_CONFIG;
66         p->default_config = "nis";
67 }
68 #endif /* PAM_NIS */
69
70 #ifdef PAM_NISPLUS
71 static void
72 nss_nisplus_passwd(p)
73         nss_db_params_t *p;
74 {
75         p->name = NSS_DBNAM_PASSWD;
76         p->flags |= NSS_USE_DEFAULT_CONFIG;
77         p->default_config = "nisplus";
78 }
79
80 static void
81 nss_nisplus_shadow(p)
82         nss_db_params_t *p;
83 {
84         p->name = NSS_DBNAM_SHADOW;
85         p->config_name    = NSS_DBNAM_PASSWD;   /* Use config for "passwd" */
86         p->flags |= NSS_USE_DEFAULT_CONFIG;
87         p->default_config = "nisplus";
88 }
89 #endif /* PAM_NISPLUS */
90
91 static char *
92 gettok(nextpp)
93         char    **nextpp;
94 {
95         char    *p = *nextpp;
96         char    *q = p;
97         char    c;
98
99         if (p == 0) {
100                 return (0);
101         }
102         while ((c = *q) != '\0' && c != ':') {
103                 q++;
104         }
105         if (c == '\0') {
106                 *nextpp = 0;
107         } else {
108                 *q++ = '\0';
109                 *nextpp = q;
110         }
111         return (p);
112 }
113
114 #if (PAM_NIS || PAM_NISPLUS)
115
116 /*
117  * Return values: 0 = success, 1 = parse error, 2 = erange ...
118  * The structure pointer passed in is a structure in the caller's space
119  * wherein the field pointers would be set to areas in the buffer if
120  * need be. instring and buffer should be separate areas.
121  */
122 static int
123 str2passwd(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
124 {
125         struct passwd   *passwd = (struct passwd *)ent;
126         char            *p, *next;
127         int             black_magic;    /* "+" or "-" entry */
128
129         if (lenstr + 1 > buflen) {
130                 return (NSS_STR_PARSE_ERANGE);
131         }
132         /*
133          * We copy the input string into the output buffer and
134          * operate on it in place.
135          */
136         (void) memcpy(buffer, instr, lenstr);
137         buffer[lenstr] = '\0';
138
139         next = buffer;
140
141         passwd->pw_name = p = gettok(&next);            /* username */
142         if (*p == '\0') {
143                 /* Empty username;  not allowed */
144                 return (NSS_STR_PARSE_PARSE);
145         }
146         black_magic = (*p == '+' || *p == '-');
147         if (black_magic) {
148                 passwd->pw_uid  = UID_NOBODY;
149                 passwd->pw_gid  = GID_NOBODY;
150                 /*
151                  * pwconv tests pw_passwd and pw_age == NULL
152                  */
153                 passwd->pw_passwd = "";
154                 passwd->pw_age  = "";
155                 /*
156                  * the rest of the passwd entry is "optional"
157                  */
158                 passwd->pw_comment = "";
159                 passwd->pw_gecos = "";
160                 passwd->pw_dir  = "";
161                 passwd->pw_shell = "";
162         }
163
164         passwd->pw_passwd = p = gettok(&next);          /* password */
165         if (p == 0) {
166                 if (black_magic)
167                         return (NSS_STR_PARSE_SUCCESS);
168                 else
169                         return (NSS_STR_PARSE_PARSE);
170         }
171         for (; *p != '\0'; p++) {                       /* age */
172                 if (*p == ',') {
173                         *p++ = '\0';
174                         break;
175                 }
176         }
177         passwd->pw_age = p;
178
179         p = next;                                       /* uid */
180         if (p == 0 || *p == '\0') {
181                 if (black_magic)
182                         return (NSS_STR_PARSE_SUCCESS);
183                 else
184                         return (NSS_STR_PARSE_PARSE);
185         }
186         if (!black_magic) {
187                 passwd->pw_uid = strtol(p, &next, 10);
188                 if (next == p) {
189                         /* uid field should be nonempty */
190                         return (NSS_STR_PARSE_PARSE);
191                 }
192                 /*
193                  * The old code (in 2.0 thru 2.5) would check
194                  * for the uid being negative, or being greater
195                  * than 60001 (the rfs limit).  If it met either of
196                  * these conditions, the uid was translated to 60001.
197                  *
198                  * Now we just check for negative uids; anything else
199                  * is administrative policy
200                  */
201                 if (passwd->pw_uid < 0)
202                         passwd->pw_uid = UID_NOBODY;
203         }
204         if (*next++ != ':') {
205                 if (black_magic)
206                         p = gettok(&next);
207                 else
208                         return (NSS_STR_PARSE_PARSE);
209         }
210         p = next;                                       /* gid */
211         if (p == 0 || *p == '\0') {
212                 if (black_magic)
213                         return (NSS_STR_PARSE_SUCCESS);
214                 else
215                         return (NSS_STR_PARSE_PARSE);
216         }
217         if (!black_magic) {
218                 passwd->pw_gid = strtol(p, &next, 10);
219                 if (next == p) {
220                         /* gid field should be nonempty */
221                         return (NSS_STR_PARSE_PARSE);
222                 }
223                 /*
224                  * gid should be non-negative; anything else
225                  * is administrative policy.
226                  */
227                 if (passwd->pw_gid < 0)
228                         passwd->pw_gid = GID_NOBODY;
229         }
230         if (*next++ != ':') {
231                 if (black_magic)
232                         p = gettok(&next);
233                 else
234                         return (NSS_STR_PARSE_PARSE);
235         }
236
237         passwd->pw_gecos = passwd->pw_comment = p = gettok(&next);
238         if (p == 0) {
239                 if (black_magic)
240                         return (NSS_STR_PARSE_SUCCESS);
241                 else
242                         return (NSS_STR_PARSE_PARSE);
243         }
244
245         passwd->pw_dir = p = gettok(&next);
246         if (p == 0) {
247                 if (black_magic)
248                         return (NSS_STR_PARSE_SUCCESS);
249                 else
250                         return (NSS_STR_PARSE_PARSE);
251         }
252
253         passwd->pw_shell = p = gettok(&next);
254         if (p == 0) {
255                 if (black_magic)
256                         return (NSS_STR_PARSE_SUCCESS);
257                 else
258                         return (NSS_STR_PARSE_PARSE);
259         }
260
261         /* Better not be any more fields... */
262         if (next == 0) {
263                 /* Successfully parsed and stored */
264                 return (NSS_STR_PARSE_SUCCESS);
265         }
266         return (NSS_STR_PARSE_PARSE);
267 }
268
269 typedef const char *constp;
270
271 static bool_t   /* 1 means success and more input, 0 means error or no more */
272 getfield(nextp, limit, uns, valp)
273         constp          *nextp;
274         constp          limit;
275         int             uns;
276         void            *valp;
277 {
278         constp          p = *nextp;
279         char            *endfield;
280         char            numbuf[12];  /* Holds -2^31 and trailing \0 */
281         int             len;
282
283         if (p == 0 || p >= limit) {
284                 return (0);
285         }
286         if (*p == ':') {
287                 p++;
288                 *nextp = p;
289                 return (p < limit);
290         }
291         if ((len = limit - p) > sizeof (numbuf) - 1) {
292                 len = sizeof (numbuf) - 1;
293         }
294         /*
295          * We want to use strtol() and we have a readonly non-zero-terminated
296          *   string, so first we copy and terminate the interesting bit.
297          *   Ugh.  (It's convenient to terminate with a colon rather than \0).
298          */
299         if ((endfield = memccpy(numbuf, p, ':', len)) == 0) {
300                 if (len != limit - p) {
301                         /* Error -- field is too big to be a legit number */
302                         return (0);
303                 }
304                 numbuf[len] = ':';
305                 p = limit;
306         } else {
307                 p += (endfield - numbuf);
308         }
309         if (uns) {
310                 *((unsigned long *)valp) = strtoul(numbuf, &endfield, 10);
311         } else {
312                 *((long *)valp) = strtol(numbuf, &endfield, 10);
313         }
314         if (*endfield != ':') {
315                 /* Error -- expected <integer><colon>, got something else */
316                 return (0);
317         }
318         *nextp = p;
319         return (p < limit);
320 }
321
322 /*
323  *  str2spwd() -- convert a string to a shadow passwd entry.  The parser is
324  *      more liberal than the passwd or group parsers;  since it's legitimate
325  *      for almost all the fields here to be blank, the parser lets one omit
326  *      any number of blank fields at the end of the entry.  The acceptable
327  *      forms for '+' and '-' entries are the same as those for normal entries.
328  *  === Is this likely to do more harm than good?
329  *
330  * Return values: 0 = success, 1 = parse error, 2 = erange ...
331  * The structure pointer passed in is a structure in the caller's space
332  * wherein the field pointers would be set to areas in the buffer if
333  * need be. instring and buffer should be separate areas.
334  */
335 int
336 str2spwd(instr, lenstr, ent, buffer, buflen)
337         const char      *instr;
338         int             lenstr;
339         void    *ent; /* really (struct spwd *) */
340         char    *buffer;
341         int     buflen;
342 {
343         struct spwd     *shadow = (struct spwd *)ent;
344         const char      *p = instr, *limit;
345         char            *bufp;
346         int     lencopy, black_magic;
347
348         limit = p + lenstr;
349         if ((p = memchr(instr, ':', lenstr)) == 0 ||
350                 ++p >= limit ||
351                 (p = memchr(p, ':', limit - p)) == 0) {
352                 lencopy = lenstr;
353                 p = 0;
354         } else {
355                 lencopy = p - instr;
356                 p++;
357         }
358         if (lencopy + 1 > buflen) {
359                 return (NSS_STR_PARSE_ERANGE);
360         }
361         (void) memcpy(buffer, instr, lencopy);
362         buffer[lencopy] = 0;
363
364         black_magic = (*instr == '+' || *instr == '-');
365         shadow->sp_namp = bufp = buffer;
366         shadow->sp_pwdp = 0;
367         shadow->sp_lstchg = -1;
368         shadow->sp_min  = -1;
369         shadow->sp_max  = -1;
370         shadow->sp_warn = -1;
371         shadow->sp_inact = -1;
372         shadow->sp_expire = -1;
373         shadow->sp_flag = 0;
374
375         if ((bufp = strchr(bufp, ':')) == 0) {
376                 if (black_magic)
377                         return (NSS_STR_PARSE_SUCCESS);
378                 else
379                         return (NSS_STR_PARSE_PARSE);
380         }
381         *bufp++ = '\0';
382
383         shadow->sp_pwdp = bufp;
384         if (instr == 0) {
385                 if ((bufp = strchr(bufp, ':')) == 0) {
386                         if (black_magic)
387                                 return (NSS_STR_PARSE_SUCCESS);
388                         else
389                                 return (NSS_STR_PARSE_PARSE);
390                 }
391                 *bufp++ = '\0';
392                 p = bufp;
393         } /* else p was set when we copied name and passwd into the buffer */
394
395         if (!getfield(&p, limit, 0, &shadow->sp_lstchg))
396                         return (NSS_STR_PARSE_SUCCESS);
397         if (!getfield(&p, limit, 0, &shadow->sp_min))
398                         return (NSS_STR_PARSE_SUCCESS);
399         if (!getfield(&p, limit, 0, &shadow->sp_max))
400                         return (NSS_STR_PARSE_SUCCESS);
401         if (!getfield(&p, limit, 0, &shadow->sp_warn))
402                         return (NSS_STR_PARSE_SUCCESS);
403         if (!getfield(&p, limit, 0, &shadow->sp_inact))
404                         return (NSS_STR_PARSE_SUCCESS);
405         if (!getfield(&p, limit, 0, &shadow->sp_expire))
406                         return (NSS_STR_PARSE_SUCCESS);
407         if (!getfield(&p, limit, 1, &shadow->sp_flag))
408                         return (NSS_STR_PARSE_SUCCESS);
409         if (p != limit) {
410                 /* Syntax error -- garbage at end of line */
411                 return (NSS_STR_PARSE_PARSE);
412         }
413         return (NSS_STR_PARSE_SUCCESS);
414 }
415
416 static nss_XbyY_buf_t *buffer;
417 static DEFINE_NSS_DB_ROOT(db_root);
418
419 #define GETBUF()        \
420         NSS_XbyY_ALLOC(&buffer, sizeof (struct passwd), NSS_BUFLEN_PASSWD)
421
422 struct passwd *
423 getpwnam_from(name, rep)
424         const char      *name;
425         int             rep;
426 {
427         nss_XbyY_buf_t  *b = GETBUF();
428         nss_XbyY_args_t arg;
429
430         if (b == 0)
431                 return (0);
432
433         NSS_XbyY_INIT(&arg, b->result, b->buffer, b->buflen, str2passwd);
434         arg.key.name = name;
435
436         switch (rep) {
437 #ifdef PAM_NISPLUS
438         case PAM_REP_NISPLUS:
439                 nss_search(&db_root, nss_nisplus_passwd, NSS_DBOP_PASSWD_BYNAME,
440                     &arg);
441                 break;
442 #endif
443 #ifdef PAM_NIS
444         case PAM_REP_NIS:
445                 nss_search(&db_root, nss_nis_passwd, NSS_DBOP_PASSWD_BYNAME,
446                     &arg);
447                 break;
448 #endif
449         default:
450                 return (NULL);
451         }
452
453         return (struct passwd *) NSS_XbyY_FINI(&arg);
454 }
455
456 static nss_XbyY_buf_t *spbuf;
457 static DEFINE_NSS_DB_ROOT(spdb_root);
458
459 #define GETSPBUF()      \
460         NSS_XbyY_ALLOC(&spbuf, sizeof (struct spwd), NSS_BUFLEN_SHADOW)
461
462 struct spwd *
463 getspnam_from(name, rep)
464         const char      *name;
465         int             rep;
466 {
467         nss_XbyY_buf_t  *b = GETSPBUF();
468         nss_XbyY_args_t arg;
469
470         if (b == 0)
471                 return (0);
472
473         NSS_XbyY_INIT(&arg, b->result, b->buffer, b->buflen, str2spwd);
474         arg.key.name = name;
475         switch (rep) {
476 #ifdef PAM_NISPLUS
477         case PAM_REP_NISPLUS:
478                 nss_search(&spdb_root, nss_nisplus_shadow,
479                     NSS_DBOP_SHADOW_BYNAME, &arg);
480                 break;
481 #endif
482 #ifdef PAM_NIS
483         case PAM_REP_NIS:
484                 nss_search(&spdb_root, nss_nis_shadow,
485                     NSS_DBOP_SHADOW_BYNAME, &arg);
486                 break;
487 #endif
488         default:
489                 return (NULL);
490         }
491         return (struct spwd *) NSS_XbyY_FINI(&arg);
492 }
493 #endif /* (PAM_NIS || PAM_NISPLUS) */
494
495 static void
496 pr_config(pamh)
497         pam_handle_t *pamh;
498 {
499         char            messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
500
501         sprintf(messages[0], PAM_MSG(pamh, 1,
502         "Supported configurations for passwd management are as follows:"));
503         sprintf(messages[1], PAM_MSG(pamh, 2, "    passwd: files"));
504         sprintf(messages[2], PAM_MSG(pamh, 3, "    passwd: files nis"));
505         sprintf(messages[3], PAM_MSG(pamh, 4, "    passwd: files nisplus"));
506         sprintf(messages[4], PAM_MSG(pamh, 5, "    passwd: compat"));
507         sprintf(messages[5], PAM_MSG(pamh, 6, "    passwd: compat AND"));
508         sprintf(messages[6], PAM_MSG(pamh, 7, "    passwd_compat: nisplus"));
509         sprintf(messages[7],
510         PAM_MSG(pamh, 8, "Please check your /etc/nsswitch.conf file"));
511
512         /* display the above 8 messages */
513         (void) __pam_display_msg(pamh, PAM_ERROR_MSG, 8, messages, NULL);
514 }
515
516 /*
517  * get name services (or repositories) of passwd.
518  * o_rep: the specified respository in command line. If no repository is
519  *      specified in the command line, o_rep is equal to PAM_REP_DEFAULT.
520  * return value: new repositories
521  *      1. In the case of PAM_REP_DEFAULT, new repositories are from nsswitch
522  *         file (as long as it represents a valid and supported configuration).
523  *      2. In the case of specified repository, it should be present as one
524  *         of the valid services (or repositories) in nsswitch file.
525  *         A warning is printed if this happens. Operation is continued.
526  */
527 int
528 get_ns(pamh, o_rep, debug, nowarn)
529         pam_handle_t *pamh;
530         int             o_rep;
531         int debug;
532         int nowarn;
533 {
534 #if (PAM_NIS || PAM_NISPLUS)
535         struct __nsw_switchconfig *conf = NULL;
536         struct __nsw_switchconfig *confcomp = NULL;
537         enum __nsw_parse_err pserr;
538         struct __nsw_lookup *lkp;
539         struct __nsw_lookup *lkp2;
540         int     rep = 0;
541         char messages[PAM_MAX_NUM_MSG][PAM_MAX_MSG_SIZE];
542
543         /* yppasswd/nispasswd doesn't care about nsswitch file */
544         if (IS_OPWCMD(o_rep))
545                 return (o_rep);
546
547         conf = __nsw_getconfig("passwd", &pserr);
548         if (conf == NULL) {
549                 if (!nowarn) {
550                         sprintf(messages[0], PAM_MSG(pamh, 9,
551                                 "Can't find name service for passwd"));
552                         __pam_display_msg(pamh, PAM_ERROR_MSG,
553                                 1, messages, NULL);
554                 }
555
556                 if (IS_NISPLUS(o_rep)) {
557                     if (!nowarn) {
558                         sprintf(messages[0], PAM_MSG(pamh, 10,
559                                 "You may not use nisplus repository"));
560                         __pam_display_msg(pamh, PAM_ERROR_MSG,
561                                 1, messages, NULL);
562                     }
563                     return (-1);
564                 } else if (o_rep != PAM_REP_DEFAULT) {
565                         /*
566                          * The user specified a repository:
567                          * Allow the user to try to change the passwd
568                          * even though the specified repository is
569                          * not listed in nsswitch.conf
570                          */
571                         return (o_rep);
572                 } else {
573                         /*
574                          * The user did not specify a repository:
575                          * Allow the user to try to change the passwd
576                          * in the default repositories (files and nis)
577                          * even though we can not find the name service
578                          * switch entry.
579                          */
580                         rep = PAM_REP_FILES | PAM_REP_NIS;
581                         return (rep);   /* default */
582                 }
583         }
584
585         if (debug)
586                 syslog(LOG_DEBUG, "number of services is %d",
587                         conf->num_lookups);
588         lkp = conf->lookups;
589
590         /*
591          * XXX: Currently we do now support more than 2 services
592          */
593         if (conf->num_lookups > 2) {
594                 pr_config(pamh);
595                 return (-1);
596         } else if (conf->num_lookups == 1) {
597                 /* files or compat */
598                 if (strcmp(lkp->service_name, "files") == 0) {
599                         rep |= PAM_REP_FILES;
600                         if (o_rep == PAM_REP_NIS || o_rep == PAM_REP_NISPLUS) {
601                             if (!nowarn) {
602                                 sprintf(messages[0],
603                                     PAM_MSG(pamh, 11,
604         "Your specified repository is not defined in the nsswitch file!"));
605                                 __pam_display_msg(pamh, PAM_ERROR_MSG,
606                                         1, messages, NULL);
607                             }
608                             return (o_rep);
609                         }
610                         return (rep);
611                 } else if (strcmp(lkp->service_name, "compat") == 0) {
612                         /* get passwd_compat */
613                         confcomp = __nsw_getconfig("passwd_compat", &pserr);
614                         if (confcomp == NULL) {
615                                 rep = PAM_REP_FILES | PAM_REP_NIS;
616                                 if (o_rep == PAM_REP_NISPLUS) {
617                                     if (!nowarn) {
618                                         sprintf(messages[0],
619                                                 PAM_MSG(pamh, 11,
620         "Your specified repository is not defined in the nsswitch file!"));
621                                         __pam_display_msg(pamh, PAM_ERROR_MSG,
622                                                 1, messages, NULL);
623                                     }
624                                     return (o_rep);
625                                 } else if (o_rep != PAM_REP_DEFAULT)
626                                         return (o_rep);
627                                 else
628                                         return (rep);
629                         } else {
630                                 /* check the service: nisplus? */
631                                 if (strcmp(confcomp->lookups->service_name,
632                                     "nisplus") == 0) {
633                                         rep = PAM_REP_FILES | PAM_REP_NISPLUS;
634                                         if (o_rep == PAM_REP_NIS) {
635                                             if (!nowarn) {
636                                                 sprintf(messages[0],
637                                                 PAM_MSG(pamh, 11,
638         "Your specified repository is not defined in the nsswitch file!"));
639                                                 __pam_display_msg(pamh,
640                                                         PAM_ERROR_MSG,
641                                                         1, messages, NULL);
642                                             }
643                                             return (o_rep);
644                                         } else if (o_rep != PAM_REP_DEFAULT)
645                                                 return (o_rep);
646                                         else
647                                                 return (rep);
648                                 } else {
649                                         /* passwd_compat must be nisplus?? */
650                                         return (-1);
651                                 }
652                         }
653                 } else {
654                         pr_config(pamh);
655                         return (-1);
656                 }
657         } else  { /* two services */
658                 lkp = conf->lookups;
659                 lkp2 = lkp->next;
660                 if (strcmp(lkp->service_name, "files") == 0) {
661                         /* files nis, or files nisplus */
662                         rep |= PAM_REP_FILES;
663                         /* continue */
664                 } else {
665                         pr_config(pamh);
666                         return (-1);
667                 }
668                 if (strcmp(lkp2->service_name, "nis") == 0) {
669                         rep |= PAM_REP_NIS;
670                         if (o_rep == PAM_REP_NISPLUS) {
671                             if (!nowarn) {
672                                 sprintf(messages[0],
673                                     PAM_MSG(pamh, 11,
674         "Your specified repository is not defined in the nsswitch file!"));
675                                 __pam_display_msg(pamh, PAM_ERROR_MSG,
676                                         1, messages, NULL);
677                             }
678                             return (o_rep);
679                         } else if (o_rep != PAM_REP_DEFAULT)
680                                 return (o_rep);
681                         else
682                                 return (rep);
683                 } else if (strcmp(lkp2->service_name, "nisplus") == 0) {
684                         rep |= PAM_REP_NISPLUS;
685                         if (o_rep == PAM_REP_NIS) {
686                             if (!nowarn) {
687                                 sprintf(messages[0],
688                                     PAM_MSG(pamh, 11,
689         "Your specified repository is not defined in the nsswitch file!"));
690                                 __pam_display_msg(pamh, PAM_ERROR_MSG,
691                                         1, messages, NULL);
692                             }
693                             return (o_rep);
694                         } else if (o_rep != PAM_REP_DEFAULT)
695                                 return (o_rep);
696                         else
697                                 return (rep);
698                 } else {
699                         pr_config(pamh);
700                         return (-1);
701                 }
702         }
703 #else
704         return (PAM_REP_FILES);
705 #endif /* (PAM_NIS || PAM_NISPLUS) */
706 }