"Fossies" - the Fresh Open Source Software Archive

Member "sudo-1.9.11p3/plugins/sudoers/auth/bsdauth.c" (12 Jun 2022, 6026 Bytes) of package /linux/misc/sudo-1.9.11p3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "bsdauth.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2000-2005, 2007-2008, 2010-2015
    5  *  Todd C. Miller <Todd.Miller@sudo.ws>
    6  *
    7  * Permission to use, copy, modify, and distribute this software for any
    8  * purpose with or without fee is hereby granted, provided that the above
    9  * copyright notice and this permission notice appear in all copies.
   10  *
   11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   18  *
   19  * Sponsored in part by the Defense Advanced Research Projects
   20  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   21  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
   22  */
   23 
   24 /*
   25  * This is an open source non-commercial project. Dear PVS-Studio, please check it.
   26  * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
   27  */
   28 
   29 #include <config.h>
   30 
   31 #ifdef HAVE_BSD_AUTH_H
   32 
   33 #include <sys/types.h>
   34 #include <stdio.h>
   35 #include <stdlib.h>
   36 #include <string.h>
   37 #include <unistd.h>
   38 #include <ctype.h>
   39 #include <pwd.h>
   40 #include <signal.h>
   41 
   42 #include <login_cap.h>
   43 #include <bsd_auth.h>
   44 
   45 #include "sudoers.h"
   46 #include "sudo_auth.h"
   47 
   48 # ifndef LOGIN_DEFROOTCLASS
   49 #  define LOGIN_DEFROOTCLASS    "daemon"
   50 # endif
   51 
   52 struct bsdauth_state {
   53     auth_session_t *as;
   54     login_cap_t *lc;
   55 };
   56 
   57 int
   58 bsdauth_init(struct passwd *pw, sudo_auth *auth)
   59 {
   60     static struct bsdauth_state state;
   61     debug_decl(bsdauth_init, SUDOERS_DEBUG_AUTH);
   62 
   63     /* Only initialize once. */
   64     if (auth->data != NULL)
   65     debug_return_int(AUTH_SUCCESS);
   66 
   67     /* Get login class based on auth user, which may not be invoking user. */
   68     if (pw->pw_class && *pw->pw_class)
   69     state.lc = login_getclass(pw->pw_class);
   70     else
   71     state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
   72     if (state.lc == NULL) {
   73     log_warning(0,
   74         N_("unable to get login class for user %s"), pw->pw_name);
   75     debug_return_int(AUTH_FATAL);
   76     }
   77 
   78     if ((state.as = auth_open()) == NULL) {
   79     log_warning(0, N_("unable to begin bsd authentication"));
   80     login_close(state.lc);
   81     debug_return_int(AUTH_FATAL);
   82     }
   83 
   84     /* XXX - maybe check the auth style earlier? */
   85     login_style = login_getstyle(state.lc, login_style, "auth-sudo");
   86     if (login_style == NULL) {
   87     log_warningx(0, N_("invalid authentication type"));
   88     auth_close(state.as);
   89     login_close(state.lc);
   90     debug_return_int(AUTH_FATAL);
   91     }
   92 
   93      if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
   94     auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
   95     auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
   96     log_warningx(0, N_("unable to initialize BSD authentication"));
   97     auth_close(state.as);
   98     login_close(state.lc);
   99     debug_return_int(AUTH_FATAL);
  100     }
  101 
  102     auth->data = (void *) &state;
  103     debug_return_int(AUTH_SUCCESS);
  104 }
  105 
  106 int
  107 bsdauth_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback)
  108 {
  109     char *pass;
  110     char *s;
  111     size_t len;
  112     int authok = 0;
  113     struct sigaction sa, osa;
  114     auth_session_t *as = ((struct bsdauth_state *) auth->data)->as;
  115     debug_decl(bsdauth_verify, SUDOERS_DEBUG_AUTH);
  116 
  117     if (IS_NONINTERACTIVE(auth))
  118         debug_return_int(AUTH_NONINTERACTIVE);
  119 
  120     /* save old signal handler */
  121     sigemptyset(&sa.sa_mask);
  122     sa.sa_flags = SA_RESTART;
  123     sa.sa_handler = SIG_DFL;
  124     (void) sigaction(SIGCHLD, &sa, &osa);
  125 
  126     /*
  127      * If there is a challenge then print that instead of the normal
  128      * prompt.  If the user just hits return we prompt again with echo
  129      * turned on, which is useful for challenge/response things like
  130      * S/Key.
  131      */
  132     if ((s = auth_challenge(as)) == NULL) {
  133     pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback);
  134     } else {
  135     pass = auth_getpass(s, SUDO_CONV_PROMPT_ECHO_OFF, callback);
  136     if (pass && *pass == '\0') {
  137         if ((prompt = strrchr(s, '\n')))
  138         prompt++;
  139         else
  140         prompt = s;
  141 
  142         /*
  143          * Append '[echo on]' to the last line of the challenge and
  144          * reprompt with echo turned on.
  145          */
  146         len = strlen(prompt) - 1;
  147         while (isspace(prompt[len]) || prompt[len] == ':')
  148         prompt[len--] = '\0';
  149         if (asprintf(&s, "%s [echo on]: ", prompt) == -1) {
  150         log_warningx(0, N_("unable to allocate memory"));
  151         debug_return_int(AUTH_FATAL);
  152         }
  153         free(pass);
  154         pass = auth_getpass(s, SUDO_CONV_PROMPT_ECHO_ON, callback);
  155         free(s);
  156     }
  157     }
  158 
  159     if (pass) {
  160     authok = auth_userresponse(as, pass, 1);
  161     freezero(pass, strlen(pass));
  162     }
  163 
  164     /* restore old signal handler */
  165     (void) sigaction(SIGCHLD, &osa, NULL);
  166 
  167     if (authok)
  168     debug_return_int(AUTH_SUCCESS);
  169 
  170     if (!pass)
  171     debug_return_int(AUTH_INTR);
  172 
  173     if ((s = auth_getvalue(as, "errormsg")) != NULL)
  174     log_warningx(0, "%s", s);
  175     debug_return_int(AUTH_FAILURE);
  176 }
  177 
  178 int
  179 bsdauth_approval(struct passwd *pw, sudo_auth *auth, bool exempt)
  180 {
  181     struct bsdauth_state *state = auth->data;
  182     debug_decl(bsdauth_approval, SUDOERS_DEBUG_AUTH);
  183 
  184     if (auth_approval(state->as, state->lc, pw->pw_name, "auth-sudo") == 0) {
  185     if (auth_getstate(state->as) & AUTH_EXPIRED)
  186         log_warningx(0, "%s", N_("your account has expired"));
  187     else
  188         log_warningx(0, "%s", N_("approval failed"));
  189     debug_return_int(AUTH_FAILURE);
  190     }
  191     debug_return_int(AUTH_SUCCESS);
  192 }
  193 
  194 int
  195 bsdauth_cleanup(struct passwd *pw, sudo_auth *auth, bool force)
  196 {
  197     struct bsdauth_state *state = auth->data;
  198     debug_decl(bsdauth_cleanup, SUDOERS_DEBUG_AUTH);
  199 
  200     if (state != NULL) {
  201     auth_close(state->as);
  202     state->as = NULL;
  203     login_close(state->lc);
  204     state->lc = NULL;
  205     auth->data = NULL;
  206     }
  207     login_style = NULL;
  208 
  209     debug_return_int(AUTH_SUCCESS);
  210 }
  211 
  212 #endif /* HAVE_BSD_AUTH_H */