Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.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: src/lib/libpam/libpam/pam_std_option.c,v 1.1.1.1.6.4 2002/07/03 21:45:44 des Exp $
27  * $DragonFly: src/lib/libpam/libpam/Attic/pam_std_option.c,v 1.2 2003/06/17 04:26:50 dillon Exp $
28  */
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <syslog.h>
33
34 #include <security/pam_appl.h>
35 #include <security/pam_mod_misc.h>
36
37 /* Everyone has to have these options. It is not an error to
38  * specify them and then not use them.
39  */
40 struct opttab std_options[PAM_MAX_OPTIONS] = {
41         { "debug",              PAM_OPT_DEBUG },
42         { "no_warn",            PAM_OPT_NO_WARN },
43         { "echo_pass",          PAM_OPT_ECHO_PASS },
44         { "use_first_pass",     PAM_OPT_USE_FIRST_PASS },
45         { "try_first_pass",     PAM_OPT_TRY_FIRST_PASS },
46         { "use_mapped_pass",    PAM_OPT_USE_MAPPED_PASS },
47         { "try_mapped_pass",    PAM_OPT_TRY_MAPPED_PASS },
48         { "expose_account",     PAM_OPT_EXPOSE_ACCOUNT },
49         { NULL,                 0 }
50 };
51
52 /* Populate the options structure, syslogging all errors */
53 void
54 pam_std_option(struct options *options, struct opttab other_options[],
55     int argc, const char *argv[])
56 {
57         struct opttab *oo;
58         int i, j, std, extra, arglen, found;
59
60         std = 1;
61         extra = 1;
62         oo = other_options;
63         for (i = 0; i < PAM_MAX_OPTIONS; i++) {
64                 if (std && std_options[i].name == NULL)
65                         std = 0;
66                 else if (extra && (oo == NULL || oo->name == NULL))
67                         extra = 0;
68
69                 if (std)
70                         options->opt[i].name = std_options[i].name;
71                 else if (extra) {
72                         if (oo->value != i)
73                                 syslog(LOG_DEBUG, "Extra option fault: %d %d",
74                                     oo->value, i);
75                         options->opt[i].name = oo->name;
76                         oo++;
77                 }
78                 else
79                         options->opt[i].name = NULL;
80
81                 options->opt[i].bool = 0;
82                 options->opt[i].arg = NULL;
83         }
84
85         for (j = 0; j < argc; j++) {
86 #ifdef DEBUG
87                 syslog(LOG_DEBUG, "Doing arg %s", argv[j]);
88 #endif
89                 found = 0;
90                 for (i = 0; i < PAM_MAX_OPTIONS; i++) {
91                         if (options->opt[i].name == NULL)
92                                 break;
93                         arglen = strlen(options->opt[i].name);
94                         if (strcmp(argv[j], options->opt[i].name) == 0) {
95                                 options->opt[i].bool = 1;
96                                 found = 1;
97                                 break;
98                         }
99                         else if (strncmp(argv[j], options->opt[i].name, arglen)
100                             == 0 && argv[j][arglen] == '=')  {
101                                 options->opt[i].bool = 1;
102                                 options->opt[i].arg
103                                     = strdup(&argv[j][arglen + 1]);
104                                 found = 1;
105                                 break;
106                         }
107                 }
108                 if (!found)
109                         syslog(LOG_WARNING, "PAM option: %s invalid", argv[j]);
110         }
111 }
112
113 /* Test if option is set in options */
114 int
115 pam_test_option(struct options *options, enum opt option, char **arg)
116 {
117         if (arg != NULL)
118                 *arg = options->opt[option].arg;
119         return options->opt[option].bool;
120 }
121
122 /* Set option in options, errors to syslog */
123 void
124 pam_set_option(struct options *options, enum opt option)
125 {
126         if (option < PAM_OPT_STD_MAX)
127                 options->opt[option].bool = 1;
128 #ifdef DEBUG
129         else
130                 syslog(LOG_DEBUG, "PAM options: attempt to set option %d",
131                     option);
132 #endif
133 }
134
135 /* Clear option in options, errors to syslog */
136 void
137 pam_clear_option(struct options *options, enum opt option)
138 {
139         if (option < PAM_OPT_STD_MAX)
140                 options->opt[option].bool = 0;
141 #ifdef DEBUG
142         else
143                 syslog(LOG_DEBUG, "PAM options: attempt to clear option %d",
144                     option);
145 #endif
146 }
147
148 #ifdef DEBUG1
149 enum { PAM_OPT_FOO=PAM_OPT_STD_MAX, PAM_OPT_BAR, PAM_OPT_BAZ, PAM_OPT_QUX };
150
151 struct opttab other_options[] = {
152         { "foo", PAM_OPT_FOO },
153         { "bar", PAM_OPT_BAR },
154         { "baz", PAM_OPT_BAZ },
155         { "qux", PAM_OPT_QUX },
156         { NULL, 0 }
157 };
158
159 int
160 main(int argc, const char *argv[])
161 {
162         struct options options;
163         int i, opt;
164         char *arg;
165
166         pam_std_option(&options, other_options, argc, argv);
167         for (i = 0; i < PAM_MAX_OPTIONS; i++) {
168                 opt = pam_test_option(&options, i, &arg);
169                 if (opt) {
170                         if (arg == NULL)
171                                 printf("%d []\n", i);
172                         else
173                                 printf("%d [%s]\n", i, arg);
174                 }
175         }
176         return 0;
177 }
178 #endif