From patchwork Tue Mar 8 04:47:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shirish Pargaonkar X-Patchwork-Id: 617261 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 p284iwv6023252 for ; Tue, 8 Mar 2011 04:45:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756259Ab1CHEpn (ORCPT ); Mon, 7 Mar 2011 23:45:43 -0500 Received: from mail-qw0-f46.google.com ([209.85.216.46]:61301 "EHLO mail-qw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756137Ab1CHEpm (ORCPT ); Mon, 7 Mar 2011 23:45:42 -0500 Received: by qwd7 with SMTP id 7so3695281qwd.19 for ; Mon, 07 Mar 2011 20:45:41 -0800 (PST) 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=TQlDvC2uk86+/k5NQHpEZeYp476XG2uP+pPB1DN0acA6Tw2qZzVkMG7pf1HlJczKZ8 s3WrgxD1lprJZ+xCxN0qaLqukUMigSWJmtVu9+to5QldN69nYOuAr1sHdLPXyuxCmZvI pcn4vtMqy7FOGR47ZbiPTNMSYiByu6RDr5Fw4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; b=fiRHpt8YpjDrY1baOli80ZdUan2G1qO6hcb8Avk3yj+UvK5XFNM4ZrCoZPMeQvLgs9 6yIxFbdXCV+T1Zplf8d1QloPDgxnSXl8R7VEpiSyqwVPEGuCRnHW+r9jUxur98cGm68D wY5JF+tQy8gyF/IUZlW8cjjQAmd0Tl3cRTQ1g= Received: by 10.229.42.21 with SMTP id q21mr3574241qce.137.1299559541848; Mon, 07 Mar 2011 20:45:41 -0800 (PST) Received: from localhost ([32.97.110.58]) by mx.google.com with ESMTPS id s9sm293666qco.36.2011.03.07.20.45.41 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 07 Mar 2011 20:45:41 -0800 (PST) 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 #8) Date: Mon, 7 Mar 2011 22:47:53 -0600 Message-Id: <1299559673-15585-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]); Tue, 08 Mar 2011 04:45:43 +0000 (UTC) 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) {