Re: [PATCH] cifs-utils: handle cifs_idmap type of key to map a SID to either an uid or gid (try #5)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 16 Feb 2011 12:05:34 -0600
Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote:

> On Tue, Feb 15, 2011 at 2:45 PM, Jeff Layton <jlayton@xxxxxxxxxx> wrote:
> > On Fri, 11 Feb 2011 12:49:09 -0600
> > shirishpargaonkar@xxxxxxxxx wrote:
> >
> >> From: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx>
> >>
> >>
> >> 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 <shirishpargaonkar@xxxxxxxxx>
> >> ---
> >>  Makefile.am   |    2 +-
> >>  cifs.upcall.c |   98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  2 files changed, 99 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..fe8a6ad 100644
> >> --- a/cifs.upcall.c
> >> +++ b/cifs.upcall.c
> >> @@ -45,6 +45,13 @@
> >>  #include <time.h>
> >>  #include <netdb.h>
> >>  #include <arpa/inet.h>
> >> +#include <stdint.h>
> >> +#include <stdbool.h>
> >> +#include <stdio.h>
> >> +#include <stdlib.h>
> >> +#include <errno.h>
> >> +#include <limits.h>
> >> +#include <wbclient.h>
> >>
> >>  #include "util.h"
> >>  #include "replace.h"
> >> @@ -695,6 +702,91 @@ 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++;
> >> +
> >> +     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) {
> >> +                     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) {
> >> +                     rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0);
> >> +                     if (rc)
> >> +                             syslog(LOG_ERR, "%s: key inst: %s",
> >> +                                     __func__, strerror(errno));
> >> +             }
> >
> >        Instead of all this if then nesting and continual checking for
> >        the value of rc, I think it would be easier to follow the logic
> >        and maintain this if it instead either did a "goto out" in the
> >        error cases or just did a return when it hits an error.
> 
> Will comments help?  I thought of using function calls and goto calls
> but none of them will make readability and logic any easier.
> There are five different calls, and if either of first two fail, insetead of
> returning, third one gets called and all calls are different
> (e.g. if either of wbcStringToSid or wbcSidToUid, getpwnam should
> be called and if either of  wbcStringToSid or wbcSidToGid fail,
> getgrnam should be called.
> keyctl_instantiate should be called if either  wbcSidToUid or getpwnam
> succeed (in that order) or  if either wbcSidToGid or getgrnam succeed
> (in that order).
> It would not be any clearer to follow this with goto statements.
> 

Ok, I see your point. Comments probably would be helpful. At least
some that lay out the overall idea behind this code and why and how it
falls back when things fail.

-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux