From patchwork Sun Jul 18 11:18:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 112601 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6IBIQ7g022023 for ; Sun, 18 Jul 2010 11:18:26 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754423Ab0GRLSZ (ORCPT ); Sun, 18 Jul 2010 07:18:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64031 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754392Ab0GRLSY (ORCPT ); Sun, 18 Jul 2010 07:18:24 -0400 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6IBIN02004357 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 18 Jul 2010 07:18:23 -0400 Received: from tlielax.poochiereds.net (vpn-11-223.rdu.redhat.com [10.11.11.223]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6IBIMGF002950; Sun, 18 Jul 2010 07:18:22 -0400 Date: Sun, 18 Jul 2010 07:18:19 -0400 From: Jeff Layton To: Jeff Layton Cc: Steve French , linux-cifs@vger.kernel.org Subject: Re: [PATCH 6/6] cifs: add separate cred_uid field to sesInfo Message-ID: <20100718071819.4264e8aa@tlielax.poochiereds.net> In-Reply-To: <20100715171936.4252a16d@corrin.poochiereds.net> References: <1277068251-16344-1-git-send-email-jlayton@redhat.com> <1277068251-16344-7-git-send-email-jlayton@redhat.com> <20100715171936.4252a16d@corrin.poochiereds.net> Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.21 Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 18 Jul 2010 11:18:27 +0000 (UTC) diff --git a/cifs.upcall.8 b/cifs.upcall.8 index 7fc1603..815dd04 100644 --- a/cifs.upcall.8 +++ b/cifs.upcall.8 @@ -22,7 +22,7 @@ cifs.upcall \- Userspace upcall helper for Common Internet File System (CIFS) .SH "SYNOPSIS" .HP \w'\ 'u -cifs\&.upcall [\-\-trust\-dns|\-t] [\-\-version|\-v] {keyid} +cifs\&.upcall [\-\-trust\-dns|\-t] [\-\-version|\-v] [\-\-legacy\-uid|\-l] {keyid} .SH "DESCRIPTION" .PP This tool is part of the cifs-utils suite\&. @@ -45,6 +45,13 @@ With krb5 upcalls, the name used as the host portion of the service principal de This is less secure than not trusting DNS\&. When using this option, it\'s possible that an attacker could get control of DNS and trick the client into mounting a different server altogether\&. It\'s preferable to instead add server principals to the KDC for every possible hostname, but this option exists for cases where that isn\'t possible\&. The default is to not trust reverse hostname lookups in this fashion\&. .RE .PP +\-\-legacy\-uid|\-l +.RS 4 +Traditionally, the kernel has sent only a single uid= parameter to the upcall for the SPNEGO upcall that\'s used to determine what user's credential cache to use. This parameter was generally determined by the uid= mount option, which also governs the ownership of files on the mount\&. +.sp +Newer kernels send a creduid= option as well, which contains what uid it thinks actually owns the credentials that it\'s looking for\&. At mount time, this is generally set to the real uid of the user doing the mount. For multisession mounts, it's set to the fsuid of the mount user. Set this option if you want cifs.upcall to use the older uid= parameter instead of the creduid= parameter\&. +.RE +.PP \-\-version|\-v .RS 4 Print version number and exit\&. diff --git a/cifs.upcall.c b/cifs.upcall.c index d4376cc..1f4341d 100644 --- a/cifs.upcall.c +++ b/cifs.upcall.c @@ -389,6 +389,7 @@ handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB * secblob, #define DKD_HAVE_IP 0x8 #define DKD_HAVE_UID 0x10 #define DKD_HAVE_PID 0x20 +#define DKD_HAVE_CREDUID 0x40 #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC) struct decoded_args { @@ -396,6 +397,7 @@ struct decoded_args { char *hostname; char *ip; uid_t uid; + uid_t creduid; pid_t pid; sectype_t sec; }; @@ -461,6 +463,16 @@ decode_key_description(const char *desc, struct decoded_args *arg) } else { retval |= DKD_HAVE_UID; } + } else if (strncmp(tkn, "creduid=", 8) == 0) { + errno = 0; + arg->creduid = strtol(tkn + 8, NULL, 16); + if (errno != 0) { + syslog(LOG_ERR, "Invalid creduid format: %s", + strerror(errno)); + return 1; + } else { + retval |= DKD_HAVE_CREDUID; + } } else if (strncmp(tkn, "ver=", 4) == 0) { /* if version */ errno = 0; arg->ver = strtol(tkn + 4, NULL, 16); @@ -584,12 +596,13 @@ static int ip_to_fqdn(const char *addrstr, char *host, size_t hostlen) static void usage(void) { - syslog(LOG_INFO, "Usage: %s [-t] [-v] key_serial", prog); - fprintf(stderr, "Usage: %s [-t] [-v] key_serial\n", prog); + syslog(LOG_INFO, "Usage: %s [-t] [-v] [-l] key_serial", prog); + fprintf(stderr, "Usage: %s [-t] [-v] [-l] key_serial\n", prog); } const struct option long_options[] = { {"trust-dns", 0, NULL, 't'}, + {"legacy-uid", 0, NULL, 'l'}, {"version", 0, NULL, 'v'}, {NULL, 0, NULL, 0} }; @@ -603,7 +616,7 @@ int main(const int argc, char *const argv[]) size_t datalen; unsigned int have; long rc = 1; - int c, try_dns = 0; + int c, try_dns = 0, legacy_uid = 0; char *buf, *princ = NULL, *ccname = NULL; char hostbuf[NI_MAXHOST], *host; struct decoded_args arg = { }; @@ -621,6 +634,9 @@ int main(const int argc, char *const argv[]) case 't': try_dns++; break; + case 'l': + legacy_uid++; + break; case 'v': printf("version: %s\n", VERSION); goto out; @@ -677,13 +693,19 @@ int main(const int argc, char *const argv[]) goto out; } - if (have & DKD_HAVE_UID) { + if (!legacy_uid && (have & DKD_HAVE_CREDUID)) { + rc = setuid(arg.creduid); + if (rc == -1) { + syslog(LOG_ERR, "setuid: %s", strerror(errno)); + goto out; + } + ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, arg.creduid); + } else if (have & DKD_HAVE_UID) { rc = setuid(arg.uid); if (rc == -1) { syslog(LOG_ERR, "setuid: %s", strerror(errno)); goto out; } - ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, arg.uid); }