]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/openpam/bin/openpam_dump_policy/openpam_dump_policy.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / openpam / bin / openpam_dump_policy / openpam_dump_policy.c
1 /*-
2  * Copyright (c) 2011 Dag-Erling Smørgrav
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  * 3. The name of the author may not be used to endorse or promote
14  *    products derived from this software without specific prior written
15  *    permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $Id: openpam_dump_policy.c 648 2013-03-05 17:54:27Z des $
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <ctype.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41
42 #include <security/pam_appl.h>
43
44 #include "openpam_impl.h"
45 #include "openpam_asprintf.h"
46
47 static char *
48 openpam_chain_name(const char *service, pam_facility_t fclt)
49 {
50         const char *facility = pam_facility_name[fclt];
51         char *name;
52
53         if (asprintf(&name, "pam_%s_%s", service, facility) == -1)
54                 return (NULL);
55         return (name);
56 }
57
58 static char *
59 openpam_facility_index_name(pam_facility_t fclt)
60 {
61         const char *facility = pam_facility_name[fclt];
62         char *name, *p;
63
64         if (asprintf(&name, "PAM_%s", facility) == -1)
65                 return (NULL);
66         for (p = name + 4; *p; ++p)
67                 *p = toupper(*p);
68         return (name);
69 }
70
71 int
72 openpam_dump_chain(const char *name, pam_chain_t *chain)
73 {
74         char *modname, **opt, *p;
75         int i;
76
77         for (i = 0; chain != NULL; ++i, chain = chain->next) {
78                 /* declare the module's struct pam_module */
79                 modname = strrchr(chain->module->path, '/');
80                 modname = strdup(modname ? modname : chain->module->path);
81                 if (modname == NULL)
82                         return (PAM_BUF_ERR);
83                 for (p = modname; *p && *p != '.'; ++p)
84                         /* nothing */ ;
85                 *p = '\0';
86                 printf("extern struct pam_module %s_pam_module;\n", modname);
87                 /* module arguments */
88                 printf("static char *%s_%d_optv[] = {\n", name, i);
89                 for (opt = chain->optv; *opt; ++opt) {
90                         printf("\t\"");
91                         for (p = *opt; *p; ++p) {
92                                 if (isprint((unsigned char)*p) && *p != '"')
93                                         printf("%c", *p);
94                                 else
95                                         printf("\\x%02x", (unsigned char)*p);
96                         }
97                         printf("\",\n");
98                 }
99                 printf("\tNULL,\n");
100                 printf("};\n");
101                 /* next module in chain */
102                 if (chain->next != NULL)
103                         printf("static pam_chain_t %s_%d;\n", name, i + 1);
104                 /* chain entry */
105                 printf("static pam_chain_t %s_%d = {\n", name, i);
106                 printf("\t.module = &%s_pam_module,\n", modname);
107                 printf("\t.flag = 0x%08x,\n", chain->flag);
108                 printf("\t.optc = %d,\n", chain->optc);
109                 printf("\t.optv = %s_%d_optv,\n", name, i);
110                 if (chain->next)
111                         printf("\t.next = &%s_%d,\n", name, i + 1);
112                 else
113                         printf("\t.next = NULL,\n");
114                 printf("};\n");
115                 free(modname);
116         }
117         return (PAM_SUCCESS);
118 }
119
120 int
121 openpam_dump_policy(const char *service)
122 {
123         pam_handle_t *pamh;
124         char *name;
125         int fclt, ret;
126
127         if ((pamh = calloc(1, sizeof *pamh)) == NULL)
128                 return (PAM_BUF_ERR);
129         if ((ret = openpam_configure(pamh, service)) != PAM_SUCCESS)
130                 return (ret);
131         for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
132                 if (pamh->chains[fclt] != NULL) {
133                         if ((name = openpam_chain_name(service, fclt)) == NULL)
134                                 return (PAM_BUF_ERR);
135                         ret = openpam_dump_chain(name, pamh->chains[fclt]);
136                         free(name);
137                         if (ret != PAM_SUCCESS)
138                                 return (ret);
139                 }
140         }
141         printf("static pam_policy_t pam_%s_policy = {\n", service);
142         printf("\t.service = \"%s\",\n", service);
143         printf("\t.chains = {\n");
144         for (fclt = 0; fclt < PAM_NUM_FACILITIES; ++fclt) {
145                 if ((name = openpam_facility_index_name(fclt)) == NULL)
146                         return (PAM_BUF_ERR);
147                 printf("\t\t[%s] = ", name);
148                 free(name);
149                 if (pamh->chains[fclt] != NULL) {
150                         if ((name = openpam_chain_name(service, fclt)) == NULL)
151                                 return (PAM_BUF_ERR);
152                         printf("&%s_0,\n", name);
153                         free(name);
154                 } else {
155                         printf("NULL,\n");
156                 }
157         }
158         printf("\t},\n");
159         printf("};\n");
160         free(pamh);
161         return (PAM_SUCCESS);
162 }
163
164 static void
165 usage(void)
166 {
167
168         fprintf(stderr, "usage: openpam_dump_policy [-d] policy ...\n");
169         exit(1);
170 }
171
172 int
173 main(int argc, char *argv[])
174 {
175         int i, opt;
176
177         while ((opt = getopt(argc, argv, "d")) != -1)
178                 switch (opt) {
179                 case 'd':
180                         openpam_debug = 1;
181                         break;
182                 default:
183                         usage();
184                 }
185
186         argc -= optind;
187         argv += optind;
188
189         if (argc < 1)
190                 usage();
191
192         printf("#include <security/pam_appl.h>\n");
193         printf("#include \"openpam_impl.h\"\n");
194         for (i = 0; i < argc; ++i)
195                 openpam_dump_policy(argv[i]);
196         printf("pam_policy_t *pam_embedded_policies[] = {\n");
197         for (i = 0; i < argc; ++i)
198                 printf("\t&pam_%s_policy,\n", argv[i]);
199         printf("\tNULL,\n");
200         printf("};\n");
201         exit(0);
202 }