File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / aix.c
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    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: #define DEFAULT_TEXT_DOMAIN	"sudo"
   35: #include "gettext.h"		/* must be included before missing.h */
   36: 
   37: #include "missing.h"
   38: #include "alloc.h"
   39: #include "fatal.h"
   40: #include "sudo_debug.h"
   41: #include "sudo_util.h"
   42: 
   43: #ifdef HAVE_GETUSERATTR
   44: 
   45: #ifndef HAVE_SETRLIMIT64
   46: # define setrlimit64(a, b) setrlimit(a, b)
   47: # define rlimit64 rlimit
   48: # define rlim64_t rlim_t
   49: # define RLIM64_INFINITY RLIM_INFINITY
   50: #endif /* HAVE_SETRLIMIT64 */
   51: 
   52: #ifndef RLIM_SAVED_MAX
   53: # define RLIM_SAVED_MAX	RLIM64_INFINITY
   54: #endif
   55: 
   56: struct aix_limit {
   57:     int resource;
   58:     char *soft;
   59:     char *hard;
   60:     int factor;
   61: };
   62: 
   63: static struct aix_limit aix_limits[] = {
   64:     { RLIMIT_FSIZE, S_UFSIZE, S_UFSIZE_HARD, 512 },
   65:     { RLIMIT_CPU, S_UCPU, S_UCPU_HARD, 1 },
   66:     { RLIMIT_DATA, S_UDATA, S_UDATA_HARD, 512 },
   67:     { RLIMIT_STACK, S_USTACK, S_USTACK_HARD, 512 },
   68:     { RLIMIT_RSS, S_URSS, S_URSS_HARD, 512 },
   69:     { RLIMIT_CORE, S_UCORE, S_UCORE_HARD, 512 },
   70:     { RLIMIT_NOFILE, S_UNOFILE, S_UNOFILE_HARD, 1 }
   71: };
   72: 
   73: static int
   74: aix_getlimit(char *user, char *lim, rlim64_t *valp)
   75: {
   76:     int val;
   77:     debug_decl(aix_getlimit, SUDO_DEBUG_UTIL)
   78: 
   79:     if (getuserattr(user, lim, &val, SEC_INT) != 0)
   80: 	debug_return_int(-1);
   81:     *valp = val;
   82:     debug_return_int(0);
   83: }
   84: 
   85: static void
   86: aix_setlimits(char *user)
   87: {
   88:     struct rlimit64 rlim;
   89:     rlim64_t val;
   90:     int n;
   91:     debug_decl(aix_setlimits, SUDO_DEBUG_UTIL)
   92: 
   93:     if (setuserdb(S_READ) != 0)
   94: 	fatal(U_("unable to open userdb"));
   95: 
   96:     /*
   97:      * For each resource limit, get the soft/hard values for the user
   98:      * and set those values via setrlimit64().  Must be run as euid 0.
   99:      */
  100:     for (n = 0; n < sizeof(aix_limits) / sizeof(aix_limits[0]); n++) {
  101: 	/*
  102: 	 * We have two strategies, depending on whether or not the
  103: 	 * hard limit has been defined.
  104: 	 */
  105: 	if (aix_getlimit(user, aix_limits[n].hard, &val) == 0) {
  106: 	    rlim.rlim_max = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  107: 	    if (aix_getlimit(user, aix_limits[n].soft, &val) == 0)
  108: 		rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  109: 	    else
  110: 		rlim.rlim_cur = rlim.rlim_max;	/* soft not specd, use hard */
  111: 	} else {
  112: 	    /* No hard limit set, try soft limit, if it exists. */
  113: 	    if (aix_getlimit(user, aix_limits[n].soft, &val) == -1)
  114: 		continue;
  115: 	    rlim.rlim_cur = val == -1 ? RLIM64_INFINITY : val * aix_limits[n].factor;
  116: 
  117: 	    /* Set hard limit per AIX /etc/security/limits documentation. */
  118: 	    switch (aix_limits[n].resource) {
  119: 		case RLIMIT_CPU:
  120: 		case RLIMIT_FSIZE:
  121: 		    rlim.rlim_max = rlim.rlim_cur;
  122: 		    break;
  123: 		case RLIMIT_STACK:
  124: 		    rlim.rlim_max = RLIM_SAVED_MAX;
  125: 		    break;
  126: 		default:
  127: 		    rlim.rlim_max = RLIM64_INFINITY;
  128: 		    break;
  129: 	    }
  130: 	}
  131: 	(void)setrlimit64(aix_limits[n].resource, &rlim);
  132:     }
  133:     enduserdb();
  134:     debug_return;
  135: }
  136: 
  137: #ifdef HAVE_SETAUTHDB
  138: /*
  139:  * Look up administrative domain for user (SYSTEM in /etc/security/user) and
  140:  * set it as the default for the process.  This ensures that password and
  141:  * group lookups are made against the correct source (files, NIS, LDAP, etc).
  142:  */
  143: void
  144: aix_setauthdb(char *user)
  145: {
  146:     char *registry;
  147:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  148: 
  149:     if (user != NULL) {
  150: 	if (setuserdb(S_READ) != 0)
  151: 	    fatal(U_("unable to open userdb"));
  152: 	if (getuserattr(user, S_REGISTRY, &registry, SEC_CHAR) == 0) {
  153: 	    if (setauthdb(registry, NULL) != 0)
  154: 		fatal(U_("unable to switch to registry \"%s\" for %s"),
  155: 		    registry, user);
  156: 	}
  157: 	enduserdb();
  158:     }
  159:     debug_return;
  160: }
  161: 
  162: /*
  163:  * Restore the saved administrative domain, if any.
  164:  */
  165: void
  166: aix_restoreauthdb(void)
  167: {
  168:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  169: 
  170:     if (setauthdb(NULL, NULL) != 0)
  171: 	fatal(U_("unable to restore registry"));
  172: 
  173:     debug_return;
  174: }
  175: #endif
  176: 
  177: void
  178: aix_prep_user(char *user, const char *tty)
  179: {
  180:     char *info;
  181:     int len;
  182:     debug_decl(aix_setauthdb, SUDO_DEBUG_UTIL)
  183: 
  184:     /* set usrinfo, like login(1) does */
  185:     len = easprintf(&info, "NAME=%s%cLOGIN=%s%cLOGNAME=%s%cTTY=%s%c",
  186: 	user, '\0', user, '\0', user, '\0', tty ? tty : "", '\0');
  187:     (void)usrinfo(SETUINFO, info, len);
  188:     efree(info);
  189: 
  190: #ifdef HAVE_SETAUTHDB
  191:     /* set administrative domain */
  192:     aix_setauthdb(user);
  193: #endif
  194: 
  195:     /* set resource limits */
  196:     aix_setlimits(user);
  197: 
  198:     debug_return;
  199: }
  200: #endif /* HAVE_GETUSERATTR */

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