1 /* This file is part of pam-modules.
2    Copyright (C) 2008, 2010-2012, 2014-2015, 2018 Sergey Poznyakoff
3 
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU General Public License as published by the
6    Free Software Foundation; either version 3 of the License, or (at your
7    option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License along
15    with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16 
17 #ifndef _graypam_h_
18 #define _graypam_h_
19 
20 #if defined(HAVE_CONFIG_H)
21 # include <config.h>
22 #endif
23 #ifdef HAVE__PAM_ACONF_H
24 #include <security/_pam_aconf.h>
25 #endif
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <ctype.h>
33 #include <syslog.h>
34 #include <errno.h>
35 #include <regex.h>
36 #include <setjmp.h>
37 
38 #ifndef LINUX_PAM
39 #include <security/pam_appl.h>
40 #endif				/* LINUX_PAM */
41 #include <security/pam_modules.h>
42 
43 #ifndef PAM_CONV_AGAIN
44 # define PAM_CONV_AGAIN PAM_TRY_AGAIN
45 #endif
46 #ifndef PAM_AUTHTOK_RECOVER_ERR
47 # define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
48 #endif
49 #ifndef PAM_EXTERN
50 # define PAM_EXTERN
51 #endif
52 
53 #define XSTRDUP(s) ((s) ? strdup(s) : NULL)
54 
55 #define PAM_OVERWRITE(s)                              \
56   do {                                                \
57 	register char *p;                             \
58         if  ((p = s) != NULL)                         \
59 	    while (*p) *p++ = 0;                      \
60   } while (0)
61 
62 #define PAM_DROP_REPLY(reply, nrepl)                  \
63   do {                                                \
64 	int i;                                        \
65 	for (i=0; i<nrepl; i++) {                     \
66             PAM_OVERWRITE(reply[i].resp);             \
67             free(reply[i].resp);                      \
68 	}                                             \
69 	if (reply)                                    \
70 	    free(reply);                              \
71   } while (0)
72 
73 
74 #define MAKE_STR(pamh, str, var) \
75  gray_make_str(pamh,str,#var,&var)
76 
77 #define WAITDEBUG(arg) do {                               \
78   size_t line = __LINE__;                                 \
79   if ((arg)[0] == '=')                                    \
80      gray_wait_debug(atoi((arg)+1), __FILE__, line);      \
81   else                                                    \
82      gray_wait_debug(0, __FILE__, line);		  \
83 } while (0)
84 
85 extern jmp_buf gray_pam_jmp;
86 
87 #define gray_pam_init(retval)            \
88 	if (setjmp(gray_pam_jmp))        \
89 		return retval;           \
90 
91 void gray_raise(const char *fmt, ...);
92 
93 void *gray_malloc(size_t size);
94 void *gray_zalloc(size_t size);
95 void *gray_calloc(size_t count, size_t size);
96 void *gray_realloc(void *ptr, size_t size);
97 void *gray_2nrealloc(void *ptr, size_t *pcount, size_t elsiz);
98 char *gray_strdup(const char *str);
99 
100 void gray_pam_delete(char *x);
101 void gray_cleanup_string(pam_handle_t *pamh, void *x, int error_status);
102 void gray_cleanup_regex(pam_handle_t *pamh, void *x, int error_status);
103 void gray_make_str(pam_handle_t *pamh, const char *str, const char *name,
104 		   char **ret);
105 
106 
107 typedef struct gray_slist *gray_slist_t;
108 
109 gray_slist_t gray_slist_create();
110 void gray_slist_clear(gray_slist_t slist);
111 void gray_slist_free(gray_slist_t *slist);
112 void gray_slist_append(gray_slist_t slist, const char *str, size_t n);
113 void gray_slist_append_char(gray_slist_t slist, char c);
114 size_t gray_slist_size(gray_slist_t slist);
115 size_t gray_slist_coalesce(gray_slist_t slist);
116 void *gray_slist_head(gray_slist_t slist, size_t *psize);
117 void *gray_slist_finish(gray_slist_t slist);
118 void gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
119 				   int len, int base);
120 void gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp);
121 
122 
123 void gray_log_init(int dont_open, const char *tag, int f);
124 void gray_pam_vlog(int err, const char *format, va_list args);
125 void gray_pam_log(int err, const char *format, ...);
126 void gray_pam_debug(const char *format, ...);
127 void gray_wait_debug(size_t interval, const char *file, size_t line);
128 
129 #define _pam_vlog gray_pam_vlog
130 #define _pam_log gray_pam_log
131 #define _pam_debug gray_pam_debug
132 
133 
134 int gray_transform_name_to_slist (gray_slist_t slist, char *input, char **output);
135 void gray_set_transform_expr (const char *expr);
136 void gray_free_transform_expr (void);
137 
138 
139 int gray_converse(pam_handle_t *pamh, int nargs,
140 		  struct pam_message **message,
141 		  struct pam_response **response);
142 
143 /* Command line parsing */
144 #define CNTL_DEBUG        0x0001
145 #define CNTL_WAITDEBUG    0x0002
146 
147 #define DEBUG(m,c) if (debug_level>=(m)) _pam_debug c
148 
149 enum pam_opt_type {
150 	pam_opt_null,
151 	pam_opt_bool,
152 	pam_opt_bitmask,
153 	pam_opt_bitmask_rev,
154 	pam_opt_long,
155 	pam_opt_string,
156 	pam_opt_enum,
157 	pam_opt_const,
158 	pam_opt_rest,
159 };
160 
161 struct pam_opt {
162 	const char *name;
163 	size_t len;
164 	enum pam_opt_type type;
165 	void *data;
166 	union {
167 		long value;
168 		const char **enumstr;
169 	} v;
170 	int (*func) (struct pam_opt *, const char *);
171 };
172 
173 #define PAM_OPTSTR(s) #s, (sizeof(#s) - 1)
174 
175 int gray_parseopt(struct pam_opt *opt, int argc, const char **argv);
176 int gray_wait_debug_fun(struct pam_opt *opt, const char *value);
177 
178 
179 ssize_t gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize);
180 int gray_check_ldap_pass (const char *db_pass, const char *pass);
181 
182 
183 void gray_expand_argv(pam_handle_t *pamh, int argc, const char **argv,
184 		      gray_slist_t slist);
185 void gray_expand_string(pam_handle_t *pamh, const char *str,
186 			gray_slist_t slist);
187 void gray_escape_string(gray_slist_t slist, const char *str, size_t len);
188 
189 struct keyword {
190 	char *name;
191 	int len;
192 	int code;
193 };
194 #define DCL(n,c) { n, sizeof n - 1, c }
195 
196 struct keyword *gray_find_keyword(struct keyword *kwtab, const char *str,
197 				  size_t len);
198 
199 
200 int gray_trim_ws(char *str);
201 
202 /* configuration file support */
203 
204 struct gray_env {
205 	struct gray_env *next;
206 	char *name;
207 	char *value;
208 };
209 
210 char *gray_env_get(struct gray_env *env, const char *name);
211 int gray_env_get_bool(struct gray_env *env, const char *name, int dfl);
212 void gray_env_free(struct gray_env *env);
213 int gray_env_read(const char *file_name, struct gray_env **penv);
214 int gray_env_read_tr(const char *file_name, struct gray_env **penv, char **tr);
215 void gray_env_merge(struct gray_env **pa, struct gray_env **pb);
216 
217 int gray_boolean_true_p(const char *value);
218 
219 #endif
220