"Fossies" - the Fresh Open Source Software Archive

Member "sudo-1.9.11p3/lib/util/aix.c" (12 Jun 2022, 8029 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 "aix.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * SPDX-License-Identifier: ISC
    3  *
    4  * Copyright (c) 2008, 2010-2016 Todd C. Miller <Todd.Miller@sudo.ws>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 /*
   20  * This is an open source non-commercial project. Dear PVS-Studio, please check it.
   21  * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
   22  */
   23 
   24 #include <config.h>
   25 
   26 #include <sys/resource.h>
   27 
   28 #include <stdio.h>
   29 #include <stdlib.h>
   30 #include <errno.h>
   31 #include <usersec.h>
   32 #include <uinfo.h>
   33 
   34 #include "sudo_compat.h"
   35 #include "sudo_debug.h"
   36 #include "sudo_fatal.h"
   37 #include "sudo_gettext.h"
   38 #include "sudo_util.h"
   39 
   40 #ifdef HAVE_GETUSERATTR
   41 
   42 #ifndef HAVE_SETRLIMIT64
   43 # define setrlimit64(a, b) setrlimit(a, b)
   44 # define rlimit64 rlimit
   45 # define rlim64_t rlim_t
   46 # define RLIM64_INFINITY RLIM_INFINITY
   47 #endif /* HAVE_SETRLIMIT64 */
   48 
   49 #ifndef RLIM_SAVED_MAX
   50 # define RLIM_SAVED_MAX RLIM64_INFINITY
   51 #endif
   52 
   53 struct aix_limit {
   54     int resource;
   55     char *soft;
   56     char *hard;
   57     int factor;
   58 };
   59 
   60 static struct aix_limit aix_limits[] = {
   61     { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
   62     { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
   63     { RLIMIT_DATA, S_UDATA, S_UDATA_HARD, 512 },
   64     { RLIMIT_STACK, S_USTACK, S_USTACK_HARD, 512 },
   65     { RLIMIT_RSS, S_URSS, S_URSS_HARD, 512 },
   66     { RLIMIT_CORE, S_UCORE, S_UCORE_HARD, 512 },
   67     { RLIMIT_NOFILE, S_UNOFILE, S_UNOFILE_HARD, 1 }
   68 };
   69 
   70 static int
   71 aix_getlimit(char *user, char *lim, int *valp)
   72 {
   73     debug_decl(aix_getlimit, SUDO_DEBUG_UTIL);
   74 
   75     if (getuserattr(user, lim, valp, SEC_INT) != 0)
   76     debug_return_int(-1);
   77     debug_return_int(0);
   78 }
   79 
   80 static int
   81 aix_setlimits(char *user)
   82 {
   83     struct rlimit64 rlim;
   84     int val;
   85     size_t n;
   86     debug_decl(aix_setlimits, SUDO_DEBUG_UTIL);
   87 
   88     if (setuserdb(S_READ) != 0) {
   89     sudo_warn("%s", U_("unable to open userdb"));
   90     debug_return_int(-1);
   91     }
   92 
   93     /*
   94      * For each resource limit, get the soft/hard values for the user
   95      * and set those values via setrlimit64().  Must be run as euid 0.
   96      */
   97     for (n = 0; n < nitems(aix_limits); n++) {
   98     /*
   99      * We have two strategies, depending on whether or not the
  100      * hard limit has been defined.
  101      */
  102     if (aix_getlimit(user, aix_limits[n].hard, &val) == 0) {
  103         rlim.rlim_max = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
  104         if (aix_getlimit(user, aix_limits[n].soft, &val) == 0)
  105         rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
  106         else
  107         rlim.rlim_cur = rlim.rlim_max;  /* soft not specd, use hard */
  108     } else {
  109         /* No hard limit set, try soft limit, if it exists. */
  110         if (aix_getlimit(user, aix_limits[n].soft, &val) == -1)
  111         continue;
  112         rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : (rlim64_t)val * aix_limits[n].factor;
  113 
  114         /* Set default hard limit as per limits(4). */
  115         switch (aix_limits[n].resource) {
  116         case RLIMIT_CPU:
  117         case RLIMIT_FSIZE:
  118             rlim.rlim_max = rlim.rlim_cur;
  119             break;
  120         case RLIMIT_STACK:
  121             rlim.rlim_max = 4194304UL * aix_limits[n].factor;
  122             break;
  123         default:
  124             rlim.rlim_max = RLIM64_INFINITY;
  125             break;
  126         }
  127     }
  128     (void)setrlimit64(aix_limits[n].resource, &rlim);
  129     }
  130     enduserdb();
  131     debug_return_int(0);
  132 }
  133 
  134 #ifdef HAVE_SETAUTHDB
  135 
  136 # ifndef HAVE_AUTHDB_T
  137 typedef char authdb_t[16];
  138 # endif
  139 
  140 /* The empty string means to access all defined authentication registries. */
  141 static authdb_t old_registry;
  142 
  143 # if defined(HAVE_DECL_SETAUTHDB) && !HAVE_DECL_SETAUTHDB
  144 int setauthdb(authdb_t new, authdb_t old);
  145 int getauthdb(authdb_t val);
  146 # endif
  147 # if defined(HAVE_DECL_USRINFO) && !HAVE_DECL_USRINFO
  148 int usrinfo(int cmd, char *buf, int count);
  149 # endif
  150 
  151 /*
  152  * Look up authentication registry for user (SYSTEM in /etc/security/user) and
  153  * set it as the default for the process.  This ensures that password and
  154  * group lookups are made against the correct source (files, NIS, LDAP, etc).
  155  * Does not modify errno even on error since callers do not check return value.
  156  */
  157 int
  158 aix_getauthregistry_v1(char *user, char *saved_registry)
  159 {
  160     int serrno = errno;
  161     int ret = -1;
  162     debug_decl(aix_getauthregistry, SUDO_DEBUG_UTIL);
  163 
  164     saved_registry[0] = '\0';
  165     if (user != NULL) {
  166     char *registry;
  167 
  168     if (setuserdb(S_READ) != 0) {
  169         sudo_warn("%s", U_("unable to open userdb"));
  170         goto done;
  171     }
  172     ret = getuserattr(user, S_REGISTRY, &registry, SEC_CHAR);
  173     if (ret == 0) {
  174         /* sizeof(authdb_t) is guaranteed to be 16 */
  175         if (strlcpy(saved_registry, registry, 16) >= 16) {
  176         sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
  177             "registry for user %s too long: %s", user, registry);
  178         }
  179         sudo_debug_printf(SUDO_DEBUG_INFO,
  180         "%s: saved authentication registry for user %s is %s",
  181         __func__, user, saved_registry);
  182     }
  183     enduserdb();
  184     } else {
  185     /* Get the process-wide registry. */
  186     ret = getauthdb(saved_registry);
  187     }
  188 done:
  189     errno = serrno;
  190     debug_return_int(ret);
  191 }
  192 
  193 /*
  194  * Set the specified authentication registry for user (SYSTEM in
  195  * /etc/security/user) and set it as the default for the process.
  196  * This ensures that password and group lookups are made against
  197  * the correct source (files, NIS, LDAP, etc).
  198  * If registry is NULL, look it up based on the user name.
  199  * Does not modify errno even on error since callers do not check return value.
  200  */
  201 int
  202 aix_setauthdb_v1(char *user)
  203 {
  204     return aix_setauthdb_v2(user, NULL);
  205 }
  206 
  207 int
  208 aix_setauthdb_v2(char *user, char *registry)
  209 {
  210     authdb_t regbuf;
  211     int serrno = errno;
  212     int ret = -1;
  213     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
  214 
  215     if (user != NULL) {
  216     /* Look up authentication registry if one is not provided. */
  217     if (registry == NULL) {
  218         if (aix_getauthregistry(user, regbuf) != 0)
  219         goto done;
  220         registry = regbuf;
  221     }
  222     ret = setauthdb(registry, old_registry);
  223     if (ret != 0) {
  224         sudo_warn(U_("unable to switch to registry \"%s\" for %s"),
  225         registry, user);
  226     } else {
  227         sudo_debug_printf(SUDO_DEBUG_INFO,
  228             "%s: setting authentication registry to %s",
  229             __func__, registry);
  230     }
  231     }
  232 done:
  233     errno = serrno;
  234     debug_return_int(ret);
  235 }
  236 
  237 /*
  238  * Restore the saved authentication registry, if any.
  239  * Does not modify errno even on error since callers do not check return value.
  240  */
  241 int
  242 aix_restoreauthdb_v1(void)
  243 {
  244     int serrno = errno;
  245     int ret = 0;
  246     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
  247 
  248     if (setauthdb(old_registry, NULL) != 0) {
  249     sudo_warn("%s", U_("unable to restore registry"));
  250     ret = -1;
  251     } else {
  252     sudo_debug_printf(SUDO_DEBUG_INFO,
  253         "%s: setting authentication registry to %s",
  254         __func__, old_registry);
  255     }
  256     errno = serrno;
  257     debug_return_int(ret);
  258 }
  259 #endif
  260 
  261 int
  262 aix_prep_user_v1(char *user, const char *tty)
  263 {
  264     char *info;
  265     int len;
  266     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL);
  267 
  268     /* set usrinfo, like login(1) does */
  269     len = asprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
  270     user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0');
  271     if (len == -1) {
  272     sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
  273     debug_return_int(-1);
  274     }
  275     (void)usrinfo(SETUINFO, info, len);
  276     free(info);
  277 
  278 #ifdef HAVE_SETAUTHDB
  279     /* set authentication registry */
  280     if (aix_setauthdb(user, NULL) != 0)
  281     debug_return_int(-1);
  282 #endif
  283 
  284     /* set resource limits */
  285     if (aix_setlimits(user) != 0)
  286     debug_return_int(-1);
  287 
  288     debug_return_int(0);
  289 }
  290 #endif /* HAVE_GETUSERATTR */