/** * _exp_file_insert -- Insert the exports directory into the file structure * using the directory as a dict. Also hashes the dirname, * stores it in a uuid type, converts the uuid type to a * string and uses that as the key to the exports map. * The exports map maps an export "uuid" to an export * directory struct. * * @file : Exports file struct to insert into * @dir : Export directory to insert * * Not for external use. */ static void _exp_file_insert(struct exports_file *file, struct export_dir *dir) { data_t *dirdata = NULL; uint32_t hashedval = 0; uuid_t export_uuid = { 0, }; char export_uuid_str[512] = { 0, }; char *dirdup = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, file, out); GF_VALIDATE_OR_GOTO(GF_EXP, dir, out); dirdata = bin_to_data(dir, sizeof(*dir)); dict_set(file->exports_dict, dir->dir_name, dirdata); dirdup = strdupa(dir->dir_name); while (strlen(dirdup) > 0 && dirdup[0] == '/') dirdup++; hashedval = SuperFastHash(dirdup, strlen(dirdup)); memset(export_uuid, 0, sizeof(export_uuid)); memcpy(export_uuid, &hashedval, sizeof(hashedval)); gf_uuid_unparse(export_uuid, export_uuid_str); dict_set(file->exports_map, export_uuid_str, dirdata); out: return; }
/** * cache_nfs_fh -- Places the nfs file handle in the underlying dict as we are * using as our cache. The key is "exportid:gfid:host_addr", the * value is an entry struct containing the export item that * was authorized for the operation and the file handle that was * authorized. * * @cache: The cache to place fh's in * @fh : The fh to cache * @host_addr: The address of the host * @export_item: The export item that was authorized * */ int cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh, const char *host_addr, struct export_item *export_item) { int ret = -EINVAL; char *hashkey = NULL; data_t *entry_data = NULL; time_t timestamp = 0; gf_boolean_t can_write = _gf_false; struct auth_cache_entry *entry = NULL; GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out); GF_VALIDATE_OR_GOTO (GF_NFS, cache, out); GF_VALIDATE_OR_GOTO (GF_NFS, fh, out); /* If we could already find it in the cache, just return */ ret = auth_cache_lookup (cache, fh, host_addr, ×tamp, &can_write); if (ret == 0) { gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host " "%s", host_addr); goto out; } hashkey = make_hashkey (fh, host_addr); if (!hashkey) { ret = -ENOMEM; goto out; } entry = auth_cache_entry_init (); if (!entry) { ret = -ENOMEM; goto out; } entry->timestamp = time (NULL); entry->item = export_item; /* The cache entry will simply be the time that the entry * was cached. */ entry_data = bin_to_data (entry, sizeof (*entry)); if (!entry_data) { GF_FREE (entry); goto out; } ret = dict_set (cache->cache_dict, hashkey, entry_data); if (ret == -1) { GF_FREE (entry); goto out; } gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr); ret = 0; out: GF_FREE (hashkey); return ret; }
/** * __exp_line_host_parse -- Extract the hosts in the line * and call helper functions to parse * the string. * * The call chain goes like this: * * 1) __exp_line_host_parse ("/test hostip(sec=sys,rw,anonuid=0)") * 2) __exp_line_ng_host_str_parse ("hostip(sec=sys,rw,anonuid=0)"); * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)"); * * * @line : The line to parse * @ng_dict : Double pointer to the dict we want to * insert hosts into. * * Allocates the dict, extracts host strings from the line, * parses them into a struct export_item structure and inserts * them in the dict. * * @return: success: GF_EXP_PARSE_SUCCESS * failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure, * GF_EXP_PARSE_ITEM_NOT_FOUND if the host was not found, * -EINVAL on bad args, -ENOMEM on allocation errors. * * Not for external use. */ static int __exp_line_host_parse(const char *line, dict_t **host_dict) { dict_t *hosts = NULL; char *strmatch = NULL; int ret = -EINVAL; struct export_item *exp_host = NULL; data_t *hostdata = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, line, out); GF_VALIDATE_OR_GOTO(GF_EXP, host_dict, out); *host_dict = NULL; /* Initialize a parser with the line to parse and the regex used to * parse it. */ ret = parser_set_string(hostname_parser, line); if (ret < 0) { goto out; } gf_msg_trace(GF_EXP, 0, "parsing line: %s", line); while ((strmatch = parser_get_next_match(hostname_parser))) { if (!hosts) { /* Allocate a new dictto store the netgroups. */ hosts = dict_new(); GF_CHECK_ALLOC(hosts, ret, free_and_out); } gf_msg_trace(GF_EXP, 0, "parsing hostname: %s", strmatch); ret = __exp_line_ng_host_str_parse(strmatch, &exp_host); if (ret != 0) { /* Parsing or other critical error, free allocated * memory and exit. The caller will handle the errors. */ _exp_dict_destroy(hosts); goto free_and_out; } /* Insert export item structure into the hosts dict. */ hostdata = bin_to_data(exp_host, sizeof(*exp_host)); dict_set(hosts, exp_host->name, hostdata); /* Free this matched string and continue parsing.*/ GF_FREE(strmatch); } /* If the hosts dict was not allocated, then we know that * no matches were found. */ if (!exp_host) { ret = GF_EXP_PARSE_ITEM_NOT_FOUND; parser_unset_string(hostname_parser); goto out; } ret = GF_EXP_PARSE_SUCCESS; *host_dict = hosts; free_and_out: parser_unset_string(hostname_parser); GF_FREE(strmatch); out: return ret; }
/** * __exp_line_ng_parse -- Extract the netgroups in the line * and call helper functions to parse * the string. * * The call chain goes like this: * * 1) __exp_line_ng_parse ("/test @test(sec=sys,rw,anonuid=0)") * 2) __exp_line_ng_str_parse ("@test(sec=sys,rw,anonuid=0)"); * 3) __exp_line_opt_parse("(sec=sys,rw,anonuid=0)"); * * * @line : The line to parse * @ng_dict : Double pointer to the dict we want to * insert netgroups into. * * Allocates the dict, extracts netgroup strings from the line, * parses them into a struct export_item structure and inserts * them in the dict. * * @return: success: GF_EXP_PARSE_SUCCESS * failure: GF_EXP_PARSE_ITEM_FAILURE on parse failure, * GF_EXP_PARSE_ITEM_NOT_FOUND if the netgroup was not found * -EINVAL on bad args, -ENOMEM on allocation errors. * * Not for external use. */ static int __exp_line_ng_parse(const char *line, dict_t **ng_dict) { dict_t *netgroups = NULL; char *strmatch = NULL; int ret = -EINVAL; struct export_item *exp_ng = NULL; data_t *ngdata = NULL; GF_VALIDATE_OR_GOTO(GF_EXP, line, out); GF_VALIDATE_OR_GOTO(GF_EXP, ng_dict, out); *ng_dict = NULL; /* Will be set if parse is successful */ /* Initialize a parser with the line to parse * and the regex used to parse it. */ ret = parser_set_string(netgroup_parser, line); if (ret < 0) { goto out; } gf_msg_trace(GF_EXP, 0, "parsing line: %s", line); while ((strmatch = parser_get_next_match(netgroup_parser))) { if (!netgroups) { /* Allocate a new dict to store the netgroups. */ netgroups = dict_new(); if (!netgroups) { ret = -ENOMEM; goto free_and_out; } } gf_msg_trace(GF_EXP, 0, "parsing netgroup: %s", strmatch); ret = __exp_line_ng_host_str_parse(strmatch, &exp_ng); if (ret != 0) { /* Parsing or other critical errors. * caller will handle return value. */ _exp_dict_destroy(netgroups); goto free_and_out; } ngdata = bin_to_data(exp_ng, sizeof(*exp_ng)); dict_set(netgroups, exp_ng->name, ngdata); /* Free this matched string and continue parsing. */ GF_FREE(strmatch); } /* If the netgroups dict was not allocated, then we know that * no matches were found. */ if (!netgroups) { ret = GF_EXP_PARSE_ITEM_NOT_FOUND; parser_unset_string(netgroup_parser); goto out; } ret = GF_EXP_PARSE_SUCCESS; *ng_dict = netgroups; free_and_out: parser_unset_string(netgroup_parser); GF_FREE(strmatch); out: return ret; }