- make LOGIN_CAP mandatory
- eliminate global pamh - use setusercontext() properly (ideas borrowed from FreeBSD) - remove stray debugging. This now works.
This commit is contained in:
parent
6b47b9b52a
commit
81b53d0cfa
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: su_pam.c,v 1.1 2005/01/10 03:11:50 christos Exp $ */
|
/* $NetBSD: su_pam.c,v 1.2 2005/01/10 23:33:53 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1988 The Regents of the University of California.
|
* Copyright (c) 1988 The Regents of the University of California.
|
||||||
|
@ -40,7 +40,7 @@ __COPYRIGHT(
|
||||||
#if 0
|
#if 0
|
||||||
static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/
|
static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/
|
||||||
#else
|
#else
|
||||||
__RCSID("$NetBSD: su_pam.c,v 1.1 2005/01/10 03:11:50 christos Exp $");
|
__RCSID("$NetBSD: su_pam.c,v 1.2 2005/01/10 23:33:53 christos Exp $");
|
||||||
#endif
|
#endif
|
||||||
#endif /* not lint */
|
#endif /* not lint */
|
||||||
|
|
||||||
|
@ -60,17 +60,13 @@ __RCSID("$NetBSD: su_pam.c,v 1.1 2005/01/10 03:11:50 christos Exp $");
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <tzfile.h>
|
#include <tzfile.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef LOGIN_CAP
|
|
||||||
#include <login_cap.h>
|
#include <login_cap.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <security/pam_appl.h>
|
#include <security/pam_appl.h>
|
||||||
#include <security/openpam.h> /* for openpam_ttyconv() */
|
#include <security/openpam.h> /* for openpam_ttyconv() */
|
||||||
|
|
||||||
|
|
||||||
static pam_handle_t *pamh = NULL;
|
|
||||||
static const struct pam_conv pamc = { &openpam_ttyconv, NULL };
|
static const struct pam_conv pamc = { &openpam_ttyconv, NULL };
|
||||||
|
|
||||||
static int chshell(const char *);
|
static int chshell(const char *);
|
||||||
static char *ontty(void);
|
static char *ontty(void);
|
||||||
|
|
||||||
|
@ -91,7 +87,7 @@ main(int argc, char **argv)
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
char *p;
|
char *p;
|
||||||
uid_t ruid;
|
uid_t ruid;
|
||||||
int asme, ch, asthem, fastlogin, prio, gohome;
|
int asme, ch, asthem, fastlogin, prio, gohome, setwhat;
|
||||||
enum { UNSET, YES, NO } iscsh = UNSET;
|
enum { UNSET, YES, NO } iscsh = UNSET;
|
||||||
char *user, *shell, *avshell, *username, **np;
|
char *user, *shell, *avshell, *username, **np;
|
||||||
char *class;
|
char *class;
|
||||||
|
@ -101,9 +97,8 @@ main(int argc, char **argv)
|
||||||
char *tty;
|
char *tty;
|
||||||
const char *func;
|
const char *func;
|
||||||
const void *newuser;
|
const void *newuser;
|
||||||
#ifdef LOGIN_CAP
|
|
||||||
login_cap_t *lc;
|
login_cap_t *lc;
|
||||||
#endif
|
pam_handle_t *pamh = NULL;
|
||||||
#ifdef PAM_DEBUG
|
#ifdef PAM_DEBUG
|
||||||
extern int _openpam_debug;
|
extern int _openpam_debug;
|
||||||
_openpam_debug = 1;
|
_openpam_debug = 1;
|
||||||
|
@ -114,11 +109,9 @@ main(int argc, char **argv)
|
||||||
shell = class = NULL;
|
shell = class = NULL;
|
||||||
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
|
while ((ch = getopt(argc, argv, ARGSTR)) != -1)
|
||||||
switch((char)ch) {
|
switch((char)ch) {
|
||||||
#ifdef LOGIN_CAP
|
|
||||||
case 'c':
|
case 'c':
|
||||||
class = optarg;
|
class = optarg;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case 'd':
|
case 'd':
|
||||||
asme = 0;
|
asme = 0;
|
||||||
asthem = 1;
|
asthem = 1;
|
||||||
|
@ -263,7 +256,6 @@ main(int argc, char **argv)
|
||||||
err args; \
|
err args; \
|
||||||
} while (/* CONSTOCOND */0)
|
} while (/* CONSTOCOND */0)
|
||||||
|
|
||||||
#ifdef LOGIN_CAP
|
|
||||||
/* force the usage of specified class */
|
/* force the usage of specified class */
|
||||||
if (class) {
|
if (class) {
|
||||||
if (ruid)
|
if (ruid)
|
||||||
|
@ -271,9 +263,9 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
pwd->pw_class = class;
|
pwd->pw_class = class;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((lc = login_getclass(pwd->pw_class)) == NULL)
|
if ((lc = login_getclass(pwd->pw_class)) == NULL)
|
||||||
ERRX_PAM_END((1, "Unknown class %s\n", pwd->pw_class));
|
ERRX_PAM_END((1, "Unknown class %s\n", pwd->pw_class));
|
||||||
#endif
|
|
||||||
|
|
||||||
if (asme) {
|
if (asme) {
|
||||||
/* if asme and non-standard target shell, must be root */
|
/* if asme and non-standard target shell, must be root */
|
||||||
|
@ -296,27 +288,16 @@ main(int argc, char **argv)
|
||||||
if (iscsh == UNSET)
|
if (iscsh == UNSET)
|
||||||
iscsh = strstr(avshell, "csh") ? YES : NO;
|
iscsh = strstr(avshell, "csh") ? YES : NO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set permissions. We change the user credentials (UID) here
|
* Initialize the supplemental groups before pam gets to them,
|
||||||
* XXX PAM should come before LOGIN_CAP so that the class
|
* so that other pam modules get a chance to add more when
|
||||||
* specified through -c can override PAM. But as we might drop
|
* we do setcred. Note, we don't relinguish our set-userid yet
|
||||||
* root UID on both operations, it is not possible to do that.
|
|
||||||
* If a login class was specified, skip PAM.
|
|
||||||
*/
|
*/
|
||||||
#ifdef LOGIN_CAP
|
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) < 0)
|
||||||
if (class) {
|
ERR_PAM_END((1, "setting user context"));
|
||||||
if (setusercontext(lc, pwd, pwd->pw_uid,
|
|
||||||
(asthem ? (LOGIN_SETPRIORITY | LOGIN_SETUMASK) : 0) |
|
if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS)
|
||||||
LOGIN_SETRESOURCES | LOGIN_SETGROUP | LOGIN_SETUSER))
|
PAM_END("pam_setcred");
|
||||||
ERR_PAM_END((1, "setting user context"));
|
|
||||||
printf("%d %d\n", asthem, pwd->pw_uid);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED);
|
|
||||||
if (pam_err != PAM_SUCCESS)
|
|
||||||
PAM_END("pam_setcred");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Manage session.
|
* Manage session.
|
||||||
|
@ -432,12 +413,8 @@ main(int argc, char **argv)
|
||||||
free(pamenv);
|
free(pamenv);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LOGIN_CAP
|
|
||||||
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH))
|
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH))
|
||||||
err(1, "setting user context");
|
err(1, "setting user context");
|
||||||
#else
|
|
||||||
(void)setenv("PATH", _PATH_DEFPATH, 1);
|
|
||||||
#endif
|
|
||||||
if (p)
|
if (p)
|
||||||
(void)setenv("TERM", p, 1);
|
(void)setenv("TERM", p, 1);
|
||||||
if (gohome && chdir(pwd->pw_dir) < 0)
|
if (gohome && chdir(pwd->pw_dir) < 0)
|
||||||
|
@ -477,10 +454,23 @@ main(int argc, char **argv)
|
||||||
syslog(LOG_NOTICE, "%s to %s%s",
|
syslog(LOG_NOTICE, "%s to %s%s",
|
||||||
username, pwd->pw_name, ontty());
|
username, pwd->pw_name, ontty());
|
||||||
|
|
||||||
/* Raise our priority back to what we had before */
|
/*
|
||||||
(void)setpriority(PRIO_PROCESS, 0, prio);
|
* Set user context, except for umask, and the stuff
|
||||||
|
* we have done before.
|
||||||
|
*/
|
||||||
|
setwhat = LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETUMASK|
|
||||||
|
LOGIN_SETLOGIN|LOGIN_SETPATH|LOGIN_SETGROUP);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't touch resource/priority settings if -m has been used
|
||||||
|
* or -l and -c hasn't, and we're not su'ing to root.
|
||||||
|
*/
|
||||||
|
if ((asme || (!asthem && class == NULL)) && pwd->pw_uid)
|
||||||
|
setwhat &= ~(LOGIN_SETPRIORITY|LOGIN_SETRESOURCES);
|
||||||
|
|
||||||
|
if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) == -1)
|
||||||
|
err(1, "setusercontext");
|
||||||
|
|
||||||
printf("%d %d\n", geteuid(), getuid());
|
|
||||||
(void)execv(shell, np);
|
(void)execv(shell, np);
|
||||||
err(1, "%s", shell);
|
err(1, "%s", shell);
|
||||||
done:
|
done:
|
||||||
|
|
Loading…
Reference in New Issue