The branch, v4-5-stable has been updated
       via  f00d8b0 VERSION: Disable git snapshots for the 4.5.4 release.
       via  9dac949 WHATSNEW: Add release notes for Samba 4.5.4.
       via  45125a4d messaging: Fix dead but not cleaned-up-yet destination 
sockets
       via  0996b58 s3:librpc/gse: make use of gss_krb5_import_cred() instead 
of gss_acquire_cred()
       via  53864b1 s3:librpc/gse: remove unused #ifdef 
HAVE_GSS_KRB5_IMPORT_CRED
       via  05534e0 s3:librpc/gse: include ccache_name in DEBUG message if 
krb5_cc_resolve() fails
       via  d60e583 ctdb-tests: Do not attempt to unregister the join handler 
multiple times
       via  ceaafa7 smbd/ioctl: match WS2016 ReFS set compression behaviour
       via  e0bb628 torture/ioctl: test set_compression(format_none)
       via  9f196e9 pam: map more NT password errors to PAM errors
       via  4d37a14 s3: torture: Add test for cli_ftruncate calling 
cli_smb2_ftruncate.
       via  aa69068 s3: libsmb: Add cli_smb2_ftruncate(), plumb into 
cli_ftruncate().
       via  ca1885a ctdbd_conn: remove unused fde from struct ctdbd_connection
       via  4e6e513 ctdbd_conn: fix a resource leak
       via  d9e5812 selftest: Do not include system krb5.conf in selftest
       via  1d22840 s3:libads: Include system /etc/krb5.conf if we use MIT 
Kerberos
       via  66fce30 s3:param: Add an 'include system krb5 conf' option
       via  e76e188 s3/smbd: remove a misleading error message
       via  586f8b7 vfs_fruit: fix fruit:resource option spelling, but not 
behaviour
       via  adbab18 winbindd: Use idmap cache in xids2sids
       via  40a5e17 idmap: Prime gencache after xids2sids calls
       via  71a9bf9 idmap: Pass up the xid2sids unix-ids from the idmap child
       via  fbd6779 ctdb-tools: Don't trust non-hosting nodes in "ctdb ip all"
       via  cfec216 ctdb-tools: Print PNN as int in "ctdb ip -v"
       via  90edef1 ctdb-tools: Skip GET_PUBLIC_IP_INFO for unassigned addresses
       via  25ba90d ctdb-tools: Fix memory corruption in "ctdb ip -v"
       via  e04ef4c ctdb-tools: Fix sort order of "ctdb ip" output
       via  94c3b81 ctdb-tests: Add unit test for protocol utilities
       via  edf4817 ctdb-protocol: Add generalised socket address comparison
       via  3427e37 ctdb-tests: Fix "ctdb reloadips" simple test
       via  9f718c5 VERSION: Bump version up to 4.5.4
       via  59738fd Merge tag 'samba-4.5.3' into v4-5-test
       via  80185ce s3: ntlm_auth: Don't corrupt the output stream with debug 
messages.
       via  234de87 s3: torture: Adds regression test case for 
se_access_check() owner rights issue.
       via  0b4e710 lib: security: se_access_check() incorrectly processes 
owner rights (S-1-3-4) DENY ace entries
       via  692f7d0 s3: torture: Regression test case for permissions check on 
rename.
       via  55fb639 s3: smbd: Add missing permissions check on destination 
folder.
       via  b6d53b6 s3: smbd: Make check_parent_access() available to rename 
code.
       via  f66b4b0 s3: smbd: rename - missing early error exit if source and 
