Line data Source code
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 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
19 : */
20 :
21 : #include <zebra.h>
22 : #include <lib/version.h>
23 :
24 : #include <pwd.h>
25 :
26 : #ifdef USE_PAM
27 : #include <security/pam_appl.h>
28 : #ifdef HAVE_PAM_MISC_H
29 : #include <security/pam_misc.h>
30 : #endif
31 : #ifdef HAVE_OPENPAM_H
32 : #include <security/openpam.h>
33 : #endif
34 : #endif /* USE_PAM */
35 :
36 : #include "memory.h"
37 : #include "linklist.h"
38 : #include "command.h"
39 : #include "vtysh/vtysh_user.h"
40 :
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 : */
46 : #ifdef USE_PAM
47 : static int vtysh_pam(const char *);
48 : #endif
49 : int vtysh_auth(void);
50 : void vtysh_user_init(void);
51 :
52 : extern struct list *config_top;
53 : extern void config_add_line(struct list *config, const char *line);
54 :
55 : #ifdef USE_PAM
56 : static struct pam_conv conv = {PAM_CONV_FUNC, NULL};
57 :
58 8 : static int vtysh_pam(const char *user)
59 : {
60 8 : int ret;
61 8 : pam_handle_t *pamh = NULL;
62 :
63 : /* Start PAM. */
64 8 : ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh);
65 :
66 : /* Is user really user? */
67 8 : if (ret == PAM_SUCCESS)
68 8 : ret = pam_authenticate(pamh, 0);
69 :
70 8 : if (ret != PAM_SUCCESS)
71 0 : fprintf(stderr, "vtysh_pam: Failure to initialize pam: %s(%d)",
72 : pam_strerror(pamh, ret), ret);
73 :
74 8 : if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS)
75 0 : fprintf(stderr, "%s: Failed in account validation: %s(%d)",
76 : __func__, pam_strerror(pamh, ret), ret);
77 :
78 : /* close Linux-PAM */
79 8 : if (pam_end(pamh, ret) != PAM_SUCCESS) {
80 0 : pamh = NULL;
81 0 : fprintf(stderr, "vtysh_pam: failed to release authenticator: %s(%d)\n",
82 : pam_strerror(pamh, ret), ret);
83 0 : exit(1);
84 : }
85 :
86 8 : return ret == PAM_SUCCESS ? 0 : 1;
87 : }
88 : #endif /* USE_PAM */
89 :
90 : struct vtysh_user {
91 : char *name;
92 : uint8_t nopassword;
93 : };
94 :
95 : struct list *userlist;
96 :
97 0 : static struct vtysh_user *user_new(void)
98 : {
99 0 : return XCALLOC(MTYPE_TMP, sizeof(struct vtysh_user));
100 : }
101 :
102 8 : static struct vtysh_user *user_lookup(const char *name)
103 : {
104 8 : struct listnode *node, *nnode;
105 8 : struct vtysh_user *user;
106 :
107 16 : for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
108 0 : if (strcmp(user->name, name) == 0)
109 0 : return user;
110 : }
111 : return NULL;
112 : }
113 :
114 0 : void user_config_write(void)
115 : {
116 0 : struct listnode *node, *nnode;
117 0 : struct vtysh_user *user;
118 0 : char line[128];
119 :
120 0 : for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
121 0 : if (user->nopassword) {
122 0 : snprintf(line, sizeof(line), "username %s nopassword",
123 : user->name);
124 0 : config_add_line(config_top, line);
125 : }
126 : }
127 0 : }
128 :
129 0 : static struct vtysh_user *user_get(const char *name)
130 : {
131 0 : struct vtysh_user *user;
132 0 : user = user_lookup(name);
133 0 : if (user)
134 : return user;
135 :
136 0 : user = user_new();
137 0 : user->name = strdup(name);
138 0 : listnode_add(userlist, user);
139 :
140 0 : return user;
141 : }
142 :
143 0 : DEFUN (vtysh_banner_motd_file,
144 : vtysh_banner_motd_file_cmd,
145 : "banner motd file FILE",
146 : "Set banner\n"
147 : "Banner for motd\n"
148 : "Banner from a file\n"
149 : "Filename\n")
150 : {
151 0 : int idx_file = 3;
152 0 : return cmd_banner_motd_file(argv[idx_file]->arg);
153 : }
154 :
155 0 : DEFUN (vtysh_banner_motd_line,
156 : vtysh_banner_motd_line_cmd,
157 : "banner motd line LINE...",
158 : "Set banner\n"
159 : "Banner for motd\n"
160 : "Banner from an input\n"
161 : "Text\n")
162 : {
163 0 : int idx = 0;
164 0 : char *motd;
165 :
166 0 : argv_find(argv, argc, "LINE", &idx);
167 0 : motd = argv_concat(argv, argc, idx);
168 :
169 0 : cmd_banner_motd_line(motd);
170 0 : XFREE(MTYPE_TMP, motd);
171 :
172 0 : return CMD_SUCCESS;
173 : }
174 :
175 0 : DEFUN (username_nopassword,
176 : username_nopassword_cmd,
177 : "username WORD nopassword",
178 : "\n"
179 : "\n"
180 : "\n")
181 : {
182 0 : int idx_word = 1;
183 0 : struct vtysh_user *user;
184 0 : user = user_get(argv[idx_word]->arg);
185 0 : user->nopassword = 1;
186 0 : return CMD_SUCCESS;
187 : }
188 :
189 8 : int vtysh_auth(void)
190 : {
191 8 : struct vtysh_user *user;
192 8 : struct passwd *passwd;
193 :
194 8 : if ((passwd = getpwuid(geteuid())) == NULL) {
195 0 : fprintf(stderr, "could not lookup user ID %d\n",
196 0 : (int)geteuid());
197 0 : exit(1);
198 : }
199 :
200 8 : user = user_lookup(passwd->pw_name);
201 8 : if (user && user->nopassword)
202 : /* Pass through */;
203 : else {
204 : #ifdef USE_PAM
205 8 : if (vtysh_pam(passwd->pw_name))
206 0 : exit(0);
207 : #endif /* USE_PAM */
208 : }
209 8 : return 0;
210 : }
211 :
212 0 : char *vtysh_get_home(void)
213 : {
214 0 : struct passwd *passwd;
215 0 : char *homedir;
216 :
217 0 : if ((homedir = getenv("HOME")) != NULL)
218 : return homedir;
219 :
220 : /* Fallback if HOME is undefined */
221 0 : passwd = getpwuid(getuid());
222 :
223 0 : return passwd ? passwd->pw_dir : NULL;
224 : }
225 :
226 8 : void vtysh_user_init(void)
227 : {
228 8 : userlist = list_new();
229 8 : install_element(CONFIG_NODE, &username_nopassword_cmd);
230 8 : install_element(CONFIG_NODE, &vtysh_banner_motd_file_cmd);
231 8 : install_element(CONFIG_NODE, &vtysh_banner_motd_line_cmd);
232 8 : }
|