Merge 0.9->trunk
[prosody.git] / prosodyctl
index d3ba8932a117d48ed7d82d4141175dfe04dbed87..4d7f678fa2e767b05381657f719f09156e8e0904 100755 (executable)
@@ -274,11 +274,12 @@ local commands = {};
 local command = arg[1];
 
 function commands.adduser(arg)
+       local jid_split = require "util.jid".split;
        if not arg[1] or arg[1] == "--help" then
                show_usage([[adduser JID]], [[Create the specified user account in Prosody]]);
                return 1;
        end
-       local user, host = arg[1]:match("([^@]+)@(.+)");
+       local user, host = jid_split(arg[1]);
        if not user and host then
                show_message [[Failed to understand JID, please supply the JID you want to create]]
                show_usage [[adduser user@host]]
@@ -313,11 +314,12 @@ function commands.adduser(arg)
 end
 
 function commands.passwd(arg)
+       local jid_split = require "util.jid".split;
        if not arg[1] or arg[1] == "--help" then
                show_usage([[passwd JID]], [[Set the password for the specified user account in Prosody]]);
                return 1;
        end
-       local user, host = arg[1]:match("([^@]+)@(.+)");
+       local user, host = jid_split(arg[1]);
        if not user and host then
                show_message [[Failed to understand JID, please supply the JID you want to set the password for]]
                show_usage [[passwd user@host]]
@@ -352,11 +354,12 @@ function commands.passwd(arg)
 end
 
 function commands.deluser(arg)
+       local jid_split = require "util.jid".split;
        if not arg[1] or arg[1] == "--help" then
                show_usage([[deluser JID]], [[Permanently remove the specified user account from Prosody]]);
                return 1;
        end
-       local user, host = arg[1]:match("([^@]+)@(.+)");
+       local user, host = jid_split(arg[1]);
        if not user and host then
                show_message [[Failed to understand JID, please supply the JID you want to set the password for]]
                show_usage [[passwd user@host]]
@@ -817,11 +820,21 @@ function commands.check(arg)
                                print("");
                                print("    You need to move the following option"..(n>1 and "s" or "")..": "..table.concat(it.to_array(misplaced_options), ", "));
                        end
+                       local subdomain = host:match("^[^.]+");
+                       if not(host_options:contains("component_module")) and (subdomain == "jabber" or subdomain == "xmpp"
+                          or subdomain == "chat" or subdomain == "im") then
+                               print("");
+                               print("    Suggestion: If "..host.. " is a new host with no real users yet, consider renaming it now to");
+                               print("     "..host:gsub("^[^.]+%.", "")..". You can use SRV records to redirect XMPP clients and servers to "..host..".");
+                               print("     For more information see: http://prosody.im/doc/dns");
+                       end
                end
+               
                print("Done.\n");
        end
        if not what or what == "dns" then
                local dns = require "net.dns";
+               local ip = require "util.ip";
                local c2s_ports = set.new(config.get("*", "c2s_ports") or {5222});
                local s2s_ports = set.new(config.get("*", "s2s_ports") or {5269});
                
@@ -835,7 +848,7 @@ function commands.check(arg)
                
                local problem_hosts = set.new();
                
-               local external_addresses = set.new();
+               local external_addresses, internal_addresses = set.new(), set.new();
                
                local fqdn = socket.dns.tohostname(socket.dns.gethostname());
                if fqdn then
@@ -853,6 +866,16 @@ function commands.check(arg)
                        end
                end
                
+               local local_addresses = socket.local_addresses and socket.local_addresses() or {};
+               
+               for addr in it.values(local_addresses) do
+                       if not ip.new_ip(addr).private then
+                               external_addresses:add(addr);
+                       else
+                               internal_addresses:add(addr);
+                       end
+               end
+               
                if external_addresses:empty() then
                        print("");
                        print("   Failed to determine the external addresses of this server. Checks may be inaccurate.");
@@ -879,6 +902,7 @@ function commands.check(arg)
                                else
                                        if c2s_srv_required then
                                                print("    No _xmpp-client SRV record found for "..host..", but it looks like you need one.");
