back to topotato report
topotato coverage report
Current view: top level - vtysh - vtysh_user.c (source / functions) Hit Total Coverage
Test: test_pim6_basic.py::PIM6Basic Lines: 28 81 34.6 %
Date: 2023-02-24 18:38:38 Functions: 4 10 40.0 %

          Line data    Source code
       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           2 : static int vtysh_pam(const char *user)
      59             : {
      60           2 :         int ret;
      61           2 :         pam_handle_t *pamh = NULL;
      62             : 
      63             :         /* Start PAM. */
      64           2 :         ret = pam_start(FRR_PAM_NAME, user, &conv, &pamh);
      65             : 
      66             :         /* Is user really user? */
      67           2 :         if (ret == PAM_SUCCESS)
      68           2 :                 ret = pam_authenticate(pamh, 0);
      69             : 
      70           2 :         if (ret != PAM_SUCCESS)
      71           0 :                 fprintf(stderr, "vtysh_pam: Failure to initialize pam: %s(%d)",
      72             :                         pam_strerror(pamh, ret), ret);
      73             : 
      74           2 :         if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS)
      75           0 :                 fprintf(stderr, "%s: Failed in account validation: %s(%d)",
      76             :                         __func__, pam_strerror(pamh, ret), ret);
      77             : 
      78             :         /* close Linux-PAM */
      79           2 :         if (pam_end(pamh, ret) != PAM_SUCCESS) {
      80           0 :                 pamh = NULL;
      81           0 :                 fprintf(stderr, "vtysh_pam: failed to release authenticator: %s(%d)\n",
      82             :                         pam_strerror(pamh, ret), ret);
      83           0 :                 exit(1);
      84             :         }
      85             : 
      86           2 :         return ret == PAM_SUCCESS ? 0 : 1;
      87             : }
      88             : #endif /* USE_PAM */
      89             : 
      90             : struct vtysh_user {
      91             :         char *name;
      92             :         uint8_t nopassword;
      93             : };
      94             : 
      95             : struct list *userlist;
      96             : 
      97           0 : static struct vtysh_user *user_new(void)
      98             : {
      99           0 :         return XCALLOC(MTYPE_TMP, sizeof(struct vtysh_user));
     100             : }
     101             : 
     102           2 : static struct vtysh_user *user_lookup(const char *name)
     103             : {
     104           2 :         struct listnode *node, *nnode;
     105           2 :         struct vtysh_user *user;
     106             : 
     107           4 :         for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
     108           0 :                 if (strcmp(user->name, name) == 0)
     109           0 :                         return user;
     110             :         }
     111             :         return NULL;
     112             : }
     113             : 
     114           0 : void user_config_write(void)
     115             : {
     116           0 :         struct listnode *node, *nnode;
     117           0 :         struct vtysh_user *user;
     118           0 :         char line[128];
     119             : 
     120           0 :         for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) {
     121           0 :                 if (user->nopassword) {
     122           0 :                         snprintf(line, sizeof(line), "username %s nopassword",
     123             :                                  user->name);
     124           0 :                         config_add_line(config_top, line);
     125             :                 }
     126             :         }
     127           0 : }
     128             : 
     129           0 : static struct vtysh_user *user_get(const char *name)
     130             : {
     131           0 :         struct vtysh_user *user;
     132           0 :         user = user_lookup(name);
     133           0 :         if (user)
     134             :                 return user;
     135             : 
     136           0 :         user = user_new();
     137           0 :         user->name = strdup(name);
     138           0 :         listnode_add(userlist, user);
     139             : 
     140           0 :         return user;
     141             : }
     142             : 
     143           0 : DEFUN (vtysh_banner_motd_file,
     144             :        vtysh_banner_motd_file_cmd,
     145             :        "banner motd file FILE",
     146             :        "Set banner\n"
     147             :        "Banner for motd\n"
     148             :        "Banner from a file\n"
     149             :        "Filename\n")
     150             : {
     151           0 :         int idx_file = 3;
     152           0 :         return cmd_banner_motd_file(argv[idx_file]->arg);
     153             : }
     154             : 
     155           0 : DEFUN (vtysh_banner_motd_line,
     156             :        vtysh_banner_motd_line_cmd,
     157             :        "banner motd line LINE...",
     158             :        "Set banner\n"
     159             :        "Banner for motd\n"
     160             :        "Banner from an input\n"
     161             :        "Text\n")
     162             : {
     163           0 :         int idx = 0;
     164           0 :         char *motd;
     165             : 
     166           0 :         argv_find(argv, argc, "LINE", &idx);
     167           0 :         motd = argv_concat(argv, argc, idx);
     168             : 
     169           0 :         cmd_banner_motd_line(motd);
     170           0 :         XFREE(MTYPE_TMP, motd);
     171             : 
     172           0 :         return CMD_SUCCESS;
     173             : }
     174             : 
     175           0 : DEFUN (username_nopassword,
     176             :        username_nopassword_cmd,
     177             :        "username WORD nopassword",
     178             :        "\n"
     179             :        "\n"
     180             :        "\n")
     181             : {
     182           0 :         int idx_word = 1;
     183           0 :         struct vtysh_user *user;
     184           0 :         user = user_get(argv[idx_word]->arg);
     185           0 :         user->nopassword = 1;
     186           0 :         return CMD_SUCCESS;
     187             : }
     188             : 
     189           2 : int vtysh_auth(void)
     190             : {
     191           2 :         struct vtysh_user *user;
     192           2 :         struct passwd *passwd;
     193             : 
     194           2 :         if ((passwd = getpwuid(geteuid())) == NULL) {
     195           0 :                 fprintf(stderr, "could not lookup user ID %d\n",
     196           0 :                         (int)geteuid());
     197           0 :                 exit(1);
     198             :         }
     199             : 
     200           2 :         user = user_lookup(passwd->pw_name);
     201           2 :         if (user && user->nopassword)
     202             :                 /* Pass through */;
     203             :         else {
     204             : #ifdef USE_PAM
     205           2 :                 if (vtysh_pam(passwd->pw_name))
     206           0 :                         exit(0);
     207             : #endif /* USE_PAM */
     208             :         }
     209           2 :         return 0;
     210             : }
     211             : 
     212           0 : char *vtysh_get_home(void)
     213             : {
     214           0 :         struct passwd *passwd;
     215           0 :         char *homedir;
     216             : 
     217           0 :         if ((homedir = getenv("HOME")) != NULL)
     218             :                 return homedir;
     219             : 
     220             :         /* Fallback if HOME is undefined */
     221           0 :         passwd = getpwuid(getuid());
     222             : 
     223           0 :         return passwd ? passwd->pw_dir : NULL;
     224             : }
     225             : 
     226           2 : void vtysh_user_init(void)
     227             : {
     228           2 :         userlist = list_new();
     229           2 :         install_element(CONFIG_NODE, &username_nopassword_cmd);
     230           2 :         install_element(CONFIG_NODE, &vtysh_banner_motd_file_cmd);
     231           2 :         install_element(CONFIG_NODE, &vtysh_banner_motd_line_cmd);
     232           2 : }

Generated by: LCOV version v1.16-topotato