Exemple #1
0
int
setclasscontext(const char *classname, unsigned int flags)
{
    int		rc;
    login_cap_t *lc;

    lc = login_getclassbyname(classname, NULL);

    flags &= LOGIN_SETRESOURCES | LOGIN_SETPRIORITY |
	    LOGIN_SETUMASK | LOGIN_SETPATH;

    rc = lc ? setusercontext(lc, NULL, 0, flags) : -1;
    login_close(lc);
    return (rc);
}
Exemple #2
0
/*ARGSUSED*/
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Authmethod *m = NULL;
	char *user, *service, *method, *style = NULL;
	int authenticated = 0;
#ifdef HAVE_LOGIN_CAP
	login_cap_t *lc;
	const char *from_host, *from_ip;

	from_host = get_canonical_hostname(options.use_dns);
	from_ip = get_remote_ipaddr();
#endif

	if (authctxt == NULL)
		fatal("input_userauth_request: no authctxt");

	user = packet_get_cstring(NULL);
	service = packet_get_cstring(NULL);
	method = packet_get_cstring(NULL);
	debug("userauth-request for user %s service %s method %s", user, service, method);
	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);

	if ((style = strchr(user, ':')) != NULL)
		*style++ = 0;

	if (authctxt->attempt++ == 0) {
		/* setup auth context */
		authctxt->pw = PRIVSEP(getpwnamallow(user));
		authctxt->user = xstrdup(user);
		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
			authctxt->valid = 1;
			debug2("input_userauth_request: setting up authctxt for %s", user);
		} else {
			logit("input_userauth_request: invalid user %s", user);
			authctxt->pw = fakepw();
#ifdef SSH_AUDIT_EVENTS
			PRIVSEP(audit_event(SSH_INVALID_USER));
#endif
		}
#ifdef USE_PAM
		if (options.use_pam)
			PRIVSEP(start_pam(authctxt));
#endif
		setproctitle("%s%s", authctxt->valid ? user : "******",
		    use_privsep ? " [net]" : "");
		authctxt->service = xstrdup(service);
		authctxt->style = style ? xstrdup(style) : NULL;
		if (use_privsep)
			mm_inform_authserv(service, style);
		userauth_banner();
		if (auth2_setup_methods_lists(authctxt) != 0)
			packet_disconnect("no authentication methods enabled");
	} else if (strcmp(user, authctxt->user) != 0 ||
	    strcmp(service, authctxt->service) != 0) {
		packet_disconnect("Change of username or service not allowed: "
		    "(%s,%s) -> (%s,%s)",
		    authctxt->user, authctxt->service, user, service);
	}

#ifdef HAVE_LOGIN_CAP
	if (authctxt->pw != NULL) {
		lc = login_getpwclass(authctxt->pw);
		if (lc == NULL)
			lc = login_getclassbyname(NULL, authctxt->pw);
		if (!auth_hostok(lc, from_host, from_ip)) {
			logit("Denied connection for %.200s from %.200s [%.200s].",
			    authctxt->pw->pw_name, from_host, from_ip);
			packet_disconnect("Sorry, you are not allowed to connect.");
		}
		if (!auth_timeok(lc, time(NULL))) {
			logit("LOGIN %.200s REFUSED (TIME) FROM %.200s",
			    authctxt->pw->pw_name, from_host);
			packet_disconnect("Logins not available right now.");
		}
		login_close(lc);
		lc = NULL;
	}
#endif  /* HAVE_LOGIN_CAP */

	/* reset state */
	auth2_challenge_stop(authctxt);

