From be0348cb75cae58cd1683f6fdbff884cb9bc405b Mon Sep 17 00:00:00 2001 From: dfr Date: Wed, 7 May 2008 13:53:12 +0000 Subject: Fix conflicts after heimdal-1.1 import and add build infrastructure. Import all non-style changes made by heimdal to our own libgssapi. --- crypto/heimdal/appl/su/Makefile.am | 11 ++- crypto/heimdal/appl/su/su.c | 183 +++++++++++++++++++++++++------------ 2 files changed, 134 insertions(+), 60 deletions(-) (limited to 'crypto/heimdal/appl/su') diff --git a/crypto/heimdal/appl/su/Makefile.am b/crypto/heimdal/appl/su/Makefile.am index 357152e..6bb584f 100644 --- a/crypto/heimdal/appl/su/Makefile.am +++ b/crypto/heimdal/appl/su/Makefile.am @@ -1,17 +1,20 @@ -# $Id: Makefile.am,v 1.7 2001/08/28 08:31:22 assar Exp $ +# $Id: Makefile.am 21986 2007-10-19 05:22:57Z lha $ # $FreeBSD$ include $(top_srcdir)/Makefile.am.common -INCLUDES += $(INCLUDE_krb4) $(INCLUDE_des) +AM_CPPFLAGS += $(INCLUDE_krb4) $(INCLUDE_hcrypto) bin_PROGRAMS = su bin_SUIDS = su -su_SOURCES = su.c +su_SOURCES = su.c supaths.h +man_MANS = su.1 LDADD = $(LIB_kafs) \ $(top_builddir)/lib/krb5/libkrb5.la \ $(LIB_krb4) \ - $(LIB_des) \ + $(LIB_hcrypto) \ $(top_builddir)/lib/asn1/libasn1.la \ $(LIB_roken) + +EXTRA_DIST = $(man_MANS) diff --git a/crypto/heimdal/appl/su/su.c b/crypto/heimdal/appl/su/su.c index 757f39d..e8e4783 100644 --- a/crypto/heimdal/appl/su/su.c +++ b/crypto/heimdal/appl/su/su.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan + * Copyright (c) 1999 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,7 @@ #include -RCSID("$Id: su.c,v 1.26.2.1 2003/05/06 12:06:44 joda Exp $"); +RCSID("$Id: su.c 21988 2007-10-19 05:36:54Z lha $"); #include #include @@ -53,6 +53,9 @@ RCSID("$Id: su.c,v 1.26.2.1 2003/05/06 12:06:44 joda Exp $"); #endif #include +#ifdef HAVE_CRYPT_H +#include +#endif #include "crypto-headers.h" #ifdef KRB5 @@ -66,13 +69,7 @@ RCSID("$Id: su.c,v 1.26.2.1 2003/05/06 12:06:44 joda Exp $"); #include #include -#ifndef _PATH_DEFPATH -#define _PATH_DEFPATH "/usr/bin:/bin" -#endif - -#ifndef _PATH_BSHELL -#define _PATH_BSHELL "/bin/sh" -#endif +#include "supaths.h" int kerberos_flag = 1; int csh_f_flag; @@ -175,7 +172,9 @@ krb5_verify(const struct passwd *login_info, { krb5_error_code ret; krb5_principal p; + krb5_realm *realms, *r; char *login_name = NULL; + int user_ok = 0; #if defined(HAVE_GETLOGIN) && !defined(POSIX_GETLOGIN) login_name = getlogin(); @@ -188,50 +187,63 @@ krb5_verify(const struct passwd *login_info, return 1; } - if (login_name == NULL || strcmp (login_name, "root") == 0) - login_name = login_info->pw_name; - if (strcmp (su_info->pw_name, "root") == 0) - ret = krb5_make_principal(context, &p, NULL, - login_name, - kerberos_instance, - NULL); - else - ret = krb5_make_principal(context, &p, NULL, - su_info->pw_name, - NULL); - if(ret) + ret = krb5_get_default_realms(context, &realms); + if (ret) return 1; + + /* Check all local realms */ + for (r = realms; *r != NULL && !user_ok; r++) { + + if (login_name == NULL || strcmp (login_name, "root") == 0) + login_name = login_info->pw_name; + if (strcmp (su_info->pw_name, "root") == 0) + ret = krb5_make_principal(context, &p, *r, + login_name, + kerberos_instance, + NULL); + else + ret = krb5_make_principal(context, &p, *r, + su_info->pw_name, + NULL); + if (ret) { + krb5_free_host_realm(context, realms); + return 1; + } - if(su_info->pw_uid != 0 || krb5_kuserok(context, p, su_info->pw_name)) { + /* if we are su-ing too root, check with krb5_kuserok */ + if (su_info->pw_uid == 0 && !krb5_kuserok(context, p, su_info->pw_name)) + continue; + ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache); if(ret) { -#if 1 - krb5_warn(context, ret, "krb5_cc_gen_new"); -#endif + krb5_free_host_realm(context, realms); krb5_free_principal (context, p); return 1; } - ret = krb5_verify_user_lrealm(context, p, ccache, NULL, TRUE, NULL); + ret = krb5_verify_user(context, p, ccache, NULL, TRUE, NULL); krb5_free_principal (context, p); - if(ret) { + switch (ret) { + case 0: + user_ok = 1; + break; + case KRB5_LIBOS_PWDINTR : 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; - } - return 1; + break; + case KRB5KRB_AP_ERR_BAD_INTEGRITY: + case KRB5KRB_AP_ERR_MODIFIED: + krb5_cc_destroy(context, ccache); + krb5_warnx(context, "Password incorrect"); + break; + default : + krb5_cc_destroy(context, ccache); + krb5_warn(context, ret, "krb5_verify_user"); + break; } - return 0; } - krb5_free_principal (context, p); - return 1; + krb5_free_host_realm(context, realms); + if (!user_ok) + return 1; + return 0; } static int @@ -249,8 +261,10 @@ krb5_start_session(void) ret = krb5_cc_copy_cache(context, ccache, ccache2); - asprintf(&cc_name, "%s:%s", krb5_cc_get_type(context, ccache2), - krb5_cc_get_name(context, ccache2)); + ret = asprintf(&cc_name, "%s:%s", krb5_cc_get_type(context, ccache2), + krb5_cc_get_name(context, ccache2)); + if (ret == -1) + errx(1, "malloc - out of memory"); esetenv("KRB5CCNAME", cc_name, 1); /* we want to export this even if we don't directly support KRB4 */ @@ -300,10 +314,12 @@ krb_verify(const struct passwd *login_info, krb_kuserok(name, instance, realm, su_info->pw_name) == 0) { char password[128]; char *prompt; - asprintf (&prompt, + ret = asprintf (&prompt, "%s's Password: ", krb_unparse_name_long (name, instance, realm)); - if (des_read_pw_string (password, sizeof (password), prompt, 0)) { + if (ret == -1) + return (1); + if (UI_UTIL_read_pw_string (password, sizeof (password), prompt, 0)) { memset (password, 0, sizeof (password)); free(prompt); return (1); @@ -341,8 +357,29 @@ krb_start_session(void) } #endif +#define GROUP_MEMBER 0 +#define GROUP_MISSING 1 +#define GROUP_EMPTY 2 +#define GROUP_NOT_MEMBER 3 + +static int +group_member_p(const char *group, const char *user) +{ + struct group *g; + int i; + g = getgrnam(group); + if(g == NULL) + return GROUP_MISSING; + if(g->gr_mem[0] == NULL) + return GROUP_EMPTY; + for(i = 0; g->gr_mem[i] != NULL; i++) + if(strcmp(user, g->gr_mem[i]) == 0) + return GROUP_MEMBER; + return GROUP_NOT_MEMBER; +} + static int -verify_unix(struct passwd *su) +verify_unix(struct passwd *login, struct passwd *su) { char prompt[128]; char pw_buf[1024]; @@ -350,13 +387,31 @@ verify_unix(struct passwd *su) int r; if(su->pw_passwd != NULL && *su->pw_passwd != '\0') { snprintf(prompt, sizeof(prompt), "%s's password: ", su->pw_name); - r = des_read_pw_string(pw_buf, sizeof(pw_buf), prompt, 0); + r = UI_UTIL_read_pw_string(pw_buf, sizeof(pw_buf), prompt, 0); if(r != 0) exit(0); pw = crypt(pw_buf, su->pw_passwd); memset(pw_buf, 0, sizeof(pw_buf)); - if(strcmp(pw, su->pw_passwd) != 0) + if(strcmp(pw, su->pw_passwd) != 0) { + syslog (LOG_ERR | LOG_AUTH, "%s to %s: incorrect password", + login->pw_name, su->pw_name); + return 1; + } + } + /* if su:ing to root, check membership of group wheel or root; if + that group doesn't exist, or is empty, allow anyone to su + root */ + if(su->pw_uid == 0) { +#ifndef ROOT_GROUP +#define ROOT_GROUP "wheel" +#endif + int gs = group_member_p(ROOT_GROUP, login->pw_name); + if(gs == GROUP_NOT_MEMBER) { + syslog (LOG_ERR | LOG_AUTH, "%s to %s: not in group %s", + login->pw_name, su->pw_name, ROOT_GROUP); return 1; + } + return 0; } return 0; } @@ -398,6 +453,9 @@ main(int argc, char **argv) else su_user = argv[optind++]; + if (!issuid() && getuid() != 0) + warnx("Not setuid and you are root, expect this to fail"); + pwd = k_getpwnam(su_user); if(pwd == NULL) errx (1, "unknown login %s", su_user); @@ -434,7 +492,7 @@ main(int argc, char **argv) ok = 4; #endif - if(ok == 0 && login_info->pw_uid && verify_unix(su_info) != 0) { + if(ok == 0 && login_info->pw_uid && verify_unix(login_info, su_info) != 0) { printf("Sorry!\n"); exit(1); } @@ -473,7 +531,7 @@ main(int argc, char **argv) #endif { char *tty = ttyname (STDERR_FILENO); - syslog (LOG_NOTICE | LOG_AUTH, tty ? "%s to %s" : "%s to %s on %s", + syslog (LOG_NOTICE | LOG_AUTH, tty ? "%s to %s on %s" : "%s to %s", login_info->pw_name, su_info->pw_name, tty); } @@ -481,11 +539,23 @@ main(int argc, char **argv) if(!env_flag) { if(full_login) { char *t = getenv ("TERM"); - - environ = malloc (10 * sizeof (char *)); + char **newenv = NULL; + int i, j; + + i = read_environment(_PATH_ETC_ENVIRONMENT, &newenv); + + environ = malloc ((10 + i) * sizeof (char *)); if (environ == NULL) err (1, "malloc"); environ[0] = NULL; + + for (j = 0; j < i; j++) { + char *p = strchr(newenv[j], '='); + *p++ = 0; + esetenv (newenv[j], p, 1); + } + free(newenv); + esetenv ("PATH", _PATH_DEFPATH, 1); if (t) esetenv ("TERM", t, 1); @@ -516,9 +586,10 @@ main(int argc, char **argv) if (args == NULL) err (1, "malloc"); i = 0; - if(full_login) - asprintf(&args[i++], "-%s", p); - else + if(full_login) { + if (asprintf(&args[i++], "-%s", p) == -1) + errx (1, "malloc"); + } else args[i++] = p; if (cmd) { args[i++] = "-c"; -- cgit v1.1