blob: e3015056c570b737ac4a6573fc9adf5e12cecfb5 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* 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>
paulbb6065a2003-08-13 04:07:52 +000023#include <lib/version.h>
paul718e3742002-12-13 20:15:29 +000024
25#include <pwd.h>
26
27#ifdef USE_PAM
28#include <security/pam_appl.h>
paul24cd4352003-05-06 12:16:27 +000029#ifdef HAVE_PAM_MISC_H
paul718e3742002-12-13 20:15:29 +000030#include <security/pam_misc.h>
paul24cd4352003-05-06 12:16:27 +000031#endif
32#ifdef HAVE_OPENPAM_H
33#include <security/openpam.h>
34#endif
paul718e3742002-12-13 20:15:29 +000035#endif /* USE_PAM */
36
37#include "memory.h"
38#include "linklist.h"
39#include "command.h"
40
41#ifdef USE_PAM
42static struct pam_conv conv =
43{
paul24cd4352003-05-06 12:16:27 +000044 PAM_CONV_FUNC,
paul718e3742002-12-13 20:15:29 +000045 NULL
46};
47
48int
hasso5862ff52004-10-11 13:20:40 +000049vtysh_pam (const char *user)
paul718e3742002-12-13 20:15:29 +000050{
51 int ret;
52 pam_handle_t *pamh = NULL;
53
54 /* Start PAM. */
paul42053f42003-08-13 02:54:44 +000055 ret = pam_start(QUAGGA_PROGNAME, user, &conv, &pamh);
paul718e3742002-12-13 20:15:29 +000056 /* printf ("ret %d\n", ret); */
57
58 /* Is user really user? */
59 if (ret == PAM_SUCCESS)
60 ret = pam_authenticate (pamh, 0);
61 /* printf ("ret %d\n", ret); */
62
63#if 0
64 /* Permitted access? */
65 if (ret == PAM_SUCCESS)
66 ret = pam_acct_mgmt (pamh, 0);
67 printf ("ret %d\n", ret);
68
69 if (ret == PAM_AUTHINFO_UNAVAIL)
70 ret = PAM_SUCCESS;
71#endif /* 0 */
72
73 /* This is where we have been authorized or not. */
74#ifdef DEBUG
75 if (ret == PAM_SUCCESS)
76 printf("Authenticated\n");
77 else
78 printf("Not Authenticated\n");
79#endif /* DEBUG */
80
81 /* close Linux-PAM */
82 if (pam_end (pamh, ret) != PAM_SUCCESS)
83 {
84 pamh = NULL;
85 fprintf(stderr, "vtysh_pam: failed to release authenticator\n");
86 exit(1);
87 }
88
89 return ret == PAM_SUCCESS ? 0 : 1;
90}
91#endif /* USE_PAM */
92
paulb8994082005-07-12 15:15:02 +000093struct vtysh_user
paul718e3742002-12-13 20:15:29 +000094{
95 char *name;
96 u_char nopassword;
97};
98
99struct list *userlist;
100
paulb8994082005-07-12 15:15:02 +0000101struct vtysh_user *
paul718e3742002-12-13 20:15:29 +0000102user_new ()
103{
paulb8994082005-07-12 15:15:02 +0000104 struct vtysh_user *user;
105 user = XMALLOC (0, sizeof (struct vtysh_user));
106 memset (user, 0, sizeof (struct vtysh_user));
paul718e3742002-12-13 20:15:29 +0000107 return user;
108}
109
110void
paulb8994082005-07-12 15:15:02 +0000111user_free (struct vtysh_user *user)
paul718e3742002-12-13 20:15:29 +0000112{
113 XFREE (0, user);
114}
115
paulb8994082005-07-12 15:15:02 +0000116struct vtysh_user *
hasso5862ff52004-10-11 13:20:40 +0000117user_lookup (const char *name)
paul718e3742002-12-13 20:15:29 +0000118{
paul1eb8ef22005-04-07 07:30:20 +0000119 struct listnode *node, *nnode;
paulb8994082005-07-12 15:15:02 +0000120 struct vtysh_user *user;
paul718e3742002-12-13 20:15:29 +0000121
paul1eb8ef22005-04-07 07:30:20 +0000122 for (ALL_LIST_ELEMENTS (userlist, node, nnode, user))
paul718e3742002-12-13 20:15:29 +0000123 {
124 if (strcmp (user->name, name) == 0)
125 return user;
126 }
127 return NULL;
128}
129
130void
131user_config_write ()
132{
paul1eb8ef22005-04-07 07:30:20 +0000133 struct listnode *node, *nnode;
paulb8994082005-07-12 15:15:02 +0000134 struct vtysh_user *user;
paul718e3742002-12-13 20:15:29 +0000135
paul1eb8ef22005-04-07 07:30:20 +0000136 for (ALL_LIST_ELEMENTS (userlist, node, nnode, user))
paul718e3742002-12-13 20:15:29 +0000137 {
138 if (user->nopassword)
139 printf (" username %s nopassword\n", user->name);
140 }
141}
142
paulb8994082005-07-12 15:15:02 +0000143struct vtysh_user *
hasso5862ff52004-10-11 13:20:40 +0000144user_get (const char *name)
paul718e3742002-12-13 20:15:29 +0000145{
paulb8994082005-07-12 15:15:02 +0000146 struct vtysh_user *user;
paul718e3742002-12-13 20:15:29 +0000147 user = user_lookup (name);
148 if (user)
149 return user;
150
151 user = user_new ();
152 user->name = strdup (name);
153 listnode_add (userlist, user);
154
155 return user;
156}
157
158DEFUN (username_nopassword,
159 username_nopassword_cmd,
160 "username WORD nopassword",
161 "\n"
162 "\n"
163 "\n")
164{
paulb8994082005-07-12 15:15:02 +0000165 struct vtysh_user *user;
paul718e3742002-12-13 20:15:29 +0000166 user = user_get (argv[0]);
167 user->nopassword = 1;
168 return CMD_SUCCESS;
169}
170
171int
172vtysh_auth ()
173{
paulb8994082005-07-12 15:15:02 +0000174 struct vtysh_user *user;
paul718e3742002-12-13 20:15:29 +0000175 struct passwd *passwd;
176
177 passwd = getpwuid (geteuid ());
178
179 user = user_lookup (passwd->pw_name);
180 if (user && user->nopassword)
181 /* Pass through */;
182 else
183 {
184#ifdef USE_PAM
185 if (vtysh_pam (passwd->pw_name))
186 exit (0);
187#endif /* USE_PAM */
188 }
189 return 0;
190}
191
192void
193vtysh_user_init ()
194{
195 userlist = list_new ();
196 install_element (CONFIG_NODE, &username_nopassword_cmd);
197}