#ifdef GSSAPI
	/* XXX move to auth2_gssapi_stop() */
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
#endif

	authctxt->postponed = 0;
	authctxt->server_caused_failure = 0;

	/* try to authenticate user */
	m = authmethod_lookup(authctxt, method);
	if (m != NULL && authctxt->failures < options.max_authtries) {
		debug2("input_userauth_request: try method %s", method);
		authenticated =	m->userauth(authctxt);
	}
	userauth_finish(authctxt, authenticated, method, NULL);

	free(service);
	free(user);
	free(method);
}
Exemple #3
0
int
main(int argc, char *argv[])
{
    char *p, *cls = NULL;
    char *cleanenv[1];
    struct passwd * pwd = NULL;
    int rcswhich, shelltype;
    int i, num_limits = 0;
    int ch, doeval = 0, doall = 0;
    int rtrn, setproc;
    login_cap_t * lc = NULL;
    enum { ANY=0, SOFT=1, HARD=2, BOTH=3, DISPLAYONLY=4 } type = ANY;
    enum { RCSUNKNOWN=0, RCSSET=1, RCSSEL=2 } todo = RCSUNKNOWN;
    int which_limits[RLIM_NLIMITS];
    rlim_t set_limits[RLIM_NLIMITS];
    struct rlimit limits[RLIM_NLIMITS];
    pid_t pid;

    /* init resource tables */
    for (i = 0; i < RLIM_NLIMITS; i++) {
	which_limits[i] = 0; /* Don't set/display any */
	set_limits[i] = RLIM_INFINITY;
    }

    pid = -1;
    optarg = NULL;
    while ((ch = getopt(argc, argv,
      ":EeC:U:BSHP:ab:c:d:f:l:m:n:s:t:u:v:p:w:k:o:")) != -1) {
	switch(ch) {
	case 'a':
	    doall = 1;
	    break;
	case 'E':
	    environ = cleanenv;
	    cleanenv[0] = NULL;
	    break;
	case 'e':
	    doeval = 1;
	    break;
	case 'C':
	    cls = optarg;
	    break;
	case 'U':
	    if ((pwd = getpwnam(optarg)) == NULL) {
		if (!isdigit(*optarg) ||
		    (pwd = getpwuid(atoi(optarg))) == NULL) {
		    warnx("invalid user `%s'", optarg);
		    usage();
		}
	    }
	    break;
	case 'H':
	    type = HARD;
	    break;
	case 'S':
	    type = SOFT;
	    break;
	case 'B':
	    type = SOFT|HARD;
	    break;
	case 'P':
	    if (!isdigit(*optarg) || (pid = atoi(optarg)) < 0) {
		warnx("invalid pid `%s'", optarg);
		usage();
	    }
	    break;
	default:
	case ':': /* Without arg */
	    if ((p = strchr(rcs_string, optopt)) != NULL) {
		int rcswhich1 = p - rcs_string;
		if (optarg && *optarg == '-') { /* 'arg' is actually a switch */
		    --optind;		/* back one arg, and make arg NULL */
		    optarg = NULL;
		}
		todo = optarg == NULL ? RCSSEL : RCSSET;
		if (type == ANY)
		    type = BOTH;
		which_limits[rcswhich1] = optarg ? type : DISPLAYONLY;
		set_limits[rcswhich1] = resource_num(rcswhich1, optopt, optarg);
		num_limits++;
		break;
	    }
	    /* FALLTHRU */
	case '?':
	    usage();
	}
	optarg = NULL;
    }

    if (pid != -1) {
	if (cls != NULL) {
	    warnx("-C cannot be used with -P option");
	    usage();
	}
	if (pwd != NULL) {
	    warnx("-U cannot be used with -P option");
	    usage();
	}
    }

    /* Get current resource values */
    setproc = 0;
    for (i = 0; i < RLIM_NLIMITS; i++) {
	if (pid == -1) {
	    getrlimit(i, &limits[i]);
	} else if (doall || num_limits == 0) {
	    getrlimit_proc(pid, i, &limits[i]);
	} else if (which_limits[i] != 0) {
	    getrlimit_proc(pid, i, &limits[i]);
	    setproc = 1;
	}
    }

    /* If user was specified, get class from that */
    if (pwd != NULL)
	lc = login_getpwclass(pwd);
    else if (cls != NULL && *cls != '\0') {
	lc = login_getclassbyname(cls, NULL);
	if (lc == NULL || strcmp(cls, lc->lc_class) != 0)
	    fprintf(stderr, "login class '%s' non-existent, using %s\n",
		    cls, lc?lc->lc_class:"current settings");
    }

    /* If we have a login class, update resource table from that */
    if (lc != NULL) {
	for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	    char str[40];
	    rlim_t val;

	    /* current value overridden by resourcename or resourcename-cur */
	    sprintf(str, "%s-cur", resources[rcswhich].cap);
	    val = resources[rcswhich].func(lc, resources[rcswhich].cap, limits[rcswhich].rlim_cur, limits[rcswhich].rlim_cur);
	    limits[rcswhich].rlim_cur = resources[rcswhich].func(lc, str, val, val);
	    /* maximum value overridden by resourcename or resourcename-max */
	    sprintf(str, "%s-max", resources[rcswhich].cap);
	    val = resources[rcswhich].func(lc, resources[rcswhich].cap, limits[rcswhich].rlim_max, limits[rcswhich].rlim_max);
	    limits[rcswhich].rlim_max = resources[rcswhich].func(lc, str, val, val);
	}
    }

    /* now, let's determine what we wish to do with all this */

    argv += optind;

    /* If we're setting limits or doing an eval (ie. we're not just
     * displaying), then check that hard limits are not lower than
     * soft limits, and force rasing the hard limit if we need to if
     * we are raising the soft limit, or lower the soft limit if we
     * are lowering the hard limit.
     */
    if ((*argv || doeval) && getuid() == 0) {

	for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	    if (limits[rcswhich].rlim_max != RLIM_INFINITY) {
		if (limits[rcswhich].rlim_cur == RLIM_INFINITY) {
		    limits[rcswhich].rlim_max = RLIM_INFINITY;
		    which_limits[rcswhich] |= HARD;
		} else if (limits[rcswhich].rlim_cur > limits[rcswhich].rlim_max) {
		    if (which_limits[rcswhich] == SOFT) {
			limits[rcswhich].rlim_max = limits[rcswhich].rlim_cur;
			which_limits[rcswhich] |= HARD;
		    }  else if (which_limits[rcswhich] == HARD) {
			limits[rcswhich].rlim_cur = limits[rcswhich].rlim_max;
			which_limits[rcswhich] |= SOFT;
		    } else {
			/* else.. if we're specifically setting both to
			 * silly values, then let it error out.
			 */
		    }
		}
	    }
	}
    }

    /* See if we've overridden anything specific on the command line */
    if (num_limits && todo == RCSSET) {
	for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	    if (which_limits[rcswhich] & HARD)
		limits[rcswhich].rlim_max = set_limits[rcswhich];
	    if (which_limits[rcswhich] & SOFT)
		limits[rcswhich].rlim_cur = set_limits[rcswhich];
	}
    }

    /* If *argv is not NULL, then we are being asked to
     * (perhaps) set environment variables and run a program
     */
    if (*argv) {
	if (doeval) {
	    warnx("-e cannot be used with `cmd' option");
	    usage();
	}
	if (pid != -1) {
	    warnx("-P cannot be used with `cmd' option");
	    usage();
	}

	login_close(lc);

	/* set leading environment variables, like eval(1) */
	while (*argv && (p = strchr(*argv, '='))) {
		*p = '\0';
		rtrn = setenv(*argv++, p + 1, 1);
		*p = '=';
		if (rtrn == -1)
			err(EXIT_FAILURE, "setenv %s", *argv);
	}

	/* Set limits */
	for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	    if (doall || num_limits == 0 || which_limits[rcswhich] != 0)
		if (setrlimit(rcswhich, &limits[rcswhich]) == -1)
		    err(1, "setrlimit %s", resources[rcswhich].cap);
	}

	if (*argv == NULL)
	    usage();

	execvp(*argv, argv);
	err(1, "%s", *argv);
    }

    if (setproc) {
	for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	    if (which_limits[rcswhich] != 0)
		setrlimit_proc(pid, rcswhich, &limits[rcswhich]);
	}
	exit(EXIT_SUCCESS);
    }

    shelltype = doeval ? getshelltype() : SH_NONE;

    if (type == ANY) /* Default to soft limits */
	type = SOFT;

    /* Display limits */
    printf(shellparm[shelltype].cmd,
	   lc ? " for class " : " (current)",
	   lc ? lc->lc_class : "");

    for (rcswhich = 0; rcswhich < RLIM_NLIMITS; rcswhich++) {
	if (doall || num_limits == 0 || which_limits[rcswhich] != 0) {
	    if (which_limits[rcswhich] == ANY || which_limits[rcswhich])
		which_limits[rcswhich] = type;
	    if (shellparm[shelltype].lprm[rcswhich].pfx) {
		if (shellparm[shelltype].both && limits[rcswhich].rlim_cur == limits[rcswhich].rlim_max) {
		    print_limit(limits[rcswhich].rlim_max,
				shellparm[shelltype].lprm[rcswhich].divisor,
				shellparm[shelltype].inf,
				shellparm[shelltype].lprm[rcswhich].pfx,
				shellparm[shelltype].lprm[rcswhich].sfx,
				shellparm[shelltype].both);
		} else {
		    if (which_limits[rcswhich] & HARD) {
			print_limit(limits[rcswhich].rlim_max,
				    shellparm[shelltype].lprm[rcswhich].divisor,
				    shellparm[shelltype].inf,
				    shellparm[shelltype].lprm[rcswhich].pfx,
				    shellparm[shelltype].lprm[rcswhich].sfx,
				    shellparm[shelltype].hard);
		    }
		    if (which_limits[rcswhich] & SOFT) {
			print_limit(limits[rcswhich].rlim_cur,
				    shellparm[shelltype].lprm[rcswhich].divisor,
				    shellparm[shelltype].inf,
				    shellparm[shelltype].lprm[rcswhich].pfx,
				    shellparm[shelltype].lprm[rcswhich].sfx,
				    shellparm[shelltype].soft);
		    }
		}
	    }
	}
    }

    login_close(lc);
    exit(EXIT_SUCCESS);
}