summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/appl/su/su.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/appl/su/su.c')
-rw-r--r--crypto/heimdal/appl/su/su.c145
1 files changed, 122 insertions, 23 deletions
diff --git a/crypto/heimdal/appl/su/su.c b/crypto/heimdal/appl/su/su.c
index c9a806e..175f375 100644
--- a/crypto/heimdal/appl/su/su.c
+++ b/crypto/heimdal/appl/su/su.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -32,7 +32,7 @@
#include <config.h>
-RCSID("$Id: su.c,v 1.23 2002/01/09 19:40:12 nectar Exp $");
+RCSID("$Id: su.c,v 1.24 2002/02/19 13:01:15 joda Exp $");
#include <stdio.h>
#include <stdlib.h>
@@ -55,12 +55,16 @@ RCSID("$Id: su.c,v 1.23 2002/01/09 19:40:12 nectar Exp $");
#else
#include <des.h>
#endif
+#ifdef KRB5
#include <krb5.h>
+#endif
+#ifdef KRB4
+#include <krb.h>
#include <kafs.h>
+#endif
#include <err.h>
#include <roken.h>
#include <getarg.h>
-#include <kafs.h>
#ifndef _PATH_DEFPATH
#define _PATH_DEFPATH "/usr/bin:/bin"
@@ -78,6 +82,7 @@ char *kerberos_instance = "root";
int help_flag;
int version_flag;
char *cmd;
+char tkfile[256];
struct getargs args[] = {
{ "kerberos", 'K', arg_negative_flag, &kerberos_flag,
@@ -139,17 +144,35 @@ dup_info(const struct passwd *pwd)
return info;
}
+#if defined(KRB4) || defined(KRB5)
+static void
+set_tkfile()
+{
+#ifndef TKT_ROOT
+#define TKT_ROOT "/tmp/tkt"
+#endif
+ int fd;
+ if(*tkfile != '\0')
+ return;
+ snprintf(tkfile, sizeof(tkfile), "%s_XXXXXX", TKT_ROOT);
+ fd = mkstemp(tkfile);
+ if(fd >= 0)
+ close(fd);
+#ifdef KRB4
+ krb_set_tkt_string(tkfile);
+#endif
+}
+#endif
+
#ifdef KRB5
static krb5_context context;
static krb5_ccache ccache;
-#endif
static int
krb5_verify(const struct passwd *login_info,
const struct passwd *su_info,
const char *kerberos_instance)
{
-#ifdef KRB5
krb5_error_code ret;
krb5_principal p;
char *login_name = NULL;
@@ -208,11 +231,9 @@ krb5_verify(const struct passwd *login_info,
return 0;
}
krb5_free_principal (context, p);
-#endif
return 1;
}
-#ifdef KRB5
static int
krb5_start_session(void)
{
@@ -233,20 +254,8 @@ krb5_start_session(void)
esetenv("KRB5CCNAME", cc_name, 1);
/* we want to export this even if we don't directly support KRB4 */
- {
-#ifndef TKT_ROOT
-#define TKT_ROOT "/tmp/tkt"
-#endif
- int fd;
- char tkfile[256];
- strlcpy(tkfile, TKT_ROOT, sizeof(tkfile));
- strlcat(tkfile, "_XXXXXX", sizeof(tkfile));
- fd = mkstemp(tkfile);
- if(fd >= 0) {
- close(fd);
- esetenv("KRBTKFILE", tkfile, 1);
- }
- }
+ set_tkfile();
+ esetenv("KRBTKFILE", tkfile, 1);
#ifdef KRB4
/* convert creds? */
@@ -262,6 +271,78 @@ krb5_start_session(void)
}
#endif
+#ifdef KRB4
+
+static int
+krb_verify(const struct passwd *login_info,
+ const struct passwd *su_info,
+ const char *kerberos_instance)
+{
+ int ret;
+ char *login_name = NULL;
+ char *name, *instance, realm[REALM_SZ];
+
+#if defined(HAVE_GETLOGIN) && !defined(POSIX_GETLOGIN)
+ login_name = getlogin();
+#endif
+
+ ret = krb_get_lrealm(realm, 1);
+
+ if (login_name == NULL || strcmp (login_name, "root") == 0)
+ login_name = login_info->pw_name;
+ if (strcmp (su_info->pw_name, "root") == 0) {
+ name = login_name;
+ instance = (char*)kerberos_instance;
+ } else {
+ name = su_info->pw_name;
+ instance = "";
+ }
+
+ if(su_info->pw_uid != 0 ||
+ krb_kuserok(name, instance, realm, su_info->pw_name) == 0) {
+ char password[128];
+ char *prompt;
+ asprintf (&prompt,
+ "%s's Password: ",
+ krb_unparse_name_long (name, instance, realm));
+ if (des_read_pw_string (password, sizeof (password), prompt, 0)) {
+ memset (password, 0, sizeof (password));
+ free(prompt);
+ return (1);
+ }
+ free(prompt);
+ if (strlen(password) == 0)
+ return (1); /* Empty passwords are not allowed */
+ set_tkfile();
+ setuid(geteuid()); /* need to run as root here */
+ ret = krb_verify_user(name, instance, realm, password,
+ KRB_VERIFY_SECURE, NULL);
+ memset(password, 0, sizeof(password));
+
+ if(ret) {
+ warnx("%s", krb_get_err_text(ret));
+ return 1;
+ }
+ chown (tkt_string(), su_info->pw_uid, su_info->pw_gid);
+ return 0;
+ }
+ return 1;
+}
+
+
+static int
+krb_start_session(void)
+{
+ esetenv("KRBTKFILE", tkfile, 1);
+
+ /* convert creds? */
+ if(k_hasafs() && k_setpag() == 0)
+ krb_afslog(NULL, NULL);
+
+ return 0;
+}
+#endif
+
static int
verify_unix(struct passwd *su)
{
@@ -343,9 +424,17 @@ main(int argc, char **argv)
if(shell == NULL || *shell == '\0')
shell = _PATH_BSHELL;
+
+#ifdef KRB5
if(kerberos_flag && ok == 0 &&
(kerberos_error=krb5_verify(login_info, su_info, kerberos_instance)) == 0)
- ok++;
+ ok = 5;
+#endif
+#ifdef KRB4
+ if(kerberos_flag && ok == 0 &&
+ (kerberos_error = krb_verify(login_info, su_info, kerberos_instance)) == 0)
+ ok = 4;
+#endif
if(ok == 0 && login_info->pw_uid && verify_unix(su_info) != 0) {
printf("Sorry!\n");
@@ -454,9 +543,19 @@ main(int argc, char **argv)
err(1, "setuid");
#ifdef KRB5
- if (!kerberos_error)
+ if (ok == 5)
krb5_start_session();
#endif
+#ifdef KRB4
+ if (ok == 4)
+ krb_start_session();
+#endif
+ {
+ char **p;
+ for(p = args; *p; p++)
+ printf("%s ", *p);
+ printf("\n");
+ }
execv(shell, args);
}
OpenPOWER on IntegriCloud