destination prefixes are different.
       via  bcc2c63 manpages/vfs_fruit: add warning to fruit:resoure=stream
       via  c764cc4 manpages/vfs_fruit: fruit:resource option misspelling
       via  91a3133 Merge tag 'samba-4.5.2' into v4-5-test
       via  343718c printing: Fix building with CUPS version older than 1.7
       via  d869ba0 VERSION: Bump version up to 4.5.3...
       via  29680f1 VERSION: Disable git snapshots for the 4.5.2 release.
       via  9991ab4 WHATSNEW: Add release notes for Samba 4.5.2.
      from  3da5d75 VERSION: Disable git snapshots for the 4.5.3 release.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-5-stable


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 VERSION                                            |    2 +-
 WHATSNEW.txt                                       |   77 +-
 ctdb/protocol/protocol_api.h                       |   10 +-
 ctdb/protocol/protocol_util.c                      |   68 +-
 .../{db_hash_test_001.sh => protocol_test_003.sh}  |    3 +-
 ctdb/tests/simple/18_ctdb_reloadips.sh             |    2 -
 ctdb/tests/src/cluster_wait.c                      |   40 +-
 ctdb/tests/src/protocol_util_test.c                |   82 +
 ctdb/tools/ctdb.c                                  |   66 +-
 ctdb/wscript                                       |    6 +
 docs-xml/manpages/vfs_fruit.8.xml                  |   39 +-
 .../smbdotconf/winbind/includesystemkrb5conf.xml   |   15 +
 lib/torture/torture.h                              |   10 +
 libcli/auth/pam_errors.c                           |    6 +-
 libcli/security/access_check.c                     |    2 +-
 librpc/idl/winbind.idl                             |    2 +-
 nsswitch/pam_winbind.c                             |    5 +
 python/samba/tests/docs.py                         |    3 +-
 selftest/selftest.pl                               |    1 +
 selftest/skip                                      |    2 +
 selftest/target/Samba3.pm                          |   27 +-
 selftest/target/Samba4.pm                          |    2 +-
 source3/include/MacExtensions.h                    |    3 +
 source3/lib/ctdbd_conn.c                           |    2 -
 source3/lib/messages.c                             |   11 +
 source3/lib/messages_ctdbd.c                       |    2 +
 source3/libads/kerberos.c                          |   13 +-
 source3/librpc/crypto/gse.c                        |   38 +-
 source3/libsmb/cli_smb2_fnum.c                     |   65 +
 source3/libsmb/cli_smb2_fnum.h                     |    3 +
 source3/libsmb/clifile.c                           |    8 +-
 source3/modules/vfs_catia.c                        | 1052 ++++++
 source3/modules/vfs_fruit.c                        | 3479 ++++++++++++++------
 source3/modules/vfs_streams_xattr.c                |    6 +-
 source3/param/loadparm.c                           |    1 +
 source3/selftest/tests.py                          |   16 +-
 source3/smbd/open.c                                |    2 +-
 source3/smbd/proto.h                               |    3 +
 source3/smbd/reply.c                               |   18 +
 source3/smbd/smb2_ioctl_filesys.c                  |   26 +-
 source3/smbd/smbd_cleanupd.c                       |    1 -
 source3/torture/proto.h                            |    1 +
 source3/torture/test_smb2.c                        |  160 +
 source3/torture/torture.c                          |  579 ++++
 source3/utils/ntlm_auth.c                          |    6 +-
 source3/winbindd/wb_xids2sids.c                    |   41 +-
 source3/winbindd/winbindd_dual_srv.c               |    1 +
 source4/torture/smb2/ioctl.c                       |   11 +-
 source4/torture/vfs/fruit.c                        |  398 ++-
 source4/torture/vfs/vfs.c                          |   37 +-
 50 files changed, 5303 insertions(+), 1150 deletions(-)
 copy ctdb/tests/cunit/{db_hash_test_001.sh => protocol_test_003.sh} (64%)
 create mode 100644 ctdb/tests/src/protocol_util_test.c
 create mode 100644 docs-xml/smbdotconf/winbind/includesystemkrb5conf.xml


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 1d7d6a2..5a6461b 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=5
-SAMBA_VERSION_RELEASE=3
+SAMBA_VERSION_RELEASE=4
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 63a0e9e..e0269f6 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,4 +1,77 @@
                    =============================
