diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-08-12 19:20:04 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-08-12 19:20:04 +0300 |
commit | 6bba235d667f25a9ae6bcd1c560b0ae28ea16505 (patch) | |
tree | 0d9e26952d7ae381f7dd78e6954fdda366a9eed7 /pam_innetgr | |
parent | 23b718d2a385bb07bcbd4584a694e9e75050098b (diff) | |
download | pam-modules-6bba235d667f25a9ae6bcd1c560b0ae28ea16505.tar.gz pam-modules-6bba235d667f25a9ae6bcd1c560b0ae28ea16505.tar.bz2 |
New module pam_innetgr.
* Makefile.am: Add new module.
* NEWS: Upgrade
* configure.ac: Add configuration for pam_innetgr
* pam_innetgr/Makefile.am: New file.
* pam_innetgr/pam_innetgr.c: New file.
* doc/Makefile.am: Add pam_innetgr.8
* doc/pam-modules.texi: Document pam_innetgr.
* doc/pam_innetgr.8: New file.
* examples/ldappubkey: Bugfixes
(publickeyattribute setting): Accept a list of attributes
(publickeyfilter): New setting.
Diffstat (limited to 'pam_innetgr')
-rw-r--r-- | pam_innetgr/Makefile.am | 22 | ||||
-rw-r--r-- | pam_innetgr/pam_innetgr.c | 319 |
2 files changed, 341 insertions, 0 deletions
diff --git a/pam_innetgr/Makefile.am b/pam_innetgr/Makefile.am new file mode 100644 index 0000000..1e5c7f8 --- /dev/null +++ b/pam_innetgr/Makefile.am | |||
@@ -0,0 +1,22 @@ | |||
1 | # This file is part of pam-modules. | ||
2 | # Copyright (C) 2018 Sergey Poznyakoff | ||
3 | # | ||
4 | # This program is free software; you can redistribute it and/or modify | ||
5 | # it under the terms of the GNU General Public License as published by | ||
6 | # the Free Software Foundation; either version 3, or (at your option) | ||
7 | # 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 | include $(top_srcdir)/Make.rules | ||
18 | |||
19 | pamdir=@PAMDIR@ | ||
20 | pam_LTLIBRARIES = pam_innetgr.la | ||
21 | pam_innetgr_la_SOURCES = pam_innetgr.c | ||
22 | AM_CPPFLAGS += -DMODULE_NAME=\"pam_innetgr\" | ||
diff --git a/pam_innetgr/pam_innetgr.c b/pam_innetgr/pam_innetgr.c new file mode 100644 index 0000000..f1f5e5d --- /dev/null +++ b/pam_innetgr/pam_innetgr.c | |||
@@ -0,0 +1,319 @@ | |||
1 | /* This file is part of pam-modules. | ||
2 | Copyright (C) 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 | #ifdef HAVE__PAM_ACONF_H | ||
18 | #include <security/_pam_aconf.h> | ||
19 | #endif | ||
20 | #include <stdlib.h> | ||
21 | #include <netdb.h> | ||
22 | #include "graypam.h" | ||
23 | |||
24 | #ifndef LINUX_PAM | ||
25 | #include <security/pam_appl.h> | ||
26 | #endif | ||
27 | #include <security/pam_modules.h> | ||
28 | |||
29 | static long debug_level; | ||
30 | char const *host_name; | ||
31 | char const *domain_name; | ||
32 | char const *netgroup_name; | ||
33 | int use_getdomainname; | ||
34 | int use_resolve; | ||
35 | enum { | ||
36 | SENSE_ALLOW, | ||
37 | SENSE_DENY | ||
38 | }; | ||
39 | const char *sense_choice[] = { "allow", "deny", NULL }; | ||
40 | static int sense; | ||
41 | |||
42 | struct pam_opt pam_opt[] = { | ||
43 | { PAM_OPTSTR(debug), pam_opt_long, &debug_level }, | ||
44 | { PAM_OPTSTR(debug), pam_opt_const, &debug_level, { 1 } }, | ||
45 | { PAM_OPTSTR(audit), pam_opt_const, &debug_level, { 100 } }, | ||
46 | { PAM_OPTSTR(waitdebug), pam_opt_null, NULL, { 0 }, | ||
47 | gray_wait_debug_fun }, | ||
48 | { PAM_OPTSTR(netgroup), pam_opt_string, &netgroup_name }, | ||
49 | { PAM_OPTSTR(hostname), pam_opt_string, &host_name }, | ||
50 | { PAM_OPTSTR(domainname), pam_opt_string, &domain_name }, | ||
51 | { PAM_OPTSTR(getdomainname), pam_opt_bool, &use_getdomainname }, | ||
52 | { PAM_OPTSTR(resolve), pam_opt_bool, &use_resolve }, | ||
53 | { PAM_OPTSTR(sense), pam_opt_enum, &sense, { enumstr: sense_choice } }, | ||
54 | { NULL } | ||
55 | }; | ||
56 | |||
57 | #ifndef MAXHOSTNAMELEN | ||
58 | # define MAXHOSTNAMELEN 64 | ||
59 | #endif | ||
60 | #ifndef SIZE_T_MAX | ||
61 | # define SIZE_T_MAX ((size_t)-1) | ||
62 | #endif | ||
63 | |||
64 | int | ||
65 | xgetname (int (*getfn)(char *, size_t), char **storage) | ||
66 | { | ||
67 | char *buffer = NULL; | ||
68 | size_t size = 0; | ||
69 | char *p; | ||
70 | |||
71 | while (1) { | ||
72 | if (size == 0) { | ||
73 | size = MAXHOSTNAMELEN; | ||
74 | p = malloc(size); | ||
75 | } else if (SIZE_T_MAX / 3 * 2 <= size) { | ||
76 | p = NULL; | ||
77 | } else { | ||
78 | size += (size + 1) / 2; | ||
79 | p = realloc(buffer, size); | ||
80 | } | ||
81 | if (!p) { | ||
82 | free(buffer); | ||
83 | errno = ENOMEM; | ||
84 | return -1; | ||
85 | } | ||
86 | buffer = p; | ||
87 | buffer[size - 1] = 0; | ||
88 | if (getfn(buffer, size - 1) == 0) { | ||
89 | if (!buffer[size - 1]) | ||
90 | break; | ||
91 | } else if (errno != 0 | ||
92 | && errno != ENAMETOOLONG | ||
93 | && errno != EINVAL | ||
94 | && errno != ENOMEM) { | ||
95 | int rc = errno; | ||
96 | free(buffer); | ||
97 | errno = rc; | ||
98 | return -1; | ||
99 | } | ||
100 | } | ||
101 | *storage = buffer; | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | int | ||
107 | stripdomain(char *hostname, char const *domainname) | ||
108 | { | ||
109 | size_t hlen, dlen; | ||
110 | |||
111 | if (!domainname) | ||
112 | return -1; | ||
113 | hlen = strlen(hostname); | ||
114 | dlen = strlen(domainname); | ||
115 | if (hlen > dlen + 1 | ||
116 | && hostname[hlen - dlen - 1] == '.' | ||
117 | && strcasecmp(hostname + hlen - dlen, domainname) == 0) { | ||
118 | hostname[hlen - dlen - 1] = 0; | ||
119 | return 0; | ||
120 | } | ||
121 | return -1; | ||
122 | } | ||
123 | |||
124 | int | ||
125 | get_host_domain_names(char **host_name_ptr, char **domain_name_ptr) | ||
126 | { | ||
127 | char *hostname; | ||
128 | char *domainname = NULL; | ||
129 | |||
130 | if (xgetname(gethostname, &hostname)) | ||
131 | return -1; | ||
132 | #if HAVE_GETDOMAINNAME | ||
133 | if (use_getdomainname) { | ||
134 | if (xgetname(getdomainname, &domainname)) { | ||
135 | _pam_log(LOG_ERR, "getdomainname: %s", strerror(errno)); | ||
136 | } else if (strcmp (domainname, "(none)") == 0) { | ||
137 | free(domainname); | ||
138 | domainname = NULL; | ||
139 | } | ||
140 | } | ||
141 | #endif | ||
142 | if (domainname) { | ||
143 | stripdomain(hostname, domainname); | ||
144 | } else if (use_resolve) { | ||
145 | char *p = strchr(hostname, '.'); | ||
146 | if (!p) { | ||
147 | struct hostent *hp = gethostbyname(hostname); | ||
148 | if (hp) { | ||
149 | size_t len = strlen(hp->h_name); | ||
150 | p = realloc(hostname, len + 1); | ||
151 | if (!p) { | ||
152 | free(hostname); | ||
153 | errno = ENOMEM; | ||
154 | return -1; | ||
155 | } | ||
156 | hostname = p; | ||
157 | strcpy(hostname, hp->h_name); | ||
158 | p = strchr(hostname, '.'); | ||
159 | } | ||
160 | } | ||
161 | if (p) { | ||
162 | *p++ = 0; | ||
163 | domainname = strdup(p); | ||
164 | if (!domainname) { | ||
165 | int rc = errno; | ||
166 | _pam_log(LOG_ERR, "getdomainname: %s", | ||
167 | strerror(errno)); | ||
168 | free(hostname); | ||
169 | errno = rc; | ||
170 | return -1; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | |||
175 | *host_name_ptr = hostname; | ||
176 | *domain_name_ptr = domainname; | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int | ||
182 | check_netgroup0(pam_handle_t *pamh, int argc, const char **argv, | ||
183 | const char *func) | ||
184 | { | ||
185 | int rc; | ||
186 | char *host_name_buf = NULL; | ||
187 | char *domain_name_buf = NULL; | ||
188 | char const *user_name; | ||
189 | |||
190 | debug_level = 0; | ||
191 | host_name = NULL; | ||
192 | domain_name = NULL; | ||
193 | netgroup_name = NULL; | ||
194 | use_getdomainname = 1; | ||
195 | use_resolve = 1; | ||
196 | sense = SENSE_ALLOW; | ||