summaryrefslogtreecommitdiffabout
path: root/lib/graypam.h
blob: 69c49092631de60e181319c454ff2e34bebff417 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/* This file is part of pam-modules.
   Copyright (C) 2008, 2010-2012, 2014-2015, 2018 Sergey Poznyakoff
 
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 3 of the License, or (at your
   option) any later version.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License along
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef _graypam_h_
#define _graypam_h_

#if defined(HAVE_CONFIG_H)
# include <config.h>
#endif
#ifdef HAVE__PAM_ACONF_H
#include <security/_pam_aconf.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <syslog.h>
#include <errno.h>
#include <regex.h>
#include <setjmp.h>

#ifndef LINUX_PAM
#include <security/pam_appl.h>
#endif				/* LINUX_PAM */
#include <security/pam_modules.h>

#ifndef PAM_CONV_AGAIN
# define PAM_CONV_AGAIN PAM_TRY_AGAIN
#endif
#ifndef PAM_AUTHTOK_RECOVER_ERR
# define PAM_AUTHTOK_RECOVER_ERR PAM_AUTHTOK_RECOVERY_ERR
#endif
#ifndef PAM_EXTERN
# define PAM_EXTERN
#endif

#define XSTRDUP(s) ((s) ? strdup(s) : NULL)

#define PAM_OVERWRITE(s)                              \
  do {                                                \
	register char *p;                             \
        if  ((p = s) != NULL)                         \
	    while (*p) *p++ = 0;                      \
  } while (0) 

#define PAM_DROP_REPLY(reply, nrepl)                  \
  do {                                                \
	int i;                                        \
	for (i=0; i<nrepl; i++) {                     \
            PAM_OVERWRITE(reply[i].resp);             \
            free(reply[i].resp);                      \
	}                                             \
	if (reply)                                    \
	    free(reply);                              \
  } while (0)


#define MAKE_STR(pamh, str, var) \
 gray_make_str(pamh,str,#var,&var)

#define WAITDEBUG(arg) do {                               \
  size_t line = __LINE__;                                 \
  if ((arg)[0] == '=')                                    \
     gray_wait_debug(atoi((arg)+1), __FILE__, line);      \
  else                                                    \
     gray_wait_debug(0, __FILE__, line);		  \
} while (0)

extern jmp_buf gray_pam_jmp;

void *gray_2nrealloc(void *ptr, size_t *pcount, size_t elsiz);

void gray_pam_delete(char *x);
void gray_cleanup_string(pam_handle_t *pamh, void *x, int error_status);
void gray_cleanup_regex(pam_handle_t *pamh, void *x, int error_status);
void gray_make_str(pam_handle_t *pamh, const char *str, const char *name,
		   char **ret);

typedef struct gray_slist *gray_slist_t;

gray_slist_t gray_slist_create(void);
int gray_slist_err(gray_slist_t slist);
void gray_slist_clrerr(gray_slist_t slist);
void gray_slist_clear(gray_slist_t slist);
void gray_slist_free(gray_slist_t *slist);
ssize_t gray_slist_append(gray_slist_t slist, const char *str, size_t n);
ssize_t gray_slist_append_char(gray_slist_t slist, char c);
size_t gray_slist_size(gray_slist_t slist);
ssize_t gray_slist_coalesce(gray_slist_t slist);
void *gray_slist_head(gray_slist_t slist, size_t *psize);
void *gray_slist_finish(gray_slist_t slist);
int gray_slist_grow_backslash_num(gray_slist_t slist, char *text, char **pend,
				  int len, int base);
int gray_slist_grow_backslash(gray_slist_t slist, char *text, char **endp);


void gray_log_init(int dont_open, const char *tag, int f);
void gray_pam_vlog(int err, const char *format, va_list args);
void gray_pam_log(int err, const char *format, ...);
void gray_pam_debug(const char *format, ...);
void gray_wait_debug(size_t interval, const char *file, size_t line);

#define _pam_vlog gray_pam_vlog
#define _pam_log gray_pam_log
#define _pam_debug gray_pam_debug

static inline int
errno_to_pam(int ec)
{
	switch (ec) {
	case EILSEQ:
		_pam_log(LOG_ERR, "malformed password hash");
		return PAM_SERVICE_ERR;

	case ENOMEM:
		_pam_log(LOG_ERR, "%s", strerror(errno));
		return PAM_BUF_ERR;

	default:
		break;
	}
	_pam_log(LOG_ERR, "%s", strerror(errno));
	return PAM_SERVICE_ERR;
}

int gray_transform_name_to_slist (gray_slist_t slist, char *input, char **output);
int gray_set_transform_expr (const char *expr);
void gray_free_transform_expr (void);


int gray_converse(pam_handle_t *pamh, int nargs,
		  struct pam_message **message,
		  struct pam_response **response);

/* Command line parsing */
#define CNTL_DEBUG        0x0001
#define CNTL_WAITDEBUG    0x0002

#define DEBUG(m,c) if (debug_level>=(m)) _pam_debug c

enum pam_opt_type {
	pam_opt_null,
	pam_opt_bool,
	pam_opt_bitmask,
	pam_opt_bitmask_rev,
	pam_opt_long,
	pam_opt_string,
	pam_opt_enum,
	pam_opt_const,
	pam_opt_rest,
};

struct pam_opt {
	const char *name;
	size_t len;
	enum pam_opt_type type;
	void *data;
	union {
		long value;
		const char **enumstr;
	} v;
	int (*func) (struct pam_opt *, const char *);
};

#define PAM_OPTSTR(s) #s, (sizeof(#s) - 1)

int gray_parseopt(struct pam_opt *opt, int argc, const char **argv);
int gray_wait_debug_fun(struct pam_opt *opt, const char *value);


ssize_t gray_base64_decode(gray_slist_t slist, const char *iptr, size_t isize);
int gray_check_ldap_pass (const char *db_pass, const char *pass);


void gray_expand_argv(pam_handle_t *pamh, int argc, const char **argv,
		      gray_slist_t slist);
void gray_expand_string(pam_handle_t *pamh, const char *str,
			gray_slist_t slist);
void gray_escape_string(gray_slist_t slist, const char *str, size_t len);

struct keyword {
	char *name;
	int len;
	int code;
};
#define DCL(n,c) { n, sizeof n - 1, c }

struct keyword *gray_find_keyword(struct keyword *kwtab, const char *str,
				  size_t len);


int gray_trim_ws(char *str);

/* configuration file support */

struct gray_env {
	struct gray_env *next;
	char *name;
	char *value;
};

char *gray_env_get(struct gray_env *env, const char *name);
int gray_env_get_bool(struct gray_env *env, const char *name, int dfl);
void gray_env_free(struct gray_env *env);
int gray_env_read(const char *file_name, struct gray_env **penv);
int gray_env_read_tr(const char *file_name, struct gray_env **penv, char **tr);
void gray_env_merge(struct gray_env **pa, struct gray_env **pb);

int gray_boolean_true_p(const char *value);

#endif

Return to:

Send suggestions and report system problems to the System administrator.