"Fossies" - the Fresh Open Source Software Archive

Member "sudo-1.9.11p3/plugins/sudoers/bsm_audit.c" (12 Jun 2022, 7085 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 "bsm_audit.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2009-2015 Todd C. Miller <Todd.Miller@sudo.ws>
    5  * Copyright (c) 2009 Christian S.J. Peron
    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 
   20 /*
   21  * This is an open source non-commercial project. Dear PVS-Studio, please check it.
   22  * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
   23  */
   24 
   25 #include <config.h>
   26 
   27 #ifdef HAVE_BSM_AUDIT
   28 
   29 #include <sys/types.h>      /* for pid_t */
   30 
   31 #include <bsm/audit.h>
   32 #include <bsm/libbsm.h>
   33 #include <bsm/audit_uevents.h>
   34 
   35 #include <stdio.h>
   36 #include <stdarg.h>
   37 #include <errno.h>
   38 #include <unistd.h>
   39 
   40 #include "sudoers.h"
   41 #include "bsm_audit.h"
   42 
   43 /*
   44  * Solaris auditon() returns EINVAL if BSM audit not configured.
   45  * OpenBSM returns ENOSYS for unimplemented options.
   46  */
   47 #ifdef __sun
   48 # define AUDIT_NOT_CONFIGURED   EINVAL
   49 #else
   50 # define AUDIT_NOT_CONFIGURED   ENOSYS
   51 #endif
   52 
   53 #ifdef __FreeBSD__
   54 # define BSM_AUDIT_COMPAT
   55 #endif
   56 
   57 static au_event_t sudo_audit_event = AUE_sudo;
   58 
   59 static int
   60 audit_sudo_selected(int sorf)
   61 {
   62     auditinfo_addr_t ainfo_addr;
   63     struct au_mask *mask;
   64     int rc;
   65     debug_decl(audit_sudo_selected, SUDOERS_DEBUG_AUDIT);
   66 
   67     if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) {
   68 #ifdef BSM_AUDIT_COMPAT
   69         if (errno == ENOSYS) {
   70             auditinfo_t ainfo;
   71 
   72             /* Fall back to older BSM API. */
   73             if (getaudit(&ainfo) < 0) {
   74                 sudo_warn("getaudit");
   75                 debug_return_int(-1);
   76             }
   77             mask = &ainfo.ai_mask;
   78         } else
   79 #endif /* BSM_AUDIT_COMPAT */
   80         {
   81             sudo_warn("getaudit_addr");
   82             debug_return_int(-1);
   83         }
   84         } else {
   85         mask = &ainfo_addr.ai_mask;
   86     }
   87     rc = au_preselect(sudo_audit_event, mask, sorf, AU_PRS_REREAD);
   88     if (rc == -1) {
   89 #if defined(__APPLE__) && defined(AUE_DARWIN_sudo)
   90         /*
   91          * Mac OS X 10.10 au_preselect() only accepts AUE_DARWIN_sudo.
   92          */
   93         sudo_audit_event = AUE_DARWIN_sudo;
   94         rc = au_preselect(sudo_audit_event, mask, sorf, AU_PRS_REREAD);
   95         if (rc == -1)
   96 #endif
   97 
   98         sudo_warn("au_preselect");
   99     }
  100         debug_return_int(rc);
  101 }
  102 
  103 /*
  104  * Returns 0 on success or -1 on error.
  105  */
  106 int
  107 bsm_audit_success(char *const exec_args[])
  108 {
  109     auditinfo_addr_t ainfo_addr;
  110     token_t *tok;
  111     au_id_t auid;
  112     long au_cond;
  113     int aufd, selected;
  114     pid_t pid;
  115     debug_decl(bsm_audit_success, SUDOERS_DEBUG_AUDIT);
  116 
  117     /*
  118      * If we are not auditing, don't cut an audit record; just return.
  119      */
  120     if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
  121         if (errno == AUDIT_NOT_CONFIGURED)
  122             debug_return_int(0);
  123         sudo_warn("%s", U_("Could not determine audit condition"));
  124         debug_return_int(-1);
  125     }
  126     if (au_cond == AUC_NOAUDIT)
  127         debug_return_int(0);
  128     /*
  129      * Check to see if the preselection masks are interested in seeing
  130      * this event.
  131      */
  132     selected = audit_sudo_selected(AU_PRS_SUCCESS);
  133     if (selected != 1)
  134         debug_return_int(!selected ? 0 : -1);
  135     if (getauid(&auid) < 0) {
  136         sudo_warn("getauid");
  137         debug_return_int(-1);
  138     }
  139     if ((aufd = au_open()) == -1) {
  140         sudo_warn("au_open");
  141         debug_return_int(-1);
  142     }
  143     pid = getpid();
  144     if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) {
  145         tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
  146             getuid(), pid, pid, &ainfo_addr.ai_termid);
  147 #ifdef BSM_AUDIT_COMPAT
  148     } else if (errno == ENOSYS) {
  149         auditinfo_t ainfo;
  150 
  151         /*
  152          * NB: We should probably watch out for ERANGE here.
  153          */
  154         if (getaudit(&ainfo) < 0) {
  155             sudo_warn("getaudit");
  156             debug_return_int(-1);
  157         }
  158         tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
  159             getuid(), pid, pid, &ainfo.ai_termid);
  160 #endif /* BSM_AUDIT_COMPAT */
  161     } else {
  162         sudo_warn("getaudit_addr");
  163         debug_return_int(-1);
  164     }
  165     if (tok == NULL) {
  166         sudo_warn("au_to_subject");
  167         debug_return_int(-1);
  168     }
  169     au_write(aufd, tok);
  170     tok = au_to_exec_args((char **)exec_args);
  171     if (tok == NULL) {
  172         sudo_warn("au_to_exec_args");
  173         debug_return_int(-1);
  174     }
  175     au_write(aufd, tok);
  176     tok = au_to_return32(0, 0);
  177     if (tok == NULL) {
  178         sudo_warn("au_to_return32");
  179         debug_return_int(-1);
  180     }
  181     au_write(aufd, tok);
  182 #ifdef HAVE_AU_CLOSE_SOLARIS11
  183     if (au_close(aufd, 1, sudo_audit_event, 0) == -1)
  184 #else
  185     if (au_close(aufd, 1, sudo_audit_event) == -1)
  186 #endif
  187     {
  188         sudo_warn("%s", U_("unable to commit audit record"));
  189         debug_return_int(-1);
  190     }
  191     debug_return_int(0);
  192 }
  193 
  194 /*
  195  * Returns 0 on success or -1 on error.
  196  */
  197 int
  198 bsm_audit_failure(char *const exec_args[], const char *errmsg)
  199 {
  200     auditinfo_addr_t ainfo_addr;
  201     token_t *tok;
  202     long au_cond;
  203     au_id_t auid;
  204     pid_t pid;
  205     int aufd;
  206     debug_decl(bsm_audit_failure, SUDOERS_DEBUG_AUDIT);
  207 
  208     /*
  209      * If we are not auditing, don't cut an audit record; just return.
  210      */
  211     if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) {
  212         if (errno == AUDIT_NOT_CONFIGURED)
  213             debug_return_int(0);
  214         sudo_warn("%s", U_("Could not determine audit condition"));
  215         debug_return_int(-1);
  216     }
  217     if (au_cond == AUC_NOAUDIT)
  218         debug_return_int(0);
  219     if (!audit_sudo_selected(AU_PRS_FAILURE))
  220         debug_return_int(0);
  221     if (getauid(&auid) < 0) {
  222         sudo_warn("getauid");
  223         debug_return_int(-1);
  224     }
  225     if ((aufd = au_open()) == -1) {
  226         sudo_warn("au_open");
  227         debug_return_int(-1);
  228     }
  229     pid = getpid();
  230     if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { 
  231         tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(),
  232             getuid(), pid, pid, &ainfo_addr.ai_termid);
  233 #ifdef BSM_AUDIT_COMPAT
  234     } else if (errno == ENOSYS) {
  235         auditinfo_t ainfo;
  236 
  237         if (getaudit(&ainfo) < 0) {
  238             sudo_warn("getaudit");
  239             debug_return_int(-1);
  240         }
  241         tok = au_to_subject(auid, geteuid(), getegid(), getuid(),
  242             getuid(), pid, pid, &ainfo.ai_termid);
  243 #endif /* BSM_AUDIT_COMPAT */
  244     } else {
  245         sudo_warn("getaudit_addr");
  246         debug_return_int(-1);
  247     }
  248     if (tok == NULL) {
  249         sudo_warn("au_to_subject");
  250         debug_return_int(-1);
  251     }
  252     au_write(aufd, tok);
  253     tok = au_to_exec_args((char **)exec_args);
  254     if (tok == NULL) {
  255         sudo_warn("au_to_exec_args");
  256         debug_return_int(-1);
  257     }
  258     au_write(aufd, tok);
  259     tok = au_to_text((char *)errmsg);
  260     if (tok == NULL) {
  261         sudo_warn("au_to_text");
  262         debug_return_int(-1);
  263     }
  264     au_write(aufd, tok);
  265     tok = au_to_return32(EPERM, 1);
  266     if (tok == NULL) {
  267         sudo_warn("au_to_return32");
  268         debug_return_int(-1);
  269     }
  270     au_write(aufd, tok);
  271 #ifdef HAVE_AU_CLOSE_SOLARIS11
  272     if (au_close(aufd, 1, sudo_audit_event, PAD_FAILURE) == -1)
  273 #else
  274     if (au_close(aufd, 1, sudo_audit_event) == -1)
  275 #endif
  276     {
  277         sudo_warn("%s", U_("unable to commit audit record"));
  278         debug_return_int(-1);
  279     }
  280     debug_return_int(0);
  281 }
  282 
  283 #endif /* HAVE_BSM_AUDIT */