+                   Release Notes for Samba 4.5.4
+                          January 18, 2017
+                   =============================
+
+
+This is the latest stable release of the Samba 4.5 release series.
+
+
+Changes since 4.5.3:
+--------------------
+
+o  Jeremy Allison <j...@samba.org>
+   * BUG 12460: rename_internals_fsp missing ACL permission-check on 
destination
+     folder.
+   * BUG 12466: lib: security: se_access_check() incorrectly processes owner
+     rights (S-1-3-4) DENY ace entries.
+   * BUG 12467: s3: ntlm_auth: Don't corrupt the output stream with debug
+     messages.
+   * BUG 12479: s3: libsmb: Add cli_smb2_ftruncate(), plumb into
+     cli_ftruncate().
+
+o  Ralph Boehme <s...@samba.org>
+   * BUG 12396: s3/smbd: Remove a misleading error message.
+   * BUG 12412: vfs_fruit: Fix "fruit:resource" option spelling, but not
+     behaviour.
+   * BUG 12485: ctdbd_conn: Fix a resource leak.
+
+o  David Disseldorp <dd...@samba.org>
+   * BUG 12144: smbd/ioctl: match WS2016 ReFS set compression behaviour.
+
+o  Björn Jacke <b...@sernet.de>
+   * BUG 2210: pam: Map more NT password errors to PAM errors.
+
+o  Volker Lendecke <v...@samba.org>
+   * BUG 12484: winbindd: Use idmap cache in xids2sids.
+   * BUG 12509: messaging: Fix dead but not cleaned-up-yet destination sockets.
+
+o  Stefan Metzmacher <me...@samba.org>
+   * BUG 12480: kinit succeeded but ads_sasl_spnego_gensec_bind(KRB5) failed: 
An
+     internal error occurred (with MIT krb5).
+
+o  Andreas Schneider <a...@samba.org>
+   * BUG 12183: printing: Fix building with CUPS version older than 1.7.
+   * BUG 12441: s3:libads: Include system /etc/krb5.conf if we use MIT 
Kerberos.
+
+o  Martin Schwenke <mar...@meltin.net>
+   * BUG 12470: Fix ctdb ip bugs.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+
+                   =============================
                    Release Notes for Samba 4.5.3
                           December 19, 2016
                    =============================
@@ -77,8 +150,8 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
 
                    =============================
                    Release Notes for Samba 4.5.2
diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h
index d5d00da..7a8357a 100644
--- a/ctdb/protocol/protocol_api.h
+++ b/ctdb/protocol/protocol_api.h
@@ -658,7 +658,13 @@ const char *ctdb_event_to_string(enum ctdb_event event);
 enum ctdb_event ctdb_event_from_string(const char *event_str);
 
 const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, ctdb_sock_addr 
*addr);
-bool ctdb_sock_addr_same_ip(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2);
-bool ctdb_sock_addr_same(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2);
+int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
+                         const ctdb_sock_addr *addr2);
+int ctdb_sock_addr_cmp(const ctdb_sock_addr *addr1,
+                      const ctdb_sock_addr *addr2);
+bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
+                           const ctdb_sock_addr *addr2);
+bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
+                        const ctdb_sock_addr *addr2);
 
 #endif /* __CTDB_PROTOCOL_API_H__ */
diff --git a/ctdb/protocol/protocol_util.c b/ctdb/protocol/protocol_util.c
index b91c652..0e1bf28 100644
--- a/ctdb/protocol/protocol_util.c
+++ b/ctdb/protocol/protocol_util.c
@@ -141,55 +141,81 @@ const char *ctdb_sock_addr_to_string(TALLOC_CTX *mem_ctx, 
ctdb_sock_addr *addr)
        return cip;
 }
 
