]>
Commit | Line | Data |
---|---|---|
718e3744 | 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 | * | |
896014f4 DL |
16 | * You should have received a copy of the GNU General Public License along |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
718e3744 | 19 | */ |
20 | ||
21 | #include <zebra.h> | |
bb6065a5 | 22 | #include <lib/version.h> |
718e3744 | 23 | |
24 | #include <pwd.h> | |
25 | ||
26 | #ifdef USE_PAM | |
27 | #include <security/pam_appl.h> | |
24cd435b | 28 | #ifdef HAVE_PAM_MISC_H |
718e3744 | 29 | #include <security/pam_misc.h> |
24cd435b | 30 | #endif |
31 | #ifdef HAVE_OPENPAM_H | |
32 | #include <security/openpam.h> | |
33 | #endif | |
718e3744 | 34 | #endif /* USE_PAM */ |
35 | ||
36 | #include "memory.h" | |
37 | #include "linklist.h" | |
38 | #include "command.h" | |
88177fe3 | 39 | #include "vtysh/vtysh_user.h" |
718e3744 | 40 | |
c0e8c16f DS |
41 | /* |
42 | * Compiler is warning about prototypes not being declared. | |
43 | * The DEFUNSH and DEFUN macro's are messing with the | |
44 | * compiler I believe. This is just to make it happy. | |
45 | */ | |
21c830a4 | 46 | #ifdef USE_PAM |
ec4ab9f3 | 47 | static int vtysh_pam(const char *); |
21c830a4 | 48 | #endif |
c0e8c16f DS |
49 | int vtysh_auth(void); |
50 | void vtysh_user_init(void); | |
51 | ||
e4421165 DS |
52 | extern struct list *config_top; |
53 | extern void config_add_line(struct list *config, const char *line); | |
54 | ||
718e3744 | 55 | #ifdef USE_PAM |
56 | static struct pam_conv conv = | |
57 | { | |
24cd435b | 58 | PAM_CONV_FUNC, |
718e3744 | 59 | NULL |
60 | }; | |
61 | ||
4e6a0534 | 62 | static int |
5862ff52 | 63 | vtysh_pam (const char *user) |
718e3744 | 64 | { |
65 | int ret; | |
66 | pam_handle_t *pamh = NULL; | |
67 | ||
68 | /* Start PAM. */ | |
b2f36157 | 69 | ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh); |
718e3744 | 70 | /* printf ("ret %d\n", ret); */ |
71 | ||
72 | /* Is user really user? */ | |
73 | if (ret == PAM_SUCCESS) | |
74 | ret = pam_authenticate (pamh, 0); | |
75 | /* printf ("ret %d\n", ret); */ | |
76 | ||
77 | #if 0 | |
78 | /* Permitted access? */ | |
79 | if (ret == PAM_SUCCESS) | |
80 | ret = pam_acct_mgmt (pamh, 0); | |
81 | printf ("ret %d\n", ret); | |
82 | ||
83 | if (ret == PAM_AUTHINFO_UNAVAIL) | |
84 | ret = PAM_SUCCESS; | |
85 | #endif /* 0 */ | |
86 | ||
87 | /* This is where we have been authorized or not. */ | |
88 | #ifdef DEBUG | |
89 | if (ret == PAM_SUCCESS) | |
90 | printf("Authenticated\n"); | |
91 | else | |
92 | printf("Not Authenticated\n"); | |
93 | #endif /* DEBUG */ | |
94 | ||
95 | /* close Linux-PAM */ | |
96 | if (pam_end (pamh, ret) != PAM_SUCCESS) | |
97 | { | |
98 | pamh = NULL; | |
99 | fprintf(stderr, "vtysh_pam: failed to release authenticator\n"); | |
100 | exit(1); | |
101 | } | |
102 | ||
103 | return ret == PAM_SUCCESS ? 0 : 1; | |
104 | } | |
105 | #endif /* USE_PAM */ | |
106 | ||
b8994085 | 107 | struct vtysh_user |
718e3744 | 108 | { |
109 | char *name; | |
110 | u_char nopassword; | |
111 | }; | |
112 | ||
113 | struct list *userlist; | |
114 | ||
4201dd11 | 115 | static struct vtysh_user * |
35dece84 | 116 | user_new (void) |
718e3744 | 117 | { |
c66f9c61 | 118 | return XCALLOC (MTYPE_TMP, sizeof (struct vtysh_user)); |
718e3744 | 119 | } |
120 | ||
4201dd11 | 121 | static struct vtysh_user * |
5862ff52 | 122 | user_lookup (const char *name) |
718e3744 | 123 | { |
1eb8ef25 | 124 | struct listnode *node, *nnode; |
b8994085 | 125 | struct vtysh_user *user; |
718e3744 | 126 | |
1eb8ef25 | 127 | for (ALL_LIST_ELEMENTS (userlist, node, nnode, user)) |
718e3744 | 128 | { |
129 | if (strcmp (user->name, name) == 0) | |
130 | return user; | |
131 | } | |
132 | return NULL; | |
133 | } | |
134 | ||
135 | void | |
136 | user_config_write () | |
137 | { | |
1eb8ef25 | 138 | struct listnode *node, *nnode; |
b8994085 | 139 | struct vtysh_user *user; |
a7222276 | 140 | char line[128]; |
718e3744 | 141 | |
1eb8ef25 | 142 | for (ALL_LIST_ELEMENTS (userlist, node, nnode, user)) |
718e3744 | 143 | { |
144 | if (user->nopassword) | |
a7222276 DS |
145 | { |
146 | sprintf(line, "username %s nopassword", user->name); | |
147 | config_add_line (config_top, line); | |
148 | } | |
718e3744 | 149 | } |
150 | } | |
151 | ||
4201dd11 | 152 | static struct vtysh_user * |
5862ff52 | 153 | user_get (const char *name) |
718e3744 | 154 | { |
b8994085 | 155 | struct vtysh_user *user; |
718e3744 | 156 | user = user_lookup (name); |
157 | if (user) | |
158 | return user; | |
159 | ||
160 | user = user_new (); | |
161 | user->name = strdup (name); | |
162 | listnode_add (userlist, user); | |
163 | ||
164 | return user; | |
165 | } | |
166 | ||
dd2ecded DS |
167 | DEFUN (vtysh_banner_motd_file, |
168 | vtysh_banner_motd_file_cmd, | |
4d833e55 DS |
169 | "banner motd file FILE", |
170 | "Set banner\n" | |
171 | "Banner for motd\n" | |
172 | "Banner from a file\n" | |
173 | "Filename\n") | |
7cfc61d3 | 174 | { |
bfbc035b DW |
175 | int idx_file = 3; |
176 | return cmd_banner_motd_file (argv[idx_file]->arg); | |
7cfc61d3 DS |
177 | } |
178 | ||
718e3744 | 179 | DEFUN (username_nopassword, |
180 | username_nopassword_cmd, | |
181 | "username WORD nopassword", | |
182 | "\n" | |
183 | "\n" | |
184 | "\n") | |
185 | { | |
bfbc035b | 186 | int idx_word = 1; |
b8994085 | 187 | struct vtysh_user *user; |
bfbc035b | 188 | user = user_get (argv[idx_word]->arg); |
718e3744 | 189 | user->nopassword = 1; |
190 | return CMD_SUCCESS; | |
191 | } | |
192 | ||
193 | int | |
4201dd11 | 194 | vtysh_auth (void) |
718e3744 | 195 | { |
b8994085 | 196 | struct vtysh_user *user; |
718e3744 | 197 | struct passwd *passwd; |
198 | ||
6d128e1d JAG |
199 | if ((passwd = getpwuid (geteuid ())) == NULL) |
200 | { | |
201 | fprintf (stderr, "could not lookup user ID %d\n", (int) geteuid()); | |
202 | exit (1); | |
203 | } | |
718e3744 | 204 | |
205 | user = user_lookup (passwd->pw_name); | |
206 | if (user && user->nopassword) | |
207 | /* Pass through */; | |
208 | else | |
209 | { | |
210 | #ifdef USE_PAM | |
211 | if (vtysh_pam (passwd->pw_name)) | |
212 | exit (0); | |
213 | #endif /* USE_PAM */ | |
214 | } | |
215 | return 0; | |
216 | } | |
217 | ||
fba55c8a DS |
218 | char * |
219 | vtysh_get_home (void) | |
220 | { | |
221 | struct passwd *passwd; | |
f38e9e49 | 222 | char * homedir; |
fba55c8a | 223 | |
f38e9e49 MW |
224 | if ((homedir = getenv("HOME")) != 0) |
225 | return homedir; | |
226 | ||
227 | /* Fallback if HOME is undefined */ | |
fba55c8a DS |
228 | passwd = getpwuid (getuid ()); |
229 | ||
230 | return passwd ? passwd->pw_dir : NULL; | |
231 | } | |
232 | ||
718e3744 | 233 | void |
fba55c8a | 234 | vtysh_user_init (void) |
718e3744 | 235 | { |
236 | userlist = list_new (); | |
237 | install_element (CONFIG_NODE, &username_nopassword_cmd); | |
dd2ecded | 238 | install_element (CONFIG_NODE, &vtysh_banner_motd_file_cmd); |
718e3744 | 239 | } |