]> git.proxmox.com Git - mirror_frr.git/blame - vtysh/vtysh_user.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / vtysh / vtysh_user.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
718e3744 2/* User authentication for vtysh.
3 * Copyright (C) 2000 Kunihiro Ishiguro
718e3744 4 */
5
6#include <zebra.h>
bb6065a5 7#include <lib/version.h>
718e3744 8
9#include <pwd.h>
10
11#ifdef USE_PAM
12#include <security/pam_appl.h>
24cd435b 13#ifdef HAVE_PAM_MISC_H
718e3744 14#include <security/pam_misc.h>
24cd435b 15#endif
16#ifdef HAVE_OPENPAM_H
17#include <security/openpam.h>
18#endif
718e3744 19#endif /* USE_PAM */
20
21#include "memory.h"
22#include "linklist.h"
23#include "command.h"
88177fe3 24#include "vtysh/vtysh_user.h"
718e3744 25
d62a17ae 26/*
c0e8c16f
DS
27 * Compiler is warning about prototypes not being declared.
28 * The DEFUNSH and DEFUN macro's are messing with the
29 * compiler I believe. This is just to make it happy.
30 */
21c830a4 31#ifdef USE_PAM
ec4ab9f3 32static int vtysh_pam(const char *);
21c830a4 33#endif
c0e8c16f
DS
34int vtysh_auth(void);
35void vtysh_user_init(void);
36
e4421165
DS
37extern struct list *config_top;
38extern void config_add_line(struct list *config, const char *line);
39
718e3744 40#ifdef USE_PAM
d62a17ae 41static struct pam_conv conv = {PAM_CONV_FUNC, NULL};
718e3744 42
d62a17ae 43static int vtysh_pam(const char *user)
718e3744 44{
d62a17ae 45 int ret;
46 pam_handle_t *pamh = NULL;
718e3744 47
d62a17ae 48 /* Start PAM. */
49 ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh);
d62a17ae 50
51 /* Is user really user? */
52 if (ret == PAM_SUCCESS)
53 ret = pam_authenticate(pamh, 0);
718e3744 54
60bc8d61
DS
55 if (ret != PAM_SUCCESS)
56 fprintf(stderr, "vtysh_pam: Failure to initialize pam: %s(%d)",
57 pam_strerror(pamh, ret), ret);
718e3744 58
264a2a27 59 if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS)
60 fprintf(stderr, "%s: Failed in account validation: %s(%d)",
61 __func__, pam_strerror(pamh, ret), ret);
62
d62a17ae 63 /* close Linux-PAM */
64 if (pam_end(pamh, ret) != PAM_SUCCESS) {
65 pamh = NULL;
60bc8d61
DS
66 fprintf(stderr, "vtysh_pam: failed to release authenticator: %s(%d)\n",
67 pam_strerror(pamh, ret), ret);
d62a17ae 68 exit(1);
69 }
718e3744 70
d62a17ae 71 return ret == PAM_SUCCESS ? 0 : 1;
718e3744 72}
73#endif /* USE_PAM */
74
d62a17ae 75struct vtysh_user {
76 char *name;
d7c0a89a 77 uint8_t nopassword;
718e3744 78};
79
80struct list *userlist;
81
d62a17ae 82static struct vtysh_user *user_new(void)
718e3744 83{
d62a17ae 84 return XCALLOC(MTYPE_TMP, sizeof(struct vtysh_user));
718e3744 85}
86
d62a17ae 87static struct vtysh_user *user_lookup(const char *name)
718e3744 88{
d62a17ae 89 struct listnode *node, *nnode;
90 struct vtysh_user *user;
718e3744 91
d62a17ae 92 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
93 if (strcmp(user->name, name) == 0)
94 return user;
95 }
96 return NULL;
718e3744 97}
98
4d762f26 99void user_config_write(void)
718e3744 100{
d62a17ae 101 struct listnode *node, *nnode;
102 struct vtysh_user *user;
103 char line[128];
104
105 for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
106 if (user->nopassword) {
772270f3
QY
107 snprintf(line, sizeof(line), "username %s nopassword",
108 user->name);
d62a17ae 109 config_add_line(config_top, line);
110 }
a7222276 111 }
718e3744 112}
113
d62a17ae 114static struct vtysh_user *user_get(const char *name)
718e3744 115{
d62a17ae 116 struct vtysh_user *user;
117 user = user_lookup(name);
118 if (user)
119 return user;
718e3744 120
d62a17ae 121 user = user_new();
122 user->name = strdup(name);
123 listnode_add(userlist, user);
718e3744 124
d62a17ae 125 return user;
718e3744 126}
127
dd2ecded
DS
128DEFUN (vtysh_banner_motd_file,
129 vtysh_banner_motd_file_cmd,
4d833e55
DS
130 "banner motd file FILE",
131 "Set banner\n"
132 "Banner for motd\n"
133 "Banner from a file\n"
134 "Filename\n")
7cfc61d3 135{
d62a17ae 136 int idx_file = 3;
137 return cmd_banner_motd_file(argv[idx_file]->arg);
7cfc61d3
DS
138}
139
19d61463
DA
140DEFUN (vtysh_banner_motd_line,
141 vtysh_banner_motd_line_cmd,
142 "banner motd line LINE...",
143 "Set banner\n"
144 "Banner for motd\n"
145 "Banner from an input\n"
146 "Text\n")
147{
148 int idx = 0;
149 char *motd;
150
151 argv_find(argv, argc, "LINE", &idx);
152 motd = argv_concat(argv, argc, idx);
153
154 cmd_banner_motd_line(motd);
155 XFREE(MTYPE_TMP, motd);
156
157 return CMD_SUCCESS;
158}
159
718e3744 160DEFUN (username_nopassword,
161 username_nopassword_cmd,
162 "username WORD nopassword",
163 "\n"
164 "\n"
165 "\n")
166{
d62a17ae 167 int idx_word = 1;
168 struct vtysh_user *user;
169 user = user_get(argv[idx_word]->arg);
170 user->nopassword = 1;
171 return CMD_SUCCESS;
718e3744 172}
173
d62a17ae 174int vtysh_auth(void)
718e3744 175{
d62a17ae 176 struct vtysh_user *user;
177 struct passwd *passwd;
178
179 if ((passwd = getpwuid(geteuid())) == NULL) {
180 fprintf(stderr, "could not lookup user ID %d\n",
181 (int)geteuid());
182 exit(1);
183 }
184
185 user = user_lookup(passwd->pw_name);
186 if (user && user->nopassword)
187 /* Pass through */;
188 else {
718e3744 189#ifdef USE_PAM
d62a17ae 190 if (vtysh_pam(passwd->pw_name))
191 exit(0);
718e3744 192#endif /* USE_PAM */
d62a17ae 193 }
194 return 0;
718e3744 195}
196
d62a17ae 197char *vtysh_get_home(void)
fba55c8a 198{
d62a17ae 199 struct passwd *passwd;
200 char *homedir;
fba55c8a 201
831600c3 202 if ((homedir = getenv("HOME")) != NULL)
d62a17ae 203 return homedir;
f38e9e49 204
d62a17ae 205 /* Fallback if HOME is undefined */
206 passwd = getpwuid(getuid());
fba55c8a 207
d62a17ae 208 return passwd ? passwd->pw_dir : NULL;
fba55c8a
DS
209}
210
d62a17ae 211void vtysh_user_init(void)
718e3744 212{
d62a17ae 213 userlist = list_new();
214 install_element(CONFIG_NODE, &username_nopassword_cmd);
215 install_element(CONFIG_NODE, &vtysh_banner_motd_file_cmd);
19d61463 216 install_element(CONFIG_NODE, &vtysh_banner_motd_line_cmd);
718e3744 217}