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
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>
23
24#include <pwd.h>
25
26#ifdef USE_PAM
27#include <security/pam_appl.h>
28#include <security/pam_misc.h>
29#endif /* USE_PAM */
30
31#include "memory.h"
32#include "linklist.h"
33#include "command.h"
34
35#ifdef USE_PAM
36static struct pam_conv conv =
37{
38  misc_conv,
39  NULL
40};
41
42int
43vtysh_pam (char *user)
44{
45  int ret;
46  pam_handle_t *pamh = NULL;
47
48  /* Start PAM. */
49  ret = pam_start("zebra", user, &conv, &pamh);
50  /* printf ("ret %d\n", ret); */
51
52  /* Is user really user? */
53  if (ret == PAM_SUCCESS)
54    ret = pam_authenticate (pamh, 0);
55  /* printf ("ret %d\n", ret); */
56
57#if 0
58  /* Permitted access? */
59  if (ret == PAM_SUCCESS)
60    ret = pam_acct_mgmt (pamh, 0);
61  printf ("ret %d\n", ret);
62
63  if (ret == PAM_AUTHINFO_UNAVAIL)
64    ret = PAM_SUCCESS;
65#endif /* 0 */
66
67  /* This is where we have been authorized or not. */
68#ifdef DEBUG
69  if (ret == PAM_SUCCESS)
70    printf("Authenticated\n");
71  else
72    printf("Not Authenticated\n");
73#endif /* DEBUG */
74
75  /* close Linux-PAM */
76  if (pam_end (pamh, ret) != PAM_SUCCESS)
77    {
78      pamh = NULL;
79      fprintf(stderr, "vtysh_pam: failed to release authenticator\n");
80      exit(1);
81    }
82
83  return ret == PAM_SUCCESS ? 0 : 1;
84}
85#endif /* USE_PAM */
86
87struct user
88{
89  char *name;
90  u_char nopassword;
91};
92
93struct list *userlist;
94
95struct user *
96user_new ()
97{
98  struct user *user;
99  user = XMALLOC (0, sizeof (struct user));
100  memset (user, 0, sizeof (struct user));
101  return user;
102}
103
104void
105user_free (struct user *user)
106{
107  XFREE (0, user);
108}
109
110struct user *
111user_lookup (char *name)
112{
113  struct listnode *nn;
114  struct user *user;
115
116  LIST_LOOP (userlist, user, nn)
117    {
118      if (strcmp (user->name, name) == 0)
119	return user;
120    }
121  return NULL;
122}
123
124void
125user_config_write ()
126{
127  struct listnode *nn;
128  struct user *user;
129
130  LIST_LOOP (userlist, user, nn)
131    {
132      if (user->nopassword)
133	printf (" username %s nopassword\n", user->name);
134    }
135}
136
137struct user *
138user_get (char *name)
139{
140  struct user *user;
141  user = user_lookup (name);
142  if (user)
143    return user;
144
145  user = user_new ();
146  user->name = strdup (name);
147  listnode_add (userlist, user);
148
149  return user;
150}
151
152DEFUN (username_nopassword,
153       username_nopassword_cmd,
154       "username WORD nopassword",
155       "\n"
156       "\n"
157       "\n")
158{
159  struct user *user;
160  user = user_get (argv[0]);
161  user->nopassword = 1;
162  return CMD_SUCCESS;
163}
164
165int
166vtysh_auth ()
167{
168  struct user *user;
169  struct passwd *passwd;
170
171  passwd = getpwuid (geteuid ());
172
173  user = user_lookup (passwd->pw_name);
174  if (user && user->nopassword)
175    /* Pass through */;
176  else
177    {
178#ifdef USE_PAM
179      if (vtysh_pam (passwd->pw_name))
180	exit (0);
181#endif /* USE_PAM */
182    }
183  return 0;
184}
185
186void
187vtysh_user_init ()
188{
189  userlist = list_new ();
190  install_element (CONFIG_NODE, &username_nopassword_cmd);
191}
192