]> git.proxmox.com Git - mirror_frr.git/blob - vtysh/vtysh_user.c
Merge pull request #3289 from donaldsharp/onlink_schmonlink
[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 /* printf ("ret %d\n", ret); */
66
67 /* Is user really user? */
68 if (ret == PAM_SUCCESS)
69 ret = pam_authenticate(pamh, 0);
70 /* printf ("ret %d\n", ret); */
71
72 #if 0
73 /* Permitted access? */
74 if (ret == PAM_SUCCESS)
75 ret = pam_acct_mgmt (pamh, 0);
76 printf ("ret %d\n", ret);
77
78 if (ret == PAM_AUTHINFO_UNAVAIL)
79 ret = PAM_SUCCESS;
80 #endif /* 0 */
81
82 /* This is where we have been authorized or not. */
83 #ifdef DEBUG
84 if (ret == PAM_SUCCESS)
85 printf("Authenticated\n");
86 else
87 printf("Not Authenticated\n");
88 #endif /* DEBUG */
89
90 /* close Linux-PAM */
91 if (pam_end(pamh, ret) != PAM_SUCCESS) {
92 pamh = NULL;
93 fprintf(stderr, "vtysh_pam: failed to release authenticator\n");
94 exit(1);
95 }
96
97 return ret == PAM_SUCCESS ? 0 : 1;
98 }
99 #endif /* USE_PAM */
100
101 struct vtysh_user {
102 char *name;
103 uint8_t nopassword;
104 };
105
106 struct list *userlist;
107
108 static struct vtysh_user *user_new(void)
109 {
110 return XCALLOC(MTYPE_TMP, sizeof(struct vtysh_user));
111 }
112
113 static struct vtysh_user *user_lookup(const char *name)
114 {
115 struct listnode *node, *nnode;
116 struct vtysh_user *user;
117
118 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
119 if (strcmp(user->name, name) == 0)
120 return user;
121 }
122 return NULL;
123 }
124
125 void user_config_write()
126 {
127 struct listnode *node, *nnode;
128 struct vtysh_user *user;
129 char line[128];
130
131 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
132 if (user->nopassword) {
133 sprintf(line, "username %s nopassword", user->name);
134 config_add_line(config_top, line);
135 }
136 }
137 }
138
139 static struct vtysh_user *user_get(const char *name)
140 {
141 struct vtysh_user *user;
142 user = user_lookup(name);
143 if (user)
144 return user;
145
146 user = user_new();
147 user->name = strdup(name);
148 listnode_add(userlist, user);
149
150 return user;
151 }
152
153 DEFUN (vtysh_banner_motd_file,
154 vtysh_banner_motd_file_cmd,
155 "banner motd file FILE",
156 "Set banner\n"
157 "Banner for motd\n"
158 "Banner from a file\n"
159 "Filename\n")
160 {
161 int idx_file = 3;
162 return cmd_banner_motd_file(argv[idx_file]->arg);
163 }
164
165 DEFUN (username_nopassword,
166 username_nopassword_cmd,
167 "username WORD nopassword",
168 "\n"
169 "\n"
170 "\n")
171 {
172 int idx_word = 1;
173 struct vtysh_user *user;
174 user = user_get(argv[idx_word]->arg);
175 user->nopassword = 1;
176 return CMD_SUCCESS;
177 }
178
179 int vtysh_auth(void)
180 {
181 struct vtysh_user *user;
182 struct passwd *passwd;
183
184 if ((passwd = getpwuid(geteuid())) == NULL) {
185 fprintf(stderr, "could not lookup user ID %d\n",
186 (int)geteuid());
187 exit(1);
188 }
189
190 user = user_lookup(passwd->pw_name);
191 if (user && user->nopassword)
192 /* Pass through */;
193 else {
194 #ifdef USE_PAM
195 if (vtysh_pam(passwd->pw_name))
196 exit(0);
197 #endif /* USE_PAM */
198 }
199 return 0;
200 }
201
202 char *vtysh_get_home(void)
203 {
204 struct passwd *passwd;
205 char *homedir;
206
207 if ((homedir = getenv("HOME")) != 0)
208 return homedir;
209
210 /* Fallback if HOME is undefined */
211 passwd = getpwuid(getuid());
212
213 return passwd ? passwd->pw_dir : NULL;
214 }
215
216 void vtysh_user_init(void)
217 {
218 userlist = list_new();
219 install_element(CONFIG_NODE, &username_nopassword_cmd);
220 install_element(CONFIG_NODE, &vtysh_banner_motd_file_cmd);
221 }