"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/rpc/rpc-lib/src/auth-glusterfs.c" (16 Sep 2020, 11202 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "auth-glusterfs.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #include "rpcsvc.h"
   12 #include <glusterfs/dict.h>
   13 #include "xdr-rpc.h"
   14 #include "xdr-common.h"
   15 #include "rpc-common-xdr.h"
   16 #include "glusterfs4-xdr.h"
   17 
   18 /* V1 */
   19 
   20 ssize_t
   21 xdr_to_glusterfs_auth(char *buf, struct auth_glusterfs_parms *req)
   22 {
   23     XDR xdr;
   24     ssize_t ret = -1;
   25 
   26     if ((!buf) || (!req))
   27         return -1;
   28 
   29     xdrmem_create(&xdr, buf, sizeof(struct auth_glusterfs_parms), XDR_DECODE);
   30     if (!xdr_auth_glusterfs_parms(&xdr, req)) {
   31         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs parameters");
   32         ret = -1;
   33         goto ret;
   34     }
   35 
   36     ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
   37 ret:
   38     return ret;
   39 }
   40 int
   41 auth_glusterfs_request_init(rpcsvc_request_t *req, void *priv)
   42 {
   43     return 0;
   44 }
   45 
   46 int
   47 auth_glusterfs_authenticate(rpcsvc_request_t *req, void *priv)
   48 {
   49     struct auth_glusterfs_parms au = {
   50         0,
   51     };
   52 
   53     int ret = RPCSVC_AUTH_REJECT;
   54     int j = 0;
   55     int i = 0;
   56     int gidcount = 0;
   57 
   58     if (!req)
   59         return ret;
   60 
   61     ret = xdr_to_glusterfs_auth(req->cred.authdata, &au);
   62     if (ret == -1) {
   63         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
   64         ret = RPCSVC_AUTH_REJECT;
   65         goto err;
   66     }
   67 
   68     req->pid = au.pid;
   69     req->uid = au.uid;
   70     req->gid = au.gid;
   71     req->lk_owner.len = 8;
   72     {
   73         for (i = 0; i < req->lk_owner.len; i++, j += 8)
   74             req->lk_owner.data[i] = (char)((au.lk_owner >> j) & 0xff);
   75     }
   76     req->auxgidcount = au.ngrps;
   77 
   78     if (req->auxgidcount > 16) {
   79         gf_log("", GF_LOG_WARNING,
   80                "more than 16 aux gids found, failing authentication");
   81         ret = RPCSVC_AUTH_REJECT;
   82         goto err;
   83     }
   84 
   85     if (req->auxgidcount > SMALL_GROUP_COUNT) {
   86         req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
   87                                      gf_common_mt_auxgids);
   88         req->auxgids = req->auxgidlarge;
   89     } else {
   90         req->auxgids = req->auxgidsmall;
   91     }
   92 
   93     if (!req->auxgids) {
   94         gf_log("auth-glusterfs", GF_LOG_WARNING, "cannot allocate gid list");
   95         ret = RPCSVC_AUTH_REJECT;
   96         goto err;
   97     }
   98 
   99     for (gidcount = 0; gidcount < au.ngrps; ++gidcount)
  100         req->auxgids[gidcount] = au.groups[gidcount];
  101 
  102     gf_log(GF_RPCSVC, GF_LOG_TRACE,
  103            "Auth Info: pid: %u, uid: %d"
  104            ", gid: %d, owner: %s",
  105            req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner));
  106     ret = RPCSVC_AUTH_ACCEPT;
  107 err:
  108     return ret;
  109 }
  110 
  111 rpcsvc_auth_ops_t auth_glusterfs_ops = {
  112     .transport_init = NULL,
  113     .request_init = auth_glusterfs_request_init,
  114     .authenticate = auth_glusterfs_authenticate};
  115 
  116 rpcsvc_auth_t rpcsvc_auth_glusterfs = {.authname = "AUTH_GLUSTERFS",
  117                                        .authnum = AUTH_GLUSTERFS,
  118                                        .authops = &auth_glusterfs_ops,
  119                                        .authprivate = NULL};
  120 
  121 rpcsvc_auth_t *
  122 rpcsvc_auth_glusterfs_init(rpcsvc_t *svc, dict_t *options)
  123 {
  124     return &rpcsvc_auth_glusterfs;
  125 }
  126 
  127 /* V2 */
  128 
  129 ssize_t
  130 xdr_to_glusterfs_auth_v2(char *buf, struct auth_glusterfs_parms_v2 *req)
  131 {
  132     XDR xdr;
  133     ssize_t ret = -1;
  134 
  135     if ((!buf) || (!req))
  136         return -1;
  137 
  138     xdrmem_create(&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
  139     if (!xdr_auth_glusterfs_parms_v2(&xdr, req)) {
  140         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs v2 parameters");
  141         ret = -1;
  142         goto ret;
  143     }
  144 
  145     ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
  146 ret:
  147     return ret;
  148 }
  149 int
  150 auth_glusterfs_v2_request_init(rpcsvc_request_t *req, void *priv)
  151 {
  152     return 0;
  153 }
  154 
  155 int
  156 auth_glusterfs_v2_authenticate(rpcsvc_request_t *req, void *priv)
  157 {
  158     struct auth_glusterfs_parms_v2 au = {
  159         0,
  160     };
  161     int ret = RPCSVC_AUTH_REJECT;
  162     int i = 0;
  163     int max_groups = 0;
  164     int max_lk_owner_len = 0;
  165 
  166     if (!req)
  167         return ret;
  168 
  169     ret = xdr_to_glusterfs_auth_v2(req->cred.authdata, &au);
  170     if (ret == -1) {
  171         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
  172         ret = RPCSVC_AUTH_REJECT;
  173         goto err;
  174     }
  175 
  176     req->pid = au.pid;
  177     req->uid = au.uid;
  178     req->gid = au.gid;
  179     req->lk_owner.len = au.lk_owner.lk_owner_len;
  180     req->auxgidcount = au.groups.groups_len;
  181 
  182     /* the number of groups and size of lk_owner depend on each other */
  183     max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS(req->lk_owner.len,
  184                                               AUTH_GLUSTERFS_v2);
  185     max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER(req->auxgidcount,
  186                                                      AUTH_GLUSTERFS_v2);
  187 
  188     if (req->auxgidcount > max_groups) {
  189         gf_log("", GF_LOG_WARNING,
  190                "more than max aux gids found (%d) , truncating it "
  191                "to %d and continuing",
  192                au.groups.groups_len, max_groups);
  193         req->auxgidcount = max_groups;
  194     }
  195 
  196     if (req->lk_owner.len > max_lk_owner_len) {
  197         gf_log("", GF_LOG_WARNING,
  198                "lkowner field to big (%d), depends on the number of "
  199                "groups (%d), failing authentication",
  200                req->lk_owner.len, req->auxgidcount);
  201         ret = RPCSVC_AUTH_REJECT;
  202         goto err;
  203     }
  204 
  205     if (req->auxgidcount > SMALL_GROUP_COUNT) {
  206         req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
  207                                      gf_common_mt_auxgids);
  208         req->auxgids = req->auxgidlarge;
  209     } else {
  210         req->auxgids = req->auxgidsmall;
  211     }
  212 
  213     if (!req->auxgids) {
  214         gf_log("auth-glusterfs-v2", GF_LOG_WARNING, "cannot allocate gid list");
  215         ret = RPCSVC_AUTH_REJECT;
  216         goto err;
  217     }
  218 
  219     for (i = 0; i < req->auxgidcount; ++i)
  220         req->auxgids[i] = au.groups.groups_val[i];
  221 
  222     for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
  223         req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
  224 
  225     gf_log(GF_RPCSVC, GF_LOG_TRACE,
  226            "Auth Info: pid: %u, uid: %d"
  227            ", gid: %d, owner: %s",
  228            req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner));
  229     ret = RPCSVC_AUTH_ACCEPT;
  230 err:
  231     /* TODO: instead use alloca() for these variables */
  232     free(au.groups.groups_val);
  233     free(au.lk_owner.lk_owner_val);
  234 
  235     return ret;
  236 }
  237 
  238 rpcsvc_auth_ops_t auth_glusterfs_ops_v2 = {
  239     .transport_init = NULL,
  240     .request_init = auth_glusterfs_v2_request_init,
  241     .authenticate = auth_glusterfs_v2_authenticate};
  242 
  243 rpcsvc_auth_t rpcsvc_auth_glusterfs_v2 = {.authname = "AUTH_GLUSTERFS-v2",
  244                                           .authnum = AUTH_GLUSTERFS_v2,
  245                                           .authops = &auth_glusterfs_ops_v2,
  246                                           .authprivate = NULL};
  247 
  248 rpcsvc_auth_t *
  249 rpcsvc_auth_glusterfs_v2_init(rpcsvc_t *svc, dict_t *options)
  250 {
  251     return &rpcsvc_auth_glusterfs_v2;
  252 }
  253 
  254 /* V3 */
  255 
  256 ssize_t
  257 xdr_to_glusterfs_auth_v3(char *buf, struct auth_glusterfs_params_v3 *req)
  258 {
  259     XDR xdr;
  260     ssize_t ret = -1;
  261 
  262     if ((!buf) || (!req))
  263         return -1;
  264 
  265     xdrmem_create(&xdr, buf, GF_MAX_AUTH_BYTES, XDR_DECODE);
  266     if (!xdr_auth_glusterfs_params_v3(&xdr, req)) {
  267         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs v3 parameters");
  268         ret = -1;
  269         goto ret;
  270     }
  271 
  272     ret = (((size_t)(&xdr)->x_private) - ((size_t)(&xdr)->x_base));
  273 ret:
  274     return ret;
  275 }
  276 
  277 int
  278 auth_glusterfs_v3_request_init(rpcsvc_request_t *req, void *priv)
  279 {
  280     return 0;
  281 }
  282 
  283 int
  284 auth_glusterfs_v3_authenticate(rpcsvc_request_t *req, void *priv)
  285 {
  286     struct auth_glusterfs_params_v3 au = {
  287         0,
  288     };
  289     int ret = RPCSVC_AUTH_REJECT;
  290     int i = 0;
  291     int max_groups = 0;
  292     int max_lk_owner_len = 0;
  293 
  294     if (!req)
  295         return ret;
  296 
  297     ret = xdr_to_glusterfs_auth_v3(req->cred.authdata, &au);
  298     if (ret == -1) {
  299         gf_log("", GF_LOG_WARNING, "failed to decode glusterfs credentials");
  300         ret = RPCSVC_AUTH_REJECT;
  301         goto err;
  302     }
  303 
  304     req->pid = au.pid;
  305     req->uid = au.uid;
  306     req->gid = au.gid;
  307     req->lk_owner.len = au.lk_owner.lk_owner_len;
  308     req->auxgidcount = au.groups.groups_len;
  309 
  310     /* the number of groups and size of lk_owner depend on each other */
  311     max_groups = GF_AUTH_GLUSTERFS_MAX_GROUPS(req->lk_owner.len,
  312                                               AUTH_GLUSTERFS_v3);
  313     max_lk_owner_len = GF_AUTH_GLUSTERFS_MAX_LKOWNER(req->auxgidcount,
  314                                                      AUTH_GLUSTERFS_v3);
  315 
  316     if (req->auxgidcount > max_groups) {
  317         gf_log("", GF_LOG_WARNING,
  318                "more than max aux gids found (%d) , truncating it "
  319                "to %d and continuing",
  320                au.groups.groups_len, max_groups);
  321         req->auxgidcount = max_groups;
  322     }
  323 
  324     if (req->lk_owner.len > max_lk_owner_len) {
  325         gf_log("", GF_LOG_WARNING,
  326                "lkowner field to big (%d), depends on the number of "
  327                "groups (%d), failing authentication",
  328                req->lk_owner.len, req->auxgidcount);
  329         ret = RPCSVC_AUTH_REJECT;
  330         goto err;
  331     }
  332 
  333     if (req->auxgidcount > SMALL_GROUP_COUNT) {
  334         req->auxgidlarge = GF_CALLOC(req->auxgidcount, sizeof(req->auxgids[0]),
  335                                      gf_common_mt_auxgids);
  336         req->auxgids = req->auxgidlarge;
  337     } else {
  338         req->auxgids = req->auxgidsmall;
  339     }
  340 
  341     if (!req->auxgids) {
  342         gf_log("auth-glusterfs-v2", GF_LOG_WARNING, "cannot allocate gid list");
  343         ret = RPCSVC_AUTH_REJECT;
  344         goto err;
  345     }
  346 
  347     for (i = 0; i < req->auxgidcount; ++i)
  348         req->auxgids[i] = au.groups.groups_val[i];
  349 
  350     for (i = 0; i < au.lk_owner.lk_owner_len; ++i)
  351         req->lk_owner.data[i] = au.lk_owner.lk_owner_val[i];
  352 
  353     /* All new things, starting glusterfs-4.0.0 */
  354     req->flags = au.flags;
  355     req->ctime.tv_sec = au.ctime_sec;
  356     req->ctime.tv_nsec = au.ctime_nsec;
  357 
  358     gf_log(GF_RPCSVC, GF_LOG_TRACE,
  359            "Auth Info: pid: %u, uid: %d"
  360            ", gid: %d, owner: %s, flags: %d",
  361            req->pid, req->uid, req->gid, lkowner_utoa(&req->lk_owner),
  362            req->flags);
  363     ret = RPCSVC_AUTH_ACCEPT;
  364 err:
  365     /* TODO: instead use alloca() for these variables */
  366     free(au.groups.groups_val);
  367     free(au.lk_owner.lk_owner_val);
  368 
  369     return ret;
  370 }
  371 
  372 rpcsvc_auth_ops_t auth_glusterfs_ops_v3 = {
  373     .transport_init = NULL,
  374     .request_init = auth_glusterfs_v3_request_init,
  375     .authenticate = auth_glusterfs_v3_authenticate};
  376 
  377 rpcsvc_auth_t rpcsvc_auth_glusterfs_v3 = {.authname = "AUTH_GLUSTERFS-v3",
  378                                           .authnum = AUTH_GLUSTERFS_v3,
  379                                           .authops = &auth_glusterfs_ops_v3,
  380                                           .authprivate = NULL};
  381 
  382 rpcsvc_auth_t *
  383 rpcsvc_auth_glusterfs_v3_init(rpcsvc_t *svc, dict_t *options)
  384 {
  385     return &rpcsvc_auth_glusterfs_v3;
  386 }