Whamcloud - gitweb
LU-6081 lfs: fixed bad return value
[fs/lustre-release.git] / lustre / utils / gss / svcgssd_proc.c
index 2ba8e37..7876c04 100644 (file)
@@ -6,6 +6,8 @@
 
   Copyright (c) 2002 Bruce Fields <bfields@UMICH.EDU>
 
+  Copyright (c) 2014, Intel Corporation.
+
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
@@ -62,6 +64,7 @@ struct svc_cred {
        uint32_t cr_remote;
        uint32_t cr_usr_root;
        uint32_t cr_usr_mds;
+       uint32_t cr_usr_oss;
        uid_t    cr_uid;
        uid_t    cr_mapped_uid;
        uid_t    cr_gid;
@@ -91,6 +94,7 @@ do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
        qword_printint(f, cred->cr_remote);
        qword_printint(f, cred->cr_usr_root);
        qword_printint(f, cred->cr_usr_mds);
+       qword_printint(f, cred->cr_usr_oss);
        qword_printint(f, cred->cr_mapped_uid);
        qword_printint(f, cred->cr_uid);
        qword_printint(f, cred->cr_gid);
@@ -308,7 +312,8 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
        gss_OID         name_type = GSS_C_NO_OID;
        struct passwd   *pw;
 
-       cred->cr_remote = cred->cr_usr_root = cred->cr_usr_mds = 0;
+       cred->cr_remote = 0;
+       cred->cr_usr_root = cred->cr_usr_mds = cred->cr_usr_oss = 0;
        cred->cr_uid = cred->cr_mapped_uid = cred->cr_gid = -1;
 
        maj_stat = gss_display_name(&min_stat, client_name, &name, &name_type);
@@ -325,6 +330,7 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
                return -1;
        }
        memcpy(sname, name.value, name.length);
+       sname[name.length] = '\0';
        gss_release_buffer(&min_stat, &name);
 
        if (lustre_svc == LUSTRE_GSS_SVC_MDS)
@@ -344,8 +350,8 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
         if (host)
                 *host++ = '\0';
 
-       if (strcmp(sname, GSSD_SERVICE_OSS) == 0) {
-               printerr(0, "forbid "GSSD_SERVICE_OSS" as user name\n");
+       if (strcmp(sname, GSSD_SERVICE_MGS) == 0) {
+               printerr(0, "forbid %s as a user name\n", sname);
                goto out_free;
        }
 
@@ -365,61 +371,84 @@ get_ids(gss_name_t client_name, gss_OID mech, struct svc_cred *cred,
                        goto out_free;
                }
        } else {
-               if (!strcmp(sname, GSSD_SERVICE_MDS)) {
-                       printerr(0, "ERROR: "GSSD_SERVICE_MDS"@%s from %016llx "
-                                "doesn't bind with hostname\n", realm, nid);
+               if (!strcmp(sname, GSSD_SERVICE_MDS) ||
+                   !strcmp(sname, GSSD_SERVICE_OSS)) {
+                       printerr(0, "ERROR: %s@%s from %016llx doesn't "
+                                "bind with hostname\n", sname, realm, nid);
                        goto out_free;
                }
        }
 
-       /* 2. check realm */
-       if (!mds_local_realm || strcasecmp(mds_local_realm, realm)) {
-               cred->cr_remote = 1;
-
-               /* Allow mapped user from remote realm */
-               if (cred->cr_mapped_uid != -1)
-                       res = 0;
-               /* Allow OSS auth using client machine credential */
-               else if (lustre_svc == LUSTRE_GSS_SVC_OSS &&
-                        !strcmp(sname, LUSTRE_ROOT_NAME))
-                       res = 0;
-               /* Invalid remote user */
-               else
-                       printerr(0, "ERROR: %s%s%s@%s from %016llx is remote "
-                                "but without mapping\n", sname,
-                                host ? "/" : "", host ? host : "", realm, nid);
+       /* 2. check realm and user */
+       switch (lustre_svc) {
+       case LUSTRE_GSS_SVC_MDS:
+               if (strcasecmp(mds_local_realm, realm)) {
+                       cred->cr_remote = 1;
+
+                       /* only allow mapped user from remote realm */
+                       if (cred->cr_mapped_uid == -1) {
+                               printerr(0, "ERROR: %s%s%s@%s from %016llx "
+                                        "is remote but without mapping\n",
+                                        sname, host ? "/" : "",
+                                        host ? host : "", realm, nid);
+                               break;
+                       }
+               } else {
+                       if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+                               cred->cr_uid = 0;
+                               cred->cr_usr_root = 1;
+                       } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+                               cred->cr_uid = 0;
+                               cred->cr_usr_mds = 1;
+                       } else if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+                               printerr(0, "ERROR: MDS doesn't accept "
+                                        "user "GSSD_SERVICE_OSS"\n");
+                               break;
+                       } else {
+                               pw = getpwnam(sname);
+                               if (pw != NULL) {
+                                       cred->cr_uid = pw->pw_uid;
+                                       printerr(2, "%s resolve to uid %u\n",
+                                                sname, cred->cr_uid);
+                               } else if (cred->cr_mapped_uid != -1) {
+                                       printerr(2, "user %s from %016llx is "
+                                                "mapped to %u\n", sname, nid,
+                                                cred->cr_mapped_uid);
+                               } else {
+                                       printerr(0, "ERROR: invalid user, "
+                                                "%s/%s@%s from %016llx\n",
+                                                sname, host, realm, nid);
+                                       break;
+                               }
+                       }
+               }
 
