1 /* User authentication for vtysh.
2 * Copyright (C) 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
22 #include <lib/version.h>
27 #include <security/pam_appl.h>
28 #ifdef HAVE_PAM_MISC_H
29 #include <security/pam_misc.h>
32 #include <security/openpam.h>
39 #include "vtysh/vtysh_user.h"
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.
47 static int vtysh_pam(const char *);
50 void vtysh_user_init(void);
52 extern struct list
*config_top
;
53 extern void config_add_line(struct list
*config
, const char *line
);
56 static struct pam_conv conv
= {PAM_CONV_FUNC
, NULL
};
58 static int vtysh_pam(const char *user
)
61 pam_handle_t
*pamh
= NULL
;
64 ret
= pam_start(FRR_PAM_NAME
, user
, &conv
, &pamh
);
66 /* Is user really user? */
67 if (ret
== PAM_SUCCESS
)
68 ret
= pam_authenticate(pamh
, 0);
70 if (ret
!= PAM_SUCCESS
)
71 fprintf(stderr
, "vtysh_pam: Failure to initialize pam: %s(%d)",
72 pam_strerror(pamh
, ret
), ret
);
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
);
79 if (pam_end(pamh
, ret
) != PAM_SUCCESS
) {
81 fprintf(stderr
, "vtysh_pam: failed to release authenticator: %s(%d)\n",
82 pam_strerror(pamh
, ret
), ret
);
86 return ret
== PAM_SUCCESS
? 0 : 1;
95 struct list
*userlist
;
97 static struct vtysh_user
*user_new(void)
99 return XCALLOC(MTYPE_TMP
, sizeof(struct vtysh_user
));
102 static struct vtysh_user
*user_lookup(const char *name
)
104 struct listnode
*node
, *nnode
;
105 struct vtysh_user
*user
;
107 for (ALL_LIST_ELEMENTS(userlist
, node
, nnode
, user
)) {
108 if (strcmp(user
->name
, name
) == 0)
114 void user_config_write(void)
116 struct listnode
*node
, *nnode
;
117 struct vtysh_user
*user
;
120 for (ALL_LIST_ELEMENTS(userlist
, node
, nnode
, user
)) {
121 if (user
->nopassword
) {
122 snprintf(line
, sizeof(line
), "username %s nopassword",
124 config_add_line(config_top
, line
);
129 static struct vtysh_user
*user_get(const char *name
)
131 struct vtysh_user
*user
;
132 user
= user_lookup(name
);
137 user
->name
= strdup(name
);
138 listnode_add(userlist
, user
);
143 DEFUN (vtysh_banner_motd_file
,
144 vtysh_banner_motd_file_cmd
,
145 "banner motd file FILE",
148 "Banner from a file\n"
152 return cmd_banner_motd_file(argv
[idx_file
]->arg
);
155 DEFUN (vtysh_banner_motd_line
,
156 vtysh_banner_motd_line_cmd
,
157 "banner motd line LINE...",
160 "Banner from an input\n"
166 argv_find(argv
, argc
, "LINE", &idx
);
167 motd
= argv_concat(argv
, argc
, idx
);
169 cmd_banner_motd_line(motd
);
170 XFREE(MTYPE_TMP
, motd
);
175 DEFUN (username_nopassword
,
176 username_nopassword_cmd
,
177 "username WORD nopassword",
183 struct vtysh_user
*user
;
184 user
= user_get(argv
[idx_word
]->arg
);
185 user
->nopassword
= 1;
191 struct vtysh_user
*user
;
192 struct passwd
*passwd
;
194 if ((passwd
= getpwuid(geteuid())) == NULL
) {
195 fprintf(stderr
, "could not lookup user ID %d\n",
200 user
= user_lookup(passwd
->pw_name
);
201 if (user
&& user
->nopassword
)
205 if (vtysh_pam(passwd
->pw_name
))
212 char *vtysh_get_home(void)
214 struct passwd
*passwd
;
217 if ((homedir
= getenv("HOME")) != NULL
)
220 /* Fallback if HOME is undefined */
221 passwd
= getpwuid(getuid());
223 return passwd
? passwd
->pw_dir
: NULL
;
226 void vtysh_user_init(void)
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
);