]> git.proxmox.com Git - mirror_frr.git/blob - vtysh/vtysh_user.c
Merge pull request #11475 from patrasar/pim_if_delete
[mirror_frr.git] / vtysh / vtysh_user.c
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 static int vtysh_pam(const char *user)
59 {
60 int ret;
61 pam_handle_t *pamh = NULL;
62
63 /* Start PAM. */
64 ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh);
65
66 /* Is user really user? */
67 if (ret == PAM_SUCCESS)
68 ret = pam_authenticate(pamh, 0);
69
70 if (ret != PAM_SUCCESS)
71 fprintf(stderr, "vtysh_pam: Failure to initialize pam: %s(%d)",
72 pam_strerror(pamh, ret), ret);
73
74 if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS)
75 fprintf(stderr, "%s: Failed in account validation: %s(%d)",
76 __func__, pam_strerror(pamh, ret), ret);
77
78 /* close Linux-PAM */
79 if (pam_end(pamh, ret) != PAM_SUCCESS) {
80 pamh = NULL;
81 fprintf(stderr, "vtysh_pam: failed to release authenticator: %s(%d)\n",
82 pam_strerror(pamh, ret), ret);
83 exit(1);
84 }
85
86 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 static struct vtysh_user *user_new(void)
98 {
99 return XCALLOC(MTYPE_TMP, sizeof(struct vtysh_user));
100 }
101
102 static struct vtysh_user *user_lookup(const char *name)
103 {
104 struct listnode *node, *nnode;
105 struct vtysh_user *user;
106
107 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
108 if (strcmp(user->name, name) == 0)
109 return user;
110 }
111 return NULL;
112 }
113
114 void user_config_write(void)
115 {
116 struct listnode *node, *nnode;
117 struct vtysh_user *user;
118 char line[128];
119
120 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
121 if (user->nopassword) {
122 snprintf(line, sizeof(line), "username %s nopassword",
123 user->name);
124 config_add_line(config_top, line);
125 }
126 }
127 }
128
129 static struct vtysh_user *user_get(const char *name)
130 {
131 struct vtysh_user *user;
132 user = user_lookup(name);
133 if (user)
134 return user;
135
136 user = user_new();
137 user->name = strdup(name);
138 listnode_add(userlist, user);
139
140 return user;
141 }
142
143 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 int idx_file = 3;
152 return cmd_banner_motd_file(argv[idx_file]->arg);
153 }
154
155 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 int idx = 0;
164 char *motd;
165
166 argv_find(argv, argc, "LINE", &idx);
167 motd = argv_concat(argv, argc, idx);
168
169 cmd_banner_motd_line(motd);
170 XFREE(MTYPE_TMP, motd);
171
172 return CMD_SUCCESS;
173 }
174
175 DEFUN (username_nopassword,
176 username_nopassword_cmd,
177 "username WORD nopassword",
178 "\n"
179 "\n"
180 "\n")
181 {
182 int idx_word = 1;
183 struct vtysh_user *user;
184 user = user_get(argv[idx_word]->arg);
185 user->nopassword = 1;
186 return CMD_SUCCESS;
187 }
188
189 int vtysh_auth(void)
190 {
191 struct vtysh_user *user;
192 struct passwd *passwd;
193
194 if ((passwd = getpwuid(geteuid())) == NULL) {
195 fprintf(stderr, "could not lookup user ID %d\n",
196 (int)geteuid());
197 exit(1);
198 }
199
200 user = user_lookup(passwd->pw_name);
201 if (user && user->nopassword)
202 /* Pass through */;
203 else {
204 #ifdef USE_PAM
205 if (vtysh_pam(passwd->pw_name))
206 exit(0);
207 #endif /* USE_PAM */
208 }
209 return 0;
210 }
211
212 char *vtysh_get_home(void)
213 {
214 struct passwd *passwd;
215 char *homedir;
216
217 if ((homedir = getenv("HOME")) != NULL)
218 return homedir;
219
220 /* Fallback if HOME is undefined */
221 passwd = getpwuid(getuid());
222
223 return passwd ? passwd->pw_dir : NULL;
224 }
225
226 void vtysh_user_init(void)
227 {
228 userlist = list_new();
229 install_element(CONFIG_NODE, &username_nopassword_cmd);
230 install_element(CONFIG_NODE, &vtysh_banner_motd_file_cmd);
231 install_element(CONFIG_NODE, &vtysh_banner_motd_line_cmd);
232 }