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