-bool ctdb_sock_addr_same_ip(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2)
+int ctdb_sock_addr_cmp_ip(const ctdb_sock_addr *addr1,
+                         const ctdb_sock_addr *addr2)
 {
-       if (addr1->sa.sa_family != addr2->sa.sa_family) {
-               return false;
+       int ret = 0;
+
+       /* This is somewhat arbitrary.  However, when used for sorting
+        * it just needs to be consistent.
+        */
+       if (addr1->sa.sa_family < addr2->sa.sa_family) {
+               return -1;
+       }
+       if (addr1->sa.sa_family > addr2->sa.sa_family) {
+               return 1;
        }
 
        switch (addr1->sa.sa_family) {
        case AF_INET:
-               if (addr1->ip.sin_addr.s_addr != addr2->ip.sin_addr.s_addr) {
-                       return false;
-               }
+               ret = memcmp(&addr1->ip.sin_addr.s_addr,
+                            &addr2->ip.sin_addr.s_addr, 4);
                break;
 
        case AF_INET6:
-               if (memcmp(addr1->ip6.sin6_addr.s6_addr,
-                          addr2->ip6.sin6_addr.s6_addr, 16) != 0) {
-                       return false;
-               }
+               ret = memcmp(addr1->ip6.sin6_addr.s6_addr,
+                            addr2->ip6.sin6_addr.s6_addr, 16);
                break;
 
        default:
-               return false;
+               ret = -1;
        }
 
-       return true;
+       return ret;
 }
 
-bool ctdb_sock_addr_same(ctdb_sock_addr *addr1, ctdb_sock_addr *addr2)
+int ctdb_sock_addr_cmp(const ctdb_sock_addr *addr1,
+                      const ctdb_sock_addr *addr2)
 {
-       if (! ctdb_sock_addr_same_ip(addr1, addr2)) {
-               return false;
+       int ret = 0;
+
+       ret = ctdb_sock_addr_cmp_ip(addr1, addr2);
+       if (ret != 0) {
+               return ret;
        }
 
        switch (addr1->sa.sa_family) {
        case AF_INET:
-               if (addr1->ip.sin_port != addr2->ip.sin_port) {
-                       return false;
+               if (addr1->ip.sin_port < addr2->ip.sin_port) {
+                       ret = -1;
+               } else if (addr1->ip.sin_port > addr2->ip.sin_port) {
+                       ret = 1;
                }
                break;
 
        case AF_INET6:
-               if (addr1->ip6.sin6_port != addr2->ip6.sin6_port) {
-                       return false;
+               if (addr1->ip6.sin6_port < addr2->ip6.sin6_port) {
+                       ret = -1;
+               } else if (addr1->ip6.sin6_port > addr2->ip6.sin6_port) {
+                       ret = 1;
                }
                break;
 
        default:
-               return false;
+               ret = -1;
        }
 
-       return true;
+       return ret;
+}
+
+bool ctdb_sock_addr_same_ip(const ctdb_sock_addr *addr1,
+                           const ctdb_sock_addr *addr2)
+{
+       return (ctdb_sock_addr_cmp_ip(addr1, addr2) == 0);
+}
+
+bool ctdb_sock_addr_same(const ctdb_sock_addr *addr1,
+                        const ctdb_sock_addr *addr2)
+{
+       return (ctdb_sock_addr_cmp(addr1, addr2) == 0);
 }
diff --git a/ctdb/tests/cunit/db_hash_test_001.sh 
b/ctdb/tests/cunit/protocol_test_003.sh
similarity index 64%
copy from ctdb/tests/cunit/db_hash_test_001.sh
copy to ctdb/tests/cunit/protocol_test_003.sh
index 76c38fe..012db90 100755
--- a/ctdb/tests/cunit/db_hash_test_001.sh
+++ b/ctdb/tests/cunit/protocol_test_003.sh
@@ -3,5 +3,4 @@
 . "${TEST_SCRIPTS_DIR}/unit.sh"
 
 ok_null
-
-unit_test db_hash_test
+unit_test protocol_util_test
diff --git a/ctdb/tests/simple/18_ctdb_reloadips.sh 
b/ctdb/tests/simple/18_ctdb_reloadips.sh
index 760e476..b68ecfa 100755
--- a/ctdb/tests/simple/18_ctdb_reloadips.sh
+++ b/ctdb/tests/simple/18_ctdb_reloadips.sh
@@ -81,8 +81,6 @@ EOF
 
 try_command_on_node any $CTDB sync
 
-select_test_node_and_ips
-
 echo "Removing IP $test_ip from node $test_node"
 
 try_command_on_node $test_node "mv $addresses $backup && grep -v 
'^${test_ip}/' $backup >$addresses"
diff --git a/ctdb/tests/src/cluster_wait.c b/ctdb/tests/src/cluster_wait.c
index ddc3e02..1405738 100644
--- a/ctdb/tests/src/cluster_wait.c
+++ b/ctdb/tests/src/cluster_wait.c
@@ -36,6 +36,7 @@ struct cluster_wait_state {
        struct ctdb_client_context *client;
        int num_nodes;
        bool *ready;
+       bool join_done;
 };
 
 static void cluster_wait_join_registered(struct tevent_req *subreq);
@@ -44,8 +45,8 @@ static void cluster_wait_join(struct tevent_req *subreq);
 static void cluster_wait_join_sent(struct tevent_req *subreq);
 static void cluster_wait_join_handler(uint64_t srvid, TDB_DATA data,
                                      void *private_data);
-static void cluster_wait_sync_sent(struct tevent_req *subreq);
 static void cluster_wait_join_unregistered(struct tevent_req *subreq);
+static void cluster_wait_sync_sent(struct tevent_req *subreq);
 static void cluster_wait_sync_handler(uint64_t srvid, TDB_DATA data,
                                      void *private_data);
 static void cluster_wait_sync_unregistered(struct tevent_req *subreq);
@@ -67,6 +68,8 @@ struct tevent_req *cluster_wait_send(TALLOC_CTX *mem_ctx,
        state->client = client;
        state->num_nodes = num_nodes;
 
+       state->join_done = false;
+
        if (ctdb_client_pnn(client) == 0) {
                state->ready = talloc_zero_array(state, bool, num_nodes);
                if (tevent_req_nomem(state->ready, req)) {
@@ -201,7 +204,6 @@ static void cluster_wait_join_handler(uint64_t srvid, 
TDB_DATA data,
                private_data, struct tevent_req);
        struct cluster_wait_state *state = tevent_req_data(
                req, struct cluster_wait_state);
-       struct ctdb_req_message msg;
        struct tevent_req *subreq;
        uint32_t pnn;
        int i;
@@ -228,50 +230,56 @@ static void cluster_wait_join_handler(uint64_t srvid, 
TDB_DATA data,
                }
        }
 
-       msg.srvid = MSG_ID_SYNC;
-       msg.data.data = tdb_null;
+       if (state->join_done) {
+               return;
+       }
 
-       subreq = ctdb_client_message_send(state, state->ev, state->client,
-                                         CTDB_BROADCAST_ALL, &msg);
+       state->join_done = true;
+       subreq = ctdb_client_remove_message_handler_send(
+                                       state, state->ev, state->client,
+                                       MSG_ID_JOIN, req);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       tevent_req_set_callback(subreq, cluster_wait_sync_sent, req);
+       tevent_req_set_callback(subreq, cluster_wait_join_unregistered, req);
 }
 
-static void cluster_wait_sync_sent(struct tevent_req *subreq)
+static void cluster_wait_join_unregistered(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
        struct cluster_wait_state *state = tevent_req_data(
                req, struct cluster_wait_state);
+       struct ctdb_req_message msg;
        bool status;
        int ret;
 
-       status = ctdb_client_message_recv(subreq, &ret);
-       TALLOC_FREE(subreq);
+       status = ctdb_client_remove_message_handler_recv(subreq, &ret);
        if (! status) {
                tevent_req_error(req, ret);
                return;
        }
 
-       subreq = ctdb_client_remove_message_handler_send(
-                                       state, state->ev, state->client,
-                                       MSG_ID_JOIN, req);
+       msg.srvid = MSG_ID_SYNC;
+       msg.data.data = tdb_null;
+
+       subreq = ctdb_client_message_send(state, state->ev, state->client,
+                                         CTDB_BROADCAST_ALL, &msg);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
-       tevent_req_set_callback(subreq, cluster_wait_join_unregistered, req);
+       tevent_req_set_callback(subreq, cluster_wait_sync_sent, req);
 }
 
-static void cluster_wait_join_unregistered(struct tevent_req *subreq)
+static void cluster_wait_sync_sent(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
        bool status;
        int ret;
 
-       status = ctdb_client_remove_message_handler_recv(subreq, &ret);
+       status = ctdb_client_message_recv(subreq, &ret);
+       TALLOC_FREE(subreq);
        if (! status) {
                tevent_req_error(req, ret);
                return;
diff --git a/ctdb/tests/src/protocol_util_test.c 
b/ctdb/tests/src/protocol_util_test.c
new file mode 100644
index 0000000..752c437
--- /dev/null
+++ b/ctdb/tests/src/protocol_util_test.c
@@ -0,0 +1,82 @@
+/*
+   protocol utilities tests
+
+   Copyright (C) Martin Schwenke  2016
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+
+#include <assert.h>
+
+#include <talloc.h>
+
+#include "protocol/protocol.h"
+#include "protocol/protocol_api.h"
+#include "common/system_util.c"
+
+/* Test parsing of IPs, conversion to string */
+static void test_sock_addr_to_string(const char *ip)
+{
+       ctdb_sock_addr sa;
+       const char *s;
+
+       assert(parse_ip(ip, NULL, 0, &sa));
+       s = ctdb_sock_addr_to_string(NULL, &sa);
+       assert(strcmp(ip, s) == 0);
+       talloc_free(discard_const(s));
+}
+
+static void test_sock_addr_cmp(const char *ip1, const char *ip2, int res)
+{
+       ctdb_sock_addr sa1, sa2;
+       int ret;
+
+       assert(parse_ip(ip1, NULL, 0, &sa1));
+       assert(parse_ip(ip2, NULL, 0, &sa2));
+       ret = ctdb_sock_addr_cmp(&sa1, &sa2);
+       if (ret < 0) {
+               ret = -1;
+       } else if (ret > 0) {
+               ret = 1;
+       }
+
+       assert(ret == res);
+}
+
+int main(int argc, char *argv[])
+{
+       test_sock_addr_to_string("0.0.0.0");
+       test_sock_addr_to_string("127.0.0.1");
+       test_sock_addr_to_string("::1");
+       test_sock_addr_to_string("192.168.2.1");
+       test_sock_addr_to_string("fe80::6af7:28ff:fefa:d136");
+
+       test_sock_addr_cmp("127.0.0.1", "127.0.0.1" , 0);
+       test_sock_addr_cmp("127.0.0.1", "127.0.0.2" , -1);
+       test_sock_addr_cmp("127.0.0.2", "127.0.0.1" , 1);
+       test_sock_addr_cmp("127.0.1.2", "127.0.2.1" , -1);
+       test_sock_addr_cmp("127.0.2.1", "127.0.1.2" , 1);
+       test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136", "127.0.1.2" , 1);
+       test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
+                          "fe80::6af7:28ff:fefa:d136" , 0);
+       test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
+                          "fe80::6af7:28ff:fefa:d137" , -1);
+       test_sock_addr_cmp("fe80::6af7:28ff:fefa:d136",
+                          "fe80:0000:0000:0000:6af7:28ff:fefa:d136" , 0);
+
+       return 0;
+}
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index 9df6b4e..9d48889 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/tools/ctdb.c
@@ -1374,6 +1374,14 @@ static int control_stats(TALLOC_CTX *mem_ctx, struct 
ctdb_context *ctdb,
        return 0;
 }
 
+static int ctdb_public_ip_cmp(const void *a, const void *b)
+{
+       const struct ctdb_public_ip *ip_a = a;
+       const struct ctdb_public_ip *ip_b = b;
+
+       return ctdb_sock_addr_cmp(&ip_a->addr, &ip_b->addr);
+}
+
 static void print_ip(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb,
                     struct ctdb_public_ip_list *ips,
                     struct ctdb_public_ip_info **ipinfo,
@@ -1402,8 +1410,7 @@ static void print_ip(TALLOC_CTX *mem_ctx, struct 
ctdb_context *ctdb,
                }
        }
 
-       /* IPs are reverse sorted */
-       for (i=ips->num-1; i>=0; i--) {
+       for (i = 0; i < ips->num; i++) {
 
                if (options.machinereadable == 1) {
                        printf("%s%s%s%d%s", options.sep,
@@ -1429,6 +1436,10 @@ static void print_ip(TALLOC_CTX *mem_ctx, struct 
ctdb_context *ctdb,
                avail = NULL;
                active = NULL;
 
+               if (ipinfo[i] == NULL) {
+                       goto skip_ipinfo;
+               }
+
                for (j=0; j<ipinfo[i]->ifaces->num; j++) {
                        struct ctdb_iface *iface;
 
@@ -1437,7 +1448,7 @@ static void print_ip(TALLOC_CTX *mem_ctx, struct 
ctdb_context *ctdb,
                                conf = talloc_strdup(mem_ctx, iface->name);


-- 
Samba Shared Repository

Reply via email to