]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libpam/libpam/pam_std_option.c
This commit was generated by cvs2svn to compensate for changes in r80231,
[FreeBSD/FreeBSD.git] / lib / libpam / libpam / pam_std_option.c
1 /*-
2  * Copyright 1998 Juniper Networks, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $FreeBSD$
27  */
28
29 #include <security/pam_modules.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <syslog.h>
33 #include "pam_mod_misc.h"
34
35 /* Everyone has to have these options. It is not an error to
36  * specify them and then not use them.
37  */
38 struct opttab std_options[PAM_MAX_OPTIONS] = {
39         { "debug",              PAM_OPT_DEBUG },
40         { "no_warn",            PAM_OPT_NO_WARN },
41         { "echo_pass",          PAM_OPT_ECHO_PASS },
42         { "use_first_pass",     PAM_OPT_USE_FIRST_PASS },
43         { "try_first_pass",     PAM_OPT_TRY_FIRST_PASS },
44         { "use_mapped_pass",    PAM_OPT_USE_MAPPED_PASS },
45         { "expose_account",     PAM_OPT_EXPOSE_ACCOUNT },
46         { NULL,                 0 }
47 };
48
49 /* Populate the options structure, syslogging all errors */
50 void
51 pam_std_option(struct options *options, struct opttab other_options[],
52     int argc, const char **argv)
53 {
54         struct opttab *oo;
55         int i, j, arglen, found;
56
57         j = 0;
58         for (i = 0; i < PAM_MAX_OPTIONS; i++) {
59                 if (std_options[i].name == NULL) {
60                         j = i;
61                         break;
62                 }
63                 /* XXX Bad juju happens if loop exits with j == 0 */
64         }
65         if (other_options)
66                 for (oo = other_options; oo->name != NULL; oo++) {
67                         found = 0;
68                         for (i = 0; std_options[i].name; i++)
69                                 if (strcmp((char *)oo->name,
70                                     std_options[i].name) == 0)
71                                         found = 1;
72                         if (!found) {
73                                 std_options[j].name = oo->name;
74                                 std_options[j].value = oo->value;
75                                 j++;
76                         }
77                 }
78         for (i = 0; i < PAM_MAX_OPTIONS; i++) {
79                 options->opt[i].bool = 0;
80                 options->opt[i].arg = NULL;
81         }
82         if (j < PAM_MAX_OPTIONS) {
83                 std_options[j].name = NULL;
84                 std_options[j].value = 0;
85         }
86         for (j = 0; j < argc; j++) {
87 #ifdef DEBUG
88                 syslog(LOG_DEBUG, "Doing arg %s ", argv[j]);
89 #endif
90                 found = 0;
91                 for (i = 0; i < PAM_MAX_OPTIONS; i++) {
92                         if (std_options[i].name == NULL)
93                                 break;
94                         if (strcmp(argv[j], std_options[i].name) == 0) {
95                                 options->opt[std_options[i].value].bool = 1;
96                                 found = 1;
97                                 break;
98                         }
99                         else {
100                                 arglen = strlen(std_options[i].name);
101                                 if (strncmp(argv[j], std_options[i].name,
102                                             arglen) == 0
103                                     && argv[j][arglen] == '=')  {
104                                         options->opt[std_options[i].value].bool
105                                             = 1;
106                                         options->opt[std_options[i].value].arg =
107                                             strdup(&argv[j][arglen + 1]);
108                                         found = 1;
109                                         break;
110                                 }
111                         }
112                 }
113                 if (!found)
114                         syslog(LOG_WARNING, "PAM option: %s invalid", argv[j]);
115         }
116 }
117
118 /* Test if option is set in options */
119 int
120 pam_test_option(struct options *options, enum opt option, char **arg)
121 {
122         if (arg != NULL)
123                 *arg = options->opt[option].arg;
124         return options->opt[option].bool;
125 }
126
127 /* Set option in options, errors to syslog */
128 void
129 pam_set_option(struct options *options, enum opt option)
130 {
131         if (option < PAM_OPT_STD_MAX)
132                 options->opt[option].bool = 1;
133 #ifdef DEBUG
134         else
135                 syslog(LOG_DEBUG, "PAM options: attempt to set option %d",
136                     option);
137 #endif
138 }
139
140 /* Clear option in options, errors to syslog */
141 void
142 pam_clear_option(struct options *options, enum opt option)
143 {
144         if (option < PAM_OPT_STD_MAX)
145                 options->opt[option].bool = 0;
146 #ifdef DEBUG
147         else
148                 syslog(LOG_DEBUG, "PAM options: attempt to clear option %d",
149                     option);
150 #endif
151 }
152
153 #if DEBUG1
154 enum { PAM_OPT_FOO=PAM_OPT_STD_MAX, PAM_OPT_BAR, PAM_OPT_BAZ, PAM_OPT_QUX };
155
156 struct opttab other_options[] = {
157         { "foo", PAM_OPT_FOO },
158         { "bar", PAM_OPT_BAR },
159         { "baz", PAM_OPT_BAZ },
160         { "qux", PAM_OPT_QUX },
161         { NULL, 0 }
162 };
163
164 int
165 main(int argc, const char *argv[])
166 {
167         struct options options;
168         int i, opt;
169         char *arg;
170
171         pam_std_option(&options, other_options, argc, argv);
172         for (i = 0; i < PAM_MAX_OPTIONS; i++) {
173                 opt = pam_test_option(&options, i, &arg);
174                 if (opt) {
175                         if (arg == NULL)
176                                 printf("%d []\n", i);
177                         else
178                                 printf("%d [%s]\n", i, arg);
179                 }
180         }
181         return 0;
182 }
183 #endif