Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

smb: client: provide dns_resolve_{unc,name} helpers

Some places pass hostnames rather than UNC paths to resolve them to ip
addresses, so provide helpers to handle both cases and then stop
converting hostnames to UNC paths by inserting path delimiters into
them. Also kill @expiry parameter as it's not used anywhere.

Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Paulo Alcantara and committed by
Steve French
4b1b4c8b 489d1523

+59 -86
+1 -1
fs/smb/client/cifsproto.h
··· 680 680 } 681 681 682 682 int match_target_ip(struct TCP_Server_Info *server, 683 - const char *share, size_t share_len, 683 + const char *host, size_t hostlen, 684 684 bool *result); 685 685 int cifs_inval_name_dfs_link_error(const unsigned int xid, 686 686 struct cifs_tcon *tcon,
+5 -22
fs/smb/client/connect.c
··· 72 72 */ 73 73 static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server) 74 74 { 75 - int rc; 76 - int len; 77 - char *unc; 78 75 struct sockaddr_storage ss; 76 + int rc; 79 77 80 78 if (!server->hostname) 81 79 return -EINVAL; ··· 82 84 if (server->hostname[0] == '\0') 83 85 return 0; 84 86 85 - len = strlen(server->hostname) + 3; 86 - 87 - unc = kmalloc(len, GFP_KERNEL); 88 - if (!unc) { 89 - cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__); 90 - return -ENOMEM; 91 - } 92 - scnprintf(unc, len, "\\\\%s", server->hostname); 93 - 94 87 spin_lock(&server->srv_lock); 95 88 ss = server->dstaddr; 96 89 spin_unlock(&server->srv_lock); 97 90 98 - rc = dns_resolve_server_name_to_ip(server->dns_dom, unc, 99 - (struct sockaddr *)&ss, NULL); 100 - kfree(unc); 101 - 102 - if (rc < 0) { 103 - cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n", 104 - __func__, server->hostname, rc); 105 - } else { 91 + rc = dns_resolve_name(server->dns_dom, server->hostname, 92 + strlen(server->hostname), 93 + (struct sockaddr *)&ss); 94 + if (!rc) { 106 95 spin_lock(&server->srv_lock); 107 96 memcpy(&server->dstaddr, &ss, sizeof(server->dstaddr)); 108 97 spin_unlock(&server->srv_lock); 109 - rc = 0; 110 98 } 111 - 112 99 return rc; 113 100 } 114 101
+3 -5
fs/smb/client/dfs.c
··· 48 48 if (rc) 49 49 goto out; 50 50 51 - rc = dns_resolve_server_name_to_ip(DFS_DOM(ctx), path, 52 - (struct sockaddr *)&ctx->dstaddr, 53 - NULL); 51 + rc = dns_resolve_unc(DFS_DOM(ctx), path, 52 + (struct sockaddr *)&ctx->dstaddr); 54 53 out: 55 54 kfree(path); 56 55 return rc; ··· 267 268 int rc = 0; 268 269 269 270 if (!ctx->nodfs && ctx->dfs_automount) { 270 - rc = dns_resolve_server_name_to_ip(NULL, ctx->source, 271 - addr, NULL); 271 + rc = dns_resolve_unc(NULL, ctx->source, addr); 272 272 if (!rc) 273 273 cifs_set_port(addr, ctx->port); 274 274 ctx->dfs_automount = false;
+4 -13
fs/smb/client/dfs_cache.c
··· 1096 1096 static bool target_share_equal(struct cifs_tcon *tcon, const char *s1) 1097 1097 { 1098 1098 struct TCP_Server_Info *server = tcon->ses->server; 1099 - struct sockaddr_storage ss; 1100 - const char *host; 1101 1099 const char *s2 = &tcon->tree_name[1]; 1102 - size_t hostlen; 1103 - char unc[sizeof("\\\\") + SERVER_NAME_LENGTH] = {0}; 1100 + struct sockaddr_storage ss; 1104 1101 bool match; 1105 1102 int rc; 1106 1103 ··· 1108 1111 * Resolve share's hostname and check if server address matches. Otherwise just ignore it 1109 1112 * as we could not have upcall to resolve hostname or failed to convert ip address. 1110 1113 */ 1111 - extract_unc_hostname(s1, &host, &hostlen); 1112 - scnprintf(unc, sizeof(unc), "\\\\%.*s", (int)hostlen, host); 1113 - 1114 - rc = dns_resolve_server_name_to_ip(server->dns_dom, unc, 1115 - (struct sockaddr *)&ss, NULL); 1116 - if (rc < 0) { 1117 - cifs_dbg(FYI, "%s: could not resolve %.*s. assuming server address matches.\n", 1118 - __func__, (int)hostlen, host); 1114 + rc = dns_resolve_unc(server->dns_dom, s1, (struct sockaddr *)&ss); 1115 + if (rc < 0) 1119 1116 return true; 1120 - } 1121 1117 1122 1118 cifs_server_lock(server); 1123 1119 match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss); 1120 + cifs_dbg(FYI, "%s: [share=%s] ipaddr matched: %s\n", __func__, s1, str_yes_no(match)); 1124 1121 cifs_server_unlock(server); 1125 1122 1126 1123 return match;
+17 -27
fs/smb/client/dns_resolve.c
··· 20 20 #include "cifsproto.h" 21 21 #include "cifs_debug.h" 22 22 23 - static int resolve_name(const char *name, size_t namelen, 24 - struct sockaddr *addr, time64_t *expiry) 23 + static int resolve_name(const char *name, size_t namelen, struct sockaddr *addr) 25 24 { 26 25 char *ip; 27 26 int rc; 28 27 29 28 rc = dns_query(current->nsproxy->net_ns, NULL, name, 30 - namelen, NULL, &ip, expiry, false); 29 + namelen, NULL, &ip, NULL, false); 31 30 if (rc < 0) { 32 31 cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n", 33 32 __func__, (int)namelen, (int)namelen, name); 34 33 } else { 35 - cifs_dbg(FYI, "%s: resolved: %*.*s to %s expiry %llu\n", 36 - __func__, (int)namelen, (int)namelen, name, ip, 37 - expiry ? (*expiry) : 0); 34 + cifs_dbg(FYI, "%s: resolved: %*.*s to %s\n", 35 + __func__, (int)namelen, (int)namelen, name, ip); 38 36 39 37 rc = cifs_convert_address(addr, ip, strlen(ip)); 40 38 kfree(ip); ··· 48 50 } 49 51 50 52 /** 51 - * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address. 52 - * @dom: optional DNS domain name 53 - * @unc: UNC path specifying the server (with '/' as delimiter) 54 - * @ip_addr: Where to return the IP address. 55 - * @expiry: Where to return the expiry time for the dns record. 53 + * dns_resolve_name - Perform an upcall to resolve hostname to an ip address. 54 + * @dom: DNS domain name (or NULL) 55 + * @name: Name to look up 56 + * @namelen: Length of name 57 + * @ip_addr: Where to return the IP address 56 58 * 57 - * Returns zero success, -ve on error. 59 + * Returns zero on success, -ve code otherwise. 58 60 */ 59 - int dns_resolve_server_name_to_ip(const char *dom, const char *unc, 60 - struct sockaddr *ip_addr, time64_t *expiry) 61 + int dns_resolve_name(const char *dom, const char *name, 62 + size_t namelen, struct sockaddr *ip_addr) 61 63 { 62 - const char *name; 63 - size_t namelen, len; 64 + size_t len; 64 65 char *s; 65 66 int rc; 66 67 67 - if (!ip_addr || !unc) 68 - return -EINVAL; 69 - 70 - cifs_dbg(FYI, "%s: dom=%s unc=%s\n", __func__, dom, unc); 71 - if (strlen(unc) < 3) 72 - return -EINVAL; 73 - 74 - extract_unc_hostname(unc, &name, &namelen); 75 - if (!namelen) 68 + cifs_dbg(FYI, "%s: dom=%s name=%.*s\n", __func__, dom, (int)namelen, name); 69 + if (!ip_addr || !name || !*name || !namelen) 76 70 return -EINVAL; 77 71 78 72 cifs_dbg(FYI, "%s: hostname=%.*s\n", __func__, (int)namelen, name); ··· 87 97 return -ENOMEM; 88 98 89 99 scnprintf(s, len, "%.*s.%s", (int)namelen, name, dom); 90 - rc = resolve_name(s, len - 1, ip_addr, expiry); 100 + rc = resolve_name(s, len - 1, ip_addr); 91 101 kfree(s); 92 102 if (!rc) 93 103 return 0; 94 104 } 95 - return resolve_name(name, namelen, ip_addr, expiry); 105 + return resolve_name(name, namelen, ip_addr); 96 106 }
+22 -2
fs/smb/client/dns_resolve.h
··· 12 12 #define _DNS_RESOLVE_H 13 13 14 14 #include <linux/net.h> 15 + #include "cifsglob.h" 16 + #include "cifsproto.h" 15 17 16 18 #ifdef __KERNEL__ 17 - int dns_resolve_server_name_to_ip(const char *dom, const char *unc, 18 - struct sockaddr *ip_addr, time64_t *expiry); 19 + 20 + int dns_resolve_name(const char *dom, const char *name, 21 + size_t namelen, struct sockaddr *ip_addr); 22 + 23 + static inline int dns_resolve_unc(const char *dom, const char *unc, 24 + struct sockaddr *ip_addr) 25 + { 26 + const char *name; 27 + size_t namelen; 28 + 29 + if (!unc || strlen(unc) < 3) 30 + return -EINVAL; 31 + 32 + extract_unc_hostname(unc, &name, &namelen); 33 + if (!namelen) 34 + return -EINVAL; 35 + 36 + return dns_resolve_name(dom, name, namelen, ip_addr); 37 + } 38 + 19 39 #endif /* KERNEL */ 20 40 21 41 #endif /* _DNS_RESOLVE_H */
+7 -16
fs/smb/client/misc.c
··· 1172 1172 1173 1173 #ifdef CONFIG_CIFS_DFS_UPCALL 1174 1174 int match_target_ip(struct TCP_Server_Info *server, 1175 - const char *share, size_t share_len, 1175 + const char *host, size_t hostlen, 1176 1176 bool *result) 1177 1177 { 1178 - int rc; 1179 - char *target; 1180 1178 struct sockaddr_storage ss; 1179 + int rc; 1180 + 1181 + cifs_dbg(FYI, "%s: hostname=%.*s\n", __func__, (int)hostlen, host); 1181 1182 1182 1183 *result = false; 1183 1184 1184 - target = kzalloc(share_len + 3, GFP_KERNEL); 1185 - if (!target) 1186 - return -ENOMEM; 1187 - 1188 - scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share); 1189 - 1190 - cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2); 1191 - 1192 - rc = dns_resolve_server_name_to_ip(server->dns_dom, target, 1193 - (struct sockaddr *)&ss, NULL); 1194 - kfree(target); 1195 - 1185 + rc = dns_resolve_name(server->dns_dom, host, hostlen, 1186 + (struct sockaddr *)&ss); 1196 1187 if (rc < 0) 1197 1188 return rc; 1198 1189 1199 1190 spin_lock(&server->srv_lock); 1200 1191 *result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss); 1201 1192 spin_unlock(&server->srv_lock); 1202 - cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result); 1193 + cifs_dbg(FYI, "%s: ip addresses matched: %s\n", __func__, str_yes_no(*result)); 1203 1194 return 0; 1204 1195 } 1205 1196