From patchwork Fri Apr 8 17:33:17 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 695241 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 p38HTXAw013936 for ; Fri, 8 Apr 2011 17:29:52 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756695Ab1DHR3v (ORCPT ); Fri, 8 Apr 2011 13:29:51 -0400 Received: from mail-yw0-f46.google.com ([209.85.213.46]:38551 "EHLO mail-yw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755015Ab1DHR3v (ORCPT ); Fri, 8 Apr 2011 13:29:51 -0400 Received: by ywj3 with SMTP id 3so1514669ywj.19 for ; Fri, 08 Apr 2011 10:29:50 -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=Q09/MUIo0pnMM6JMwl70M0PyWYy3AodR4XBdCbu+/vM=; b=Pwil2bw4YEdfLGW3aSAiJpOFNeS62e2CYDZn5g6y8wmcmwn8PS5xFSgIxy4WSOkVPH IClqTgQR2w+L5XI0dFt6wKq3BwXUukgNghCDaAyhEegQBE6W9STIp8+iD28RF2CR3eSG L2TYX39Kv/QCIMAQNYS1n8G97Dz4vEFsovXx8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=Sfx50ksoOWsqzVMkYEN2X+1P1J3AFc1dnXF/pldoysohlDB+2eenUStzvnrZensX4B hWgMjCWUJgIF6zJe5FeQOuVKBxXpbbyyCyDE1yGpiVMtxI8lX1Lfa1faeM4fvZ77Ntcf Xf1kUy98tmtjzbInkFbICEd7wZPDozhXe4wJ0= Received: by 10.150.116.17 with SMTP id o17mr2069507ybc.394.1302283790757; Fri, 08 Apr 2011 10:29:50 -0700 (PDT) Received: from localhost ([32.97.110.58]) by mx.google.com with ESMTPS id w1sm1524297ybl.9.2011.04.08.10.29.49 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 08 Apr 2011 10:29:50 -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 #13) Date: Fri, 8 Apr 2011 12:33:17 -0500 Message-Id: <1302283997-9376-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]); Fri, 08 Apr 2011 17:29:52 +0000 (UTC) From: Shirish Pargaonkar 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) {