aboutsummaryrefslogtreecommitdiff
path: root/pam_innetgr
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-08-12 19:20:04 +0300
committerSergey Poznyakoff <gray@gnu.org>2018-08-12 19:20:04 +0300
commit6bba235d667f25a9ae6bcd1c560b0ae28ea16505 (patch)
tree0d9e26952d7ae381f7dd78e6954fdda366a9eed7 /pam_innetgr
parent23b718d2a385bb07bcbd4584a694e9e75050098b (diff)
downloadpam-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.am22
-rw-r--r--pam_innetgr/pam_innetgr.c319
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
17include $(top_srcdir)/Make.rules
18
19pamdir=@PAMDIR@
20pam_LTLIBRARIES = pam_innetgr.la
21pam_innetgr_la_SOURCES = pam_innetgr.c
22AM_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
29static long debug_level;
30char const *host_name;
31char const *domain_name;
32char const *netgroup_name;
33int use_getdomainname;
34int use_resolve;
35enum {
36 SENSE_ALLOW,
37 SENSE_DENY
38};
39const char *sense_choice[] = { "allow", "deny", NULL };
40static int sense;
41
42struct 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
64int
65xgetname (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
106int
107stripdomain(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
124int
125get_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
181static int
182check_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;