From aa66b8404f45712c45d75d6a2a37f32e2792cc83 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 1 Jan 2015 13:15:45 +0100 Subject: gNFS: Export / Netgroup authentication on Gluster NFS mount * Parses linux style export file/netgroups file into a structure that can be lookedup. * This parser turns each line into a structure called an "export directory". Each of these has a dictionary of hosts and netgroups which can be looked up during the mount authentication process. (See Change-Id Ic060aac and I7e6aa6bc) * A string beginning withan '@' is treated as a netgroup and a string beginning without an @ is a host. (See Change-Id Ie04800d) * This parser does not currently support all the options in the man page ('man exports'), but we can easily add them. BUG: 1143880 URL: http://www.gluster.org/community/documentation/index.php/Features/Exports_Netgroups_Authentication Change-Id: I181e8c1814d6ef3cae5b4d88353622734f0c0f0b Original-author: Shreyas Siravara CC: Richard Wareing CC: Jiffin Tony Thottan Signed-off-by: Niels de Vos Reviewed-on: http://review.gluster.org/8758 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- libglusterfs/src/common-utils.c | 112 ++++++++++++++++++++++++++++++++++++++++ libglusterfs/src/common-utils.h | 3 ++ 2 files changed, 115 insertions(+) (limited to 'libglusterfs') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 6dcfc098dc2..751dc8a2e50 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -34,6 +34,7 @@ #include #include #include +#include /* for dirname() */ #if defined(GF_BSD_HOST_OS) || defined(GF_DARWIN_HOST_OS) #include @@ -171,6 +172,86 @@ log_base2 (unsigned long x) return val; } +/** + * gf_rev_dns_lookup -- Perform a reverse DNS lookup on the IP address. + * + * @ip: The IP address to perform a reverse lookup on + * + * @return: success: Allocated string containing the hostname + * failure: NULL + */ +char * +gf_rev_dns_lookup (const char *ip) +{ + char *fqdn = NULL; + int ret = 0; + struct sockaddr_in sa = {0}; + char host_addr[256] = {0, }; + + GF_VALIDATE_OR_GOTO ("resolver", ip, out); + + sa.sin_family = AF_INET; + inet_pton (AF_INET, ip, &sa.sin_addr); + ret = getnameinfo ((struct sockaddr *)&sa, sizeof (sa), host_addr, + sizeof (host_addr), NULL, 0, 0); + + if (ret != 0) { + gf_log ("resolver", GF_LOG_INFO, "could not resolve hostname " + "for %s: %s", ip, strerror (errno)); + goto out; + } + + /* Get the FQDN */ + fqdn = gf_strdup (host_addr); + if (!fqdn) + gf_log ("resolver", GF_LOG_CRITICAL, "Allocation failed for " + "the host address"); + +out: + return fqdn; +} + +/** + * gf_resolve_parent_path -- Given a path, returns an allocated string + * containing the parent's path. + * @path: Path to parse + * @return: The parent path if found, NULL otherwise + */ +char * +gf_resolve_path_parent (const char *path) +{ + char *parent = NULL; + char *tmp = NULL; + char *pathc = NULL; + + GF_VALIDATE_OR_GOTO (THIS->name, path, out); + + if (strlen (path) <= 0) { + gf_log_callingfn (THIS->name, GF_LOG_DEBUG, + "invalid string for 'path'"); + goto out; + } + + /* dup the parameter, we don't want to modify it */ + pathc = strdupa (path); + if (!pathc) { + gf_log (THIS->name, GF_LOG_CRITICAL, + "Allocation failed for the parent"); + goto out; + } + + /* Get the parent directory */ + tmp = dirname (pathc); + if (strcmp (tmp, "/") == 0) + goto out; + + parent = gf_strdup (tmp); + if (!parent) + gf_log (THIS->name, GF_LOG_CRITICAL, + "Allocation failed for the parent"); +out: + return parent; +} int32_t gf_resolve_ip6 (const char *hostname, @@ -1688,6 +1769,37 @@ out: return ret; } +/** + * get_file_mtime -- Given a path, get the mtime for the file + * + * @path: The filepath to check the mtime on + * @stamp: The parameter to set after we get the mtime + * + * @returns: success: 0 + * errors : Errors returned by the stat () call + */ +int +get_file_mtime (const char *path, time_t *stamp) +{ + struct stat f_stat = {0}; + int ret = -EINVAL; + + GF_VALIDATE_OR_GOTO (THIS->name, path, out); + GF_VALIDATE_OR_GOTO (THIS->name, stamp, out); + + ret = stat (path, &f_stat); + if (ret < 0) { + gf_log (THIS->name, GF_LOG_ERROR, "failed to stat %s: %s", + path, strerror (errno)); + goto out; + } + + /* Set the mtime */ + *stamp = f_stat.st_mtime; +out: + return ret; +} + /** * gf_is_ip_in_net -- Checks if an IP Address is in a network. * A network should be specified by something like diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 64544126836..f76059b3082 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -609,6 +609,8 @@ int get_checksum_for_file (int fd, uint32_t *checksum); int log_base2 (unsigned long x); int get_checksum_for_path (char *path, uint32_t *checksum); +int get_file_mtime (const char *path, time_t *stamp); +char *gf_resolve_path_parent (const char *path); char *strtail (char *str, const char *pattern); void skipwhite (char **s); @@ -627,6 +629,7 @@ gf_boolean_t valid_mount_auth_address (char *address); gf_boolean_t valid_ipv4_subnetwork (const char *address); gf_boolean_t gf_sock_union_equal_addr (union gf_sock_union *a, union gf_sock_union *b); +char *gf_rev_dns_lookup (const char *ip); char *uuid_utoa (uuid_t uuid); char *uuid_utoa_r (uuid_t uuid, char *dst); -- cgit