^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/cifs/dns_resolve.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2007 Igor Mammedov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author(s): Igor Mammedov (niallain@gmail.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Steve French (sfrench@us.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Wang Lei (wang840925@gmail.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Contains the CIFS DFS upcall routines used for hostname to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * IP address translation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This library is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * it under the terms of the GNU Lesser General Public License as published
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * by the Free Software Foundation; either version 2.1 of the License, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * This library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * the GNU Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * You should have received a copy of the GNU Lesser General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/dns_resolver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "dns_resolve.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "cifsglob.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "cifsproto.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "cifs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * @unc: UNC path specifying the server (with '/' as delimiter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * @ip_addr: Where to return the IP address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * The IP address will be returned in string form, and the caller is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * responsible for freeing it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Returns length of result on success, -ve on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct sockaddr_storage ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) const char *hostname, *sep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) int len, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!ip_addr || !unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) len = strlen(unc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (len < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) cifs_dbg(FYI, "%s: unc is too short: %s\n", __func__, unc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Discount leading slashes for cifs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) hostname = unc + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* Search for server name delimiter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) sep = memchr(hostname, '/', len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (sep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) len = sep - hostname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) cifs_dbg(FYI, "%s: probably server name is whole unc: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) __func__, unc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Try to interpret hostname as an IPv4 or IPv6 address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (rc > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) goto name_is_IP_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Perform the upcall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) rc = dns_query(current->nsproxy->net_ns, NULL, hostname, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) NULL, ip_addr, NULL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) cifs_dbg(FYI, "%s: unable to resolve: %*.*s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) __func__, len, len, hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) cifs_dbg(FYI, "%s: resolved: %*.*s to %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) __func__, len, len, hostname, *ip_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) name_is_IP_address:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) name = kmalloc(len + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) memcpy(name, hostname, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) name[len] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) cifs_dbg(FYI, "%s: unc is IP, skipping dns upcall: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) __func__, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) *ip_addr = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }