File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / aix.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:23:02 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

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

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