1 /* This file is part of pam-modules.
2 Copyright (C) 2009-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 #include "pamck.h"
18 char *program_name;
19
20 void
usage()21 usage()
22 {
23 printf("usage: %s [-hv] [-s service] [-g group] user [password]\n",
24 program_name);
25 }
26
27 void
help()28 help()
29 {
30 printf("usage: %s [-hv] [-s service] [-g group] user [password]\n",
31 program_name);
32 printf("\nReport bugs to <%s>.\n", PACKAGE_BUGREPORT);
33 printf("%s home page: <http://www.gnu.org.ua/software/%s/>.\n",
34 PACKAGE_NAME, PACKAGE);
35 }
36
37 void
version()38 version()
39 {
40 printf("%s (%s) %s\n", program_name, PACKAGE, PACKAGE_VERSION);
41 fputs ("\
42 Copyright (C) 2009-2015 Sergey Poznyakoff\n\
43 \n\
44 License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\
45 This is free software: you are free to change and redistribute it.\n\
46 There is NO WARRANTY, to the extent permitted by law.\n\
47 \n\
48 ", stdout);
49 }
50
51 void
error(int code,const char * fmt,...)52 error(int code, const char *fmt, ...)
53 {
54 va_list ap;
55 va_start(ap, fmt);
56 fprintf(stderr, "%s: ", program_name);
57 vfprintf(stderr, fmt, ap);
58 fputc('\n', stderr);
59 va_end(ap);
60 if (code)
61 exit(code);
62 }
63
64
65 struct grouptab {
66 char *name;
67 char *funcname;
68 int (*pam_fn) (pam_handle_t *pamh, int flags);
69 } grouptab[] = {
70 { "auth", "pam_authenticate", pam_authenticate },
71 { "acct", "pam_acct_mgmt", pam_acct_mgmt },
72 { "open", "pam_open_session", pam_open_session },
73 { "close", "pam_close_session", pam_close_session },
74 { "pass", "pam_chauthtok", pam_chauthtok },
75 { NULL }
76 };
77
78 struct grouptab *
find_group(char * name)79 find_group(char *name)
80 {
81 struct grouptab *p;
82 for (p = grouptab; p->name; p++)
83 if (strcmp(p->name, name) == 0)
84 return p;
85 return NULL;
86 }
87
88 void
groupprint()89 groupprint()
90 {
91 struct grouptab *p;
92 for (p = grouptab; p->name; p++)
93 printf("%s\n", p->name);
94 }
95
96 char *service = "check";
97 struct grouptab *group;
98 char *user;
99 char *pass;
100
101 static struct pam_conv conv = {
102 pamck_conv,
103 NULL
104 };
105
106 void
check_default(pam_handle_t * pamh)107 check_default(pam_handle_t *pamh)
108 {
109 int rc;
110
111 rc = pam_authenticate(pamh, 0);
112 if (rc)
113 error(2, "%s failed: %s",
114 "pam_authenticate", pam_strerror (pamh, rc));
115 rc = pam_acct_mgmt(pamh, 0);
116 if (rc)
117 error(2, "%s failed: %s",
118 "pam_acct_mgmt", pam_strerror (pamh, rc));
119 printf("OK\n");
120 }
121
122 void
check_group(pam_handle_t * pamh,struct grouptab * grp)123 check_group(pam_handle_t *pamh, struct grouptab *grp)
124 {
125 int rc = grp->pam_fn(pamh, 0);
126 if (rc)
127 error(2, "%s failed: %s", grp->funcname,
128 pam_strerror (pamh, rc));
129 }
130
131 int
main(int argc,char ** argv)132 main (int argc, char **argv)
133 {
134 int c;
135 int rc;
136 pam_handle_t *pamh = NULL;
137
138 program_name = argv[0];
139 /* A bit of sugar to fake common GNU-style long options */
140 if (argc == 2) {
141 if (strcmp (argv[1], "--help") == 0) {
142 help();
143 exit(0);
144 } if (strcmp (argv[1], "--usage") == 0) {
145 usage();
146 exit(0);
147 } else if (strcmp (argv[1], "--version") == 0) {
148 version();
149 exit(0);
150 }
151 }
152 /* Normal option processing */
153 while ((c = getopt (argc, argv, "hg:s:v")) != EOF) {
154 switch (c) {
155 case 'h':
156 help();
157 exit(0);
158
159 case 'g':
160 if (strcmp(optarg, "help") == 0) {
161 groupprint();
162 exit(0);
163 }
164 group = find_group(optarg);
165 if (!group)
166 error(1,
167 "no such management group, try `%s -g help' for the list",
168 program_name);
169
170 break;
171
172 case 's':
173 service = optarg;
174 break;
175
176 case 'v':
177 version();
178 exit(0);
179
180 default:
181 exit(1);
182 }
183 }
184
185 argc -= optind;
186 argv += optind;
187
188 switch (argc) {
189 case 2:
190 pass = argv[1];
191 case 1:
192 user = argv[0];
193 break;
194 default:
195 usage();
196 exit(1);
197 }
198
199 rc = pam_start(service, user, &conv, &pamh);
200 if (rc)
201 error(2, "pam_start failed");
202
203 if (group)
204 check_group(pamh, group);
205 else
206 check_default(pamh);
207
208 if (pam_end(pamh, rc) != PAM_SUCCESS) {
209 pamh = NULL;
210 error(2, "failed to release authenticator");
211 }
212
213 exit (0);
214 }
215