-               /* skip local user check */
-               goto out_free;
+               res = 0;
+               break;
+       case LUSTRE_GSS_SVC_MGS:
+               if (!strcmp(sname, GSSD_SERVICE_OSS)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_oss = 1;
+               }
+               /* fall through */
+       case LUSTRE_GSS_SVC_OSS:
+               if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_root = 1;
+               } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
+                       cred->cr_uid = 0;
+                       cred->cr_usr_mds = 1;
+               } else {
+                       printerr(0, "ERROR: svc %d doesn't accept user %s"
+                                "from %016llx\n", lustre_svc, sname, nid);
+                       break;
+               }
+               res = 0;
+               break;
+       default:
+               assert(0);
        }
 
-       /* 3. check user */
-        if (!(pw = getpwnam(sname))) {
-                /* map lustre_root/lustre_mds to root user, which is subject
-                * to further mapping by root-squash in kernel. */
-                if (!strcmp(sname, LUSTRE_ROOT_NAME)) {
-                        cred->cr_uid = 0;
-                        cred->cr_usr_root = 1;
-                } else if (!strcmp(sname, GSSD_SERVICE_MDS)) {
-                        cred->cr_uid = 0;
-                        cred->cr_usr_mds = 1;
-                } else {
-                        if (cred->cr_mapped_uid == -1) {
-                                printerr(0, "ERROR: invalid user, %s/%s@%s "
-                                        "from %016llx\n", sname, host,
-                                        realm, nid);
-                                goto out_free;
-                        }
-                }
-               printerr(2, "user %s from %016llx is mapped to %u\n",
-                        sname, nid, cred->cr_mapped_uid);
-        } else {
-               /* note: a mapped local user will go to here too */
-                cred->cr_uid = pw->pw_uid;
-                printerr(2, "%s resolve to uid %u\n", sname, cred->cr_uid);
-        }
-
-        res = 0;
 out_free:
        if (!res)
                printerr(1, "%s: authenticated %s%s%s@%s from %016llx\n",
@@ -461,6 +490,7 @@ handle_nullreq(FILE *f) {
        gss_cred_id_t           svc_cred;
        u_int32_t               maj_stat = GSS_S_FAILURE, min_stat = 0;
        u_int32_t               ignore_min_stat;
+       int                     get_len;
        struct svc_cred         cred;
        static char             *lbuf = NULL;
        static int              lbuflen = 0;
@@ -482,21 +512,27 @@ handle_nullreq(FILE *f) {
        printerr(2, "handling req: svc %u, nid %016llx, idx %llx\n",
                 lustre_svc, nid, handle_seq);
 
-       in_handle.length = (size_t) qword_get(&cp, in_handle.value,
-                                             sizeof(in_handle_buf));
-       printerr(3, "in_handle: \n");
-       print_hexl(3, in_handle.value, in_handle.length);
+       get_len = qword_get(&cp, in_handle.value, sizeof(in_handle_buf));
+       if (get_len < 0) {
+               printerr(0, "WARNING: handle_nullreq: "
+                           "failed parsing request\n");
+               goto out_err;
+       }
+       in_handle.length = (size_t)get_len;
 
-       in_tok.length = (size_t) qword_get(&cp, in_tok.value,
-                                          sizeof(in_tok_buf));
-       printerr(3, "in_tok: \n");
-       print_hexl(3, in_tok.value, in_tok.length);
+       printerr(3, "in_handle:\n");
+       print_hexl(3, in_handle.value, in_handle.length);
 
-       if (in_tok.length < 0) {
+       get_len = qword_get(&cp, in_tok.value, sizeof(in_tok_buf));
+       if (get_len < 0) {
                printerr(0, "WARNING: handle_nullreq: "
                            "failed parsing request\n");
                goto out_err;
        }
+       in_tok.length = (size_t)get_len;
+
+       printerr(3, "in_tok:\n");
+       print_hexl(3, in_tok.value, in_tok.length);
 
        if (in_handle.length != 0) { /* CONTINUE_INIT case */
                if (in_handle.length != sizeof(ctx)) {