X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fgss%2Flsupport.c;h=f27ba4ad2d1a327da6400a81689e1901aaa44e5a;hp=f20f2084126dcb6bfe04e221808ca444d0db84f4;hb=70e9d4ecc9130aeed1260d78cd8b33a5cde6edd7;hpb=8a41cc258a4cf12f779b82c32d98e9696aa49833 diff --git a/lustre/utils/gss/lsupport.c b/lustre/utils/gss/lsupport.c index f20f208..f27ba4a 100644 --- a/lustre/utils/gss/lsupport.c +++ b/lustre/utils/gss/lsupport.c @@ -1,22 +1,33 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: +/* + * GPL HEADER START * - * Copyright (c) 2005 Cluster File Systems, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * This file is part of Lustre, http://www.lustre.org. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. * - * Lustre is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). * - * Lustre is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html * - * You should have received a copy of the GNU General Public License - * along with Lustre; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * GPL HEADER END + */ +/* + * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + * + * Copyright (c) 2014, Intel Corporation. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + * Lustre is a trademark of Sun Microsystems, Inc. */ #ifndef _GNU_SOURCE @@ -32,6 +43,7 @@ #include #include +#include #include #include #include @@ -44,10 +56,10 @@ #include #include #include -#ifdef HAVE_GETHOSTBYNAME +#ifdef HAVE_NETDB_H # include #endif - +#include #ifdef _NEW_BUILD_ # include "lgss_utils.h" #else @@ -56,6 +68,13 @@ #endif #include "lsupport.h" +const char * lustre_svc_name[] = +{ + [LUSTRE_GSS_SVC_MGS] = "MGS", + [LUSTRE_GSS_SVC_MDS] = "MDS", + [LUSTRE_GSS_SVC_OSS] = "OSS", +}; + /**************************************** * exclusive startup * ****************************************/ @@ -238,7 +257,7 @@ int external_nid2hostname(char *lnd, uint32_t net, uint32_t addr, head++; tail = head + strlen(head); - if (tail <= head) { + if (tail <= head) { printerr(0, "no output from %s\n", gethostname_ex); return -1; } @@ -267,24 +286,21 @@ int external_nid2hostname(char *lnd, uint32_t net, uint32_t addr, return 0; } -static struct { +struct convert_struct { char *name; lnd_nid2hostname_t *nid2name; -} converter[LND_ENUM_END_MARKER] = { - {"UNUSED0", NULL}, - [QSWLND] = { "QSWLND", external_nid2hostname}, - [SOCKLND] = { "SOCKLND", ipv4_nid2hostname }, - [GMLND] = { "GMLND", external_nid2hostname}, - [PTLLND] = { "PTLLND", external_nid2hostname }, - [O2IBLND] = { "O2IBLND", ipv4_nid2hostname }, - [CIBLND] = { "CIBLND", external_nid2hostname }, - [OPENIBLND] = { "OPENIBLND",external_nid2hostname }, - [IIBLND] = { "IIBLND", external_nid2hostname }, - [LOLND] = { "LOLND", lolnd_nid2hostname }, - [RALND] = { "RALND", external_nid2hostname }, - [VIBLND] = { "VIBLND", external_nid2hostname }, }; +static struct convert_struct converter[] = { + [0] = { .name = "UNUSED0" }, + [SOCKLND] = { .name = "SOCKLND", .nid2name = ipv4_nid2hostname }, + [O2IBLND] = { .name = "O2IBLND", .nid2name = ipv4_nid2hostname }, + [LOLND] = { .name = "LOLND", .nid2name = lolnd_nid2hostname }, + [PTL4LND] = { .name = "PTL4LND", .nid2name = external_nid2hostname } +}; + +#define LND_MAX (sizeof(converter) / sizeof(converter[0])) + int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen) { uint32_t lnd, net, addr; @@ -293,7 +309,7 @@ int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen) net = LNET_NIDNET(nid); lnd = LNET_NETTYP(net); - if (lnd >= LND_ENUM_END_MARKER) { + if (lnd >= LND_MAX) { printerr(0, "ERROR: Unrecognized LND %u\n", lnd); return -1; } @@ -310,268 +326,6 @@ int lnet_nid2hostname(lnet_nid_t nid, char *buf, int buflen) /**************************************** - * lnet support routine * - * (from lnet/libcfs/nidstrings.c * - ****************************************/ - -#define LNET_NIDSTR_SIZE 32 /* size of each one (see below for usage) */ - -static int libcfs_lo_str2addr(char *str, int nob, uint32_t *addr); -static void libcfs_ip_addr2str(uint32_t addr, char *str); -static int libcfs_ip_str2addr(char *str, int nob, uint32_t *addr); -static void libcfs_decnum_addr2str(uint32_t addr, char *str); -static void libcfs_hexnum_addr2str(uint32_t addr, char *str); -static int libcfs_num_str2addr(char *str, int nob, uint32_t *addr); - -struct netstrfns { - int nf_type; - char *nf_name; - char *nf_modname; - void (*nf_addr2str)(uint32_t addr, char *str); - int (*nf_str2addr)(char *str, int nob, uint32_t *addr); -}; - -static struct netstrfns libcfs_netstrfns[] = { - {/* .nf_type */ LOLND, - /* .nf_name */ "lo", - /* .nf_modname */ "klolnd", - /* .nf_addr2str */ libcfs_decnum_addr2str, - /* .nf_str2addr */ libcfs_lo_str2addr}, - {/* .nf_type */ SOCKLND, - /* .nf_name */ "tcp", - /* .nf_modname */ "ksocklnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ O2IBLND, - /* .nf_name */ "o2ib", - /* .nf_modname */ "ko2iblnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ CIBLND, - /* .nf_name */ "cib", - /* .nf_modname */ "kciblnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ OPENIBLND, - /* .nf_name */ "openib", - /* .nf_modname */ "kopeniblnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ IIBLND, - /* .nf_name */ "iib", - /* .nf_modname */ "kiiblnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ VIBLND, - /* .nf_name */ "vib", - /* .nf_modname */ "kviblnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ RALND, - /* .nf_name */ "ra", - /* .nf_modname */ "kralnd", - /* .nf_addr2str */ libcfs_ip_addr2str, - /* .nf_str2addr */ libcfs_ip_str2addr}, - {/* .nf_type */ QSWLND, - /* .nf_name */ "elan", - /* .nf_modname */ "kqswlnd", - /* .nf_addr2str */ libcfs_decnum_addr2str, - /* .nf_str2addr */ libcfs_num_str2addr}, - {/* .nf_type */ GMLND, - /* .nf_name */ "gm", - /* .nf_modname */ "kgmlnd", - /* .nf_addr2str */ libcfs_hexnum_addr2str, - /* .nf_str2addr */ libcfs_num_str2addr}, - {/* .nf_type */ PTLLND, - /* .nf_name */ "ptl", - /* .nf_modname */ "kptllnd", - /* .nf_addr2str */ libcfs_decnum_addr2str, - /* .nf_str2addr */ libcfs_num_str2addr}, - /* placeholder for net0 alias. It MUST BE THE LAST ENTRY */ - {/* .nf_type */ -1}, -}; - -const int libcfs_nnetstrfns = sizeof(libcfs_netstrfns)/sizeof(libcfs_netstrfns[0]); - -static int -libcfs_lo_str2addr(char *str, int nob, uint32_t *addr) -{ - *addr = 0; - return 1; -} - -static void -libcfs_ip_addr2str(uint32_t addr, char *str) -{ - snprintf(str, LNET_NIDSTR_SIZE, "%u.%u.%u.%u", - (addr >> 24) & 0xff, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff); -} - -/* CAVEAT EMPTOR XscanfX - * I use "%n" at the end of a sscanf format to detect trailing junk. However - * sscanf may return immediately if it sees the terminating '0' in a string, so - * I initialise the %n variable to the expected length. If sscanf sets it; - * fine, if it doesn't, then the scan ended at the end of the string, which is - * fine too :) */ - -static int -libcfs_ip_str2addr(char *str, int nob, uint32_t *addr) -{ - int a; - int b; - int c; - int d; - int n = nob; /* XscanfX */ - - /* numeric IP? */ - if (sscanf(str, "%u.%u.%u.%u%n", &a, &b, &c, &d, &n) >= 4 && - n == nob && - (a & ~0xff) == 0 && (b & ~0xff) == 0 && - (c & ~0xff) == 0 && (d & ~0xff) == 0) { - *addr = ((a<<24)|(b<<16)|(c<<8)|d); - return 1; - } - -#ifdef HAVE_GETHOSTBYNAME - /* known hostname? */ - if (('a' <= str[0] && str[0] <= 'z') || - ('A' <= str[0] && str[0] <= 'Z')) { - char *tmp; - - tmp = malloc(nob + 1); - if (tmp != NULL) { - struct hostent *he; - - memcpy(tmp, str, nob); - tmp[nob] = 0; - - he = gethostbyname(tmp); - - free(tmp); - tmp = NULL; - - if (he != NULL) { - uint32_t ip = *(uint32_t *)he->h_addr; - - *addr = ntohl(ip); - return 1; - } - } - } -#endif - return 0; -} - -static void -libcfs_decnum_addr2str(uint32_t addr, char *str) -{ - snprintf(str, LNET_NIDSTR_SIZE, "%u", addr); -} - -static void -libcfs_hexnum_addr2str(uint32_t addr, char *str) -{ - snprintf(str, LNET_NIDSTR_SIZE, "0x%x", addr); -} - -static int -libcfs_num_str2addr(char *str, int nob, uint32_t *addr) -{ - int n; - - n = nob; - if (sscanf(str, "0x%x%n", addr, &n) >= 1 && n == nob) - return 1; - - n = nob; - if (sscanf(str, "0X%x%n", addr, &n) >= 1 && n == nob) - return 1; - - n = nob; - if (sscanf(str, "%u%n", addr, &n) >= 1 && n == nob) - return 1; - - return 0; -} - -static struct netstrfns * -libcfs_lnd2netstrfns(int lnd) -{ - int i; - - if (lnd >= 0) - for (i = 0; i < libcfs_nnetstrfns; i++) - if (lnd == libcfs_netstrfns[i].nf_type) - return &libcfs_netstrfns[i]; - - return NULL; -} - -static struct netstrfns * -libcfs_str2net_internal(char *str, uint32_t *net) -{ - struct netstrfns *nf; - int nob; - int netnum; - int i; - - for (i = 0; i < libcfs_nnetstrfns; i++) { - nf = &libcfs_netstrfns[i]; - if (nf->nf_type >= 0 && - !strncmp(str, nf->nf_name, strlen(nf->nf_name))) - break; - } - - if (i == libcfs_nnetstrfns) - return NULL; - - nob = strlen(nf->nf_name); - - if (strlen(str) == (unsigned int)nob) { - netnum = 0; - } else { - if (nf->nf_type == LOLND) /* net number not allowed */ - return NULL; - - str += nob; - i = strlen(str); - if (sscanf(str, "%u%n", &netnum, &i) < 1 || - i != (int)strlen(str)) - return NULL; - } - - *net = LNET_MKNET(nf->nf_type, netnum); - return nf; -} - -lnet_nid_t -libcfs_str2nid(char *str) -{ - char *sep = strchr(str, '@'); - struct netstrfns *nf; - uint32_t net; - uint32_t addr; - - if (sep != NULL) { - nf = libcfs_str2net_internal(sep + 1, &net); - if (nf == NULL) - return LNET_NID_ANY; - } else { - sep = str + strlen(str); - net = LNET_MKNET(SOCKLND, 0); - nf = libcfs_lnd2netstrfns(SOCKLND); - if (!nf) - return LNET_NID_ANY; - } - - if (!nf->nf_str2addr(str, sep - str, &addr)) - return LNET_NID_ANY; - - return LNET_MKNID(net, addr); -} - -/**************************************** * user mapping database handling * * (very rudiment) * ****************************************/ @@ -580,7 +334,7 @@ libcfs_str2nid(char *str) #define MAX_LINE_LEN 256 struct user_map_item { - char *principal; /* NULL means match all, will cause multi->single mapped, FORBID */ + char *principal; /* NULL means match all */ lnet_nid_t nid; uid_t uid; }; @@ -590,7 +344,7 @@ struct user_mapping { struct user_map_item *items; }; -static struct user_mapping mapping = {0, NULL}; +static struct user_mapping mapping; /* FIXME to be finished: monitor change of mapping database */ static int mapping_mtime = 0; @@ -598,7 +352,9 @@ void cleanup_mapping(void) { if (mapping.items) { for (; mapping.nitems > 0; mapping.nitems--) - free(mapping.items[mapping.nitems - 1].principal); + if (mapping.items[mapping.nitems-1].principal) + free(mapping.items[mapping.nitems-1].principal); + free(mapping.items); mapping.items = NULL; } @@ -624,7 +380,8 @@ static int grow_mapping(int nitems) } if (mapping.items) { - memcpy(new, mapping.items, mapping.nitems * sizeof(struct user_map_item)); + memcpy(new, mapping.items, + mapping.nitems * sizeof(struct user_map_item)); free(mapping.items); } mapping.items = new; @@ -672,20 +429,13 @@ static int read_mapping_db(void) while ((line = fgets(linebuf, MAX_LINE_LEN, f)) != NULL) { char *name; - if (strlen(line) >= MAX_LINE_LEN) { - printerr(0, "invalid mapping db: line too long (%d)\n", - strlen(line)); - continue; - } - if (sscanf(line, "%s %s %s", princ, nid_str, dest) != 3) { printerr(0, "mapping db: syntax error\n"); continue; } if (!strcmp(princ, "*")) { - printerr(0, "NOT permit \"*\" princ, it will cause multi->single mapped\n"); - continue; + name = NULL; } else { name = strdup(princ); if (!name) { @@ -700,6 +450,7 @@ static int read_mapping_db(void) nid = libcfs_str2nid(nid_str); if (nid == LNET_NID_ANY) { printerr(0, "fail to parse nid %s\n", nid_str); + if (name) free(name); continue; } @@ -708,6 +459,7 @@ static int read_mapping_db(void) dest_uid = parse_uid(dest); if (dest_uid == -1) { printerr(0, "no valid user: %s\n", dest); + if (name) free(name); continue; } @@ -715,6 +467,7 @@ static int read_mapping_db(void) if (grow_mapping(mapping.nitems + 1)) { printerr(0, "fail to grow mapping to %d\n", mapping.nitems + 1); + if (name) free(name); fclose(f); return -1; @@ -774,7 +527,7 @@ int lookup_mapping(char *princ, lnet_nid_t nid, uid_t *uid) if (entry->nid != LNET_NID_ANY && entry->nid != nid) continue; - if (!strcasecmp(entry->principal, princ)) { + if (!entry->principal || !strcasecmp(entry->principal, princ)) { printerr(1, "found mapping: %s ==> %d\n", princ, entry->uid); *uid = entry->uid;