]>
Commit | Line | Data |
---|---|---|
1 | /* User authentication for vtysh. | |
2 | * Copyright (C) 2000 Kunihiro Ishiguro | |
3 | * | |
4 | * This file is part of GNU Zebra. | |
5 | * | |
6 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License as published by the | |
8 | * Free Software Foundation; either version 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * GNU Zebra is distributed in the hope that it will be useful, but | |
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with GNU Zebra; see the file COPYING. If not, write to the Free | |
18 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
19 | * 02111-1307, USA. | |
20 | */ | |
21 | ||
22 | #include <zebra.h> | |
23 | #include <lib/version.h> | |
24 | ||
25 | #include <pwd.h> | |
26 | ||
27 | #ifdef USE_PAM | |
28 | #include <security/pam_appl.h> | |
29 | #ifdef HAVE_PAM_MISC_H | |
30 | #include <security/pam_misc.h> | |
31 | #endif | |
32 | #ifdef HAVE_OPENPAM_H | |
33 | #include <security/openpam.h> | |
34 | #endif | |
35 | #endif /* USE_PAM */ | |
36 | ||
37 | #include "memory.h" | |
38 | #include "linklist.h" | |
39 | #include "command.h" | |
40 | #include "vtysh/vtysh_user.h" | |
41 | ||
42 | /* | |
43 | * Compiler is warning about prototypes not being declared. | |
44 | * The DEFUNSH and DEFUN macro's are messing with the | |
45 | * compiler I believe. This is just to make it happy. | |
46 | */ | |
47 | #ifdef USE_PAM | |
48 | static int vtysh_pam(const char *); | |
49 | #endif | |
50 | int vtysh_auth(void); | |
51 | void vtysh_user_init(void); | |
52 | ||
53 | extern struct list *config_top; | |
54 | extern void config_add_line(struct list *config, const char *line); | |
55 | ||
56 | #ifdef USE_PAM | |
57 | static struct pam_conv conv = | |
58 | { | |
59 | PAM_CONV_FUNC, | |
60 | NULL | |
61 | }; | |
62 | ||
63 | static int | |
64 | vtysh_pam (const char *user) | |
65 | { | |
66 | int ret; | |
67 | pam_handle_t *pamh = NULL; | |
68 | ||
69 | /* Start PAM. */ | |
70 | ret = pam_start(QUAGGA_PROGNAME, user, &conv, &pamh); | |
71 | /* printf ("ret %d\n", ret); */ | |
72 | ||
73 | /* Is user really user? */ | |
74 | if (ret == PAM_SUCCESS) | |
75 | ret = pam_authenticate (pamh, 0); | |
76 | /* printf ("ret %d\n", ret); */ | |
77 | ||
78 | #if 0 | |
79 | /* Permitted access? */ | |
80 | if (ret == PAM_SUCCESS) | |
81 | ret = pam_acct_mgmt (pamh, 0); | |
82 | printf ("ret %d\n", ret); | |
83 | ||
84 | if (ret == PAM_AUTHINFO_UNAVAIL) | |
85 | ret = PAM_SUCCESS; | |
86 | #endif /* 0 */ | |
87 | ||
88 | /* This is where we have been authorized or not. */ | |
89 | #ifdef DEBUG | |
90 | if (ret == PAM_SUCCESS) | |
91 | printf("Authenticated\n"); | |
92 | else | |
93 | printf("Not Authenticated\n"); | |
94 | #endif /* DEBUG */ | |
95 | ||
96 | /* close Linux-PAM */ | |
97 | if (pam_end (pamh, ret) != PAM_SUCCESS) | |
98 | { | |
99 | pamh = NULL; | |
100 | fprintf(stderr, "vtysh_pam: failed to release authenticator\n"); | |
101 | exit(1); | |
102 | } | |
103 | ||
104 | return ret == PAM_SUCCESS ? 0 : 1; | |
105 | } | |
106 | #endif /* USE_PAM */ | |
107 | ||
108 | struct vtysh_user | |
109 | { | |
110 | char *name; | |
111 | u_char nopassword; | |
112 | }; | |
113 | ||
114 | struct list *userlist; | |
115 | ||
116 | static struct vtysh_user * | |
117 | user_new (void) | |
118 | { | |
119 | return XCALLOC (MTYPE_TMP, sizeof (struct vtysh_user)); | |
120 | } | |
121 | ||
122 | static struct vtysh_user * | |
123 | user_lookup (const char *name) | |
124 | { | |
125 | struct listnode *node, *nnode; | |
126 | struct vtysh_user *user; | |
127 | ||
128 | for (ALL_LIST_ELEMENTS (userlist, node, nnode, user)) | |
129 | { | |
130 | if (strcmp (user->name, name) == 0) | |
131 | return user; | |
132 | } | |
133 | return NULL; | |
134 | } | |
135 | ||
136 | void | |
137 | user_config_write () | |
138 | { | |
139 | struct listnode *node, *nnode; | |
140 | struct vtysh_user *user; | |
141 | char line[128]; | |
142 | ||
143 | for (ALL_LIST_ELEMENTS (userlist, node, nnode, user)) | |
144 | { | |
145 | if (user->nopassword) | |
146 | { | |
147 | sprintf(line, "username %s nopassword", user->name); | |
148 | config_add_line (config_top, line); | |
149 | } | |
150 | } | |
151 | } | |
152 | ||
153 | static struct vtysh_user * | |
154 | user_get (const char *name) | |
155 | { | |
156 | struct vtysh_user *user; | |
157 | user = user_lookup (name); | |
158 | if (user) | |
159 | return user; | |
160 | ||
161 | user = user_new (); | |
162 | user->name = strdup (name); | |
163 | listnode_add (userlist, user); | |
164 | ||
165 | return user; | |
166 | } | |
167 | ||
168 | DEFUN (banner_motd_file, | |
169 | banner_motd_file_cmd, | |
170 | "banner motd file FILE", | |
171 | "Set banner\n" | |
172 | "Banner for motd\n" | |
173 | "Banner from a file\n" | |
174 | "Filename\n") | |
175 | { | |
176 | int idx_file = 3; | |
177 | return cmd_banner_motd_file (argv[idx_file]->arg); | |
178 | } | |
179 | ||
180 | DEFUN (username_nopassword, | |
181 | username_nopassword_cmd, | |
182 | "username WORD nopassword", | |
183 | "\n" | |
184 | "\n" | |
185 | "\n") | |
186 | { | |
187 | int idx_word = 1; | |
188 | struct vtysh_user *user; | |
189 | user = user_get (argv[idx_word]->arg); | |
190 | user->nopassword = 1; | |
191 | return CMD_SUCCESS; | |
192 | } | |
193 | ||
194 | int | |
195 | vtysh_auth (void) | |
196 | { | |
197 | struct vtysh_user *user; | |
198 | struct passwd *passwd; | |
199 | ||
200 | if ((passwd = getpwuid (geteuid ())) == NULL) | |
201 | { | |
202 | fprintf (stderr, "could not lookup user ID %d\n", (int) geteuid()); | |
203 | exit (1); | |
204 | } | |
205 | ||
206 | user = user_lookup (passwd->pw_name); | |
207 | if (user && user->nopassword) | |
208 | /* Pass through */; | |
209 | else | |
210 | { | |
211 | #ifdef USE_PAM | |
212 | if (vtysh_pam (passwd->pw_name)) | |
213 | exit (0); | |
214 | #endif /* USE_PAM */ | |
215 | } | |
216 | return 0; | |
217 | } | |
218 | ||
219 | char * | |
220 | vtysh_get_home (void) | |
221 | { | |
222 | struct passwd *passwd; | |
223 | ||
224 | passwd = getpwuid (getuid ()); | |
225 | ||
226 | return passwd ? passwd->pw_dir : NULL; | |
227 | } | |
228 | ||
229 | void | |
230 | vtysh_user_init (void) | |
231 | { | |
232 | userlist = list_new (); | |
233 | install_element (CONFIG_NODE, &username_nopassword_cmd); | |
234 | install_element (CONFIG_NODE, &banner_motd_file_cmd); | |
235 | } |