Re: [PATCH 2/3] Try to use kernel function to determine supported Kerberos enctypes.

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

 



On Wed, Apr 14, 2010 at 3:18 PM,  <steved@xxxxxxxxxx> wrote:
> From: Kevin Coffman <kwc@xxxxxxxxxxxxxx>
>
> This patch replaces a hard-coded list with a function to obtain
> the Kerberos encryption types that the kernel's rpcsec_gss code
> can support.  Defaults to old behavior if kernel does not supply
> information.
>
> Signed-off-by: Steve Dickson <steved@xxxxxxxxxx>
> ---
>  utils/gssd/gssd_proc.c |   81 +++++++++++++++++++++++++++++++++++++++++++++++-
>  utils/gssd/krb5_util.c |   16 ++++++++-
>  2 files changed, 94 insertions(+), 3 deletions(-)
>
> diff --git a/utils/gssd/gssd_proc.c b/utils/gssd/gssd_proc.c
> index be4fb11..12e11d5 100644
> --- a/utils/gssd/gssd_proc.c
> +++ b/utils/gssd/gssd_proc.c
> @@ -600,6 +600,67 @@ update_client_list(void)
>        return retval;
>  }
>
> +/* Encryption types supported by the kernel rpcsec_gss code */
> +int num_krb5_enctypes = 0;
> +krb5_enctype *krb5_enctypes = NULL;
> +
> +/*
> + * Parse the supported encryption type information
> + */
> +static int
> +parse_enctypes(char *enctypes)
> +{
> +       int n = 0;
> +       char *curr, *comma;
> +       int i;
> +       static char *cached_types;
> +
> +       if (cached_types && strcmp(cached_types, enctypes) == 0)
> +               return 0;
> +       free(cached_types);
> +
> +       if (krb5_enctypes != NULL) {
> +               free(krb5_enctypes);
> +               krb5_enctypes = NULL;
> +               num_krb5_enctypes = 0;
> +       }
> +
> +       /* count the number of commas */
> +       for (curr = enctypes; curr && *curr != '\0'; curr = ++comma) {
> +               comma = strchr(curr, ',');
> +               if (comma != NULL)
> +                       n++;
> +               else
> +                       break;
> +       }
> +       /* If no more commas and we're not at the end, there's one more value */
> +       if (*curr != '\0')
> +               n++;
> +
> +       /* Empty string, return an error */
> +       if (n == 0)
> +               return ENOENT;
> +
> +       /* Allocate space for enctypes array */
> +       if ((krb5_enctypes = (int *) calloc(n, sizeof(int))) == NULL) {
> +               return ENOMEM;
> +       }
> +
> +       /* Now parse each value into the array */
> +       for (curr = enctypes, i = 0; curr && *curr != '\0'; curr = ++comma) {
> +               krb5_enctypes[i++] = atoi(curr);
> +               comma = strchr(curr, ',');
> +               if (comma == NULL)
> +                       break;
> +       }
> +
> +       num_krb5_enctypes = n;
> +       if (cached_types = malloc(strlen(enctypes)+1))
> +               strcpy(cached_types, enctypes);
> +
> +       return 0;
> +}
> +
>  static int
>  do_downcall(int k5_fd, uid_t uid, struct authgss_private_data *pd,
>            gss_buffer_desc *context_token)
> @@ -1128,11 +1189,12 @@ handle_gssd_upcall(struct clnt_info *clp)
>  {
>        uid_t                   uid;
>        char                    *lbuf = NULL;
> -       int                     lbuflen = 0;
> +       int                     lbuflen = 0, code;
>        char                    *p;
>        char                    *mech = NULL;
>        char                    *target = NULL;
>        char                    *service = NULL;
> +       char                    *enctypes = NULL;
>
>        printerr(1, "handling gssd upcall (%s)\n", clp->dirname);
>
> @@ -1176,6 +1238,23 @@ handle_gssd_upcall(struct clnt_info *clp)
>                goto out;
>        }
>
> +       /* read supported encryption types if supplied */
> +       if ((p = strstr(lbuf, "enctypes=")) != NULL) {
> +               enctypes = malloc(lbuflen);
> +               if (!enctypes)
> +                       goto out;
> +               if (sscanf(p, "enctypes=%s", enctypes) != 1) {
> +                       printerr(0, "WARNING: handle_gssd_upcall: "
> +                                   "failed to parse target name "
> +                                   "in upcall string '%s'\n", lbuf);
> +                       goto out;
> +               }
> +               if (parse_enctypes(enctypes) != 0) {
> +                       printerr(0, "WARNING: handle_gssd_upcall: "
> +                               "parsing encryption types failed: errno %d\n", code);
> +               }
> +       }
> +
>        /* read target name */
>        if ((p = strstr(lbuf, "target=")) != NULL) {
>                target = malloc(lbuflen);
> diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c
> index 1c10bd4..0f56b1d 100644
> --- a/utils/gssd/krb5_util.c
> +++ b/utils/gssd/krb5_util.c
> @@ -1274,6 +1274,8 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
>                                    ENCTYPE_DES_CBC_MD5,
>                                    ENCTYPE_DES_CBC_MD4 };
>        int num_enctypes = sizeof(enctypes) / sizeof(enctypes[0]);
> +       extern int num_krb5_enctypes;
> +       extern krb5_enctype *krb5_enctypes;
>
>        /* We only care about getting a krb5 cred */
>        desired_mechs.count = 1;
> @@ -1290,8 +1292,18 @@ limit_krb5_enctypes(struct rpc_gss_sec *sec, uid_t uid)
>                return -1;
>        }
>
> -       maj_stat = gss_set_allowable_enctypes(&min_stat, credh, &krb5oid,
> -                                            num_enctypes, &enctypes);
> +       /*
> +        * If we failed for any reason to produce global
> +        * list of supported enctypes, use local default here.
> +        */
> +       if (krb5_enctypes == NULL)
> +               maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
> +                                       &krb5oid, num_enctypes, &enctypes);
> +       else
> +               maj_stat = gss_set_allowable_enctypes(&min_stat, credh,
> +                                       &krb5oid, num_krb5_enctypes,
> +                                       krb5_enctypes);
> +
>        if (maj_stat != GSS_S_COMPLETE) {
>                pgsserr("gss_set_allowable_enctypes",
>                        maj_stat, min_stat, &krb5oid);
> --

Hi Steve,

The global krb5_enctypes array was used when the list was being read
once from a file.  With the list now coming up with each request in
the updated upcall, I think the list obtained in the upcall should be
added to the clnt_info structure and then passed to the
limit_krb5_enctypes function as a parameter.

K.C.
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux