File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / aix.c
Revision 1.1.1.5 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:33 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

    1: /*
    2:  * Copyright (c) 2008, 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
    3:  *
    4:  * Permission to use, copy, modify, and distribute this software for any
    5:  * purpose with or without fee is hereby granted, provided that the above
    6:  * copyright notice and this permission notice appear in all copies.
    7:  *
    8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   15:  */
   16: 
   17: #include <config.h>
   18: 
   19: #include <sys/types.h>
   20: #include <sys/resource.h>
   21: 
   22: #include <stdio.h>
   23: #ifdef STDC_HEADERS
   24: # include <stdlib.h>
   25: # include <stddef.h>
   26: #else
   27: # ifdef HAVE_STDLIB_H
   28: #  include <stdlib.h>
   29: # endif
   30: #endif /* STDC_HEADERS */
   31: #include <usersec.h>
   32: #include <uinfo.h>
   33: 
   34: #include "missing.h"
   35: #include "alloc.h"
   36: #include "fatal.h"
   37: #include "sudo_debug.h"
   38: 
   39: #define DEFAULT_TEXT_DOMAIN	"sudo"
   40: #include "gettext.h"
   41: 
   42: #ifdef HAVE_GETUSERATTR
   43: 
   44: #ifndef HAVE_SETRLIMIT64
   45: # define setrlimit64(a, b) setrlimit(a, b)
   46: # define rlimit64 rlimit
   47: # define rlim64_t rlim_t
   48: # define RLIM64_INFINITY RLIM_INFINITY
   49: #endif /* HAVE_SETRLIMIT64 */
   50: 
   51: #ifndef RLIM_SAVED_MAX
   52: # define RLIM_SAVED_MAX	RLIM64_INFINITY
   53: #endif
   54: 
   55: struct aix_limit {
   56:     int resource;
   57:     char *soft;
   58:     char *hard;
   59:     int factor;
   60: };
   61: 
   62: static struct aix_limit aix_limits[] = {
   63:     { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
   64:     { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
   65:     { RLIMIT_DATA, S_UDATA, S_UDATA_HARD, 512 },
   66:     { RLIMIT_STACK, S_USTACK, S_USTACK_HARD, 512 },
   67:     { RLIMIT_RSS, S_URSS, S_URSS_HARD, 512 },
   68:     { RLIMIT_CORE, S_UCORE, S_UCORE_HARD, 512 },
   69:     { RLIMIT_NOFILE, S_UNOFILE, S_UNOFILE_HARD, 1 }
   70: };
   71: 
   72: static int
   73: aix_getlimit(char *user, char *lim, rlim64_t *valp)
   74: {
   75:     int val;
   76:     debug_decl(aix_getlimit, SUDO_DEBUG_UTIL)
   77: 
   78:     if (getuserattr(user, lim, &val, SEC_INT) != 0)
   79: 	debug_return_int(-1);
   80:     *valp = val;
   81:     debug_return_int(0);
   82: }
   83: 
   84: static void
   85: aix_setlimits(char *user)
   86: {
   87:     struct rlimit64 rlim;
   88:     rlim64_t val;
   89:     int n;
   90:     debug_decl(aix_setlimits, SUDO_DEBUG_UTIL)
   91: 
   92:     if (setuserdb(S_READ) != 0)
   93: 	fatal("unable to open userdb");
   94: 
   95:     /*
   96:      * For each resource limit, get the soft/hard values for the user
   97:      * and set those values via setrlimit64().  Must be run as euid 0.
   98:      */
   99:     for (n = 0; n < sizeof(aix_limits) / sizeof(aix_limits[0]); n++) {
  100: 	/*
  101: 	 * We have two strategies, depending on whether or not the
  102: 	 * hard limit has been defined.
  103: 	 */
  104: 	if (aix_getlimit(user, aix_limits[n].hard, &val) == 0) {
  105: 	    rlim.rlim_max = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  106: 	    if (aix_getlimit(user, aix_limits[n].soft, &val) == 0)
  107: 		rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  108: 	    else
  109: 		rlim.rlim_cur = rlim.rlim_max;	/* soft not specd, use hard */
  110: 	} else {
  111: 	    /* No hard limit set, try soft limit, if it exists. */
  112: 	    if (aix_getlimit(user, aix_limits[n].soft, &val) == -1)
  113: 		continue;
  114: 	    rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  115: 
  116: 	    /* Set hard limit per AIX /etc/security/limits documentation. */
  117: 	    switch (aix_limits[n].resource) {
  118: 		case RLIMIT_CPU:
  119: 		case RLIMIT_FSIZE:
  120: 		    rlim.rlim_max = rlim.rlim_cur;
  121: 		    break;
  122: 		case RLIMIT_STACK:
  123: 		    rlim.rlim_max = RLIM_SAVED_MAX;
  124: 		    break;
  125: 		default:
  126: 		    rlim.rlim_max = RLIM64_INFINITY;
  127: 		    break;
  128: 	    }
  129: 	}
  130: 	(void)setrlimit64(aix_limits[n].resource, &rlim);
  131:     }
  132:     enduserdb();
  133:     debug_return;
  134: }
  135: 
  136: #ifdef HAVE_SETAUTHDB
  137: /*
  138:  * Look up administrative domain for user (SYSTEM in /etc/security/user) and
  139:  * set it as the default for the process.  This ensures that password and
  140:  * group lookups are made against the correct source (files, NIS, LDAP, etc).
  141:  */
  142: void
  143: aix_setauthdb(char *user)
  144: {
  145:     char *registry;
  146:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  147: 
  148:     if (user != NULL) {
  149: 	if (setuserdb(S_READ) != 0)
  150: 	    fatal(_("unable to open userdb"));
  151: 	if (getuserattr(user, S_REGISTRY, &registry, SEC_CHAR) == 0) {
  152: 	    if (setauthdb(registry, NULL) != 0)
  153: 		fatal(_("unable to switch to registry \"%s\" for %s"),
  154: 		    registry, user);
  155: 	}
  156: 	enduserdb();
  157:     }
  158:     debug_return;
  159: }
  160: 
  161: /*
  162:  * Restore the saved administrative domain, if any.
  163:  */
  164: void
  165: aix_restoreauthdb(void)
  166: {
  167:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  168: 
  169:     if (setauthdb(NULL, NULL) != 0)
  170: 	fatal(_("unable to restore registry"));
  171: 
  172:     debug_return;
  173: }
  174: #endif
  175: 
  176: void
  177: aix_prep_user(char *user, const char *tty)
  178: {
  179:     char *info;
  180:     int len;
  181:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  182: 
  183:     /* set usrinfo, like login(1) does */
  184:     len = easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
  185: 	user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0');
  186:     (void)usrinfo(SETUINFO, info, len);
  187:     efree(info);
  188: 
  189: #ifdef HAVE_SETAUTHDB
  190:     /* set administrative domain */
  191:     aix_setauthdb(user);
  192: #endif
  193: 
  194:     /* set resource limits */
  195:     aix_setlimits(user);
  196: 
  197:     debug_return;
  198: }
  199: #endif /* HAVE_GETUSERATTR */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>