From patchwork Sat Apr 9 01:20:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 695671 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p391GocN008997 for ; Sat, 9 Apr 2011 01:16:59 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757983Ab1DIBQ7 (ORCPT ); Fri, 8 Apr 2011 21:16:59 -0400 Received: from mail-iw0-f174.google.com ([209.85.214.174]:43253 "EHLO mail-iw0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757660Ab1DIBQ6 (ORCPT ); Fri, 8 Apr 2011 21:16:58 -0400 Received: by mail-iw0-f174.google.com with SMTP id 34so3919651iwn.19 for ; Fri, 08 Apr 2011 18:16:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer; bh=2NVYUU6egE6mVIkEB8eiCYBMtmXHzybXyVuXa3cuRAk=; b=PDMqHk2eWMJAaQEoun3AgPoDu7+faVdr3QycXRB58uzSvR9Q4kR55aMk+MWVpXD1nS RlWEz5axYh8bKXTtXaZbHvL1qKuiLVkUoYdfcWjFrs3d8+Phe02WLI3yb2jZ7uGn3sAp KQ5iSXaFk+BLcoFxTyIzQpC8ag3J4ew9x0CGU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=Na9zlZX6FNfknrbTP62LFWXK4fSZv1SJYKumVKdb7ODdRW7HQFYR4UhXiQ4EfWTMJ0 nMO25X0LGS9glBL/tDGDAV9lXbX31NoB7jHsP/OnLoz9Z4M/6omhJDbg+y87WeR4KnRl PSECbNV1i63e+ofyOTKMBi7z42G0FkVozsTw8= Received: by 10.42.159.6 with SMTP id j6mr3750322icx.260.1302311818346; Fri, 08 Apr 2011 18:16:58 -0700 (PDT) Received: from localhost ([32.97.110.58]) by mx.google.com with ESMTPS id o3sm2234630ibd.10.2011.04.08.18.16.56 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 08 Apr 2011 18:16:57 -0700 (PDT) From: shirishpargaonkar@gmail.com To: jlayton@redhat.com Cc: linux-cifs@vger.kernel.org, Shirish Pargaonkar Subject: [PATCH] cifs-utils: Handle cifs_idmap type of key to map a SID to either an uid or gid (try #14) Date: Fri, 8 Apr 2011 20:20:25 -0500 Message-Id: <1302312025-17464-1-git-send-email-shirishpargaonkar@gmail.com> X-Mailer: git-send-email 1.6.0.2 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.6 (demeter1.kernel.org [140.211.167.41]); Sat, 09 Apr 2011 01:16:59 +0000 (UTC) From: Shirish Pargaonkar Handle cifs_idmap type of key. Extract a SID string from the description and map it to either an uid or gid using winbind APIs. If that fails (e.g. because winbind is not installed/running or winbind returns an error), try to obtain uid of 'nobody' and gid of 'nogroup'. And if that fails, kernel assigns uid and gid (from mount superblock). An entry such as this create cifs.cifs_idmap * * /usr/sbin/cifs.upcall %k is needed in the file /etc/request-key.conf. Signed-off-by: Shirish Pargaonkar --- Makefile.am | 2 +- cifs.upcall.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletions(-) diff --git a/Makefile.am b/Makefile.am index 67a0190..c9018ae 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ man_MANS = mount.cifs.8 if CONFIG_CIFSUPCALL sbin_PROGRAMS = cifs.upcall cifs_upcall_SOURCES = cifs.upcall.c data_blob.c asn1.c spnego.c util.c -cifs_upcall_LDADD = -ltalloc -lkeyutils $(KRB5_LDADD) +cifs_upcall_LDADD = -ltalloc -lwbclient -lkeyutils $(KRB5_LDADD) man_MANS += cifs.upcall.8 # diff --git a/cifs.upcall.c b/cifs.upcall.c index 479517c..68a8059 100644 --- a/cifs.upcall.c +++ b/cifs.upcall.c @@ -45,6 +45,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include "util.h" #include "replace.h" @@ -695,6 +702,103 @@ static int cifs_resolver(const key_serial_t key, const char *key_descr) return 0; } +static int +cifs_sid_resolver(const key_serial_t key, const char *key_descr) +{ + int i; + uid_t uid = 0; + gid_t gid = 0;; + wbcErr rc = 1; + const char *keyend = key_descr; + struct wbcDomainSid sid; + struct passwd *pw; + struct group *gr; + + /* skip next 4 ';' delimiters to get to description */ + for (i = 1; i <= 4; ++i) { + keyend = index(keyend + 1, ';'); + if (!keyend) { + syslog(LOG_ERR, "invalid key description: %s", + key_descr); + return 1; + } + } + keyend++; + + /* + * Use winbind to convert received string to a SID and lookup + * name and map that SID to an uid. If either of these + * function calls return with an error, use system calls to obtain + * uid of user "nobody". If winbind fails to map a SID to an UID + * and there is no user named "nobody", return error to the + * upcall caller. Otherwise instanticate a key using that uid. + * + * The same applies to SID and gid mapping. Instead of a + * user "nobody", user "nogroup" is looked up if winbind + * fails to map a SID to a gid. + */ + if (strncmp(keyend, "os", 2) == 0) { + keyend = index(keyend + 1, ':'); + keyend++; + rc = wbcStringToSid(keyend, &sid); + if (rc) + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); + else { + rc = wbcSidToUid(&sid, &uid); + if (rc) + syslog(LOG_DEBUG, "SID %s to uid wbc error: %d", + keyend, rc); + } + if (rc) { /* either of the two wbcSid functions failed */ + pw = getpwnam("nobody"); + if (!pw) + syslog(LOG_DEBUG, "SID %s to uid pw error: %d", + keyend, rc); + else { + uid = pw->pw_uid; + rc = 0; + } + } + if (!rc) { /* SID has been mapped to a uid */ + rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0); + if (rc) + syslog(LOG_ERR, "%s: key inst: %s", + __func__, strerror(errno)); + } + } else if (strncmp(keyend, "gs", 2) == 0) { + keyend = index(keyend + 1, ':'); + keyend++; + rc = wbcStringToSid(keyend, &sid); + if (rc) + syslog(LOG_DEBUG, "O strtosid: %s, rc: %d", keyend, rc); + else { + rc = wbcSidToGid(&sid, &gid); + if (rc) + syslog(LOG_DEBUG, "SID %s to gid wbc error: %d", + keyend, rc); + } + if (rc) { /* either of the two wbcSid functions failed */ + gr = getgrnam("nogroup"); + if (!gr) + syslog(LOG_DEBUG, "SID %s to gid pw error: %d", + keyend, rc); + else { + gid = gr->gr_gid; + rc = 0; + } + } + if (!rc) { /* SID has been mapped to a gid */ + rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0); + if (rc) + syslog(LOG_ERR, "%s: key inst: %s", + __func__, strerror(errno)); + } + } else + syslog(LOG_DEBUG, "Invalid SID: %s", keyend); + + return rc; +} + /* * Older kernels sent IPv6 addresses without colons. Well, at least * they're fixed-length strings. Convert these addresses to have colon @@ -833,6 +937,12 @@ int main(const int argc, char *const argv[]) goto out; } + if ((strncmp(buf, "cifs.cifs_idmap", sizeof("cifs.cifs_idmap") - 1) + == 0)) { + rc = cifs_sid_resolver(key, buf); + goto out; + } + have = decode_key_description(buf, &arg); SAFE_FREE(buf); if ((have & DKD_MUSTHAVE_SET) != DKD_MUSTHAVE_SET) {