+                                               all_targst_ok = false;
                                        else
                                                target_hosts:add(host);
                                        end
@@ -895,6 +919,7 @@ function commands.check(arg)
                        else
                                if s2s_srv_required then
                                        print("    No _xmpp-server SRV record found for "..host..", but it looks like you need one.");
+                                       all_targets_ok = false;
                                else
                                        target_hosts:add(host);
                                end
@@ -908,6 +933,25 @@ function commands.check(arg)
                                target_hosts:remove("localhost");
                        end
                        
+                       local modules = set.new(it.to_array(it.values(host_options.modules_enabled)))
+                                       + set.new(it.to_array(it.values(config.get("*", "modules_enabled"))))
+                                       + set.new({ config.get(host, "component_module") });
+
+                       if modules:contains("proxy65") then
+                               local proxy65_target = config.get(host, "proxy65_address") or host;
+                               local A, AAAA = dns.lookup(proxy65_target, "A"), dns.lookup(proxy65_target, "AAAA");
+                               local prob = {};
+                               if not A then
+                                       table.insert(prob, "A");
+                               end
+                               if v6_supported and not AAAA then
+                                       table.insert(prob, "AAAA");
+                               end
+                               if #prob > 0 then
+                                       print("    File transfer proxy "..proxy65_target.." has no "..table.concat(prob, "/").." record. Create one or set 'proxy65_address' to the correct host/IP.");
+                               end
+                       end
+                       
                        for host in target_hosts do
                                local host_ok_v4, host_ok_v6;
                                local res = dns.lookup(host, "A");
@@ -916,6 +960,10 @@ function commands.check(arg)
                                                if external_addresses:contains(record.a) then
                                                        some_targets_ok = true;
                                                        host_ok_v4 = true;
+                                               elseif internal_addresses:contains(record.a) then
+                                                       host_ok_v4 = true;
+                                                       some_targets_ok = true;
+                                                       print("    "..host.." A record points to internal address, external connections might fail");
                                                else
                                                        print("    "..host.." A record points to unknown address "..record.a);
                                                        all_targets_ok = false;
@@ -928,6 +976,10 @@ function commands.check(arg)
                                                if external_addresses:contains(record.aaaa) then
                                                        some_targets_ok = true;
                                                        host_ok_v6 = true;
+                                               elseif internal_addresses:contains(record.aaaa) then
+                                                       host_ok_v6 = true;
+                                                       some_targets_ok = true;
+                                                       print("    "..host.." AAAA record points to internal address, external connections might fail");
                                                else
                                                        print("    "..host.." AAAA record points to unknown address "..record.aaaa);
                                                        all_targets_ok = false;
@@ -935,12 +987,17 @@ function commands.check(arg)
                                        end
                                end
                                
+                               local bad_protos = {}
                                if not host_ok_v4 then
-                                       print("    Host "..host.." does not seem to resolve to this server for IPv4");
+                                       table.insert(bad_protos, "IPv4");
+                               end
+                               if not host_ok_v6 then
+                                       table.insert(bad_protos, "IPv6");
+                               end
+                               if #bad_protos > 0 then
+                                       print("    Host "..host.." does not seem to resolve to this server ("..table.concat(bad_protos, "/")..")");
                                end
-                               if not host_ok_v6 and v6_supported then
-                                       print("    Host "..host.." does not seem to resolve to this server for IPv6");
-                               elseif host_ok_v6 and not v6_supported then
+                               if host_ok_v6 and not v6_supported then
                                        print("    Host "..host.." has AAAA records, but your version of LuaSocket does not support IPv6.");
                                        print("      Please see http://prosody.im/doc/ipv6 for more information.");
                                end
@@ -950,9 +1007,9 @@ function commands.check(arg)
                                if is_component then
                                        print("    DNS records are necessary if you want users on other servers to access this component.");
                                end
-                               print("");
                                problem_hosts:add(host);
                        end
+                       print("");
                end
                if not problem_hosts:empty() then
                        print("");