Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/usr.bin/su merge 1.39->1.43



details:   https://anonhg.NetBSD.org/src/rev/8ad1e26326c9
branches:  netbsd-1-5
changeset: 488996:8ad1e26326c9
user:      assar <assar%NetBSD.org@localhost>
date:      Wed Aug 09 14:52:15 2000 +0000

description:
merge 1.39->1.43

approved by thorpej

diffstat:

 usr.bin/su/su.c |  162 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 138 insertions(+), 24 deletions(-)

diffs (237 lines):

diff -r 40f87d90aa0a -r 8ad1e26326c9 usr.bin/su/su.c
--- a/usr.bin/su/su.c   Wed Aug 09 14:39:02 2000 +0000
+++ b/usr.bin/su/su.c   Wed Aug 09 14:52:15 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: su.c,v 1.39 2000/02/11 00:30:07 abs Exp $      */
+/*     $NetBSD: su.c,v 1.39.4.1 2000/08/09 14:52:15 assar Exp $        */
 
 /*
  * Copyright (c) 1988 The Regents of the University of California.
@@ -44,7 +44,7 @@
 #if 0
 static char sccsid[] = "@(#)su.c       8.3 (Berkeley) 4/2/94";*/
 #else
-__RCSID("$NetBSD: su.c,v 1.39 2000/02/11 00:30:07 abs Exp $");
+__RCSID("$NetBSD: su.c,v 1.39.4.1 2000/08/09 14:52:15 assar Exp $");
 #endif
 #endif /* not lint */
 
@@ -72,17 +72,28 @@
 #endif
 
 #ifdef KERBEROS
-#include <kerberosIV/des.h>
-#include <kerberosIV/krb.h>
+#include <des.h>
+#include <krb.h>
 #include <netdb.h>
 
+static int kerberos __P((char *, char *, int));
+static int koktologin __P((char *, char *, char *));
+
+#endif
+
+#ifdef KERBEROS5
+#include <krb5.h>
+
+static int kerberos5 __P((char *, char *, int));
+
+#endif
+
+#if defined(KERBEROS) || defined(KERBEROS5)
+
 #define        ARGSTRX "-Kflm"
 
 int use_kerberos = 1;
 
-static int kerberos __P((char *, char *, int));
-static int koktologin __P((char *, char *, char *));
-
 #else
 #define        ARGSTRX "-flm"
 #endif
@@ -131,7 +142,7 @@
        shell = class = NULL;
        while ((ch = getopt(argc, argv, ARGSTR)) != -1)
                switch((char)ch) {
-#ifdef KERBEROS
+#if defined(KERBEROS) || defined(KERBEROS5)
                case 'K':
                        use_kerberos = 0;
                        break;
@@ -216,6 +227,9 @@
 #endif
 
        if (ruid
+#ifdef KERBEROS5
+           && (!use_kerberos || kerberos5(username, user, pwd->pw_uid))
+#endif
 #ifdef KERBEROS
            && (!use_kerberos || kerberos(username, user, pwd->pw_uid))
 #endif
@@ -438,6 +452,92 @@
        return (buf);
 }
 
+#ifdef KERBEROS5
+static int
+kerberos5(username, user, uid)
+       char *username, *user;
+       int uid;
+{
+       krb5_error_code ret;
+       krb5_context context;
+       krb5_principal princ = NULL;
+       krb5_ccache ccache, ccache2;
+       char *cc_name;
+       const char *filename;
+
+       ret = krb5_init_context(&context);
+       if (ret)
+               return (1);
+
+       if (strcmp (user, "root") == 0)
+               ret = krb5_make_principal(context, &princ,
+                                         NULL, username, "root", NULL);
+       else
+               ret = krb5_make_principal(context, &princ,
+                                         NULL, user, NULL);
+       if (ret)
+               goto fail;
+       if (!krb5_kuserok(context, princ, user) && !uid) {
+               warnx ("kerberos5: not in %s's ACL.", user);
+               goto fail;
+       }
+       ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
+       if (ret)
+               goto fail;
+       ret = krb5_verify_user_lrealm(context, princ, ccache, NULL, TRUE,
+                                     NULL);
+       if (ret) {
+               krb5_cc_destroy(context, ccache);
+               switch (ret) {
+               case KRB5_LIBOS_PWDINTR :
+                       break;
+               case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+               case KRB5KRB_AP_ERR_MODIFIED:
+                       krb5_warnx(context, "Password incorrect");
+                       break;
+               default :
+                       krb5_warn(context, ret, "krb5_verify_user");
+                       break;
+               }
+               goto fail;
+       }
+       ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache2);
+       if (ret) {
+               krb5_cc_destroy(context, ccache);
+               goto fail;
+       }
+       ret = krb5_cc_copy_cache(context, ccache, ccache2);
+       if (ret) {
+               krb5_cc_destroy(context, ccache);
+               krb5_cc_destroy(context, ccache2);
+               goto fail;
+       }
+
+       filename = krb5_cc_get_name(context, ccache2);
+       asprintf(&cc_name, "%s:%s", krb5_cc_get_type(context, ccache2),
+                filename);
+       if (chown (filename, uid, -1) < 0) {
+               warn("chown %s", filename);
+               free(cc_name);
+               krb5_cc_destroy(context, ccache);
+               krb5_cc_destroy(context, ccache2);
+               goto fail;
+       }
+
+       setenv("KRB5CCNAME", cc_name, 1);
+       free(cc_name);
+       krb5_cc_close(context, ccache2);
+       krb5_cc_destroy(context, ccache);
+       return (0);
+
+ fail:
+       if (princ != NULL)
+               krb5_free_principal (context, princ);
+       krb5_free_context (context);
+       return (1);
+}
+#endif
+
 #ifdef KERBEROS
 static int
 kerberos(username, user, uid)
@@ -452,8 +552,7 @@
        char lrealm[REALM_SZ], krbtkfile[MAXPATHLEN];
        char hostname[MAXHOSTNAMELEN + 1], savehost[MAXHOSTNAMELEN + 1];
 
-       if (krb_get_lrealm(lrealm, 1) != KSUCCESS ||
-           strcmp(lrealm, KRB_REALM) == 0)
+       if (krb_get_lrealm(lrealm, 1) != KSUCCESS)
                return (1);
        if (koktologin(username, lrealm, user) && !uid) {
                warnx("kerberos: not in %s's ACL.", user);
@@ -483,9 +582,30 @@
         * We should have a way to set the ticket lifetime,
         * with a system default for root.
         */
-       kerno = krb_get_pw_in_tkt((uid == 0 ? username : user),
-               (uid == 0 ? "root" : ""), lrealm,
-               "krbtgt", lrealm, DEFAULT_TKT_LIFE, 0);
+       {
+               char prompt[128];
+               char passw[256];
+
+               (void)snprintf (prompt, sizeof(prompt),
+                         "%s's Password: ",
+                         krb_unparse_name_long ((uid == 0 ? username : user),
+                                                (uid == 0 ? "root" : ""),
+                                                lrealm));
+               if (des_read_pw_string (passw, sizeof (passw), prompt, 0)) {
+                       memset (passw, 0, sizeof (passw));
+                       return (1);
+               }
+               if (strlen(passw) == 0)
+                       return (1); /* Empty passwords are not allowed */
+
+               kerno = krb_get_pw_in_tkt((uid == 0 ? username : user),
+                                         (uid == 0 ? "root" : ""), lrealm,
+                                         KRB_TICKET_GRANTING_TICKET,
+                                         lrealm,
+                                         DEFAULT_TKT_LIFE,
+                                         passw);
+               memset (passw, 0, strlen (passw));
+       }
 
        if (kerno != KSUCCESS) {
                if (kerno == KDC_PR_UNKNOWN) {
@@ -516,7 +636,7 @@
        }
        hostname[sizeof(hostname) - 1] = '\0';
 
-       (void)strncpy(savehost, krb_get_phost(hostname), sizeof(savehost));
+       (void)strlcpy(savehost, krb_get_phost(hostname), sizeof(savehost));
        savehost[sizeof(savehost) - 1] = '\0';
 
        kerno = krb_mk_req(&ticket, "rcmd", savehost, lrealm, 33);
@@ -559,15 +679,9 @@
 koktologin(name, realm, toname)
        char *name, *realm, *toname;
 {
-       AUTH_DAT *kdata;
-       AUTH_DAT kdata_st;
-
-       kdata = &kdata_st;
-       memset((char *)kdata, 0, sizeof(*kdata));
-       (void)strncpy(kdata->pname, name, sizeof(kdata->pname) - 1);
-       (void)strncpy(kdata->pinst,
-           ((strcmp(toname, "root") == 0) ? "root" : ""), sizeof(kdata->pinst) - 1);
-       (void)strncpy(kdata->prealm, realm, sizeof(kdata->prealm) - 1);
-       return (kuserok(kdata, toname));
+       return krb_kuserok(name,
+                          strcmp (toname, "root") == 0 ? "root" : "",
+                          realm,
+                          toname);
 }
 #endif



Home | Main Index | Thread Index | Old Index