diff options
Diffstat (limited to '')
-rw-r--r-- | plugins/sudoers/auth/sia.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/plugins/sudoers/auth/sia.c b/plugins/sudoers/auth/sia.c new file mode 100644 index 0000000..9c55071 --- /dev/null +++ b/plugins/sudoers/auth/sia.c @@ -0,0 +1,160 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 1999-2005, 2007, 2010-2015 + * Todd C. Miller <Todd.Miller@sudo.ws> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include <config.h> + +#ifdef HAVE_SIA_SES_INIT + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <pwd.h> +#include <signal.h> +#include <siad.h> + +#include <sudoers.h> +#include "sudo_auth.h" + +static int sudo_argc; +static char **sudo_argv; +static char *sudo_tty; + +int +sudo_sia_setup(const struct sudoers_context *ctx, struct passwd *pw, + char **promptp, sudo_auth *auth) +{ + SIAENTITY *siah; + int i; + debug_decl(sudo_sia_setup, SUDOERS_DEBUG_AUTH); + + /* Rebuild argv for sia_ses_init() */ + sudo_argc = ctx->runas.argc + 1; + sudo_argv = reallocarray(NULL, sudo_argc + 1, sizeof(char *)); + if (sudo_argv == NULL) { + log_warningx(ctx, 0, N_("unable to allocate memory")); + debug_return_int(AUTH_ERROR); + } + sudo_argv[0] = "sudo"; + for (i = 0; i < ctx->runas.argc; i++) + sudo_argv[i + 1] = ctx->runas.argv[i]; + sudo_argv[sudo_argc] = NULL; + + /* We don't let SIA prompt the user for input. */ + sudo_tty = ctx->user.ttypath; + if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, sudo_tty, 0, NULL) != SIASUCCESS) { + log_warning(ctx, 0, N_("unable to initialize SIA session")); + debug_return_int(AUTH_ERROR); + } + + auth->data = siah; + debug_return_int(AUTH_SUCCESS); +} + +int +sudo_sia_verify(const struct sudoers_context *ctx, struct passwd *pw, + const char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback) +{ + SIAENTITY *siah = auth->data; + char *pass; + int rc; + debug_decl(sudo_sia_verify, SUDOERS_DEBUG_AUTH); + + if (IS_NONINTERACTIVE(auth)) + debug_return_int(AUTH_NONINTERACTIVE); + + /* Get password, return AUTH_INTR if we got ^C */ + pass = auth_getpass(prompt, SUDO_CONV_PROMPT_ECHO_OFF, callback); + if (pass == NULL) + debug_return_int(AUTH_INTR); + + /* Check password and zero out plaintext copy. */ + rc = sia_ses_authent(NULL, pass, siah); + freezero(pass, strlen(pass)); + + if (rc == SIASUCCESS) + debug_return_int(AUTH_SUCCESS); + if (ISSET(rc, SIASTOP)) + debug_return_int(AUTH_ERROR); + debug_return_int(AUTH_FAILURE); +} + +int +sudo_sia_cleanup(const struct sudoers_context *ctx, struct passwd *pw, + sudo_auth *auth, bool force) +{ + SIAENTITY *siah = auth->data; + debug_decl(sudo_sia_cleanup, SUDOERS_DEBUG_AUTH); + + (void) sia_ses_release(&siah); + auth->data = NULL; + free(sudo_argv); + debug_return_int(AUTH_SUCCESS); +} + +int +sudo_sia_begin_session(const struct sudoers_context *ctx, struct passwd *pw, + char **user_envp[], sudo_auth *auth) +{ + SIAENTITY *siah; + int status = AUTH_ERROR; + debug_decl(sudo_sia_begin_session, SUDOERS_DEBUG_AUTH); + + /* Re-init sia for the target user's session. */ + if (sia_ses_init(&siah, sudo_argc - 1, sudo_argv + 1, NULL, pw->pw_name, sudo_tty, 0, NULL) != SIASUCCESS) { + log_warning(ctx, 0, N_("unable to initialize SIA session")); + goto done; + } + + if (sia_make_entity_pwd(pw, siah) != SIASUCCESS) { + sudo_warn("sia_make_entity_pwd"); + goto done; + } + + status = AUTH_FAILURE; /* no more fatal errors. */ + + siah->authtype = SIA_A_NONE; + if (sia_ses_estab(sia_collect_trm, siah) != SIASUCCESS) { + sudo_warn("sia_ses_estab"); + goto done; + } + + if (sia_ses_launch(sia_collect_trm, siah) != SIASUCCESS) { + sudo_warn("sia_ses_launch"); + goto done; + } + + status = AUTH_SUCCESS; + +done: + (void) sia_ses_release(&siah); + debug_return_int(status); +} + +#endif /* HAVE_SIA_SES_INIT */ |