[Pkg-samba-maint] Bug#857339: unblock: samba/2:4.5.6+dfsg-1
Mathieu Parent
sathieu at debian.org
Fri Mar 10 08:37:38 UTC 2017
Package: release.debian.org
Severity: normal
User: release.debian.org at packages.debian.org
Usertags: unblock
Please unblock package samba
This includes all latest stability fixes from upstream in the 4.5 branch
and a fix for a typo in smbd.service and winbind.service (#857232):
s/nmb.service/nmbd.service
See attached (big) debdiff.
unblock samba/2:4.5.6+dfsg-1
-- System Information:
Debian Release: 9.0
APT prefers testing-debug
APT policy: (500, 'testing-debug'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 4.9.0-1-amd64 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.utf8, LC_CTYPE=fr_FR.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
-------------- next part --------------
diff -Nru samba-4.5.5+dfsg/auth/credentials/credentials_secrets.c samba-4.5.6+dfsg/auth/credentials/credentials_secrets.c
--- samba-4.5.5+dfsg/auth/credentials/credentials_secrets.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/auth/credentials/credentials_secrets.c 2017-03-09 10:21:43.000000000 +0100
@@ -39,7 +39,7 @@
#include "dbwrap/dbwrap.h"
#include "dbwrap/dbwrap_open.h"
#include "lib/util/util_tdb.h"
-
+#include "libds/common/roles.h"
/**
* Fill in credentials for the machine trust account, from the secrets database.
@@ -276,6 +276,8 @@
char *secrets_tdb_password = NULL;
char *secrets_tdb_old_password = NULL;
uint32_t secrets_tdb_secure_channel_type = SEC_CHAN_NULL;
+ int server_role = lpcfg_server_role(lp_ctx);
+ int security = lpcfg_security(lp_ctx);
char *keystr;
char *keystr_upper = NULL;
TALLOC_CTX *tmp_ctx = talloc_named(cred, 0, "cli_credentials_set_secrets from ldb");
@@ -354,13 +356,26 @@
}
if (secrets_tdb_password_more_recent) {
+ enum credentials_use_kerberos use_kerberos = CRED_DONT_USE_KERBEROS;
char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx));
cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED);
cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
if (strequal(domain, lpcfg_workgroup(lp_ctx))) {
cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_SPECIFIED);
+
+ switch (server_role) {
+ case ROLE_DOMAIN_MEMBER:
+ if (security != SEC_ADS) {
+ break;
+ }
+ /* fall through */
+ case ROLE_ACTIVE_DIRECTORY_DC:
+ use_kerberos = CRED_AUTO_USE_KERBEROS;
+ break;
+ }
}
+ cli_credentials_set_kerberos_state(cred, use_kerberos);
cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
cli_credentials_set_password_last_changed_time(cred, secrets_tdb_lct);
cli_credentials_set_secure_channel_type(cred, secrets_tdb_secure_channel_type);
diff -Nru samba-4.5.5+dfsg/ctdb/common/comm.c samba-4.5.6+dfsg/ctdb/common/comm.c
--- samba-4.5.5+dfsg/ctdb/common/comm.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/ctdb/common/comm.c 2017-03-09 10:21:43.000000000 +0100
@@ -251,14 +251,22 @@
* Write packets
*/
+struct comm_write_entry {
+ struct comm_context *comm;
+ struct tevent_queue_entry *qentry;
+ struct tevent_req *req;
+};
+
struct comm_write_state {
struct tevent_context *ev;
struct comm_context *comm;
+ struct comm_write_entry *entry;
struct tevent_req *subreq;
uint8_t *buf;
size_t buflen, nwritten;
};
+static int comm_write_entry_destructor(struct comm_write_entry *entry);
static void comm_write_trigger(struct tevent_req *req, void *private_data);
static void comm_write_done(struct tevent_req *subreq);
@@ -269,6 +277,7 @@
{
struct tevent_req *req;
struct comm_write_state *state;
+ struct comm_write_entry *entry;
req = tevent_req_create(mem_ctx, &state, struct comm_write_state);
if (req == NULL) {
@@ -280,15 +289,38 @@
state->buf = buf;
state->buflen = buflen;
- if (!tevent_queue_add_entry(comm->queue, ev, req,
- comm_write_trigger, NULL)) {
- talloc_free(req);
- return NULL;
+ entry = talloc_zero(state, struct comm_write_entry);
+ if (tevent_req_nomem(entry, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ entry->comm = comm;
+ entry->req = req;
+ entry->qentry = tevent_queue_add_entry(comm->queue, ev, req,
+ comm_write_trigger, NULL);
+ if (tevent_req_nomem(entry->qentry, req)) {
+ return tevent_req_post(req, ev);
}
+ state->entry = entry;
+ talloc_set_destructor(entry, comm_write_entry_destructor);
+
return req;
}
+static int comm_write_entry_destructor(struct comm_write_entry *entry)
+{
+ struct comm_context *comm = entry->comm;
+
+ if (comm->write_req == entry->req) {
+ comm->write_req = NULL;
+ TEVENT_FD_NOT_WRITEABLE(comm->fde);
+ }
+
+ TALLOC_FREE(entry->qentry);
+ return 0;
+}
+
static void comm_write_trigger(struct tevent_req *req, void *private_data)
{
struct comm_write_state *state = tevent_req_data(
@@ -333,6 +365,8 @@
}
state->nwritten = nwritten;
+ state->entry->qentry = NULL;
+ TALLOC_FREE(state->entry);
tevent_req_done(req);
}
@@ -382,8 +416,8 @@
struct comm_write_state *write_state;
if (comm->write_req == NULL) {
- /* This should never happen */
- abort();
+ TEVENT_FD_NOT_WRITEABLE(comm->fde);
+ return;
}
write_state = tevent_req_data(comm->write_req,
diff -Nru samba-4.5.5+dfsg/ctdb/config/statd-callout samba-4.5.6+dfsg/ctdb/config/statd-callout
--- samba-4.5.5+dfsg/ctdb/config/statd-callout 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/ctdb/config/statd-callout 2017-03-09 10:21:43.000000000 +0100
@@ -128,6 +128,7 @@
# where the lock manager will respond "strangely" immediately
# after restarting it, which causes clients to fail to reclaim
# their locks.
+ nfs_callout_init
"$CTDB_NFS_CALLOUT" "stop" "nlockmgr" >/dev/null 2>&1
sleep 2
"$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1
diff -Nru samba-4.5.5+dfsg/ctdb/tests/cunit/comm_test_001.sh samba-4.5.6+dfsg/ctdb/tests/cunit/comm_test_001.sh
--- samba-4.5.5+dfsg/ctdb/tests/cunit/comm_test_001.sh 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/ctdb/tests/cunit/comm_test_001.sh 2017-03-09 10:21:43.000000000 +0100
@@ -2,6 +2,12 @@
. "${TEST_SCRIPTS_DIR}/unit.sh"
-ok "100 2048 500 4096 1024 8192 200 16384 300 32768 400 65536 1048576 "
-unit_test comm_test
+ok_null
+unit_test comm_test 1
+
+ok_null
+unit_test comm_test 2
+
+ok "100 2048 500 4096 1024 8192 200 16384 300 32768 400 65536 1048576 "
+unit_test comm_test 3
diff -Nru samba-4.5.5+dfsg/ctdb/tests/eventscripts/etc-ctdb/statd-callout samba-4.5.6+dfsg/ctdb/tests/eventscripts/etc-ctdb/statd-callout
--- samba-4.5.5+dfsg/ctdb/tests/eventscripts/etc-ctdb/statd-callout 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/ctdb/tests/eventscripts/etc-ctdb/statd-callout 2017-03-09 10:21:43.000000000 +0100
@@ -128,6 +128,7 @@
# where the lock manager will respond "strangely" immediately
# after restarting it, which causes clients to fail to reclaim
# their locks.
+ nfs_callout_init
"$CTDB_NFS_CALLOUT" "stop" "nlockmgr" >/dev/null 2>&1
sleep 2
"$CTDB_NFS_CALLOUT" "start" "nlockmgr" >/dev/null 2>&1
diff -Nru samba-4.5.5+dfsg/ctdb/tests/src/comm_test.c samba-4.5.6+dfsg/ctdb/tests/src/comm_test.c
--- samba-4.5.5+dfsg/ctdb/tests/src/comm_test.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/ctdb/tests/src/comm_test.c 2017-03-09 10:21:43.000000000 +0100
@@ -26,7 +26,218 @@
#include "common/pkt_write.c"
#include "common/comm.c"
-static void dead_handler(void *private_data)
+/*
+ * Test read_handler and dead_handler
+ */
+
+static void test1_read_handler(uint8_t *buf, size_t buflen,
+ void *private_data)
+{
+ int *result = (int *)private_data;
+
+ *result = -1;
+}
+
+static void test1_dead_handler(void *private_data)
+{
+ int *result = (int *)private_data;
+
+ *result = 1;
+}
+
+static void test1(void)
+{
+ TALLOC_CTX *mem_ctx;
+ struct tevent_context *ev;
+ struct comm_context *comm;
+ int fd[2];
+ int result = 0;
+ uint32_t data[2];
+ int ret;
+ ssize_t n;
+
+ mem_ctx = talloc_new(NULL);
+ assert(mem_ctx != NULL);
+
+ ev = tevent_context_init(mem_ctx);
+ assert(ev != NULL);
+
+ ret = pipe(fd);
+ assert(ret == 0);
+
+ ret = comm_setup(ev, ev, fd[0], test1_read_handler, &result,
+ test1_dead_handler, &result, &comm);
+ assert(ret == 0);
+
+ data[0] = 2 * sizeof(uint32_t);
+ data[1] = 0;
+
+ n = write(fd[1], (void *)&data, data[0]);
+ assert(n == data[0]);
+
+ while (result == 0) {
+ tevent_loop_once(ev);
+ }
+
+ assert(result == -1);
+
+ result = 0;
+ close(fd[1]);
+
+ while (result == 0) {
+ tevent_loop_once(ev);
+ }
+
+ assert(result == 1);
+
+ talloc_free(mem_ctx);
+}
+
+/*
+ * Test that the tevent_req returned by comm_write_send() can be free'd.
+ */
+
+struct test2_state {
+ TALLOC_CTX *mem_ctx;
+ bool done;
+};
+
+static void test2_read_handler(uint8_t *buf, size_t buflen,
+ void *private_data)
+{
+ struct test2_state *state = (struct test2_state *)private_data;
+
+ TALLOC_FREE(state->mem_ctx);
+}
+
+static void test2_dead_handler(void *private_data)
+{
+ abort();
+}
+
+struct test2_write_state {
+ int count;
+};
+
+static void test2_write_done(struct tevent_req *subreq);
+
+static struct tevent_req *test2_write_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct comm_context *comm,
+ uint8_t *buf, size_t buflen)
+{
+ struct tevent_req *req, *subreq;
+ struct test2_write_state *state;
+ int i;
+
+ req = tevent_req_create(mem_ctx, &state, struct test2_write_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ state->count = 0;
+
+ for (i=0; i<10; i++) {
+ subreq = comm_write_send(state, ev, comm, buf, buflen);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, test2_write_done, req);
+ }
+
+ return req;
+}
+
+static void test2_write_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct test2_write_state *state = tevent_req_data(
+ req, struct test2_write_state);
+ bool status;
+ int ret;
+
+ status = comm_write_recv(subreq, &ret);
+ TALLOC_FREE(subreq);
+ if (! status) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ state->count += 1;
+
+ if (state->count == 10) {
+ tevent_req_done(req);
+ }
+}
+
+static void test2_timer_handler(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval cur_time,
+ void *private_data)
+{
+ struct test2_state *state = (struct test2_state *)private_data;
+
+ state->done = true;
+}
+
+static void test2(void)
+{
+ TALLOC_CTX *mem_ctx;
+ struct tevent_context *ev;
+ struct comm_context *comm_reader, *comm_writer;
+ struct test2_state test2_state;
+ struct tevent_req *req;
+ struct tevent_timer *te;
+ int fd[2];
+ uint32_t data[2];
+ int ret;
+
+ mem_ctx = talloc_new(NULL);
+ assert(mem_ctx != NULL);
+
+ test2_state.mem_ctx = talloc_new(mem_ctx);
+ assert(test2_state.mem_ctx != NULL);
+
+ test2_state.done = false;
+
+ ev = tevent_context_init(mem_ctx);
+ assert(ev != NULL);
+
+ ret = pipe(fd);
+ assert(ret == 0);
+
+ ret = comm_setup(ev, ev, fd[0], test2_read_handler, &test2_state,
+ test2_dead_handler, NULL, &comm_reader);
+ assert(ret == 0);
+
+ ret = comm_setup(ev, ev, fd[1], NULL, NULL, test2_dead_handler, NULL,
+ &comm_writer);
+ assert(ret == 0);
+
+ data[0] = 2 * sizeof(uint32_t);
+ data[1] = 0;
+
+ req = test2_write_send(test2_state.mem_ctx, ev, comm_writer,
+ (uint8_t *)data, data[0]);
+ assert(req != NULL);
+
+ te = tevent_add_timer(ev, ev, tevent_timeval_current_ofs(5,0),
+ test2_timer_handler, &test2_state);
+ assert(te != NULL);
+
+ while (! test2_state.done) {
+ tevent_loop_once(ev);
+ }
+
+ talloc_free(mem_ctx);
+}
+
+/*
+ * Test that data is written and read correctly.
+ */
+
+static void test3_dead_handler(void *private_data)
{
int dead_data = *(int *)private_data;
@@ -34,14 +245,14 @@
if (dead_data == 1) {
/* reader */
- printf("writer closed pipe\n");
+ fprintf(stderr, "writer closed pipe\n");
} else {
/* writer */
- printf("reader closed pipe\n");
+ fprintf(stderr, "reader closed pipe\n");
}
}
-struct writer_state {
+struct test3_writer_state {
struct tevent_context *ev;
struct comm_context *comm;
uint8_t *buf;
@@ -49,15 +260,15 @@
int count, id;
};
-static void writer_next(struct tevent_req *subreq);
+static void test3_writer_next(struct tevent_req *subreq);
-static struct tevent_req *writer_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct comm_context *comm,
- size_t *pkt_size, int count)
+static struct tevent_req *test3_writer_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct comm_context *comm,
+ size_t *pkt_size, int count)
{
struct tevent_req *req, *subreq;
- struct writer_state *state;
+ struct test3_writer_state *state;
size_t max_size = 0, buflen;
int i;
@@ -67,7 +278,7 @@
}
}
- req = tevent_req_create(mem_ctx, &state, struct writer_state);
+ req = tevent_req_create(mem_ctx, &state, struct test3_writer_state);
if (req == NULL) {
return NULL;
}
@@ -95,16 +306,16 @@
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, writer_next, req);
+ tevent_req_set_callback(subreq, test3_writer_next, req);
return req;
}
-static void writer_next(struct tevent_req *subreq)
+static void test3_writer_next(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(
subreq, struct tevent_req);
- struct writer_state *state = tevent_req_data(
- req, struct writer_state);
+ struct test3_writer_state *state = tevent_req_data(
+ req, struct test3_writer_state);
bool ret;
int err;
size_t buflen;
@@ -130,10 +341,10 @@
return;
}
- tevent_req_set_callback(subreq, writer_next, req);
+ tevent_req_set_callback(subreq, test3_writer_next, req);
}
-static void writer_recv(struct tevent_req *req, int *perr)
+static void test3_writer_recv(struct tevent_req *req, int *perr)
{
if (tevent_req_is_unix_error(req, perr)) {
return;
@@ -141,7 +352,7 @@
*perr = 0;
}
-static void writer(int fd, size_t *pkt_size, int count)
+static void test3_writer(int fd, size_t *pkt_size, int count)
{
TALLOC_CTX *mem_ctx;
struct tevent_context *ev;
@@ -157,31 +368,32 @@
assert(ev != NULL);
err = comm_setup(mem_ctx, ev, fd, NULL, NULL,
- dead_handler, &dead_data, &comm);
+ test3_dead_handler, &dead_data, &comm);
assert(err == 0);
assert(comm != NULL);
- req = writer_send(mem_ctx, ev, comm, pkt_size, count);
+ req = test3_writer_send(mem_ctx, ev, comm, pkt_size, count);
assert(req != NULL);
tevent_req_poll(req, ev);
- writer_recv(req, &err);
+ test3_writer_recv(req, &err);
assert(err == 0);
talloc_free(mem_ctx);
}
-struct reader_state {
+struct test3_reader_state {
size_t *pkt_size;
int count, received;
bool done;
};
-static void reader_handler(uint8_t *buf, size_t buflen, void *private_data)
+static void test3_reader_handler(uint8_t *buf, size_t buflen,
+ void *private_data)
{
- struct reader_state *state = talloc_get_type_abort(
- private_data, struct reader_state);
+ struct test3_reader_state *state = talloc_get_type_abort(
+ private_data, struct test3_reader_state);
assert(buflen == state->pkt_size[state->received]);
printf("%zi ", buflen);
@@ -193,12 +405,12 @@
}
}
-static void reader(int fd, size_t *pkt_size, int count)
+static void test3_reader(int fd, size_t *pkt_size, int count)
{
TALLOC_CTX *mem_ctx;
struct tevent_context *ev;
struct comm_context *comm;
- struct reader_state *state;
+ struct test3_reader_state *state;
int dead_data = 1;
int err;
@@ -208,7 +420,7 @@
ev = tevent_context_init(mem_ctx);
assert(ev != NULL);
- state = talloc_zero(mem_ctx, struct reader_state);
+ state = talloc_zero(mem_ctx, struct test3_reader_state);
assert(state != NULL);
state->pkt_size = pkt_size;
@@ -216,8 +428,8 @@
state->received = 0;
state->done = false;
- err = comm_setup(mem_ctx, ev, fd, reader_handler, state,
- dead_handler, &dead_data, &comm);
+ err = comm_setup(mem_ctx, ev, fd, test3_reader_handler, state,
+ test3_dead_handler, &dead_data, &comm);
assert(err == 0);
assert(comm != NULL);
@@ -228,7 +440,7 @@
talloc_free(mem_ctx);
}
-int main(void)
+static void test3(void)
{
int fd[2];
int ret;
@@ -237,7 +449,6 @@
200, 16384, 300, 32768, 400, 65536,
1024*1024 };
-
ret = pipe(fd);
assert(ret == 0);
@@ -247,14 +458,44 @@
if (pid == 0) {
/* Child process */
close(fd[0]);
- writer(fd[1], pkt_size, 13);
+ test3_writer(fd[1], pkt_size, 13);
close(fd[1]);
exit(0);
}
close(fd[1]);
- reader(fd[0], pkt_size, 13);
+ test3_reader(fd[0], pkt_size, 13);
close(fd[0]);
+}
+
+
+int main(int argc, const char **argv)
+{
+ int num;
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <testnum>\n", argv[0]);
+ exit(1);
+ }
+
+ num = atoi(argv[1]);
+
+ switch (num) {
+ case 1:
+ test1();
+ break;
+
+ case 2:
+ test2();
+ break;
+
+ case 3:
+ test3();
+ break;
+
+ default:
+ fprintf(stderr, "Unknown test number %s\n", argv[1]);
+ }
return 0;
}
diff -Nru samba-4.5.5+dfsg/ctdb/tests/src/test_mutex_raw.c samba-4.5.6+dfsg/ctdb/tests/src/test_mutex_raw.c
--- samba-4.5.5+dfsg/ctdb/tests/src/test_mutex_raw.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/ctdb/tests/src/test_mutex_raw.c 2017-03-09 10:21:43.000000000 +0100
@@ -38,21 +38,11 @@
* If no pid is printed, then no process is holding the mutex.
*/
-#include <stdio.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <sys/fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <sched.h>
-#include <sys/mman.h>
-#include <pthread.h>
-#include <errno.h>
-#include <stdbool.h>
-
-int pthread_mutex_consistent_np(pthread_mutex_t *);
+#include "replace.h"
+#include "system/filesys.h"
+#include "system/wait.h"
+#include "system/shmem.h"
+#include "system/threads.h"
static void set_realtime(void)
{
@@ -99,7 +89,7 @@
again:
ret = pthread_mutex_lock(mutex);
if (ret == EOWNERDEAD) {
- ret = pthread_mutex_consistent_np(mutex);
+ ret = pthread_mutex_consistent(mutex);
} else if (ret == EAGAIN) {
goto again;
}
@@ -172,7 +162,7 @@
if (strcmp(argv[2], "debug") == 0) {
ret = pthread_mutex_trylock(mutex);
if (ret == EOWNERDEAD) {
- ret = pthread_mutex_consistent_np(mutex);
+ ret = pthread_mutex_consistent(mutex);
if (ret == 0) {
pthread_mutex_unlock(mutex);
}
diff -Nru samba-4.5.5+dfsg/ctdb/wscript samba-4.5.6+dfsg/ctdb/wscript
--- samba-4.5.5+dfsg/ctdb/wscript 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/ctdb/wscript 2017-03-09 10:21:43.000000000 +0100
@@ -750,10 +750,11 @@
ib_deps,
install_path='${CTDB_TEST_LIBEXECDIR}')
- bld.SAMBA_BINARY('test_mutex_raw',
- source='tests/src/test_mutex_raw.c',
- deps='pthread',
- install_path='${CTDB_TEST_LIBEXECDIR}')
+ if bld.env.HAVE_ROBUST_MUTEXES:
+ bld.SAMBA_BINARY('test_mutex_raw',
+ source='tests/src/test_mutex_raw.c',
+ deps='pthread',
+ install_path='${CTDB_TEST_LIBEXECDIR}')
test_subdirs = [
'complex',
@@ -767,8 +768,13 @@
'tool'
]
+ if bld.env.standalone_ctdb:
+ testdir = 'tests'
+ else:
+ testdir = 'ctdb/tests'
+
for t in test_subdirs:
- files = SUBDIR_MODE('tests/%s' % t, trim_path='tests')
+ files = SUBDIR_MODE('%s/%s' % (testdir, t), trim_path=testdir)
for fmode in files:
bld.INSTALL_FILES(bld.env.CTDB_TEST_DATADIR, 'tests/%s' % fmode[0],
destname=fmode[0], chmod=fmode[1])
diff -Nru samba-4.5.5+dfsg/debian/changelog samba-4.5.6+dfsg/debian/changelog
--- samba-4.5.5+dfsg/debian/changelog 2017-03-05 23:21:09.000000000 +0100
+++ samba-4.5.6+dfsg/debian/changelog 2017-03-09 15:42:37.000000000 +0100
@@ -1,3 +1,11 @@
+samba (2:4.5.6+dfsg-1) unstable; urgency=medium
+
+ * New upstream version
+ * Fix typo in smbd.service and winbind.service (s/nmb.service/nmbd.service)
+ (Closes: #857232)
+
+ -- Mathieu Parent <sathieu at debian.org> Thu, 09 Mar 2017 15:42:37 +0100
+
samba (2:4.5.5+dfsg-1) unstable; urgency=medium
* New upstream version
diff -Nru samba-4.5.5+dfsg/debian/rules samba-4.5.6+dfsg/debian/rules
--- samba-4.5.5+dfsg/debian/rules 2017-03-05 22:37:17.000000000 +0100
+++ samba-4.5.6+dfsg/debian/rules 2017-03-08 22:53:03.000000000 +0100
@@ -180,9 +180,9 @@
mv $(DESTDIR)/lib/systemd/system/samba.service $(DESTDIR)/lib/systemd/system/samba-ad-dc.service
sed -i \
-e 's|/etc/sysconfig/|/etc/default/|' \
- -e 's|/nmb\.service|nmbd.service|' \
- -e 's|/smb\.service|smbd.service|' \
- -e 's|/samba\.service|samba-ad-dc.service|' \
+ -e 's|nmb\.service|nmbd.service|' \
+ -e 's|smb\.service|smbd.service|' \
+ -e 's|samba\.service|samba-ad-dc.service|' \
-e 's|^PIDFile=/run/|PIDFile=/var/run/samba/|' \
$(DESTDIR)/lib/systemd/system/nmbd.service \
$(DESTDIR)/lib/systemd/system/samba-ad-dc.service \
diff -Nru samba-4.5.5+dfsg/docs/manpages/cifsdd.8 samba-4.5.6+dfsg/docs/manpages/cifsdd.8
--- samba-4.5.5+dfsg/docs/manpages/cifsdd.8 2017-01-30 11:15:43.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/cifsdd.8 2017-03-09 10:24:56.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: cifsdd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "CIFSDD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "CIFSDD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/dbwrap_tool.1 samba-4.5.6+dfsg/docs/manpages/dbwrap_tool.1
--- samba-4.5.5+dfsg/docs/manpages/dbwrap_tool.1 2017-01-30 11:15:43.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/dbwrap_tool.1 2017-03-09 10:24:56.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: dbwrap_tool
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "DBWRAP_TOOL" "1" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "DBWRAP_TOOL" "1" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/eventlogadm.8 samba-4.5.6+dfsg/docs/manpages/eventlogadm.8
--- samba-4.5.5+dfsg/docs/manpages/eventlogadm.8 2017-01-30 11:15:43.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/eventlogadm.8 2017-03-09 10:24:56.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: eventlogadm
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "EVENTLOGADM" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "EVENTLOGADM" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/findsmb.1 samba-4.5.6+dfsg/docs/manpages/findsmb.1
--- samba-4.5.5+dfsg/docs/manpages/findsmb.1 2017-01-30 11:15:44.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/findsmb.1 2017-03-09 10:24:57.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: findsmb
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "FINDSMB" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "FINDSMB" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_ad.8 samba-4.5.6+dfsg/docs/manpages/idmap_ad.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_ad.8 2017-01-30 11:15:44.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_ad.8 2017-03-09 10:24:57.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_ad
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_AD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_AD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_autorid.8 samba-4.5.6+dfsg/docs/manpages/idmap_autorid.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_autorid.8 2017-01-30 11:15:44.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_autorid.8 2017-03-09 10:24:57.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_autorid
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_AUTORID" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_AUTORID" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_hash.8 samba-4.5.6+dfsg/docs/manpages/idmap_hash.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_hash.8 2017-01-30 11:15:44.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_hash.8 2017-03-09 10:24:57.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_hash
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_HASH" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_HASH" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_ldap.8 samba-4.5.6+dfsg/docs/manpages/idmap_ldap.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_ldap.8 2017-01-30 11:15:44.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_ldap.8 2017-03-09 10:24:58.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_ldap
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_LDAP" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_LDAP" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_nss.8 samba-4.5.6+dfsg/docs/manpages/idmap_nss.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_nss.8 2017-01-30 11:15:45.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_nss.8 2017-03-09 10:24:58.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_nss
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_NSS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_NSS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_rfc2307.8 samba-4.5.6+dfsg/docs/manpages/idmap_rfc2307.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_rfc2307.8 2017-01-30 11:15:45.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_rfc2307.8 2017-03-09 10:24:58.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_rfc2307
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_RFC2307" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_RFC2307" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_rid.8 samba-4.5.6+dfsg/docs/manpages/idmap_rid.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_rid.8 2017-01-30 11:15:45.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_rid.8 2017-03-09 10:24:58.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_rid
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_RID" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_RID" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_script.8 samba-4.5.6+dfsg/docs/manpages/idmap_script.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_script.8 2017-01-30 11:15:45.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_script.8 2017-03-09 10:24:58.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_script
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_SCRIPT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_SCRIPT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_tdb2.8 samba-4.5.6+dfsg/docs/manpages/idmap_tdb2.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_tdb2.8 2017-01-30 11:15:46.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_tdb2.8 2017-03-09 10:24:59.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_tdb2
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_TDB2" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_TDB2" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/idmap_tdb.8 samba-4.5.6+dfsg/docs/manpages/idmap_tdb.8
--- samba-4.5.5+dfsg/docs/manpages/idmap_tdb.8 2017-01-30 11:15:46.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/idmap_tdb.8 2017-03-09 10:24:59.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: idmap_tdb
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "IDMAP_TDB" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "IDMAP_TDB" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/libsmbclient.7 samba-4.5.6+dfsg/docs/manpages/libsmbclient.7
--- samba-4.5.5+dfsg/docs/manpages/libsmbclient.7 2017-01-30 11:15:46.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/libsmbclient.7 2017-03-09 10:24:59.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: libsmbclient
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: 7
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "LIBSMBCLIENT" "7" "01/30/2017" "Samba 4\&.5" "7"
+.TH "LIBSMBCLIENT" "7" "03/09/2017" "Samba 4\&.5" "7"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/lmhosts.5 samba-4.5.6+dfsg/docs/manpages/lmhosts.5
--- samba-4.5.5+dfsg/docs/manpages/lmhosts.5 2017-01-30 11:15:46.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/lmhosts.5 2017-03-09 10:24:59.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: lmhosts
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: File Formats and Conventions
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "LMHOSTS" "5" "01/30/2017" "Samba 4\&.5" "File Formats and Conventions"
+.TH "LMHOSTS" "5" "03/09/2017" "Samba 4\&.5" "File Formats and Conventions"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/log2pcap.1 samba-4.5.6+dfsg/docs/manpages/log2pcap.1
--- samba-4.5.5+dfsg/docs/manpages/log2pcap.1 2017-01-30 11:15:47.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/log2pcap.1 2017-03-09 10:25:00.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: log2pcap
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "LOG2PCAP" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "LOG2PCAP" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/net.8 samba-4.5.6+dfsg/docs/manpages/net.8
--- samba-4.5.5+dfsg/docs/manpages/net.8 2017-01-30 11:15:47.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/net.8 2017-03-09 10:25:00.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: net
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "NET" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "NET" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/nmbd.8 samba-4.5.6+dfsg/docs/manpages/nmbd.8
--- samba-4.5.5+dfsg/docs/manpages/nmbd.8 2017-01-30 11:15:47.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/nmbd.8 2017-03-09 10:25:00.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: nmbd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "NMBD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "NMBD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/nmblookup.1 samba-4.5.6+dfsg/docs/manpages/nmblookup.1
--- samba-4.5.5+dfsg/docs/manpages/nmblookup.1 2017-01-30 11:15:47.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/nmblookup.1 2017-03-09 10:25:00.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: nmblookup
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "NMBLOOKUP" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "NMBLOOKUP" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/ntlm_auth.1 samba-4.5.6+dfsg/docs/manpages/ntlm_auth.1
--- samba-4.5.5+dfsg/docs/manpages/ntlm_auth.1 2017-01-30 11:15:48.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/ntlm_auth.1 2017-03-09 10:25:01.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: ntlm_auth
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "NTLM_AUTH" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "NTLM_AUTH" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/pam_winbind.8 samba-4.5.6+dfsg/docs/manpages/pam_winbind.8
--- samba-4.5.5+dfsg/docs/manpages/pam_winbind.8 2017-01-30 11:15:48.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/pam_winbind.8 2017-03-09 10:25:01.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: pam_winbind
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: 8
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "PAM_WINBIND" "8" "01/30/2017" "Samba 4\&.5" "8"
+.TH "PAM_WINBIND" "8" "03/09/2017" "Samba 4\&.5" "8"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/pam_winbind.conf.5 samba-4.5.6+dfsg/docs/manpages/pam_winbind.conf.5
--- samba-4.5.5+dfsg/docs/manpages/pam_winbind.conf.5 2017-01-30 11:15:48.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/pam_winbind.conf.5 2017-03-09 10:25:01.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: pam_winbind.conf
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: 5
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "PAM_WINBIND\&.CONF" "5" "01/30/2017" "Samba 4\&.5" "5"
+.TH "PAM_WINBIND\&.CONF" "5" "03/09/2017" "Samba 4\&.5" "5"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/pdbedit.8 samba-4.5.6+dfsg/docs/manpages/pdbedit.8
--- samba-4.5.5+dfsg/docs/manpages/pdbedit.8 2017-01-30 11:15:48.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/pdbedit.8 2017-03-09 10:25:01.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: pdbedit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "PDBEDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "PDBEDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/profiles.1 samba-4.5.6+dfsg/docs/manpages/profiles.1
--- samba-4.5.5+dfsg/docs/manpages/profiles.1 2017-01-30 11:15:49.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/profiles.1 2017-03-09 10:25:01.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: profiles
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "PROFILES" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "PROFILES" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/rpcclient.1 samba-4.5.6+dfsg/docs/manpages/rpcclient.1
--- samba-4.5.5+dfsg/docs/manpages/rpcclient.1 2017-01-30 11:15:49.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/rpcclient.1 2017-03-09 10:25:02.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: rpcclient
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "RPCCLIENT" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "RPCCLIENT" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/samba.7 samba-4.5.6+dfsg/docs/manpages/samba.7
--- samba-4.5.5+dfsg/docs/manpages/samba.7 2017-01-30 11:15:50.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/samba.7 2017-03-09 10:25:02.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: samba
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: Miscellanea
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SAMBA" "7" "01/30/2017" "Samba 4\&.5" "Miscellanea"
+.TH "SAMBA" "7" "03/09/2017" "Samba 4\&.5" "Miscellanea"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/samba.8 samba-4.5.6+dfsg/docs/manpages/samba.8
--- samba-4.5.5+dfsg/docs/manpages/samba.8 2017-01-30 11:15:50.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/samba.8 2017-03-09 10:25:03.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: samba
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SAMBA" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SAMBA" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/samba-regedit.8 samba-4.5.6+dfsg/docs/manpages/samba-regedit.8
--- samba-4.5.5+dfsg/docs/manpages/samba-regedit.8 2017-01-30 11:15:49.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/samba-regedit.8 2017-03-09 10:25:02.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: samba-regedit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SAMBA\-REGEDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SAMBA\-REGEDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/samba-tool.8 samba-4.5.6+dfsg/docs/manpages/samba-tool.8
--- samba-4.5.5+dfsg/docs/manpages/samba-tool.8 2017-01-30 11:15:49.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/samba-tool.8 2017-03-09 10:25:02.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: samba-tool
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SAMBA\-TOOL" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SAMBA\-TOOL" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/sharesec.1 samba-4.5.6+dfsg/docs/manpages/sharesec.1
--- samba-4.5.5+dfsg/docs/manpages/sharesec.1 2017-01-30 11:15:50.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/sharesec.1 2017-03-09 10:25:03.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: sharesec
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SHARESEC" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SHARESEC" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbcacls.1 samba-4.5.6+dfsg/docs/manpages/smbcacls.1
--- samba-4.5.5+dfsg/docs/manpages/smbcacls.1 2017-01-30 11:15:54.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbcacls.1 2017-03-09 10:25:07.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbcacls
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBCACLS" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBCACLS" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbclient.1 samba-4.5.6+dfsg/docs/manpages/smbclient.1
--- samba-4.5.5+dfsg/docs/manpages/smbclient.1 2017-01-30 11:15:54.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbclient.1 2017-03-09 10:25:07.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbclient
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBCLIENT" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBCLIENT" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smb.conf.5 samba-4.5.6+dfsg/docs/manpages/smb.conf.5
--- samba-4.5.5+dfsg/docs/manpages/smb.conf.5 2017-01-30 11:15:53.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smb.conf.5 2017-03-09 10:25:06.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smb.conf
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: File Formats and Conventions
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMB\&.CONF" "5" "01/30/2017" "Samba 4\&.5" "File Formats and Conventions"
+.TH "SMB\&.CONF" "5" "03/09/2017" "Samba 4\&.5" "File Formats and Conventions"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -10473,7 +10473,9 @@
.\}
Setting it to
\fIoff\fR
-globally will completely disable the encryption feature\&.
+globally will completely disable the encryption feature for all connections\&. Setting
+\fIsmb encrypt = required\fR
+for individual shares (while it\*(Aqs globally off) will deny access to this shares for all clients\&.
.RE
.sp
.RS 4
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbcontrol.1 samba-4.5.6+dfsg/docs/manpages/smbcontrol.1
--- samba-4.5.5+dfsg/docs/manpages/smbcontrol.1 2017-01-30 11:15:54.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbcontrol.1 2017-03-09 10:25:07.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbcontrol
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBCONTROL" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBCONTROL" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbcquotas.1 samba-4.5.6+dfsg/docs/manpages/smbcquotas.1
--- samba-4.5.5+dfsg/docs/manpages/smbcquotas.1 2017-01-30 11:15:54.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbcquotas.1 2017-03-09 10:25:07.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbcquotas
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBCQUOTAS" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBCQUOTAS" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbd.8 samba-4.5.6+dfsg/docs/manpages/smbd.8
--- samba-4.5.5+dfsg/docs/manpages/smbd.8 2017-01-30 11:15:55.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbd.8 2017-03-09 10:25:08.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SMBD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbget.1 samba-4.5.6+dfsg/docs/manpages/smbget.1
--- samba-4.5.5+dfsg/docs/manpages/smbget.1 2017-01-30 11:15:55.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbget.1 2017-03-09 10:25:08.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbget
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBGET" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBGET" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbgetrc.5 samba-4.5.6+dfsg/docs/manpages/smbgetrc.5
--- samba-4.5.5+dfsg/docs/manpages/smbgetrc.5 2017-01-30 11:15:55.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbgetrc.5 2017-03-09 10:25:08.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbgetrc
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: File Formats and Conventions
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBGETRC" "5" "01/30/2017" "Samba 4\&.5" "File Formats and Conventions"
+.TH "SMBGETRC" "5" "03/09/2017" "Samba 4\&.5" "File Formats and Conventions"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbpasswd.5 samba-4.5.6+dfsg/docs/manpages/smbpasswd.5
--- samba-4.5.5+dfsg/docs/manpages/smbpasswd.5 2017-01-30 11:15:55.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbpasswd.5 2017-03-09 10:25:08.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbpasswd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: File Formats and Conventions
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBPASSWD" "5" "01/30/2017" "Samba 4\&.5" "File Formats and Conventions"
+.TH "SMBPASSWD" "5" "03/09/2017" "Samba 4\&.5" "File Formats and Conventions"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbpasswd.8 samba-4.5.6+dfsg/docs/manpages/smbpasswd.8
--- samba-4.5.5+dfsg/docs/manpages/smbpasswd.8 2017-01-30 11:15:56.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbpasswd.8 2017-03-09 10:25:09.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbpasswd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBPASSWD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SMBPASSWD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbspool.8 samba-4.5.6+dfsg/docs/manpages/smbspool.8
--- samba-4.5.5+dfsg/docs/manpages/smbspool.8 2017-01-30 11:15:56.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbspool.8 2017-03-09 10:25:09.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbspool
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBSPOOL" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SMBSPOOL" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbspool_krb5_wrapper.8 samba-4.5.6+dfsg/docs/manpages/smbspool_krb5_wrapper.8
--- samba-4.5.5+dfsg/docs/manpages/smbspool_krb5_wrapper.8 2017-01-30 11:15:56.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbspool_krb5_wrapper.8 2017-03-09 10:25:09.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbspool_krb5_wrapper
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBSPOOL_KRB5_WRAPPE" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "SMBSPOOL_KRB5_WRAPPE" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbstatus.1 samba-4.5.6+dfsg/docs/manpages/smbstatus.1
--- samba-4.5.5+dfsg/docs/manpages/smbstatus.1 2017-01-30 11:15:56.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbstatus.1 2017-03-09 10:25:09.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbstatus
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBSTATUS" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBSTATUS" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbtar.1 samba-4.5.6+dfsg/docs/manpages/smbtar.1
--- samba-4.5.5+dfsg/docs/manpages/smbtar.1 2017-01-30 11:15:56.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbtar.1 2017-03-09 10:25:09.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbtar
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBTAR" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBTAR" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/smbtree.1 samba-4.5.6+dfsg/docs/manpages/smbtree.1
--- samba-4.5.5+dfsg/docs/manpages/smbtree.1 2017-01-30 11:15:57.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/smbtree.1 2017-03-09 10:25:10.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: smbtree
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "SMBTREE" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "SMBTREE" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/testparm.1 samba-4.5.6+dfsg/docs/manpages/testparm.1
--- samba-4.5.5+dfsg/docs/manpages/testparm.1 2017-01-30 11:15:57.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/testparm.1 2017-03-09 10:25:10.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: testparm
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "TESTPARM" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "TESTPARM" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_acl_tdb.8 samba-4.5.6+dfsg/docs/manpages/vfs_acl_tdb.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_acl_tdb.8 2017-01-30 11:15:57.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_acl_tdb.8 2017-03-09 10:25:10.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_acl_tdb
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_ACL_TDB" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_ACL_TDB" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_acl_xattr.8 samba-4.5.6+dfsg/docs/manpages/vfs_acl_xattr.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_acl_xattr.8 2017-01-30 11:15:57.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_acl_xattr.8 2017-03-09 10:25:10.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_acl_xattr
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_ACL_XATTR" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_ACL_XATTR" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_aio_fork.8 samba-4.5.6+dfsg/docs/manpages/vfs_aio_fork.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_aio_fork.8 2017-01-30 11:15:58.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_aio_fork.8 2017-03-09 10:25:11.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_aio_fork
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_AIO_FORK" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_AIO_FORK" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_aio_linux.8 samba-4.5.6+dfsg/docs/manpages/vfs_aio_linux.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_aio_linux.8 2017-01-30 11:15:58.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_aio_linux.8 2017-03-09 10:25:11.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_aio_linux
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_AIO_LINUX" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_AIO_LINUX" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_aio_pthread.8 samba-4.5.6+dfsg/docs/manpages/vfs_aio_pthread.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_aio_pthread.8 2017-01-30 11:15:58.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_aio_pthread.8 2017-03-09 10:25:11.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_aio_pthread
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_AIO_PTHREAD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_AIO_PTHREAD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_audit.8 samba-4.5.6+dfsg/docs/manpages/vfs_audit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_audit.8 2017-01-30 11:15:58.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_audit.8 2017-03-09 10:25:11.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_audit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_AUDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_AUDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_btrfs.8 samba-4.5.6+dfsg/docs/manpages/vfs_btrfs.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_btrfs.8 2017-01-30 11:15:59.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_btrfs.8 2017-03-09 10:25:11.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_btrfs
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_BTRFS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_BTRFS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_cacheprime.8 samba-4.5.6+dfsg/docs/manpages/vfs_cacheprime.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_cacheprime.8 2017-01-30 11:15:59.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_cacheprime.8 2017-03-09 10:25:12.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_cacheprime
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_CACHEPRIME" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_CACHEPRIME" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_cap.8 samba-4.5.6+dfsg/docs/manpages/vfs_cap.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_cap.8 2017-01-30 11:15:59.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_cap.8 2017-03-09 10:25:12.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_cap
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_CAP" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_CAP" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_catia.8 samba-4.5.6+dfsg/docs/manpages/vfs_catia.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_catia.8 2017-01-30 11:15:59.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_catia.8 2017-03-09 10:25:12.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_catia
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_CATIA" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_CATIA" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_ceph.8 samba-4.5.6+dfsg/docs/manpages/vfs_ceph.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_ceph.8 2017-01-30 11:15:59.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_ceph.8 2017-03-09 10:25:12.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_ceph
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_CEPH" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_CEPH" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_commit.8 samba-4.5.6+dfsg/docs/manpages/vfs_commit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_commit.8 2017-01-30 11:16:00.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_commit.8 2017-03-09 10:25:13.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_commit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_COMMIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_COMMIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_crossrename.8 samba-4.5.6+dfsg/docs/manpages/vfs_crossrename.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_crossrename.8 2017-01-30 11:16:00.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_crossrename.8 2017-03-09 10:25:13.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_crossrename
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_CROSSRENAME" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_CROSSRENAME" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_default_quota.8 samba-4.5.6+dfsg/docs/manpages/vfs_default_quota.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_default_quota.8 2017-01-30 11:16:00.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_default_quota.8 2017-03-09 10:25:13.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_default_quota
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_DEFAULT_QUOTA" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_DEFAULT_QUOTA" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_dirsort.8 samba-4.5.6+dfsg/docs/manpages/vfs_dirsort.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_dirsort.8 2017-01-30 11:16:00.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_dirsort.8 2017-03-09 10:25:13.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_dirsort
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_DIRSORT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_DIRSORT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_extd_audit.8 samba-4.5.6+dfsg/docs/manpages/vfs_extd_audit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_extd_audit.8 2017-01-30 11:16:01.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_extd_audit.8 2017-03-09 10:25:13.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_extd_audit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_EXTD_AUDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_EXTD_AUDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_fake_perms.8 samba-4.5.6+dfsg/docs/manpages/vfs_fake_perms.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_fake_perms.8 2017-01-30 11:16:01.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_fake_perms.8 2017-03-09 10:25:14.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_fake_perms
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_FAKE_PERMS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_FAKE_PERMS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_fileid.8 samba-4.5.6+dfsg/docs/manpages/vfs_fileid.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_fileid.8 2017-01-30 11:16:01.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_fileid.8 2017-03-09 10:25:14.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_fileid
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_FILEID" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_FILEID" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_fruit.8 samba-4.5.6+dfsg/docs/manpages/vfs_fruit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_fruit.8 2017-01-30 11:16:01.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_fruit.8 2017-03-09 10:25:14.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_fruit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_FRUIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_FRUIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -197,7 +197,13 @@
.PP
fruit:encoding = [ native | private ]
.RS 4
-Controls how the set of illegal NTFS ASCII character, commonly used by OS X clients, are stored in the filesystem:
+Controls how the set of illegal NTFS ASCII character, commonly used by OS X clients, are stored in the filesystem\&.
+.sp
+\fIImportant:\fR
+this is known to not fully work with
+\fIfruit:metadata=stream\fR
+or
+\fIfruit:resource=stream\fR\&.
.sp
.RS 4
.ie n \{\
@@ -300,7 +306,17 @@
.PP
fruit:veto_appledouble = yes | no
.RS 4
-Whether \&._ AppleDouble files are vetoed which prevents the client from seing and accessing internal AppleDouble files created by vfs_fruit itself for the purpose of storing a Mac resource fork\&.
+\fINote:\fR
+this option only applies when
+\fIfruit:resource\fR
+is set to
+\fIfile\fR
+(the default)\&.
+.sp
+When
+\fIfruit:resource\fR
+is set to
+\fIfile\fR, vfs_fruit may create \&._ AppleDouble files\&. This options controls whether these \&._ AppleDouble files are vetoed which prevents the client from accessing them\&.
.sp
Vetoing \&._ files may break some applications, eg extracting Mac ZIP archives from Mac clients failes, because they contain \&._ files\&. Setting this option to false will fix this, but the abstraction leak of exposing the internally created \&._ files may have other unknown side effects\&.
.sp
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_full_audit.8 samba-4.5.6+dfsg/docs/manpages/vfs_full_audit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_full_audit.8 2017-01-30 11:16:02.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_full_audit.8 2017-03-09 10:25:14.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_full_audit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_FULL_AUDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_FULL_AUDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_glusterfs.8 samba-4.5.6+dfsg/docs/manpages/vfs_glusterfs.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_glusterfs.8 2017-01-30 11:16:02.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_glusterfs.8 2017-03-09 10:25:15.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_glusterfs
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_GLUSTERFS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_GLUSTERFS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_gpfs.8 samba-4.5.6+dfsg/docs/manpages/vfs_gpfs.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_gpfs.8 2017-01-30 11:16:02.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_gpfs.8 2017-03-09 10:25:15.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_gpfs
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_GPFS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_GPFS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_linux_xfs_sgid.8 samba-4.5.6+dfsg/docs/manpages/vfs_linux_xfs_sgid.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_linux_xfs_sgid.8 2017-01-30 11:16:02.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_linux_xfs_sgid.8 2017-03-09 10:25:15.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_syncops
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SYNCOPS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SYNCOPS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_media_harmony.8 samba-4.5.6+dfsg/docs/manpages/vfs_media_harmony.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_media_harmony.8 2017-01-30 11:16:03.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_media_harmony.8 2017-03-09 10:25:15.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_media_harmony
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_MEDIA_HARMONY" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_MEDIA_HARMONY" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_netatalk.8 samba-4.5.6+dfsg/docs/manpages/vfs_netatalk.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_netatalk.8 2017-01-30 11:16:03.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_netatalk.8 2017-03-09 10:25:16.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_netatalk
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_NETATALK" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_NETATALK" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_offline.8 samba-4.5.6+dfsg/docs/manpages/vfs_offline.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_offline.8 2017-01-30 11:16:03.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_offline.8 2017-03-09 10:25:16.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_offline
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_OFFLINE" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_OFFLINE" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_prealloc.8 samba-4.5.6+dfsg/docs/manpages/vfs_prealloc.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_prealloc.8 2017-01-30 11:16:03.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_prealloc.8 2017-03-09 10:25:16.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_prealloc
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_PREALLOC" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_PREALLOC" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_preopen.8 samba-4.5.6+dfsg/docs/manpages/vfs_preopen.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_preopen.8 2017-01-30 11:16:04.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_preopen.8 2017-03-09 10:25:16.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_preopen
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_PREOPEN" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_PREOPEN" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_readahead.8 samba-4.5.6+dfsg/docs/manpages/vfs_readahead.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_readahead.8 2017-01-30 11:16:04.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_readahead.8 2017-03-09 10:25:16.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_readahead
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_READAHEAD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_READAHEAD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_readonly.8 samba-4.5.6+dfsg/docs/manpages/vfs_readonly.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_readonly.8 2017-01-30 11:16:04.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_readonly.8 2017-03-09 10:25:17.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_readonly
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_READONLY" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_READONLY" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_recycle.8 samba-4.5.6+dfsg/docs/manpages/vfs_recycle.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_recycle.8 2017-01-30 11:16:04.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_recycle.8 2017-03-09 10:25:17.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_recycle
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_RECYCLE" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_RECYCLE" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_shadow_copy2.8 samba-4.5.6+dfsg/docs/manpages/vfs_shadow_copy2.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_shadow_copy2.8 2017-01-30 11:16:05.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_shadow_copy2.8 2017-03-09 10:25:17.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_shadow_copy2
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SHADOW_COPY2" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SHADOW_COPY2" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_shadow_copy.8 samba-4.5.6+dfsg/docs/manpages/vfs_shadow_copy.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_shadow_copy.8 2017-01-30 11:16:04.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_shadow_copy.8 2017-03-09 10:25:17.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_shadow_copy
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SHADOW_COPY" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SHADOW_COPY" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_shell_snap.8 samba-4.5.6+dfsg/docs/manpages/vfs_shell_snap.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_shell_snap.8 2017-01-30 11:16:05.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_shell_snap.8 2017-03-09 10:25:18.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_shell_snap
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SHELL_SNAP" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SHELL_SNAP" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_snapper.8 samba-4.5.6+dfsg/docs/manpages/vfs_snapper.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_snapper.8 2017-01-30 11:16:05.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_snapper.8 2017-03-09 10:25:18.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_snapper
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SNAPPER" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SNAPPER" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_streams_depot.8 samba-4.5.6+dfsg/docs/manpages/vfs_streams_depot.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_streams_depot.8 2017-01-30 11:16:05.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_streams_depot.8 2017-03-09 10:25:18.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_streams_depot
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_STREAMS_DEPOT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_STREAMS_DEPOT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_streams_xattr.8 samba-4.5.6+dfsg/docs/manpages/vfs_streams_xattr.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_streams_xattr.8 2017-01-30 11:16:06.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_streams_xattr.8 2017-03-09 10:25:18.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_streams_xattr
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_STREAMS_XATTR" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_STREAMS_XATTR" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_syncops.8 samba-4.5.6+dfsg/docs/manpages/vfs_syncops.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_syncops.8 2017-01-30 11:16:06.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_syncops.8 2017-03-09 10:25:18.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_syncops
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_SYNCOPS" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_SYNCOPS" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfstest.1 samba-4.5.6+dfsg/docs/manpages/vfstest.1
--- samba-4.5.5+dfsg/docs/manpages/vfstest.1 2017-01-30 11:16:08.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfstest.1 2017-03-09 10:25:20.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfstest
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFSTEST" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "VFSTEST" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_time_audit.8 samba-4.5.6+dfsg/docs/manpages/vfs_time_audit.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_time_audit.8 2017-01-30 11:16:06.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_time_audit.8 2017-03-09 10:25:19.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_time_audit
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_TIME_AUDIT" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_TIME_AUDIT" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_tsmsm.8 samba-4.5.6+dfsg/docs/manpages/vfs_tsmsm.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_tsmsm.8 2017-01-30 11:16:06.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_tsmsm.8 2017-03-09 10:25:19.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_tsmsm
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_TSMSM" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_TSMSM" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_unityed_media.8 samba-4.5.6+dfsg/docs/manpages/vfs_unityed_media.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_unityed_media.8 2017-01-30 11:16:07.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_unityed_media.8 2017-03-09 10:25:19.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_unityed_media
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_UNITYED_MEDIA" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_UNITYED_MEDIA" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_worm.8 samba-4.5.6+dfsg/docs/manpages/vfs_worm.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_worm.8 2017-01-30 11:16:07.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_worm.8 2017-03-09 10:25:19.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_worm
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_WORM" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_WORM" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_xattr_tdb.8 samba-4.5.6+dfsg/docs/manpages/vfs_xattr_tdb.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_xattr_tdb.8 2017-01-30 11:16:07.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_xattr_tdb.8 2017-03-09 10:25:20.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_xattr_tdb
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_XATTR_TDB" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_XATTR_TDB" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/vfs_zfsacl.8 samba-4.5.6+dfsg/docs/manpages/vfs_zfsacl.8
--- samba-4.5.5+dfsg/docs/manpages/vfs_zfsacl.8 2017-01-30 11:16:07.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/vfs_zfsacl.8 2017-03-09 10:25:20.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: vfs_zfsacl
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "VFS_ZFSACL" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "VFS_ZFSACL" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/wbinfo.1 samba-4.5.6+dfsg/docs/manpages/wbinfo.1
--- samba-4.5.5+dfsg/docs/manpages/wbinfo.1 2017-01-30 11:16:08.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/wbinfo.1 2017-03-09 10:25:20.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: wbinfo
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: User Commands
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "WBINFO" "1" "01/30/2017" "Samba 4\&.5" "User Commands"
+.TH "WBINFO" "1" "03/09/2017" "Samba 4\&.5" "User Commands"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/winbindd.8 samba-4.5.6+dfsg/docs/manpages/winbindd.8
--- samba-4.5.5+dfsg/docs/manpages/winbindd.8 2017-01-30 11:16:08.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/winbindd.8 2017-03-09 10:25:21.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: winbindd
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: System Administration tools
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "WINBINDD" "8" "01/30/2017" "Samba 4\&.5" "System Administration tools"
+.TH "WINBINDD" "8" "03/09/2017" "Samba 4\&.5" "System Administration tools"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs/manpages/winbind_krb5_locator.7 samba-4.5.6+dfsg/docs/manpages/winbind_krb5_locator.7
--- samba-4.5.5+dfsg/docs/manpages/winbind_krb5_locator.7 2017-01-30 11:16:08.000000000 +0100
+++ samba-4.5.6+dfsg/docs/manpages/winbind_krb5_locator.7 2017-03-09 10:25:20.000000000 +0100
@@ -2,12 +2,12 @@
.\" Title: winbind_krb5_locator
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\" Date: 01/30/2017
+.\" Date: 03/09/2017
.\" Manual: 7
.\" Source: Samba 4.5
.\" Language: English
.\"
-.TH "WINBIND_KRB5_LOCATOR" "7" "01/30/2017" "Samba 4\&.5" "7"
+.TH "WINBIND_KRB5_LOCATOR" "7" "03/09/2017" "Samba 4\&.5" "7"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
diff -Nru samba-4.5.5+dfsg/docs-xml/manpages/vfs_fruit.8.xml samba-4.5.6+dfsg/docs-xml/manpages/vfs_fruit.8.xml
--- samba-4.5.5+dfsg/docs-xml/manpages/vfs_fruit.8.xml 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/docs-xml/manpages/vfs_fruit.8.xml 2017-03-09 10:21:43.000000000 +0100
@@ -168,9 +168,13 @@
<para>Controls how the set of illegal NTFS ASCII
character, commonly used by OS X clients, are stored in
- the filesystem:</para>
+ the filesystem.</para>
- <itemizedlist>
+ <para><emphasis>Important:</emphasis> this is known to not fully
+ work with <emphasis>fruit:metadata=stream</emphasis> or
+ <emphasis>fruit:resource=stream</emphasis>.</para>
+
+ <itemizedlist>
<listitem><para><command>private (default)</command> -
store characters as encoded by the OS X client: mapped
@@ -231,10 +235,14 @@
<varlistentry>
<term>fruit:veto_appledouble = yes | no</term>
<listitem>
- <para>Whether ._ AppleDouble files are vetoed which
- prevents the client from seing and accessing internal
- AppleDouble files created by vfs_fruit itself for the
- purpose of storing a Mac resource fork.</para>
+ <para><emphasis>Note:</emphasis> this option only applies when
+ <parameter>fruit:resource</parameter> is set to
+ <parameter>file</parameter> (the default).</para>
+
+ <para>When <parameter>fruit:resource</parameter> is set to
+ <parameter>file</parameter>, vfs_fruit may create ._ AppleDouble
+ files. This options controls whether these ._ AppleDouble files
+ are vetoed which prevents the client from accessing them.</para>
<para>Vetoing ._ files may break some applications, eg
extracting Mac ZIP archives from Mac clients failes,
because they contain ._ files. Setting this option to
diff -Nru samba-4.5.5+dfsg/docs-xml/smbdotconf/security/smbencrypt.xml samba-4.5.6+dfsg/docs-xml/smbdotconf/security/smbencrypt.xml
--- samba-4.5.5+dfsg/docs-xml/smbdotconf/security/smbencrypt.xml 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/docs-xml/smbdotconf/security/smbencrypt.xml 2017-03-09 10:21:43.000000000 +0100
@@ -180,7 +180,11 @@
<listitem>
<para>
Setting it to <emphasis>off</emphasis> globally will
- completely disable the encryption feature.
+ completely disable the encryption feature for all
+ connections. Setting <parameter>smb encrypt =
+ required</parameter> for individual shares (while it's
+ globally off) will deny access to this shares for all
+ clients.
</para>
</listitem>
diff -Nru samba-4.5.5+dfsg/lib/krb5_wrap/krb5_samba.c samba-4.5.6+dfsg/lib/krb5_wrap/krb5_samba.c
--- samba-4.5.5+dfsg/lib/krb5_wrap/krb5_samba.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/lib/krb5_wrap/krb5_samba.c 2017-03-09 10:21:43.000000000 +0100
@@ -24,6 +24,7 @@
#include "system/filesys.h"
#include "krb5_samba.h"
#include "lib/util/asn1.h"
+#include "lib/crypto/crypto.h"
#ifdef HAVE_COM_ERR_H
#include <com_err.h>
@@ -202,6 +203,42 @@
return -1;
}
+ if ((int)enctype == (int)ENCTYPE_ARCFOUR_HMAC) {
+ TALLOC_CTX *frame = talloc_stackframe();
+ uint8_t *utf16 = NULL;
+ size_t utf16_size = 0;
+ uint8_t nt_hash[16];
+ bool ok;
+
+ ok = convert_string_talloc(frame, CH_UNIX, CH_UTF16LE,
+ password->data, password->length,
+ (void **)&utf16, &utf16_size);
+ if (!ok) {
+ if (errno == 0) {
+ errno = EINVAL;
+ }
+ ret = errno;
+ TALLOC_FREE(frame);
+ return ret;
+ }
+
+ mdfour(nt_hash, utf16, utf16_size);
+ memset(utf16, 0, utf16_size);
+ ret = smb_krb5_keyblock_init_contents(context,
+ ENCTYPE_ARCFOUR_HMAC,
+ nt_hash,
+ sizeof(nt_hash),
+ key);
+ ZERO_STRUCT(nt_hash);
+ if (ret != 0) {
+ TALLOC_FREE(frame);
+ return ret;
+ }
+
+ TALLOC_FREE(frame);
+ return 0;
+ }
+
#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
{/* MIT */
krb5_data _salt;
diff -Nru samba-4.5.5+dfsg/lib/ldb-samba/ldb_ildap.c samba-4.5.6+dfsg/lib/ldb-samba/ldb_ildap.c
--- samba-4.5.5+dfsg/lib/ldb-samba/ldb_ildap.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/lib/ldb-samba/ldb_ildap.c 2017-03-09 10:21:43.000000000 +0100
@@ -863,6 +863,7 @@
return LDB_SUCCESS;
failed:
+ ldb_set_errstring(ldb, ldap_errstr(ildb->ldap, module, status));
talloc_free(module);
if (NT_STATUS_IS_LDAP(status)) {
return NT_STATUS_LDAP_CODE(status);
diff -Nru samba-4.5.5+dfsg/lib/torture/torture.h samba-4.5.6+dfsg/lib/torture/torture.h
--- samba-4.5.5+dfsg/lib/torture/torture.h 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/lib/torture/torture.h 2017-03-09 10:21:43.000000000 +0100
@@ -357,6 +357,16 @@
} \
} while(0)
+#define torture_assert_mem_equal_goto(torture_ctx,got,expected,len,ret,label,cmt) \
+ do { const void *__got = (got), *__expected = (expected); \
+ if (memcmp(__got, __expected, len) != 0) { \
+ torture_result(torture_ctx, TORTURE_FAIL, \
+ __location__": "#got" of len %d did not match "#expected": %s", (int)len, cmt); \
+ ret = false; \
+ goto label; \
+ } \
+ } while(0)
+
static inline void torture_dump_data_str_cb(const char *buf, void *private_data)
{
char **dump = (char **)private_data;
diff -Nru samba-4.5.5+dfsg/lib/util/genrand_util.c samba-4.5.6+dfsg/lib/util/genrand_util.c
--- samba-4.5.5+dfsg/lib/util/genrand_util.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/lib/util/genrand_util.c 2017-03-09 10:21:43.000000000 +0100
@@ -210,7 +210,7 @@
}
/**
- * Generate a random text password.
+ * Generate a random text password (based on printable ascii characters).
*/
_PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max)
@@ -258,6 +258,172 @@
}
/**
+ * Generate a random machine password (based on random utf16 characters,
+ * converted to utf8). min must be at least 14, max must be at most 255.
+ *
+ * If 'unix charset' is not utf8, the password consist of random ascii
+ * values!
+ */
+
+_PUBLIC_ char *generate_random_machine_password(TALLOC_CTX *mem_ctx, size_t min, size_t max)
+{
+ TALLOC_CTX *frame = NULL;
+ struct generate_random_machine_password_state {
+ uint8_t password_buffer[256 * 2];
+ uint8_t tmp;
+ } *state;
+ char *new_pw = NULL;
+ size_t len = max;
+ char *utf8_pw = NULL;
+ size_t utf8_len = 0;
+ char *unix_pw = NULL;
+ size_t unix_len = 0;
+ size_t diff;
+ size_t i;
+ bool ok;
+ int cmp;
+
+ if (max > 255) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (min < 14) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (min > max) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ frame = talloc_stackframe_pool(2048);
+ state = talloc_zero(frame, struct generate_random_machine_password_state);
+
+ diff = max - min;
+
+ if (diff > 0) {
+ size_t tmp;
+
+ generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
+
+ tmp %= diff;
+
+ len = min + tmp;
+ }
+
+ /*
+ * Create a random machine account password
+ * We create a random buffer and convert that to utf8.
+ * This is similar to what windows is doing.
+ *
+ * In future we may store the raw random buffer,
+ * but for now we need to pass the password as
+ * char pointer through some layers.
+ *
+ * As most kerberos keys are derived from the
+ * utf8 password we need to fallback to
+ * ASCII passwords if "unix charset" is not utf8.
+ */
+ generate_secret_buffer(state->password_buffer, len * 2);
+ for (i = 0; i < len; i++) {
+ size_t idx = i*2;
+ uint16_t c;
+
+ /*
+ * both MIT krb5 and HEIMDAL only
+ * handle codepoints up to 0xffff.
+ *
+ * It means we need to avoid
+ * 0xD800 - 0xDBFF (high surrogate)
+ * and
+ * 0xDC00 - 0xDFFF (low surrogate)
+ * in the random utf16 data.
+ *
+ * 55296 0xD800 0154000 0b1101100000000000
+ * 57343 0xDFFF 0157777 0b1101111111111111
+ * 8192 0x2000 020000 0b10000000000000
+ *
+ * The above values show that we can check
+ * for 0xD800 and just add 0x2000 to avoid
+ * the surrogate ranges.
+ *
+ * The rest will be handled by CH_UTF16MUNGED
+ * see utf16_munged_pull().
+ */
+ c = SVAL(state->password_buffer, idx);
+ if (c & 0xD800) {
+ c |= 0x2000;
+ }
+ SSVAL(state->password_buffer, idx, c);
+ }
+ ok = convert_string_talloc(frame,
+ CH_UTF16MUNGED, CH_UTF8,
+ state->password_buffer, len * 2,
+ (void *)&utf8_pw, &utf8_len);
+ if (!ok) {
+ DEBUG(0, ("%s: convert_string_talloc() failed\n",
+ __func__));
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+
+ ok = convert_string_talloc(frame,
+ CH_UTF16MUNGED, CH_UNIX,
+ state->password_buffer, len * 2,
+ (void *)&unix_pw, &unix_len);
+ if (!ok) {
+ goto ascii_fallback;
+ }
+
+ if (utf8_len != unix_len) {
+ goto ascii_fallback;
+ }
+
+ cmp = memcmp((const uint8_t *)utf8_pw,
+ (const uint8_t *)unix_pw,
+ utf8_len);
+ if (cmp != 0) {
+ goto ascii_fallback;
+ }
+
+ new_pw = talloc_strdup(mem_ctx, utf8_pw);
+ if (new_pw == NULL) {
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ talloc_set_name_const(new_pw, __func__);
+ TALLOC_FREE(frame);
+ return new_pw;
+
+ascii_fallback:
+ for (i = 0; i < len; i++) {
+ /*
+ * truncate to ascii
+ */
+ state->tmp = state->password_buffer[i] & 0x7f;
+ if (state->tmp == 0) {
+ state->tmp = state->password_buffer[i] >> 1;
+ }
+ if (state->tmp == 0) {
+ state->tmp = 0x01;
+ }
+ state->password_buffer[i] = state->tmp;
+ }
+ state->password_buffer[i] = '\0';
+
+ new_pw = talloc_strdup(mem_ctx, (const char *)state->password_buffer);
+ if (new_pw == NULL) {
+ TALLOC_FREE(frame);
+ return NULL;
+ }
+ talloc_set_name_const(new_pw, __func__);
+ TALLOC_FREE(frame);
+ return new_pw;
+}
+
+/**
* Generate an array of unique text strings all of the same length.
* The returned string will be allocated.
* Returns NULL if the number of unique combinations cannot be created.
diff -Nru samba-4.5.5+dfsg/lib/util/samba_util.h samba-4.5.6+dfsg/lib/util/samba_util.h
--- samba-4.5.5+dfsg/lib/util/samba_util.h 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/lib/util/samba_util.h 2017-03-09 10:21:43.000000000 +0100
@@ -103,11 +103,41 @@
_PUBLIC_ bool check_password_quality(const char *s);
/**
- * Generate a random text password.
+ * Generate a random text password (based on printable ascii characters).
+ * This function is designed to provide a password that
+ * meats the complexity requirements of UF_NORMAL_ACCOUNT objects
+ * and they should be human readable and writeable on any keyboard layout.
+ *
+ * Characters used are:
+ * ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_-#.,@$%&!?:;<=>()[]~
*/
_PUBLIC_ char *generate_random_password(TALLOC_CTX *mem_ctx, size_t min, size_t max);
/**
+ * Generate a random machine password
+ *
+ * min and max are the number of utf16 characters used
+ * to generate on utf8 compatible password.
+ *
+ * Note: if 'unix charset' is not 'utf8' (the default)
+ * then each utf16 character is only filled with
+ * values from 0x01 to 0x7f (ascii values without 0x00).
+ * This is important as the password neets to be
+ * a valid value as utf8 string and at the same time
+ * a valid value in the 'unix charset'.
+ *
+ * If 'unix charset' is 'utf8' (the default) then
+ * each utf16 character is a random value from 0x0000
+ * 0xFFFF (exluding the surrogate ranges from 0xD800-0xDFFF)
+ * while the translation from CH_UTF16MUNGED
+ * to CH_UTF8 replaces invalid values (see utf16_munged_pull()).
+ *
+ * Note: these passwords may not pass the complexity requirements
+ * for UF_NORMAL_ACCOUNT objects (except krbtgt accounts).
+ */
+_PUBLIC_ char *generate_random_machine_password(TALLOC_CTX *mem_ctx, size_t min, size_t max);
+
+/**
Use the random number generator to generate a random string.
**/
_PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const char *list);
diff -Nru samba-4.5.5+dfsg/libcli/auth/netlogon_creds_cli.c samba-4.5.6+dfsg/libcli/auth/netlogon_creds_cli.c
--- samba-4.5.5+dfsg/libcli/auth/netlogon_creds_cli.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/libcli/auth/netlogon_creds_cli.c 2017-03-09 10:21:43.000000000 +0100
@@ -484,6 +484,14 @@
return NT_STATUS_OK;
}
+char *netlogon_creds_cli_debug_string(
+ const struct netlogon_creds_cli_context *context,
+ TALLOC_CTX *mem_ctx)
+{
+ return talloc_asprintf(mem_ctx, "netlogon_creds_cli:%s",
+ context->db.key_name);
+}
+
enum dcerpc_AuthLevel netlogon_creds_cli_auth_level(
struct netlogon_creds_cli_context *context)
{
@@ -1747,7 +1755,11 @@
/*
* netr_ServerPasswordSet
*/
- E_md4hash(new_password, state->samr_password.hash);
+ ok = E_md4hash(new_password, state->samr_password.hash);
+ if (!ok) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+ return tevent_req_post(req, ev);
+ }
/*
* netr_ServerPasswordSet2
@@ -2075,11 +2087,24 @@
/*
* the read only credentials before we started the operation
+ * used for netr_LogonSamLogonEx() if required (validation_level = 3).
*/
struct netlogon_creds_CredentialState *ro_creds;
+ /*
+ * The (locked) credentials used for the credential chain
+ * used for netr_LogonSamLogonWithFlags() or
+ * netr_LogonSamLogonWith().
+ */
struct netlogon_creds_CredentialState *lk_creds;
+ /*
+ * While we have locked the global credentials (lk_creds above)
+ * we operate an a temporary copy, because a server
+ * may not support netr_LogonSamLogonWithFlags() and
+ * didn't process our netr_Authenticator, so we need to
+ * restart from lk_creds.
+ */
struct netlogon_creds_CredentialState tmp_creds;
struct netr_Authenticator req_auth;
struct netr_Authenticator rep_auth;
@@ -2311,7 +2336,7 @@
return;
}
- netlogon_creds_encrypt_samlogon_logon(state->ro_creds,
+ netlogon_creds_encrypt_samlogon_logon(&state->tmp_creds,
state->logon_level,
state->logon);
@@ -2414,8 +2439,10 @@
/*
* We got a race, lets retry with on authenticator
* protection.
+ *
+ * netlogon_creds_cli_LogonSamLogon_start()
+ * will TALLOC_FREE(state->ro_creds);
*/
- TALLOC_FREE(state->ro_creds);
state->try_logon_ex = false;
netlogon_creds_cli_LogonSamLogon_start(req);
return;
diff -Nru samba-4.5.5+dfsg/libcli/auth/netlogon_creds_cli.h samba-4.5.6+dfsg/libcli/auth/netlogon_creds_cli.h
--- samba-4.5.5+dfsg/libcli/auth/netlogon_creds_cli.h 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/libcli/auth/netlogon_creds_cli.h 2017-03-09 10:21:43.000000000 +0100
@@ -52,6 +52,10 @@
TALLOC_CTX *mem_ctx,
struct netlogon_creds_cli_context **_context);
+char *netlogon_creds_cli_debug_string(
+ const struct netlogon_creds_cli_context *context,
+ TALLOC_CTX *mem_ctx);
+
enum dcerpc_AuthLevel netlogon_creds_cli_auth_level(
struct netlogon_creds_cli_context *context);
diff -Nru samba-4.5.5+dfsg/librpc/rpc/dcerpc_error.c samba-4.5.6+dfsg/librpc/rpc/dcerpc_error.c
--- samba-4.5.5+dfsg/librpc/rpc/dcerpc_error.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/librpc/rpc/dcerpc_error.c 2017-03-09 10:21:43.000000000 +0100
@@ -50,12 +50,10 @@
_FAULT_STR(DCERPC_NCA_S_FAULT_INT_DIV_BY_ZERO, NT_STATUS_RPC_FP_DIV_ZERO),
_FAULT_STR(DCERPC_NCA_S_FAULT_INT_OVERFLOW, NT_STATUS_RPC_FP_OVERFLOW),
/*
- * What's the difference between NT_STATUS_RPC_INVALID_TAG
- * and NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE ???
- *
- * Our callers expect NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE.
+ * Our callers expect NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE
+ * instead of NT_STATUS_RPC_INVALID_TAG.
*/
- _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE),
+ _FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE),
_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_TAG, NT_STATUS_RPC_INVALID_TAG),
_FAULT_STR(DCERPC_NCA_S_FAULT_INVALID_BOUND, NT_STATUS_RPC_INVALID_BOUND),
_FAULT_STR(DCERPC_NCA_S_FAULT_RPC_VERSION_MISMATCH, NT_STATUS_RPC_PROTOCOL_ERROR),
diff -Nru samba-4.5.5+dfsg/python/pyglue.c samba-4.5.6+dfsg/python/pyglue.c
--- samba-4.5.5+dfsg/python/pyglue.c 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/python/pyglue.c 2017-03-09 10:21:43.000000000 +0100
@@ -60,6 +60,23 @@
return ret;
}
+static PyObject *py_generate_random_machine_password(PyObject *self, PyObject *args)
+{
+ int min, max;
+ PyObject *ret;
+ char *retstr;
+ if (!PyArg_ParseTuple(args, "ii", &min, &max))
+ return NULL;
+
+ retstr = generate_random_machine_password(NULL, min, max);
+ if (retstr == NULL) {
+ return NULL;
+ }
+ ret = PyUnicode_FromString(retstr);
+ talloc_free(retstr);
+ return ret;
+}
+
static PyObject *py_unix2nttime(PyObject *self, PyObject *args)
{
time_t t;
@@ -261,7 +278,14 @@
"Generate random string with specified length." },
{ "generate_random_password", (PyCFunction)py_generate_random_password,
METH_VARARGS, "generate_random_password(min, max) -> string\n"
- "Generate random password with a length >= min and <= max." },
+ "Generate random password (based on printable ascii characters) "
+ "with a length >= min and <= max." },
+ { "generate_random_machine_password", (PyCFunction)py_generate_random_machine_password,
+ METH_VARARGS, "generate_random_machine_password(min, max) -> string\n"
+ "Generate random password "
+ "(based on random utf16 characters converted to utf8 or "
+ "random ascii characters if 'unix charset' is not 'utf8')"
+ "with a length >= min (at least 14) and <= max (at most 255)." },
{ "unix2nttime", (PyCFunction)py_unix2nttime, METH_VARARGS,
"unix2nttime(timestamp) -> nttime" },
{ "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
diff -Nru samba-4.5.5+dfsg/python/samba/dbchecker.py samba-4.5.6+dfsg/python/samba/dbchecker.py
--- samba-4.5.5+dfsg/python/samba/dbchecker.py 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/python/samba/dbchecker.py 2017-03-09 10:21:43.000000000 +0100
@@ -59,6 +59,7 @@
self.fix_all_string_dn_component_mismatch = False
self.fix_all_GUID_dn_component_mismatch = False
self.fix_all_SID_dn_component_mismatch = False
+ self.fix_all_old_dn_string_component_mismatch = False
self.fix_all_metadata = False
self.fix_time_metadata = False
self.fix_undead_linked_attributes = False
@@ -574,6 +575,23 @@
"Failed to fix %s on attribute %s" % (errstr, attrname)):
self.report("Fixed %s on attribute %s" % (errstr, attrname))
+ def err_dn_string_component_old(self, dn, attrname, val, dsdb_dn, correct_dn):
+ """handle a DN string being incorrect"""
+ self.report("NOTE: old (due to rename or delete) DN string component for %s in object %s - %s" % (attrname, dn, val))
+ dsdb_dn.dn = correct_dn
+
+ if not self.confirm_all('Change DN to %s?' % str(dsdb_dn),
+ 'fix_all_old_dn_string_component_mismatch'):
+ self.report("Not fixing old string component")
+ return
+ m = ldb.Message()
+ m.dn = dn
+ m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
+ m['new_value'] = ldb.MessageElement(str(dsdb_dn), ldb.FLAG_MOD_ADD, attrname)
+ if self.do_modify(m, ["show_recycled:1"],
+ "Failed to fix old DN string on attribute %s" % (attrname)):
+ self.report("Fixed old DN string on attribute %s" % (attrname))
+
def err_dn_component_target_mismatch(self, dn, attrname, val, dsdb_dn, correct_dn, mismatch_type):
"""handle a DN string being incorrect"""
self.report("ERROR: incorrect DN %s component for %s in object %s - %s" % (mismatch_type, attrname, dn, val))
@@ -627,10 +645,9 @@
self.report("Not fixing missing backlink %s" % backlink_name)
return
m = ldb.Message()
- m.dn = obj.dn
- m['old_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_DELETE, attrname)
- m['new_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_ADD, attrname)
- if self.do_modify(m, ["show_recycled:1"],
+ m.dn = target_dn
+ m['new_value'] = ldb.MessageElement(val, ldb.FLAG_MOD_ADD, backlink_name)
+ if self.do_modify(m, ["show_recycled:1", "relax:0"],
"Failed to fix missing backlink %s" % backlink_name):
self.report("Fixed missing backlink %s" % (backlink_name))
@@ -914,12 +931,16 @@
if rmd_flags & 1:
continue
- # check the DN matches in string form
- if str(res[0].dn) != str(dsdb_dn.dn):
- error_count += 1
- self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn,
- res[0].dn, "string")
- continue
+ # assert the DN matches in string form, where a reverse
+ # link exists, otherwise (below) offer to fix it as a non-error.
+ # The string form is essentially only kept for forensics,
+ # as we always re-resolve by GUID in normal operations.
+ if reverse_link_name is not None:
+ if str(res[0].dn) != str(dsdb_dn.dn):
+ error_count += 1
+ self.err_dn_component_target_mismatch(obj.dn, attrname, val, dsdb_dn,
+ res[0].dn, "string")
+ continue
if res[0].dn.get_extended_component("GUID") != dsdb_dn.dn.get_extended_component("GUID"):
error_count += 1
@@ -933,9 +954,18 @@
res[0].dn, "SID")
continue
+ # Now we have checked the GUID and SID, offer to fix old
+ # DN strings as a non-error (for forward links with no
+ # backlink). Samba does not maintain this string
+ # otherwise, so we don't increment error_count.
+ if reverse_link_name is None:
+ if str(res[0].dn) != str(dsdb_dn.dn):
+ self.err_dn_string_component_old(obj.dn, attrname, val, dsdb_dn,
+ res[0].dn)
+ continue
- # check the reverse_link is correct if there should be one
- if reverse_link_name is not None:
+ else:
+ # check the reverse_link is correct if there should be one
match_count = 0
if reverse_link_name in res[0]:
for v in res[0][reverse_link_name]:
@@ -943,12 +973,16 @@
if v_guid == obj_guid:
match_count += 1
if match_count != 1:
- if target_is_deleted:
- error_count += 1
- if linkID & 1:
- self.err_missing_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
- else:
- self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
+ error_count += 1
+ if linkID & 1:
+ # Backlink exists, but forward link does not
+ # Delete the hanging backlink
+ self.err_orphaned_backlink(obj, attrname, val, reverse_link_name, dsdb_dn.dn)
+ else:
+ # Forward link exists, but backlink does not
+ # Add the missing backlink (if the target object is not Deleted Objects?)
+ if not target_is_deleted:
+ self.err_missing_backlink(obj, attrname, obj.dn.extended_str(), reverse_link_name, dsdb_dn.dn)
continue
diff -Nru samba-4.5.5+dfsg/python/samba/__init__.py samba-4.5.6+dfsg/python/samba/__init__.py
--- samba-4.5.5+dfsg/python/samba/__init__.py 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/python/samba/__init__.py 2017-03-09 10:21:43.000000000 +0100
@@ -396,6 +396,7 @@
nttime2unix = _glue.nttime2unix
unix2nttime = _glue.unix2nttime
generate_random_password = _glue.generate_random_password
+generate_random_machine_password = _glue.generate_random_machine_password
strcasecmp_m = _glue.strcasecmp_m
strstr_m = _glue.strstr_m
is_ntvfs_fileserver_built = _glue.is_ntvfs_fileserver_built
diff -Nru samba-4.5.5+dfsg/python/samba/join.py samba-4.5.6+dfsg/python/samba/join.py
--- samba-4.5.5+dfsg/python/samba/join.py 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/python/samba/join.py 2017-03-09 10:21:43.000000000 +0100
@@ -104,7 +104,7 @@
if machinepass is not None:
ctx.acct_pass = machinepass
else:
- ctx.acct_pass = samba.generate_random_password(32, 40)
+ ctx.acct_pass = samba.generate_random_machine_password(128, 255)
ctx.dnsdomain = ctx.samdb.domain_dns_name()
if clone_only:
@@ -667,7 +667,7 @@
pass
ctx.net.set_password(account_name=ctx.samname,
domain_name=ctx.domain_name,
- newpassword=ctx.acct_pass)
+ newpassword=ctx.acct_pass.encode('utf-8'))
res = ctx.samdb.search(base=ctx.acct_dn, scope=ldb.SCOPE_BASE,
attrs=["msDS-KeyVersionNumber"])
@@ -691,7 +691,7 @@
{"DNSDOMAIN": ctx.dnsdomain,
"DOMAINDN": ctx.base_dn,
"HOSTNAME" : ctx.myname,
- "DNSPASS_B64": b64encode(ctx.dnspass),
+ "DNSPASS_B64": b64encode(ctx.dnspass.encode('utf-16-le')),
"DNSNAME" : ctx.dnshostname}))
for changetype, msg in recs:
assert changetype == ldb.CHANGETYPE_NONE
@@ -863,7 +863,7 @@
repl_creds.guess(ctx.lp)
repl_creds.set_kerberos_state(DONT_USE_KERBEROS)
repl_creds.set_username(ctx.samname)
- repl_creds.set_password(ctx.acct_pass)
+ repl_creds.set_password(ctx.acct_pass.encode('utf-8'))
else:
repl_creds = ctx.creds
@@ -1314,7 +1314,8 @@
ctx.domsid = security.random_sid()
ctx.acct_dn = None
ctx.dnshostname = "%s.%s" % (ctx.myname.lower(), ctx.dnsdomain)
- ctx.trustdom_pass = samba.generate_random_password(128, 128)
+ # Windows uses 240 bytes as UTF16 so we do
+ ctx.trustdom_pass = samba.generate_random_machine_password(120, 120)
ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION
diff -Nru samba-4.5.5+dfsg/python/samba/netcmd/domain.py samba-4.5.6+dfsg/python/samba/netcmd/domain.py
--- samba-4.5.5+dfsg/python/samba/netcmd/domain.py 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/python/samba/netcmd/domain.py 2017-03-09 10:21:43.000000000 +0100
@@ -2254,33 +2254,14 @@
# needs to pass the NL_PASSWORD_VERSION structure within the
# 512 bytes and a 2 bytes confounder is required.
#
- def random_trust_secret(length, use_aes_keys=True):
- secret = [0] * length
-
- pw1 = samba.generate_random_password(length/2, length/2)
- if not use_aes_keys:
- # With arcfour-hmac-md5 we have to use valid utf16
- # in order to generate the correct pre-auth key
- # based on a utf8 password.
- #
- # We can remove this once our client libraries
- # support using the correct NTHASH.
- return string_to_byte_array(pw1.encode('utf-16-le'))
-
- # We mix characters from generate_random_password
- # with random numbers from random.randint()
- for i in range(len(secret)):
- if len(pw1) > i:
- secret[i] = ord(pw1[i])
- else:
- secret[i] = random.randint(0, 255)
-
- return secret
+ def random_trust_secret(length):
+ pw = samba.generate_random_machine_password(length/2, length/2)
+ return string_to_byte_array(pw.encode('utf-16-le'))
if local_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_INBOUND:
- incoming_secret = random_trust_secret(240, use_aes_keys=use_aes_keys)
+ incoming_secret = random_trust_secret(240)
if local_trust_info.trust_direction & lsa.LSA_TRUST_DIRECTION_OUTBOUND:
- outgoing_secret = random_trust_secret(240, use_aes_keys=use_aes_keys)
+ outgoing_secret = random_trust_secret(240)
remote_policy_access |= lsa.LSA_POLICY_TRUST_ADMIN
remote_policy_access |= lsa.LSA_POLICY_CREATE_SECRET
diff -Nru samba-4.5.5+dfsg/python/samba/netcmd/user.py samba-4.5.6+dfsg/python/samba/netcmd/user.py
--- samba-4.5.5+dfsg/python/samba/netcmd/user.py 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/python/samba/netcmd/user.py 2017-03-09 10:21:43.000000000 +0100
@@ -670,7 +670,7 @@
self.outf.write("Sorry, passwords do not match.\n")
try:
- net.change_password(password)
+ net.change_password(password.encode('utf-8'))
except Exception, msg:
# FIXME: catch more specific exception
raise CommandError("Failed to change password : %s" % msg)
diff -Nru samba-4.5.5+dfsg/python/samba/provision/__init__.py samba-4.5.6+dfsg/python/samba/provision/__init__.py
--- samba-4.5.5+dfsg/python/samba/provision/__init__.py 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/python/samba/provision/__init__.py 2017-03-09 10:21:43.000000000 +0100
@@ -877,7 +877,7 @@
msg["msDS-KeyVersionNumber"] = [str(key_version_number)]
msg["privateKeytab"] = ["secrets.keytab"]
- msg["secret"] = [machinepass]
+ msg["secret"] = [machinepass.encode('utf-8')]
msg["samAccountName"] = ["%s$" % netbiosname]
msg["secureChannelType"] = [str(secure_channel_type)]
if domainsid is not None:
@@ -1768,9 +1768,9 @@
invocationid = str(uuid.uuid4())
if krbtgtpass is None:
- krbtgtpass = samba.generate_random_password(128, 255)
+ krbtgtpass = samba.generate_random_machine_password(128, 255)
if machinepass is None:
- machinepass = samba.generate_random_password(128, 255)
+ machinepass = samba.generate_random_machine_password(128, 255)
if dnspass is None:
dnspass = samba.generate_random_password(128, 255)
diff -Nru samba-4.5.5+dfsg/python/samba/provision/sambadns.py samba-4.5.6+dfsg/python/samba/provision/sambadns.py
--- samba-4.5.5+dfsg/python/samba/provision/sambadns.py 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/python/samba/provision/sambadns.py 2017-03-09 10:21:43.000000000 +0100
@@ -661,7 +661,7 @@
"REALM": realm,
"DNSDOMAIN": dnsdomain,
"DNS_KEYTAB": dns_keytab_path,
- "DNSPASS_B64": b64encode(dnspass),
+ "DNSPASS_B64": b64encode(dnspass.encode('utf-8')),
"KEY_VERSION_NUMBER": str(key_version_number),
"HOSTNAME": names.hostname,
"DNSNAME" : '%s.%s' % (
diff -Nru samba-4.5.5+dfsg/python/samba/samdb.py samba-4.5.6+dfsg/python/samba/samdb.py
--- samba-4.5.5+dfsg/python/samba/samdb.py 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/python/samba/samdb.py 2017-03-09 10:21:43.000000000 +0100
@@ -503,7 +503,7 @@
if len(res) > 1:
raise Exception('Matched %u multiple users with filter "%s"' % (len(res), search_filter))
user_dn = res[0].dn
- pw = unicode('"' + password + '"', 'utf-8').encode('utf-16-le')
+ pw = unicode('"' + password.encode('utf-8') + '"', 'utf-8').encode('utf-16-le')
setpw = """
dn: %s
changetype: modify
diff -Nru samba-4.5.5+dfsg/python/samba/upgradehelpers.py samba-4.5.6+dfsg/python/samba/upgradehelpers.py
--- samba-4.5.5+dfsg/python/samba/upgradehelpers.py 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/python/samba/upgradehelpers.py 2017-03-09 10:21:43.000000000 +0100
@@ -573,7 +573,7 @@
assert(len(res) == 1)
msg = ldb.Message(res[0].dn)
- machinepass = samba.generate_random_password(128, 255)
+ machinepass = samba.generate_random_machine_password(128, 255)
mputf16 = machinepass.encode('utf-16-le')
msg["clearTextPassword"] = ldb.MessageElement(mputf16,
ldb.FLAG_MOD_REPLACE,
@@ -648,7 +648,7 @@
assert(len(res) == 1)
msg = ldb.Message(res[0].dn)
- machinepass = samba.generate_random_password(128, 255)
+ machinepass = samba.generate_random_machine_password(128, 255)
mputf16 = machinepass.encode('utf-16-le')
msg["clearTextPassword"] = ldb.MessageElement(mputf16,
ldb.FLAG_MOD_REPLACE,
diff -Nru samba-4.5.5+dfsg/selftest/skip samba-4.5.6+dfsg/selftest/skip
--- samba-4.5.5+dfsg/selftest/skip 2017-01-17 20:55:44.000000000 +0100
+++ samba-4.5.6+dfsg/selftest/skip 2017-03-09 10:21:43.000000000 +0100
@@ -48,6 +48,7 @@
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-SYMLINK-EA # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-OFD-LOCK # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).POSIX-STREAM-DELETE # Fails against the s4 ntvfs server
+^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).WINDOWS-BAD-SYMLINK # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).RENAME-ACCESS # Fails against the s4 ntvfs server
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).OWNER-RIGHTS # Don't test against the s4 ntvfs server anymore
^samba3.smbtorture_s3.plain\(ad_dc_ntvfs\).PIDHIGH # Fails against the s4 ntvfs server
diff -Nru samba-4.5.5+dfsg/selftest/target/Samba3.pm samba-4.5.6+dfsg/selftest/target/Samba3.pm
--- samba-4.5.5+dfsg/selftest/target/Samba3.pm 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/selftest/target/Samba3.pm 2017-03-09 10:21:43.000000000 +0100
@@ -554,6 +554,7 @@
ntlm auth = yes
vfs objects = xattr_tdb streams_depot time_audit full_audit
change notify = no
+ smb encrypt = off
full_audit:syslog = no
full_audit:success = none
@@ -571,6 +572,11 @@
store dos attributes = yes
hide files = /hidefile/
hide dot files = yes
+
+[enc_desired]
+ path = $prefix_abs/share
+ vfs objects =
+ smb encrypt = desired
";
my $vars = $self->provision($path,
@@ -757,6 +763,8 @@
security = ads
username map = $prefix/lib/username.map
server signing = required
+ server min protocol = SMB3_00
+ client max protocol = SMB3
";
my $ret = $self->provision($prefix,
@@ -1615,6 +1623,30 @@
fruit:locking = netatalk
fruit:encoding = native
+[vfs_fruit_metadata_stream]
+ path = $shrdir
+ vfs objects = fruit streams_xattr acl_xattr
+ ea support = yes
+ fruit:resource = file
+ fruit:metadata = stream
+
+[vfs_fruit_stream_depot]
+ path = $shrdir
+ vfs objects = fruit streams_depot acl_xattr
+ ea support = yes
+ fruit:resource = stream
+ fruit:metadata = stream
+
+[vfs_wo_fruit]
+ path = $shrdir
+ vfs objects = streams_xattr acl_xattr
+ ea support = yes
+
+[vfs_wo_fruit_stream_depot]
+ path = $shrdir
+ vfs objects = streams_depot acl_xattr
+ ea support = yes
+
[badname-tmp]
path = $badnames_shrdir
guest ok = yes
diff -Nru samba-4.5.5+dfsg/source3/include/MacExtensions.h samba-4.5.6+dfsg/source3/include/MacExtensions.h
--- samba-4.5.5+dfsg/source3/include/MacExtensions.h 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source3/include/MacExtensions.h 2017-03-09 10:21:43.000000000 +0100
@@ -51,6 +51,9 @@
#define AFP_Version 0x00000100
#define AFP_BackupTime 0x80000000
#define AFP_FinderSize 32
+
+#define AFP_OFF_FinderInfo 16
+
/*
** Orginal AFP_AfpInfo stream used by NT
** We needed a way to store the create date so SAMBA
diff -Nru samba-4.5.5+dfsg/source3/include/proto.h samba-4.5.6+dfsg/source3/include/proto.h
--- samba-4.5.5+dfsg/source3/include/proto.h 2016-09-13 10:21:35.000000000 +0200
+++ samba-4.5.6+dfsg/source3/include/proto.h 2017-03-09 10:21:43.000000000 +0100
@@ -880,6 +880,9 @@
struct netlogon_creds_cli_context;
struct messaging_context;
struct dcerpc_binding_handle;
+char *trust_pw_new_value(TALLOC_CTX *mem_ctx,
+ enum netr_SchannelType sec_channel_type,
+ int security);
NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
struct messaging_context *msg_ctx,
struct dcerpc_binding_handle *b,
diff -Nru samba-4.5.5+dfsg/source3/include/smb.h samba-4.5.6+dfsg/source3/include/smb.h
--- samba-4.5.5+dfsg/source3/include/smb.h 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/include/smb.h 2017-03-09 10:21:43.000000000 +0100
@@ -733,12 +733,6 @@
#define SAFE_NETBIOS_CHARS ". -_"
-/* The maximum length of a trust account password.
- Used when we randomly create it, 15 char passwords
- exceed NT4's max password length */
-
-#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
-
#define PORT_NONE 0
#ifndef LDAP_PORT
#define LDAP_PORT 389
diff -Nru samba-4.5.5+dfsg/source3/lib/util_path.c samba-4.5.6+dfsg/source3/lib/util_path.c
--- samba-4.5.5+dfsg/source3/lib/util_path.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/lib/util_path.c 2017-03-09 10:21:43.000000000 +0100
@@ -93,3 +93,142 @@
{
return xx_path(name, lp_cache_directory());
}
+
+/**
+ * @brief Removes any invalid path components in an absolute POSIX path.
+ *
+ * @param ctx Talloc context to return string.
+ *
+ * @param abs_path Absolute path string to process.
+ *
+ * @retval Pointer to a talloc'ed string containing the absolute full path.
+ **/
+
+char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path)
+{
+ char *destname;
+ char *d;
+ const char *s = abs_path;
+ bool start_of_name_component = true;
+
+ /* Allocate for strlen + '\0' + possible leading '/' */
+ destname = (char *)talloc_size(ctx, strlen(abs_path) + 2);
+ if (destname == NULL) {
+ return NULL;
+ }
+ d = destname;
+
+ *d++ = '/'; /* Always start with root. */
+
+ while (*s) {
+ if (*s == '/') {
+ /* Eat multiple '/' */
+ while (*s == '/') {
+ s++;
+ }
+ if ((d > destname + 1) && (*s != '\0')) {
+ *d++ = '/';
+ }
+ start_of_name_component = true;
+ continue;
+ }
+
+ if (start_of_name_component) {
+ if ((s[0] == '.') && (s[1] == '.') &&
+ (s[2] == '/' || s[2] == '\0')) {
+ /* Uh oh - "/../" or "/..\0" ! */
+
+ /* Go past the .. leaving us on the / or '\0' */
+ s += 2;
+
+ /* If we just added a '/' - delete it */
+ if ((d > destname) && (*(d-1) == '/')) {
+ *(d-1) = '\0';
+ d--;
+ }
+
+ /*
+ * Are we at the start ?
+ * Can't go back further if so.
+ */
+ if (d <= destname) {
+ *d++ = '/'; /* Can't delete root */
+ continue;
+ }
+ /* Go back one level... */
+ /*
+ * Decrement d first as d points to
+ * the *next* char to write into.
+ */
+ for (d--; d > destname; d--) {
+ if (*d == '/') {
+ break;
+ }
+ }
+
+ /*
+ * Are we at the start ?
+ * Can't go back further if so.
+ */
+ if (d <= destname) {
+ *d++ = '/'; /* Can't delete root */
+ continue;
+ }
+
+ /*
+ * We're still at the start of a name
+ * component, just the previous one.
+ */
+ continue;
+ } else if ((s[0] == '.') &&
+ ((s[1] == '\0') || s[1] == '/')) {
+ /*
+ * Component of pathname can't be "." only.
+ * Skip the '.' .
+ */
+ if (s[1] == '/') {
+ s += 2;
+ } else {
+ s++;
+ }
+ continue;
+ }
+ }
+
+ if (!(*s & 0x80)) {
+ *d++ = *s++;
+ } else {
+ size_t siz;
+ /* Get the size of the next MB character. */
+ next_codepoint(s,&siz);
+ switch(siz) {
+ case 5:
+ *d++ = *s++;
+ /*fall through*/
+ case 4:
+ *d++ = *s++;
+ /*fall through*/
+ case 3:
+ *d++ = *s++;
+ /*fall through*/
+ case 2:
+ *d++ = *s++;
+ /*fall through*/
+ case 1:
+ *d++ = *s++;
+ break;
+ default:
+ break;
+ }
+ }
+ start_of_name_component = false;
+ }
+ *d = '\0';
+
+ /* And must not end in '/' */
+ if (d > destname + 1 && (*(d-1) == '/')) {
+ *(d-1) = '\0';
+ }
+
+ return destname;
+}
diff -Nru samba-4.5.5+dfsg/source3/lib/util_path.h samba-4.5.6+dfsg/source3/lib/util_path.h
--- samba-4.5.5+dfsg/source3/lib/util_path.h 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/lib/util_path.h 2017-03-09 10:21:43.000000000 +0100
@@ -27,5 +27,6 @@
char *lock_path(const char *name);
char *state_path(const char *name);
char *cache_path(const char *name);
+char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path);
#endif
diff -Nru samba-4.5.5+dfsg/source3/libads/sasl.c samba-4.5.6+dfsg/source3/libads/sasl.c
--- samba-4.5.5+dfsg/source3/libads/sasl.c 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/source3/libads/sasl.c 2017-03-09 10:21:43.000000000 +0100
@@ -703,6 +703,7 @@
#ifdef HAVE_KRB5
bool got_kerberos_mechanism = False;
#endif
+ const char *mech = NULL;
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
@@ -749,6 +750,8 @@
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
got_kerberos_mechanism)
{
+ mech = "KRB5";
+
if (ads->auth.password == NULL ||
ads->auth.password[0] == '\0')
{
@@ -775,7 +778,11 @@
blob);
if (!ADS_ERR_OK(status)) {
DEBUG(0,("kinit succeeded but "
- "ads_sasl_spnego_gensec_bind(KRB5) failed: %s\n",
+ "ads_sasl_spnego_gensec_bind(KRB5) failed: "
+ "for %s/%s user[%s] realm[%s]: %s\n",
+ p.service, p.hostname,
+ ads->auth.user_name,
+ ads->auth.realm,
ads_errstr(status)));
}
}
@@ -785,17 +792,33 @@
!(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
goto done;
}
+
+ DEBUG(1,("ads_sasl_spnego_gensec_bind(KRB5) failed for %s/%s "
+ "with user[%s] realm[%s]: %s, fallback to NTLMSSP\n",
+ p.service, p.hostname,
+ ads->auth.user_name,
+ ads->auth.realm,
+ ads_errstr(status)));
}
#endif
/* lets do NTLMSSP ... this has the big advantage that we don't need
to sync clocks, and we don't rely on special versions of the krb5
library for HMAC_MD4 encryption */
+ mech = "NTLMSSP";
status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
CRED_DONT_USE_KERBEROS,
p.service, p.hostname,
data_blob_null);
done:
+ if (!ADS_ERR_OK(status)) {
+ DEBUG(1,("ads_sasl_spnego_gensec_bind(%s) failed for %s/%s "
+ "with user[%s] realm=[%s]: %s\n", mech,
+ p.service, p.hostname,
+ ads->auth.user_name,
+ ads->auth.realm,
+ ads_errstr(status)));
+ }
ads_free_service_principal(&p);
TALLOC_FREE(frame);
if (blob.data != NULL) {
diff -Nru samba-4.5.5+dfsg/source3/libads/util.c samba-4.5.6+dfsg/source3/libads/util.c
--- samba-4.5.5+dfsg/source3/libads/util.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/libads/util.c 2017-03-09 10:21:43.000000000 +0100
@@ -35,9 +35,12 @@
return ADS_ERROR_SYSTEM(ENOENT);
}
- new_password = generate_random_password(talloc_tos(),
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ new_password = trust_pw_new_value(talloc_tos(), SEC_CHAN_WKSTA, SEC_ADS);
+ if (new_password == NULL) {
+ ret = ADS_ERROR_SYSTEM(errno);
+ DEBUG(1,("Failed to generate machine password\n"));
+ goto failed;
+ }
ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, host_principal, new_password, ads->auth.time_offset);
diff -Nru samba-4.5.5+dfsg/source3/libnet/libnet_join.c samba-4.5.6+dfsg/source3/libnet/libnet_join.c
--- samba-4.5.5+dfsg/source3/libnet/libnet_join.c 2016-09-13 10:21:35.000000000 +0200
+++ samba-4.5.6+dfsg/source3/libnet/libnet_join.c 2017-03-09 10:21:43.000000000 +0100
@@ -1138,9 +1138,11 @@
}
if (!r->in.machine_password) {
- r->in.machine_password = generate_random_password(mem_ctx,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ int security = r->in.ads ? SEC_ADS : SEC_DOMAIN;
+
+ r->in.machine_password = trust_pw_new_value(mem_ctx,
+ r->in.secure_channel_type,
+ security);
if (r->in.machine_password == NULL) {
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
@@ -1233,9 +1235,11 @@
}
if (!r->in.machine_password) {
- r->in.machine_password = generate_random_password(mem_ctx,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ int security = r->in.ads ? SEC_ADS : SEC_DOMAIN;
+
+ r->in.machine_password = trust_pw_new_value(mem_ctx,
+ r->in.secure_channel_type,
+ security);
NT_STATUS_HAVE_NO_MEMORY(r->in.machine_password);
}
diff -Nru samba-4.5.5+dfsg/source3/librpc/rpc/dcerpc.h samba-4.5.6+dfsg/source3/librpc/rpc/dcerpc.h
--- samba-4.5.5+dfsg/source3/librpc/rpc/dcerpc.h 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/librpc/rpc/dcerpc.h 2017-03-09 10:21:43.000000000 +0100
@@ -61,8 +61,7 @@
DATA_BLOB *blob);
NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct ncacn_packet *r,
- bool bigendian);
+ struct ncacn_packet *r);
NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
enum dcerpc_AuthType auth_type,
enum dcerpc_AuthLevel auth_level,
diff -Nru samba-4.5.5+dfsg/source3/librpc/rpc/dcerpc_helpers.c samba-4.5.6+dfsg/source3/librpc/rpc/dcerpc_helpers.c
--- samba-4.5.5+dfsg/source3/librpc/rpc/dcerpc_helpers.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/librpc/rpc/dcerpc_helpers.c 2017-03-09 10:21:43.000000000 +0100
@@ -88,14 +88,12 @@
* elements
* @param blob The blob of data to decode
* @param r An empty ncacn_packet, must not be NULL
-* @param bigendian Whether the packet is bignedian encoded
*
* @return a NTSTATUS error code
*/
NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
- struct ncacn_packet *r,
- bool bigendian)
+ struct ncacn_packet *r)
{
enum ndr_err_code ndr_err;
struct ndr_pull *ndr;
@@ -104,11 +102,12 @@
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
- if (bigendian) {
+
+ if (!(CVAL(ndr->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
- if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
+ if (CVAL(ndr->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) {
ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT;
}
diff -Nru samba-4.5.5+dfsg/source3/libsmb/trusts_util.c samba-4.5.6+dfsg/source3/libsmb/trusts_util.c
--- samba-4.5.5+dfsg/source3/libsmb/trusts_util.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/libsmb/trusts_util.c 2017-03-09 10:21:43.000000000 +0100
@@ -47,6 +47,62 @@
return 0;
}
+char *trust_pw_new_value(TALLOC_CTX *mem_ctx,
+ enum netr_SchannelType sec_channel_type,
+ int security)
+{
+ /*
+ * use secure defaults.
+ */
+ size_t min = 128;
+ size_t max = 255;
+
+ switch (sec_channel_type) {
+ case SEC_CHAN_WKSTA:
+ case SEC_CHAN_BDC:
+ if (security == SEC_DOMAIN) {
+ /*
+ * The maximum length of a trust account password.
+ * Used when we randomly create it, 15 char passwords
+ * exceed NT4's max password length.
+ */
+ min = 14;
+ max = 14;
+ }
+ break;
+ case SEC_CHAN_DNS_DOMAIN:
+ /*
+ * new_len * 2 = 498 bytes is the largest possible length
+ * NL_PASSWORD_VERSION consumes the rest of the possible 512 bytes
+ * and a confounder with at least 2 bytes is required.
+ *
+ * Windows uses new_len = 120 => 240 bytes (utf16)
+ */
+ min = 120;
+ max = 120;
+ break;
+ /* fall through */
+ case SEC_CHAN_DOMAIN:
+ /*
+ * The maximum length of a trust account password.
+ * Used when we randomly create it, 15 char passwords
+ * exceed NT4's max password length.
+ */
+ min = 14;
+ max = 14;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * Create a random machine account password
+ * We create a random buffer and convert that to utf8.
+ * This is similar to what windows is doing.
+ */
+ return generate_random_machine_password(mem_ctx, min, max);
+}
+
NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
struct messaging_context *msg_ctx,
struct dcerpc_binding_handle *b,
@@ -54,6 +110,7 @@
bool force)
{
TALLOC_CTX *frame = talloc_stackframe();
+ const char *context_name = NULL;
struct trust_pw_change_state *state;
struct cli_credentials *creds = NULL;
const struct samr_Password *current_nt_hash = NULL;
@@ -65,10 +122,7 @@
struct timeval g_timeout = { 0, };
int timeout = 0;
struct timeval tv = { 0, };
- size_t new_len = DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH;
- uint8_t new_password_buffer[256 * 2] = { 0, };
char *new_trust_passwd = NULL;
- size_t len = 0;
uint32_t new_version = 0;
uint32_t *new_trust_version = NULL;
NTSTATUS status;
@@ -134,16 +188,6 @@
case SEC_CHAN_BDC:
break;
case SEC_CHAN_DNS_DOMAIN:
- /*
- * new_len * 2 = 498 bytes is the largest possible length
- * NL_PASSWORD_VERSION consumes the rest of the possible 512 bytes
- * and a confounder with at least 2 bytes is required.
- *
- * Windows uses new_len = 120 => 240 bytes.
- */
- new_len = 120;
-
- /* fall through */
case SEC_CHAN_DOMAIN:
status = pdb_get_trusted_domain(frame, domain, &td);
if (!NT_STATUS_IS_OK(status)) {
@@ -181,19 +225,21 @@
return NT_STATUS_OK;
}
+ context_name = netlogon_creds_cli_debug_string(context, talloc_tos());
+ if (context_name == NULL) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
/*
* Create a random machine account password
* We create a random buffer and convert that to utf8.
* This is similar to what windows is doing.
*/
- generate_secret_buffer(new_password_buffer, new_len * 2);
- ok = convert_string_talloc(frame,
- CH_UTF16MUNGED, CH_UTF8,
- new_password_buffer, new_len * 2,
- (void *)&new_trust_passwd, &len);
- ZERO_STRUCT(new_password_buffer);
- if (!ok) {
- DEBUG(0, ("convert_string_talloc failed\n"));
+ new_trust_passwd = trust_pw_new_value(frame, sec_channel_type,
+ lp_security());
+ if (new_trust_passwd == NULL) {
+ DEBUG(0, ("trust_pw_new_value() failed\n"));
TALLOC_FREE(frame);
return NT_STATUS_NO_MEMORY;
}
@@ -215,12 +261,16 @@
*current_nt_hash,
previous_nt_hash);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("netlogon_creds_cli_auth for domain %s - %s!\n",
- domain, nt_errstr(status)));
+ DEBUG(0, ("netlogon_creds_cli_auth(%s) failed for old password - %s!\n",
+ context_name, nt_errstr(status)));
TALLOC_FREE(frame);
return status;
}
+ DEBUG(0,("%s : %s(%s): Verified old password remotely using %s\n",
+ current_timestring(talloc_tos(), false),
+ __func__, domain, context_name));
+
/*
* Return the result of trying to write the new password
* back into the trust account file.
@@ -260,22 +310,57 @@
break;
}
- DEBUG(1,("%s : %s(%s): Changed password locally\n",
+ DEBUG(0,("%s : %s(%s): Changed password locally\n",
current_timestring(talloc_tos(), false), __func__, domain));
status = netlogon_creds_cli_ServerPasswordSet(context, b,
new_trust_passwd,
new_trust_version);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("%s : %s(%s) remote password change set failed - %s\n",
- current_timestring(talloc_tos(), false), __func__,
- domain, nt_errstr(status)));
+ DEBUG(0,("%s : %s(%s) remote password change set with %s failed - %s\n",
+ current_timestring(talloc_tos(), false),
+ __func__, domain, context_name,
+ nt_errstr(status)));
TALLOC_FREE(frame);
return status;
}
- DEBUG(1,("%s : %s(%s): Changed password remotely.\n",
- current_timestring(talloc_tos(), false), __func__, domain));
+ DEBUG(0,("%s : %s(%s): Changed password remotely using %s\n",
+ current_timestring(talloc_tos(), false),
+ __func__, domain, context_name));
+
+ ok = cli_credentials_set_password(creds, new_trust_passwd, CRED_SPECIFIED);
+ if (!ok) {
+ DEBUG(0, ("cli_credentials_set_password failed for domain %s!\n",
+ domain));
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ current_nt_hash = cli_credentials_get_nt_hash(creds, frame);
+ if (current_nt_hash == NULL) {
+ DEBUG(0, ("cli_credentials_get_nt_hash failed for domain %s!\n",
+ domain));
+ TALLOC_FREE(frame);
+ return NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE;
+ }
+
+ /*
+ * Now we verify the new password.
+ */
+ status = netlogon_creds_cli_auth(context, b,
+ *current_nt_hash,
+ NULL); /* previous_nt_hash */
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("netlogon_creds_cli_auth(%s) failed for new password - %s!\n",
+ context_name, nt_errstr(status)));
+ TALLOC_FREE(frame);
+ return status;
+ }
+
+ DEBUG(0,("%s : %s(%s): Verified new password remotely using %s\n",
+ current_timestring(talloc_tos(), false),
+ __func__, domain, context_name));
TALLOC_FREE(frame);
return NT_STATUS_OK;
diff -Nru samba-4.5.5+dfsg/source3/modules/vfs_catia.c samba-4.5.6+dfsg/source3/modules/vfs_catia.c
--- samba-4.5.5+dfsg/source3/modules/vfs_catia.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source3/modules/vfs_catia.c 2017-03-09 10:21:43.000000000 +0100
@@ -4,13 +4,13 @@
* Implement a fixed mapping of forbidden NT characters in filenames that are
* used a lot by the CAD package Catia.
*
- * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
- * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
- * under Windows...
+ * Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden under
+ * Windows...
*
* Copyright (C) Volker Lendecke, 2005
* Copyright (C) Aravind Srinivasan, 2009
* Copyright (C) Guenter Kukkukk, 2013
+ * Copyright (C) Ralph Boehme, 2017
*
* 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
@@ -29,6 +29,8 @@
#include "includes.h"
#include "smbd/smbd.h"
+#include "lib/util/tevent_unix.h"
+#include "lib/util/tevent_ntstatus.h"
static int vfs_catia_debug_level = DBGC_VFS;
@@ -52,6 +54,15 @@
struct char_mappings **mappings;
};
+struct catia_cache {
+ bool is_fsp_ext;
+ const struct catia_cache * const *busy;
+ char *orig_fname;
+ char *fname;
+ char *orig_base_fname;
+ char *base_fname;
+};
+
struct share_mapping_entry *srt_head = NULL;
static bool build_table(struct char_mappings **cmaps, int value)
@@ -353,30 +364,305 @@
return ret;
}
+#define CATIA_DEBUG_CC(lvl, cc, fsp) \
+ catia_debug_cc((lvl), (cc), (fsp), __location__);
+
+static void catia_debug_cc(int lvl,
+ struct catia_cache *cc,
+ files_struct *fsp,
+ const char *location)
+{
+ DEBUG(lvl, ("%s: cc [0x%p] cc->busy [0x%p] "
+ "is_fsp_ext [%s] "
+ "fsp [0x%p] fsp name [%s] "
+ "orig_fname [%s] "
+ "fname [%s] "
+ "orig_base_fname [%s] "
+ "base_fname [%s]\n",
+ location,
+ cc, cc->busy,
+ cc->is_fsp_ext ? "yes" : "no",
+ fsp, fsp_str_dbg(fsp),
+ cc->orig_fname, cc->fname,
+ cc->orig_base_fname, cc->base_fname));
+}
+
+static void catia_free_cc(struct catia_cache **_cc,
+ vfs_handle_struct *handle,
+ files_struct *fsp)
+{
+ struct catia_cache *cc = *_cc;
+
+ if (cc->is_fsp_ext) {
+ VFS_REMOVE_FSP_EXTENSION(handle, fsp);
+ cc = NULL;
+ } else {
+ TALLOC_FREE(cc);
+ }
+
+ *_cc = NULL;
+}
+
+static struct catia_cache *catia_validate_and_apply_cc(
+ vfs_handle_struct *handle,
+ files_struct *fsp,
+ const struct catia_cache * const *busy,
+ bool *make_tmp_cache)
+{
+ struct catia_cache *cc = NULL;
+
+ *make_tmp_cache = false;
+
+ cc = (struct catia_cache *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ if (cc == NULL) {
+ return NULL;
+ }
+
+ if (cc->busy != NULL) {
+ if (cc->busy == busy) {
+ /* This should never happen */
+ CATIA_DEBUG_CC(0, cc, fsp);
+ smb_panic(__location__);
+ }
+
+ /*
+ * Recursion. Validate names, the names in the fsp's should be
+ * the translated names we had set.
+ */
+
+ if ((cc->fname != fsp->fsp_name->base_name)
+ ||
+ ((fsp->base_fsp != NULL) &&
+ (cc->base_fname != fsp->base_fsp->fsp_name->base_name)))
+ {
+ CATIA_DEBUG_CC(10, cc, fsp);
+
+ /*
+ * Names changed. Setting don't expose the cache on the
+ * fsp and ask the caller to create a temporary cache.
+ */
+ *make_tmp_cache = true;
+ return NULL;
+ }
+
+ /*
+ * Ok, a validated cache while in a recursion, just let the
+ * caller detect that cc->busy is != busy and there's
+ * nothing else to do.
+ */
+ CATIA_DEBUG_CC(10, cc, fsp);
+ return cc;
+ }
+
+ /* Not in a recursion */
+
+ if ((cc->orig_fname != fsp->fsp_name->base_name)
+ ||
+ ((fsp->base_fsp != NULL) &&
+ (cc->orig_base_fname != fsp->base_fsp->fsp_name->base_name)))
+ {
+ /*
+ * fsp names changed, this can happen in an rename op.
+ * Trigger recreation as a full fledged fsp extension.
+ */
+
+ CATIA_DEBUG_CC(10, cc, fsp);
+ catia_free_cc(&cc, handle, fsp);
+ return NULL;
+ }
+
+
+ /*
+ * Ok, we found a valid cache entry, no recursion. Just set translated
+ * names from the cache and mark the cc as busy.
+ */
+ fsp->fsp_name->base_name = cc->fname;
+ if (fsp->base_fsp != NULL) {
+ fsp->base_fsp->fsp_name->base_name = cc->base_fname;
+ }
+
+ cc->busy = busy;
+ CATIA_DEBUG_CC(10, cc, fsp);
+ return cc;
+}
+
+#define CATIA_FETCH_FSP_PRE_NEXT(mem_ctx, handle, fsp, _cc) \
+ catia_fetch_fsp_pre_next((mem_ctx), (handle), (fsp), (_cc), __func__);
+
+static int catia_fetch_fsp_pre_next(TALLOC_CTX *mem_ctx,
+ vfs_handle_struct *handle,
+ files_struct *fsp,
+ struct catia_cache **_cc,
+ const char *function)
+{
+ const struct catia_cache * const *busy =
+ (const struct catia_cache * const *)_cc;
+ struct catia_cache *cc = NULL;
+ NTSTATUS status;
+ bool make_tmp_cache = false;
+
+ *_cc = NULL;
+
+ DBG_DEBUG("Called from [%s]\n", function);
+
+ cc = catia_validate_and_apply_cc(handle,
+ fsp,
+ busy,
+ &make_tmp_cache);
+ if (cc != NULL) {
+ if (cc->busy != busy) {
+ return 0;
+ }
+ *_cc = cc;
+ return 0;
+ }
+
+ if (!make_tmp_cache) {
+ cc = (struct catia_cache *)VFS_ADD_FSP_EXTENSION(
+ handle, fsp, struct catia_cache, NULL);
+ if (cc == NULL) {
+ return -1;
+ }
+ *cc = (struct catia_cache) {
+ .is_fsp_ext = true,
+ };
+
+ mem_ctx = VFS_MEMCTX_FSP_EXTENSION(handle, fsp);
+ if (mem_ctx == NULL) {
+ DBG_ERR("VFS_MEMCTX_FSP_EXTENSION failed\n");
+ catia_free_cc(&cc, handle, fsp);
+ return -1;
+ }
+ } else {
+ cc = talloc_zero(mem_ctx, struct catia_cache);
+ if (cc == NULL) {
+ return -1;
+ }
+ mem_ctx = cc;
+ }
+
+
+ status = catia_string_replace_allocate(handle->conn,
+ fsp->fsp_name->base_name,
+ &cc->fname,
+ vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ catia_free_cc(&cc, handle, fsp);
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ talloc_steal(mem_ctx, cc->fname);
+
+ if (fsp->base_fsp != NULL) {
+ status = catia_string_replace_allocate(
+ handle->conn,
+ fsp->base_fsp->fsp_name->base_name,
+ &cc->base_fname,
+ vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ catia_free_cc(&cc, handle, fsp);
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+ talloc_steal(mem_ctx, cc->base_fname);
+ }
+
+ cc->orig_fname = fsp->fsp_name->base_name;
+ fsp->fsp_name->base_name = cc->fname;
+
+ if (fsp->base_fsp != NULL) {
+ cc->orig_base_fname = fsp->base_fsp->fsp_name->base_name;
+ fsp->base_fsp->fsp_name->base_name = cc->base_fname;
+ }
+
+ cc->busy = busy;
+ CATIA_DEBUG_CC(10, cc, fsp);
+
+ *_cc = cc;
+
+ return 0;
+}
+
+#define CATIA_FETCH_FSP_POST_NEXT(_cc, fsp) do { \
+ int saved_errno = errno; \
+ catia_fetch_fsp_post_next((_cc), (fsp), __func__); \
+ errno = saved_errno; \
+} while(0)
+
+static void catia_fetch_fsp_post_next(struct catia_cache **_cc,
+ files_struct *fsp,
+ const char *function)
+{
+ const struct catia_cache * const *busy =
+ (const struct catia_cache * const *)_cc;
+ struct catia_cache *cc = *_cc;
+
+ DBG_DEBUG("Called from [%s]\n", function);
+
+ if (cc == NULL) {
+ /*
+ * This can happen when recursing in the VFS on the fsp when the
+ * pre_next func noticed the recursion and set out cc pointer to
+ * NULL.
+ */
+ return;
+ }
+
+ if (cc->busy != busy) {
+ CATIA_DEBUG_CC(0, cc, fsp);
+ smb_panic(__location__);
+ return;
+ }
+
+ cc->busy = NULL;
+ *_cc = NULL;
+
+ fsp->fsp_name->base_name = cc->orig_fname;
+ if (fsp->base_fsp != NULL) {
+ fsp->base_fsp->fsp_name->base_name = cc->orig_base_fname;
+ }
+
+ CATIA_DEBUG_CC(10, cc, fsp);
+
+ if (!cc->is_fsp_ext) {
+ TALLOC_FREE(cc);
+ }
+
+ return;
+}
+
static int catia_open(vfs_handle_struct *handle,
struct smb_filename *smb_fname,
files_struct *fsp,
int flags,
mode_t mode)
{
- char *name_mapped = NULL;
- char *tmp_base_name;
- int ret;
+ struct catia_cache *cc = NULL;
+ char *orig_smb_fname = smb_fname->base_name;
+ char *mapped_smb_fname = NULL;
NTSTATUS status;
+ int ret;
- tmp_base_name = smb_fname->base_name;
status = catia_string_replace_allocate(handle->conn,
- smb_fname->base_name,
- &name_mapped, vfs_translate_to_unix);
+ smb_fname->base_name,
+ &mapped_smb_fname,
+ vfs_translate_to_unix);
if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
return -1;
}
- smb_fname->base_name = name_mapped;
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ TALLOC_FREE(mapped_smb_fname);
+ return ret;
+ }
+
+ smb_fname->base_name = mapped_smb_fname;
ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- smb_fname->base_name = tmp_base_name;
- TALLOC_FREE(name_mapped);
+ smb_fname->base_name = orig_smb_fname;
+
+ TALLOC_FREE(mapped_smb_fname);
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
return ret;
}
@@ -1114,33 +1400,1030 @@
return ret;
}
+static int catia_fstat(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static ssize_t catia_pread(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ struct catia_cache *cc = NULL;
+ ssize_t result;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static ssize_t catia_pwrite(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct catia_cache *cc = NULL;
+ ssize_t result;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static int catia_ftruncate(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ off_t offset)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static int catia_fallocate(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t mode,
+ off_t offset,
+ off_t len)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static ssize_t catia_fgetxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *name,
+ void *value,
+ size_t size)
+{
+ char *mapped_xattr_name = NULL;
+ NTSTATUS status;
+ ssize_t result;
+
+ status = catia_string_replace_allocate(handle->conn,
+ name, &mapped_xattr_name,
+ vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, mapped_xattr_name,
+ value, size);
+
+ TALLOC_FREE(mapped_xattr_name);
+
+ return result;
+}
+
+static ssize_t catia_flistxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ char *list,
+ size_t size)
+{
+ struct catia_cache *cc = NULL;
+ ssize_t result;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ result = SMB_VFS_NEXT_FLISTXATTR(handle, fsp, list, size);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static int catia_fremovexattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *name)
+{
+ char *mapped_name = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = catia_string_replace_allocate(handle->conn,
+ name, &mapped_name, vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, mapped_name);
+
+ TALLOC_FREE(mapped_name);
+
+ return ret;
+}
+
+static int catia_fsetxattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const char *name,
+ const void *value,
+ size_t size,
+ int flags)
+{
+ char *mapped_xattr_name = NULL;
+ NTSTATUS status;
+ int ret;
+
+ status = catia_string_replace_allocate(
+ handle->conn, name, &mapped_xattr_name, vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_FSETXATTR(handle, fsp, mapped_xattr_name,
+ value, size, flags);
+
+ TALLOC_FREE(mapped_xattr_name);
+
+ return ret;
+}
+
+static SMB_ACL_T catia_sys_acl_get_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ TALLOC_CTX *mem_ctx)
+{
+ struct catia_cache *cc = NULL;
+ struct smb_acl_t *result = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return NULL;
+ }
+
+ result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static int catia_sys_acl_blob_get_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ TALLOC_CTX *mem_ctx,
+ char **blob_description,
+ DATA_BLOB *blob)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx,
+ blob_description, blob);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static int catia_sys_acl_set_fd(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_ACL_T theacl)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static int catia_fchmod_acl(vfs_handle_struct *handle,
+ files_struct *fsp,
+ mode_t mode)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static NTSTATUS catia_fget_nt_acl(vfs_handle_struct *handle,
+ files_struct *fsp,
+ uint32_t security_info,
+ TALLOC_CTX *mem_ctx,
+ struct security_descriptor **ppdesc)
+{
+ struct catia_cache *cc = NULL;
+ NTSTATUS status;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ status = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info,
+ mem_ctx, ppdesc);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return status;
+}
+
+static NTSTATUS catia_fset_nt_acl(vfs_handle_struct *handle,
+ files_struct *fsp,
+ uint32_t security_info_sent,
+ const struct security_descriptor *psd)
+{
+ struct catia_cache *cc = NULL;
+ NTSTATUS status;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return status;
+}
+
+static NTSTATUS catia_fset_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t dosmode)
+{
+ struct catia_cache *cc = NULL;
+ NTSTATUS status;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ status = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return status;
+}
+
+static NTSTATUS catia_fget_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t *dosmode)
+{
+ struct catia_cache *cc = NULL;
+ NTSTATUS status;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ status = SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return status;
+}
+
+static int catia_fchown(vfs_handle_struct *handle,
+ files_struct *fsp,
+ uid_t uid,
+ gid_t gid)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FCHOWN(handle, fsp, uid, gid);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static int catia_fchmod(vfs_handle_struct *handle,
+ files_struct *fsp,
+ mode_t mode)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+struct catia_pread_state {
+ ssize_t ret;
+ struct vfs_aio_state vfs_aio_state;
+ struct files_struct *fsp;
+ struct catia_cache *cc;
+};
+
+static void catia_pread_done(struct tevent_req *subreq);
+
+static struct tevent_req *catia_pread_send(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct files_struct *fsp,
+ void *data,
+ size_t n,
+ off_t offset)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct catia_pread_state *state = NULL;
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct catia_pread_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->fsp = fsp;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
+ if (ret != 0) {
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = SMB_VFS_NEXT_PREAD_SEND(state, ev, handle, fsp, data,
+ n, offset);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, catia_pread_done, req);
+
+ return req;
+}
+
+static void catia_pread_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct catia_pread_state *state = tevent_req_data(
+ req, struct catia_pread_state);
+
+ state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
+ TALLOC_FREE(subreq);
+
+ CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
+
+ tevent_req_done(req);
+}
+
+static ssize_t catia_pread_recv(struct tevent_req *req,
+ struct vfs_aio_state *vfs_aio_state)
+{
+ struct catia_pread_state *state = tevent_req_data(
+ req, struct catia_pread_state);
+
+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+ return -1;
+ }
+
+ *vfs_aio_state = state->vfs_aio_state;
+ return state->ret;
+}
+
+struct catia_pwrite_state {
+ ssize_t ret;
+ struct vfs_aio_state vfs_aio_state;
+ struct files_struct *fsp;
+ struct catia_cache *cc;
+};
+
+static void catia_pwrite_done(struct tevent_req *subreq);
+
+static struct tevent_req *catia_pwrite_send(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct files_struct *fsp,
+ const void *data,
+ size_t n,
+ off_t offset)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct catia_pwrite_state *state = NULL;
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct catia_pwrite_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->fsp = fsp;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
+ if (ret != 0) {
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = SMB_VFS_NEXT_PWRITE_SEND(state, ev, handle, fsp, data,
+ n, offset);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, catia_pwrite_done, req);
+
+ return req;
+}
+
+static void catia_pwrite_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct catia_pwrite_state *state = tevent_req_data(
+ req, struct catia_pwrite_state);
+
+ state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
+ TALLOC_FREE(subreq);
+
+ CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
+
+ tevent_req_done(req);
+}
+
+static ssize_t catia_pwrite_recv(struct tevent_req *req,
+ struct vfs_aio_state *vfs_aio_state)
+{
+ struct catia_pwrite_state *state = tevent_req_data(
+ req, struct catia_pwrite_state);
+
+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+ return -1;
+ }
+
+ *vfs_aio_state = state->vfs_aio_state;
+ return state->ret;
+}
+
+static off_t catia_lseek(vfs_handle_struct *handle,
+ files_struct *fsp,
+ off_t offset,
+ int whence)
+{
+ struct catia_cache *cc = NULL;
+ ssize_t result;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ result = SMB_VFS_NEXT_LSEEK(handle, fsp, offset, whence);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static int catia_fsync(vfs_handle_struct *handle, files_struct *fsp)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_FSYNC(handle, fsp);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+struct catia_fsync_state {
+ int ret;
+ struct vfs_aio_state vfs_aio_state;
+ struct files_struct *fsp;
+ struct catia_cache *cc;
+};
+
+static void catia_fsync_done(struct tevent_req *subreq);
+
+static struct tevent_req *catia_fsync_send(struct vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct files_struct *fsp)
+{
+ struct tevent_req *req = NULL, *subreq = NULL;
+ struct catia_fsync_state *state = NULL;
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct catia_fsync_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->fsp = fsp;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(state, handle, fsp, &state->cc);
+ if (ret != 0) {
+ tevent_req_error(req, errno);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = SMB_VFS_NEXT_FSYNC_SEND(state, ev, handle, fsp);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, catia_fsync_done, req);
+
+ return req;
+}
+
+static void catia_fsync_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct catia_fsync_state *state = tevent_req_data(
+ req, struct catia_fsync_state);
+
+ state->ret = SMB_VFS_FSYNC_RECV(subreq, &state->vfs_aio_state);
+ TALLOC_FREE(subreq);
+
+ CATIA_FETCH_FSP_POST_NEXT(&state->cc, state->fsp);
+
+ tevent_req_done(req);
+}
+
+static int catia_fsync_recv(struct tevent_req *req,
+ struct vfs_aio_state *vfs_aio_state)
+{
+ struct catia_fsync_state *state = tevent_req_data(
+ req, struct catia_fsync_state);
+
+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+ return -1;
+ }
+
+ *vfs_aio_state = state->vfs_aio_state;
+ return state->ret;
+}
+
+static bool catia_lock(vfs_handle_struct *handle,
+ files_struct *fsp,
+ int op,
+ off_t offset,
+ off_t count,
+ int type)
+{
+ struct catia_cache *cc = NULL;
+ bool ok;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ok = SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ok;
+}
+
+static int catia_kernel_flock(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t share_mode,
+ uint32_t access_mask)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode, access_mask);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static int catia_linux_setlease(vfs_handle_struct *handle,
+ files_struct *fsp,
+ int leasetype)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_LINUX_SETLEASE(handle, fsp, leasetype);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ret;
+}
+
+static bool catia_getlock(vfs_handle_struct *handle,
+ files_struct *fsp,
+ off_t *poffset,
+ off_t *pcount,
+ int *ptype,
+ pid_t *ppid)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+ bool ok;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ok = SMB_VFS_NEXT_GETLOCK(handle, fsp, poffset, pcount, ptype, ppid);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ok;
+}
+
+static bool catia_strict_lock(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct lock_struct *plock)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+ bool ok;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return -1;
+ }
+
+ ok = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return ok;
+}
+
+static void catia_strict_unlock(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ struct lock_struct *plock)
+{
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ smb_panic("CATIA_FETCH_FSP_PRE_NEXT failed\n");
+ }
+
+ SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+}
+
+static NTSTATUS catia_fsctl(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ TALLOC_CTX *ctx,
+ uint32_t function,
+ uint16_t req_flags,
+ const uint8_t *_in_data,
+ uint32_t in_len,
+ uint8_t **_out_data,
+ uint32_t max_out_len,
+ uint32_t *out_len)
+{
+ NTSTATUS result;
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ result = SMB_VFS_NEXT_FSCTL(handle,
+ fsp,
+ ctx,
+ function,
+ req_flags,
+ _in_data,
+ in_len,
+ _out_data,
+ max_out_len,
+ out_len);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static NTSTATUS catia_get_compression(vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct *fsp,
+ struct smb_filename *smb_fname,
+ uint16_t *_compression_fmt)
+{
+ NTSTATUS result;
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ result = SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname,
+ _compression_fmt);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static NTSTATUS catia_set_compression(vfs_handle_struct *handle,
+ TALLOC_CTX *mem_ctx,
+ struct files_struct *fsp,
+ uint16_t compression_fmt)
+{
+ NTSTATUS result;
+ struct catia_cache *cc = NULL;
+ int ret;
+
+ ret = CATIA_FETCH_FSP_PRE_NEXT(talloc_tos(), handle, fsp, &cc);
+ if (ret != 0) {
+ return map_nt_error_from_unix(errno);
+ }
+
+ result = SMB_VFS_NEXT_SET_COMPRESSION(handle, mem_ctx, fsp,
+ compression_fmt);
+
+ CATIA_FETCH_FSP_POST_NEXT(&cc, fsp);
+
+ return result;
+}
+
+static NTSTATUS catia_readdir_attr(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname_in,
+ TALLOC_CTX *mem_ctx,
+ struct readdir_attr_data **pattr_data)
+{
+ struct smb_filename *smb_fname;
+ char *fname = NULL;
+ NTSTATUS status;
+
+ status = catia_string_replace_allocate(handle->conn,
+ smb_fname_in->base_name,
+ &fname,
+ vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return status;
+ }
+
+ smb_fname = synthetic_smb_fname(talloc_tos(), fname, NULL,
+ &smb_fname_in->st, 0);
+
+ status = SMB_VFS_NEXT_READDIR_ATTR(handle, smb_fname, mem_ctx, pattr_data);
+
+ TALLOC_FREE(smb_fname);
+ return status;
+}
+
+static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ uint32_t *dosmode)
+{
+ char *mapped_name = NULL;
+ const char *path = smb_fname->base_name;
+ struct smb_filename *mapped_smb_fname = NULL;
+ NTSTATUS status;
+
+ status = catia_string_replace_allocate(handle->conn,
+ path, &mapped_name, vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return status;
+ }
+ mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+ mapped_name,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (mapped_smb_fname == NULL) {
+ TALLOC_FREE(mapped_name);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
+ mapped_smb_fname,
+ dosmode);
+ TALLOC_FREE(mapped_name);
+ TALLOC_FREE(mapped_smb_fname);
+
+ return status;
+}
+
+static NTSTATUS catia_set_dos_attributes(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint32_t dosmode)
+{
+ char *mapped_name = NULL;
+ const char *path = smb_fname->base_name;
+ struct smb_filename *mapped_smb_fname = NULL;
+ NTSTATUS status;
+
+ status = catia_string_replace_allocate(handle->conn,
+ path, &mapped_name, vfs_translate_to_unix);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
+ return status;
+ }
+ mapped_smb_fname = synthetic_smb_fname(talloc_tos(),
+ mapped_name,
+ NULL,
+ NULL,
+ smb_fname->flags);
+ if (mapped_smb_fname == NULL) {
+ TALLOC_FREE(mapped_name);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
+ mapped_smb_fname,
+ dosmode);
+ TALLOC_FREE(mapped_name);
+ TALLOC_FREE(mapped_smb_fname);
+
+ return status;
+}
+
static struct vfs_fn_pointers vfs_catia_fns = {
+ /* Directory operations */
.mkdir_fn = catia_mkdir,
.rmdir_fn = catia_rmdir,
.opendir_fn = catia_opendir,
+ .readdir_attr_fn = catia_readdir_attr,
+
+ /* File operations */
.open_fn = catia_open,
+ .pread_fn = catia_pread,
+ .pread_send_fn = catia_pread_send,
+ .pread_recv_fn = catia_pread_recv,
+ .pwrite_fn = catia_pwrite,
+ .pwrite_send_fn = catia_pwrite_send,
+ .pwrite_recv_fn = catia_pwrite_recv,
+ .lseek_fn = catia_lseek,
.rename_fn = catia_rename,
+ .fsync_fn = catia_fsync,
+ .fsync_send_fn = catia_fsync_send,
+ .fsync_recv_fn = catia_fsync_recv,
.stat_fn = catia_stat,
+ .fstat_fn = catia_fstat,
.lstat_fn = catia_lstat,
.unlink_fn = catia_unlink,
+ .chmod_fn = catia_chmod,
+ .fchmod_fn = catia_fchmod,
.chown_fn = catia_chown,
+ .fchown_fn = catia_fchown,
.lchown_fn = catia_lchown,
- .chmod_fn = catia_chmod,
.chdir_fn = catia_chdir,
.ntimes_fn = catia_ntimes,
+ .ftruncate_fn = catia_ftruncate,
+ .fallocate_fn = catia_fallocate,
+ .lock_fn = catia_lock,
+ .kernel_flock_fn = catia_kernel_flock,
+ .linux_setlease_fn = catia_linux_setlease,
+ .getlock_fn = catia_getlock,
.realpath_fn = catia_realpath,
.chflags_fn = catia_chflags,
.streaminfo_fn = catia_streaminfo,
+ .strict_lock_fn = catia_strict_lock,
+ .strict_unlock_fn = catia_strict_unlock,
.translate_name_fn = catia_translate_name,
+ .fsctl_fn = catia_fsctl,
+ .get_dos_attributes_fn = catia_get_dos_attributes,
+ .set_dos_attributes_fn = catia_set_dos_attributes,
+ .fset_dos_attributes_fn = catia_fset_dos_attributes,
+ .fget_dos_attributes_fn = catia_fget_dos_attributes,
+ .get_compression_fn = catia_get_compression,
+ .set_compression_fn = catia_set_compression,
+
+ /* NT ACL operations. */
.get_nt_acl_fn = catia_get_nt_acl,
+ .fget_nt_acl_fn = catia_fget_nt_acl,
+ .fset_nt_acl_fn = catia_fset_nt_acl,
+
+ /* POSIX ACL operations. */
.chmod_acl_fn = catia_chmod_acl,
+ .fchmod_acl_fn = catia_fchmod_acl,
+
.sys_acl_get_file_fn = catia_sys_acl_get_file,
+ .sys_acl_get_fd_fn = catia_sys_acl_get_fd,
+ .sys_acl_blob_get_fd_fn = catia_sys_acl_blob_get_fd,
.sys_acl_set_file_fn = catia_sys_acl_set_file,
+ .sys_acl_set_fd_fn = catia_sys_acl_set_fd,
.sys_acl_delete_def_file_fn = catia_sys_acl_delete_def_file,
+
+ /* EA operations. */
.getxattr_fn = catia_getxattr,
.listxattr_fn = catia_listxattr,
.removexattr_fn = catia_removexattr,
.setxattr_fn = catia_setxattr,
+ .fgetxattr_fn = catia_fgetxattr,
+ .flistxattr_fn = catia_flistxattr,
+ .fremovexattr_fn = catia_fremovexattr,
+ .fsetxattr_fn = catia_fsetxattr,
};
static_decl_vfs;
diff -Nru samba-4.5.5+dfsg/source3/modules/vfs_dirsort.c samba-4.5.6+dfsg/source3/modules/vfs_dirsort.c
--- samba-4.5.5+dfsg/source3/modules/vfs_dirsort.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/modules/vfs_dirsort.c 2017-03-09 10:21:43.000000000 +0100
@@ -65,8 +65,10 @@
static bool open_and_sort_dir(vfs_handle_struct *handle,
struct dirsort_privates *data)
{
- unsigned int i = 0;
- unsigned int total_count = 0;
+ uint32_t total_count = 0;
+ /* This should be enough for most use cases */
+ uint32_t dirent_allocated = 64;
+ struct dirent *dp;
data->number_of_entries = 0;
@@ -74,38 +76,51 @@
return false;
}
- while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
- != NULL) {
- total_count++;
- }
-
- if (total_count == 0) {
+ dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL);
+ if (dp == NULL) {
return false;
}
- /* Open the underlying directory and count the number of entries
- Skip back to the beginning as we'll read it again */
- SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);
-
/* Set up an array and read the directory entries into it */
TALLOC_FREE(data->directory_list); /* destroy previous cache if needed */
data->directory_list = talloc_zero_array(data,
- struct dirent,
- total_count);
- if (!data->directory_list) {
+ struct dirent,
+ dirent_allocated);
+ if (data->directory_list == NULL) {
return false;
}
- for (i = 0; i < total_count; i++) {
- struct dirent *dp = SMB_VFS_NEXT_READDIR(handle,
- data->source_directory,
- NULL);
- if (dp == NULL) {
- break;
+
+ do {
+ if (total_count >= dirent_allocated) {
+ struct dirent *dlist;
+
+ /*
+ * Be memory friendly.
+ *
+ * We should not double the amount of memory. With a lot
+ * of files we reach easily 50MB, and doubling will
+ * get much bigger just for a few files more.
+ *
+ * For 200k files this means 50 memory reallocations.
+ */
+ dirent_allocated += 4096;
+
+ dlist = talloc_realloc(data,
+ data->directory_list,
+ struct dirent,
+ dirent_allocated);
+ if (dlist == NULL) {
+ break;
+ }
+ data->directory_list = dlist;
}
- data->directory_list[i] = *dp;
- }
+ data->directory_list[total_count] = *dp;
+
+ total_count++;
+ dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL);
+ } while (dp != NULL);
- data->number_of_entries = i;
+ data->number_of_entries = total_count;
/* Sort the directory entries by name */
TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent);
@@ -138,6 +153,10 @@
return NULL;
}
+ if (ISDOT(data->smb_fname->base_name)) {
+ data->smb_fname->base_name = vfs_GetWd(data, handle->conn);
+ }
+
/* Open the underlying directory and count the number of entries */
data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, smb_fname, mask,
attr);
diff -Nru samba-4.5.5+dfsg/source3/modules/vfs_fruit.c samba-4.5.6+dfsg/source3/modules/vfs_fruit.c
--- samba-4.5.5+dfsg/source3/modules/vfs_fruit.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source3/modules/vfs_fruit.c 2017-03-09 10:21:43.000000000 +0100
@@ -94,6 +94,11 @@
static int vfs_fruit_debug_level = DBGC_VFS;
+static struct global_fruit_config {
+ bool nego_aapl; /* client negotiated AAPL */
+
+} global_fruit_config;
+
#undef DBGC_CLASS
#define DBGC_CLASS vfs_fruit_debug_level
@@ -126,7 +131,6 @@
enum fruit_locking locking;
enum fruit_encoding encoding;
bool use_aapl; /* config from smb.conf */
- bool nego_aapl; /* client negotiated AAPL */
bool use_copyfile;
bool readdir_attr_enabled;
bool unix_info_enabled;
@@ -343,7 +347,6 @@
#define ad_getentryoff(ad,eid) ((ad)->ad_eid[(eid)].ade_off)
#define ad_setentrylen(ad,eid,len) ((ad)->ad_eid[(eid)].ade_len = (len))
#define ad_setentryoff(ad,eid,off) ((ad)->ad_eid[(eid)].ade_off = (off))
-#define ad_entry(ad,eid) ((ad)->ad_data + ad_getentryoff((ad),(eid)))
struct ad_entry {
size_t ade_off;
@@ -352,7 +355,8 @@
struct adouble {
vfs_handle_struct *ad_handle;
- files_struct *ad_fsp;
+ int ad_fd;
+ bool ad_opened;
adouble_type_t ad_type;
uint32_t ad_magic;
uint32_t ad_version;
@@ -405,15 +409,41 @@
AD_DEV, AD_INO, AD_SYN, AD_ID
};
+struct fio {
+ /* tcon config handle */
+ struct fruit_config_data *config;
+
+ /* Denote stream type, meta or rsrc */
+ adouble_type_t type;
+};
+
/*
* Forward declarations
*/
static struct adouble *ad_init(TALLOC_CTX *ctx, vfs_handle_struct *handle,
- adouble_type_t type, files_struct *fsp);
-static int ad_write(struct adouble *ad, const char *path);
+ adouble_type_t type);
+static int ad_set(struct adouble *ad, const char *path);
+static int ad_fset(struct adouble *ad, files_struct *fsp);
static int adouble_path(TALLOC_CTX *ctx, const char *path_in, char **path_out);
/**
+ * Return a pointer to an AppleDouble entry
+ *
+ * Returns NULL if the entry is not present
+ **/
+static char *ad_get_entry(const struct adouble *ad, int eid)
+{
+ off_t off = ad_getentryoff(ad, eid);
+ size_t len = ad_getentrylen(ad, eid);
+
+ if (off == 0 || len == 0) {
+ return NULL;
+ }
+
+ return ad->ad_data + off;
+}
+
+/**
* Get a date
**/
static int ad_getdate(const struct adouble *ad,
@@ -421,18 +451,19 @@
uint32_t *date)
{
bool xlate = (dateoff & AD_DATE_UNIX);
+ char *p = NULL;
dateoff &= AD_DATE_MASK;
- if (!ad_getentryoff(ad, ADEID_FILEDATESI)) {
+ p = ad_get_entry(ad, ADEID_FILEDATESI);
+ if (p == NULL) {
return -1;
}
if (dateoff > AD_DATE_ACCESS) {
return -1;
}
- memcpy(date,
- ad_entry(ad, ADEID_FILEDATESI) + dateoff,
- sizeof(uint32_t));
+
+ memcpy(date, p + dateoff, sizeof(uint32_t));
if (xlate) {
*date = AD_DATE_TO_UNIX(*date);
@@ -446,9 +477,11 @@
static int ad_setdate(struct adouble *ad, unsigned int dateoff, uint32_t date)
{
bool xlate = (dateoff & AD_DATE_UNIX);
+ char *p = NULL;
- if (!ad_getentryoff(ad, ADEID_FILEDATESI)) {
- return 0;
+ p = ad_get_entry(ad, ADEID_FILEDATESI);
+ if (p == NULL) {
+ return -1;
}
dateoff &= AD_DATE_MASK;
@@ -460,7 +493,7 @@
return -1;
}
- memcpy(ad_entry(ad, ADEID_FILEDATESI) + dateoff, &date, sizeof(date));
+ memcpy(p + dateoff, &date, sizeof(date));
return 0;
}
@@ -752,7 +785,7 @@
/**
* Read and parse Netatalk AppleDouble metadata xattr
**/
-static ssize_t ad_header_read_meta(struct adouble *ad, const char *path)
+static ssize_t ad_read_meta(struct adouble *ad, const char *path)
{
int rc = 0;
ssize_t ealen;
@@ -824,184 +857,220 @@
return ealen;
}
-/**
- * Read and parse resource fork, either ._ AppleDouble file or xattr
- **/
-static ssize_t ad_header_read_rsrc(struct adouble *ad, const char *path)
+static int ad_open_meta(const char *path, int flags, mode_t mode)
+{
+ return open(path, flags, mode);
+}
+
+static int ad_open_rsrc_xattr(const char *path, int flags, mode_t mode)
+{
+#ifdef HAVE_ATTROPEN
+ /* FIXME: direct Solaris xattr syscall */
+ return attropen(path, AFPRESOURCE_EA_NETATALK, flags, mode);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int ad_open_rsrc_adouble(const char *path, int flags, mode_t mode)
+{
+ char *adp = NULL;
+ int ret;
+ int fd;
+
+ ret = adouble_path(talloc_tos(), path, &adp);
+ if (ret != 0) {
+ return -1;
+ }
+
+ fd = open(adp, flags, mode);
+ TALLOC_FREE(adp);
+
+ return fd;
+}
+
+static int ad_open_rsrc(vfs_handle_struct *handle,
+ const char *path,
+ int flags,
+ mode_t mode)
{
struct fruit_config_data *config = NULL;
- int fd = -1;
- int rc = 0;
- ssize_t len;
- char *adpath = NULL;
- bool opened = false;
- int mode;
- struct adouble *meta_ad = NULL;
- SMB_STRUCT_STAT sbuf;
- bool ok;
- int saved_errno = 0;
+ int fd;
- SMB_VFS_HANDLE_GET_DATA(ad->ad_handle, config,
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- /* Try rw first so we can use the fd in ad_convert() */
- mode = O_RDWR;
-
- if (ad->ad_fsp && ad->ad_fsp->fh && (ad->ad_fsp->fh->fd != -1)) {
- fd = ad->ad_fsp->fh->fd;
+ if (config->rsrc == FRUIT_RSRC_XATTR) {
+ fd = ad_open_rsrc_xattr(path, flags, mode);
} else {
- if (config->rsrc == FRUIT_RSRC_XATTR) {
- adpath = talloc_strdup(talloc_tos(), path);
- } else {
- rc = adouble_path(talloc_tos(), path, &adpath);
- if (rc != 0) {
- goto exit;
- }
- }
+ fd = ad_open_rsrc_adouble(path, flags, mode);
+ }
- retry:
- if (config->rsrc == FRUIT_RSRC_XATTR) {
-#ifndef HAVE_ATTROPEN
- errno = ENOSYS;
- rc = -1;
- goto exit;
-#else
- /* FIXME: direct Solaris xattr syscall */
- fd = attropen(adpath, AFPRESOURCE_EA_NETATALK,
- mode, 0);
-#endif
- } else {
- /* FIXME: direct open(), don't have an fsp */
- fd = open(adpath, mode);
- }
+ return fd;
+}
- if (fd == -1) {
- switch (errno) {
- case EROFS:
- case EACCES:
- if (mode == O_RDWR) {
- mode = O_RDONLY;
- goto retry;
- }
- /* fall through ... */
- default:
- DEBUG(2, ("open AppleDouble: %s, %s\n",
- adpath, strerror(errno)));
- rc = -1;
- goto exit;
- }
- }
- opened = true;
+static int ad_open(vfs_handle_struct *handle,
+ struct adouble *ad,
+ const char *path,
+ adouble_type_t t,
+ int flags,
+ mode_t mode)
+{
+ int fd;
+
+ DBG_DEBUG("Path [%s] type [%s]\n",
+ path, t == ADOUBLE_META ? "meta" : "rsrc");
+
+ if (t == ADOUBLE_META) {
+ fd = ad_open_meta(path, flags, mode);
+ } else {
+ fd = ad_open_rsrc(handle, path, flags, mode);
}
- if (config->rsrc == FRUIT_RSRC_XATTR) {
- /* FIXME: direct sys_fstat(), don't have an fsp */
- rc = sys_fstat(
- fd, &sbuf,
+ if (fd != -1) {
+ ad->ad_opened = true;
+ ad->ad_fd = fd;
+ }
+
+ DBG_DEBUG("Path [%s] type [%s] fd [%d]\n",
+ path, t == ADOUBLE_META ? "meta" : "rsrc", fd);
+
+ return fd;
+}
+
+static ssize_t ad_read_rsrc_xattr(struct adouble *ad,
+ const char *path)
+{
+ int ret;
+ SMB_STRUCT_STAT st;
+
+ /* FIXME: direct sys_fstat(), don't have an fsp */
+ ret = sys_fstat(ad->ad_fd, &st,
lp_fake_directory_create_times(
SNUM(ad->ad_handle->conn)));
- if (rc != 0) {
- goto exit;
- }
- len = sbuf.st_ex_size;
- ad_setentrylen(ad, ADEID_RFORK, len);
- } else {
- /* FIXME: direct sys_pread(), don't have an fsp */
- len = sys_pread(fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
- if (len != AD_DATASZ_DOT_UND) {
- DEBUG(2, ("%s: bad size: %zd\n",
- strerror(errno), len));
- rc = -1;
- goto exit;
- }
+ if (ret != 0) {
+ return -1;
+ }
- /* FIXME: direct sys_fstat(), we don't have an fsp */
- rc = sys_fstat(fd, &sbuf,
- lp_fake_directory_create_times(
- SNUM(ad->ad_handle->conn)));
- if (rc != 0) {
- goto exit;
- }
+ ad_setentrylen(ad, ADEID_RFORK, st.st_ex_size);
+ return st.st_ex_size;
+}
- /* Now parse entries */
- ok = ad_unpack(ad, ADEID_NUM_DOT_UND, sbuf.st_ex_size);
- if (!ok) {
- DEBUG(1, ("invalid AppleDouble ressource %s\n", path));
- errno = EINVAL;
- rc = -1;
- goto exit;
- }
+static ssize_t ad_read_rsrc_adouble(struct adouble *ad,
+ const char *path)
+{
+ struct adouble *meta_ad = NULL;
+ SMB_STRUCT_STAT sbuf;
+ char *p_ad = NULL;
+ char *p_meta_ad = NULL;
+ ssize_t len;
+ int ret;
+ bool ok;
- if ((ad_getentryoff(ad, ADEID_FINDERI)
- != ADEDOFF_FINDERI_DOT_UND)
- || (ad_getentrylen(ad, ADEID_FINDERI)
- < ADEDLEN_FINDERI)
- || (ad_getentryoff(ad, ADEID_RFORK)
- < ADEDOFF_RFORK_DOT_UND)) {
- DEBUG(2, ("invalid AppleDouble ressource %s\n", path));
- errno = EINVAL;
- rc = -1;
- goto exit;
- }
+ len = sys_pread(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+ if (len != AD_DATASZ_DOT_UND) {
+ DBG_NOTICE("%s %s: bad size: %zd\n",
+ path, strerror(errno), len);
+ return -1;
+ }
- if ((mode == O_RDWR)
- && (ad_getentrylen(ad, ADEID_FINDERI) > ADEDLEN_FINDERI)) {
- rc = ad_convert(ad, fd);
- if (rc != 0) {
- rc = -1;
- goto exit;
- }
- /*
- * Can't use ad_write() because we might not have a fsp
- */
- ok = ad_pack(ad);
- if (!ok) {
- rc = -1;
- goto exit;
- }
- /* FIXME: direct sys_pwrite(), don't have an fsp */
- len = sys_pwrite(fd, ad->ad_data,
- AD_DATASZ_DOT_UND, 0);
- if (len != AD_DATASZ_DOT_UND) {
- DEBUG(2, ("%s: bad size: %zd\n", adpath, len));
- rc = -1;
- goto exit;
- }
+ ret = sys_fstat(ad->ad_fd, &sbuf, lp_fake_directory_create_times(
+ SNUM(ad->ad_handle->conn)));
+ if (ret != 0) {
+ return -1;
+ }
- meta_ad = ad_init(talloc_tos(), ad->ad_handle,
- ADOUBLE_META, NULL);
- if (meta_ad == NULL) {
- rc = -1;
- goto exit;
- }
+ /* Now parse entries */
+ ok = ad_unpack(ad, ADEID_NUM_DOT_UND, sbuf.st_ex_size);
+ if (!ok) {
+ DBG_ERR("invalid AppleDouble resource %s\n", path);
+ errno = EINVAL;
+ return -1;
+ }
- memcpy(ad_entry(meta_ad, ADEID_FINDERI),
- ad_entry(ad, ADEID_FINDERI),
- ADEDLEN_FINDERI);
+ if ((ad_getentryoff(ad, ADEID_FINDERI) != ADEDOFF_FINDERI_DOT_UND)
+ || (ad_getentrylen(ad, ADEID_FINDERI) < ADEDLEN_FINDERI)
+ || (ad_getentryoff(ad, ADEID_RFORK) < ADEDOFF_RFORK_DOT_UND)) {
+ DBG_ERR("invalid AppleDouble resource %s\n", path);
+ errno = EINVAL;
+ return -1;
+ }
- rc = ad_write(meta_ad, path);
- if (rc != 0) {
- rc = -1;
- goto exit;
- }
- }
+ if (ad_getentrylen(ad, ADEID_FINDERI) == ADEDLEN_FINDERI) {
+ return len;
}
- DEBUG(10, ("opened AppleDouble: %s\n", path));
+ /*
+ * Try to fixup AppleDouble files created by OS X with xattrs
+ * appended to the ADEID_FINDERI entry. We simply remove the
+ * xattrs blob, this means any fancy xattr that was stored
+ * there is lost.
+ */
-exit:
- if (rc != 0) {
- saved_errno = errno;
- len = -1;
+ ret = ad_convert(ad, ad->ad_fd);
+ if (ret != 0) {
+ DBG_WARNING("Failed to convert [%s]\n", path);
+ return len;
}
- if (opened && fd != -1) {
- close(fd);
+
+ ok = ad_pack(ad);
+ if (!ok) {
+ DBG_WARNING("ad_pack [%s] failed\n", path);
+ return -1;
}
- TALLOC_FREE(adpath);
+
+ len = sys_pwrite(ad->ad_fd, ad->ad_data, AD_DATASZ_DOT_UND, 0);
+ if (len != AD_DATASZ_DOT_UND) {
+ DBG_ERR("%s: bad size: %zd\n", path, len);
+ return -1;
+ }
+
+ meta_ad = ad_init(talloc_tos(), ad->ad_handle, ADOUBLE_META);
+ if (meta_ad == NULL) {
+ return -1;
+ }
+
+ p_ad = ad_get_entry(ad, ADEID_FINDERI);
+ if (p_ad == NULL) {
+ TALLOC_FREE(meta_ad);
+ return -1;
+ }
+ p_meta_ad = ad_get_entry(meta_ad, ADEID_FINDERI);
+ if (p_meta_ad == NULL) {
+ TALLOC_FREE(meta_ad);
+ return -1;
+ }
+
+ memcpy(p_meta_ad, p_ad, ADEDLEN_FINDERI);
+
+ ret = ad_set(meta_ad, path);
TALLOC_FREE(meta_ad);
- if (rc != 0) {
- errno = saved_errno;
+ if (ret != 0) {
+ return -1;
+ }
+
+ return len;
+}
+
+/**
+ * Read and parse resource fork, either ._ AppleDouble file or xattr
+ **/
+static ssize_t ad_read_rsrc(struct adouble *ad,
+ const char *path)
+{
+ struct fruit_config_data *config = NULL;
+ ssize_t len;
+
+ SMB_VFS_HANDLE_GET_DATA(ad->ad_handle, config,
+ struct fruit_config_data, return -1);
+
+ if (config->rsrc == FRUIT_RSRC_XATTR) {
+ len = ad_read_rsrc_xattr(ad, path);
+ } else {
+ len = ad_read_rsrc_adouble(ad, path);
}
+
return len;
}
@@ -1012,14 +1081,23 @@
{
switch (ad->ad_type) {
case ADOUBLE_META:
- return ad_header_read_meta(ad, path);
+ return ad_read_meta(ad, path);
case ADOUBLE_RSRC:
- return ad_header_read_rsrc(ad, path);
+ return ad_read_rsrc(ad, path);
default:
return -1;
}
}
+static int adouble_destructor(struct adouble *ad)
+{
+ if ((ad->ad_fd != -1) && ad->ad_opened) {
+ close(ad->ad_fd);
+ ad->ad_fd = -1;
+ }
+ return 0;
+}
+
/**
* Allocate a struct adouble without initialiing it
*
@@ -1029,14 +1107,11 @@
* @param[in] ctx talloc context
* @param[in] handle vfs handle
* @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC
-
- * @param[in] fsp if not NULL (for stream IO), the adouble handle is
- * added as an fsp extension
*
* @return adouble handle
**/
static struct adouble *ad_alloc(TALLOC_CTX *ctx, vfs_handle_struct *handle,
- adouble_type_t type, files_struct *fsp)
+ adouble_type_t type)
{
int rc = 0;
size_t adsize = 0;
@@ -1059,39 +1134,27 @@
return NULL;
}
- if (!fsp) {
- ad = talloc_zero(ctx, struct adouble);
- if (ad == NULL) {
- rc = -1;
- goto exit;
- }
- if (adsize) {
- ad->ad_data = talloc_zero_array(ad, char, adsize);
- }
- } else {
- ad = (struct adouble *)VFS_ADD_FSP_EXTENSION(handle, fsp,
- struct adouble,
- NULL);
- if (ad == NULL) {
+ ad = talloc_zero(ctx, struct adouble);
+ if (ad == NULL) {
+ rc = -1;
+ goto exit;
+ }
+
+ if (adsize) {
+ ad->ad_data = talloc_zero_array(ad, char, adsize);
+ if (ad->ad_data == NULL) {
rc = -1;
goto exit;
}
- if (adsize) {
- ad->ad_data = talloc_zero_array(
- VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- char, adsize);
- }
- ad->ad_fsp = fsp;
}
- if (adsize && ad->ad_data == NULL) {
- rc = -1;
- goto exit;
- }
ad->ad_handle = handle;
ad->ad_type = type;
ad->ad_magic = AD_MAGIC;
ad->ad_version = AD_VERSION;
+ ad->ad_fd = -1;
+
+ talloc_set_destructor(ad, adouble_destructor);
exit:
if (rc != 0) {
@@ -1106,12 +1169,11 @@
* @param[in] ctx talloc context
* @param[in] handle vfs handle
* @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC
- * @param[in] fsp file handle, may be NULL for a type of e_ad_meta
*
* @return adouble handle, initialized
**/
static struct adouble *ad_init(TALLOC_CTX *ctx, vfs_handle_struct *handle,
- adouble_type_t type, files_struct *fsp)
+ adouble_type_t type)
{
int rc = 0;
const struct ad_entry_order *eid;
@@ -1137,7 +1199,7 @@
return NULL;
}
- ad = ad_alloc(ctx, handle, type, fsp);
+ ad = ad_alloc(ctx, handle, type);
if (ad == NULL) {
return NULL;
}
@@ -1176,16 +1238,42 @@
int rc = 0;
ssize_t len;
struct adouble *ad = NULL;
+ int fd;
+ int mode;
DEBUG(10, ("ad_get(%s) called for %s\n",
type == ADOUBLE_META ? "meta" : "rsrc", path));
- ad = ad_alloc(ctx, handle, type, NULL);
+ ad = ad_alloc(ctx, handle, type);
if (ad == NULL) {
rc = -1;
goto exit;
}
+ /*
+ * Here's the deal: for ADOUBLE_META we can do without an fd
+ * as we can issue path based xattr calls. For ADOUBLE_RSRC
+ * however we need a full-fledged fd for file IO on the ._
+ * file.
+ */
+ if (type == ADOUBLE_RSRC) {
+ /* Try rw first so we can use the fd in ad_convert() */
+ mode = O_RDWR;
+
+ fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0);
+ if (fd == -1 && ((errno == EROFS) || (errno == EACCES))) {
+ mode = O_RDONLY;
+ fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0);
+ }
+
+ if (fd == -1) {
+ DBG_DEBUG("ad_open [%s] error [%s]\n",
+ path, strerror(errno));
+ rc = -1;
+ goto exit;
+ }
+ }
+
len = ad_read(ad, path);
if (len == -1) {
DEBUG(10, ("error reading AppleDouble for %s\n", path));
@@ -1204,21 +1292,144 @@
}
/**
+ * Return AppleDouble data for a file
+ *
+ * @param[in] ctx talloc context
+ * @param[in] handle vfs handle
+ * @param[in] fsp fsp to use for IO
+ * @param[in] type type of AppleDouble, ADOUBLE_META or ADOUBLE_RSRC
+ *
+ * @return talloced struct adouble or NULL on error
+ **/
+static struct adouble *ad_fget(TALLOC_CTX *ctx, vfs_handle_struct *handle,
+ files_struct *fsp, adouble_type_t type)
+{
+ int rc = 0;
+ ssize_t len;
+ struct adouble *ad = NULL;
+ char *path = fsp->base_fsp->fsp_name->base_name;
+
+ DBG_DEBUG("ad_get(%s) path [%s]\n",
+ type == ADOUBLE_META ? "meta" : "rsrc",
+ fsp_str_dbg(fsp));
+
+ ad = ad_alloc(ctx, handle, type);
+ if (ad == NULL) {
+ rc = -1;
+ goto exit;
+ }
+
+ if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
+ ad->ad_fd = fsp->fh->fd;
+ } else {
+ /*
+ * Here's the deal: for ADOUBLE_META we can do without an fd
+ * as we can issue path based xattr calls. For ADOUBLE_RSRC
+ * however we need a full-fledged fd for file IO on the ._
+ * file.
+ */
+ int fd;
+ int mode;
+
+ if (type == ADOUBLE_RSRC) {
+ /* Try rw first so we can use the fd in ad_convert() */
+ mode = O_RDWR;
+
+ fd = ad_open(handle, ad, path, ADOUBLE_RSRC, mode, 0);
+ if (fd == -1 &&
+ ((errno == EROFS) || (errno == EACCES)))
+ {
+ mode = O_RDONLY;
+ fd = ad_open(handle, ad, path, ADOUBLE_RSRC,
+ mode, 0);
+ }
+
+ if (fd == -1) {
+ DBG_DEBUG("error opening AppleDouble for %s\n", path);
+ rc = -1;
+ goto exit;
+ }
+ }
+ }
+
+ len = ad_read(ad, path);
+ if (len == -1) {
+ DBG_DEBUG("error reading AppleDouble for %s\n", path);
+ rc = -1;
+ goto exit;
+ }
+
+exit:
+ DBG_DEBUG("ad_get(%s) path [%s] rc [%d]\n",
+ type == ADOUBLE_META ? "meta" : "rsrc",
+ fsp_str_dbg(fsp), rc);
+
+ if (rc != 0) {
+ TALLOC_FREE(ad);
+ }
+ return ad;
+}
+
+/**
* Set AppleDouble metadata on a file or directory
*
* @param[in] ad adouble handle
+ *
+ * @param[in] path pathname to file or directory
+ *
+ * @return status code, 0 means success
+ **/
+static int ad_set(struct adouble *ad, const char *path)
+{
+ bool ok;
+ int ret;
+
+ DBG_DEBUG("Path [%s]\n", path);
+
+ if (ad->ad_type != ADOUBLE_META) {
+ DBG_ERR("ad_set on [%s] used with ADOUBLE_RSRC\n", path);
+ return -1;
+ }
+
+ ok = ad_pack(ad);
+ if (!ok) {
+ return -1;
+ }
+
+ ret = SMB_VFS_SETXATTR(ad->ad_handle->conn,
+ path,
+ AFPINFO_EA_NETATALK,
+ ad->ad_data,
+ AD_DATASZ_XATTR, 0);
+
+ DBG_DEBUG("Path [%s] ret [%d]\n", path, ret);
+
+ return ret;
+}
- * @param[in] path pathname to file or directory, may be NULL for a
- * resource fork
+/**
+ * Set AppleDouble metadata on a file or directory
+ *
+ * @param[in] ad adouble handle
+ * @param[in] fsp file handle
*
* @return status code, 0 means success
**/
-static int ad_write(struct adouble *ad, const char *path)
+static int ad_fset(struct adouble *ad, files_struct *fsp)
{
- int rc = 0;
+ int rc = -1;
ssize_t len;
bool ok;
+ DBG_DEBUG("Path [%s]\n", fsp_str_dbg(fsp));
+
+ if ((fsp == NULL)
+ || (fsp->fh == NULL)
+ || (fsp->fh->fd == -1))
+ {
+ smb_panic("bad fsp");
+ }
+
ok = ad_pack(ad);
if (!ok) {
return -1;
@@ -1226,31 +1437,32 @@
switch (ad->ad_type) {
case ADOUBLE_META:
- rc = SMB_VFS_SETXATTR(ad->ad_handle->conn, path,
- AFPINFO_EA_NETATALK, ad->ad_data,
- AD_DATASZ_XATTR, 0);
+ rc = SMB_VFS_NEXT_FSETXATTR(ad->ad_handle,
+ fsp,
+ AFPINFO_EA_NETATALK,
+ ad->ad_data,
+ AD_DATASZ_XATTR, 0);
break;
+
case ADOUBLE_RSRC:
- if ((ad->ad_fsp == NULL)
- || (ad->ad_fsp->fh == NULL)
- || (ad->ad_fsp->fh->fd == -1)) {
- rc = -1;
- goto exit;
- }
- /* FIXME: direct sys_pwrite(), don't have an fsp */
- len = sys_pwrite(ad->ad_fsp->fh->fd, ad->ad_data,
- talloc_get_size(ad->ad_data), 0);
- if (len != talloc_get_size(ad->ad_data)) {
- DEBUG(1, ("short write on %s: %zd",
- fsp_str_dbg(ad->ad_fsp), len));
- rc = -1;
- goto exit;
+ len = SMB_VFS_NEXT_PWRITE(ad->ad_handle,
+ fsp,
+ ad->ad_data,
+ talloc_get_size(ad->ad_data),
+ 0);
+ if (len != (ssize_t)talloc_get_size(ad->ad_data)) {
+ DBG_ERR("short write on %s: %zd", fsp_str_dbg(fsp), len);
+ return -1;
}
+ rc = 0;
break;
+
default:
return -1;
}
-exit:
+
+ DBG_DEBUG("Path [%s] rc [%d]\n", fsp_str_dbg(fsp), rc);
+
return rc;
}
@@ -1345,9 +1557,12 @@
}
config->encoding = (enum fruit_encoding)enumval;
- config->veto_appledouble = lp_parm_bool(
- SNUM(handle->conn), FRUIT_PARAM_TYPE_NAME,
- "veto_appledouble", true);
+ if (config->rsrc == FRUIT_RSRC_ADFILE) {
+ config->veto_appledouble = lp_parm_bool(SNUM(handle->conn),
+ FRUIT_PARAM_TYPE_NAME,
+ "veto_appledouble",
+ true);
+ }
config->use_aapl = lp_parm_bool(
-1, FRUIT_PARAM_TYPE_NAME, "aapl", true);
@@ -1491,19 +1706,6 @@
return result;
}
-/**
- * Ensure ad_fsp is still valid
- **/
-static bool fruit_fsp_recheck(struct adouble *ad, files_struct *fsp)
-{
- if (ad->ad_fsp == fsp) {
- return true;
- }
- ad->ad_fsp = fsp;
-
- return true;
-}
-
static bool add_fruit_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams,
struct stream_struct **streams,
const char *name, off_t size,
@@ -1530,6 +1732,40 @@
return true;
}
+static bool filter_empty_rsrc_stream(unsigned int *num_streams,
+ struct stream_struct **streams)
+{
+ struct stream_struct *tmp = *streams;
+ unsigned int i;
+
+ if (*num_streams == 0) {
+ return true;
+ }
+
+ for (i = 0; i < *num_streams; i++) {
+ if (strequal_m(tmp[i].name, AFPRESOURCE_STREAM)) {
+ break;
+ }
+ }
+
+ if (i == *num_streams) {
+ return true;
+ }
+
+ if (tmp[i].size > 0) {
+ return true;
+ }
+
+ TALLOC_FREE(tmp[i].name);
+ if (*num_streams - 1 > i) {
+ memmove(&tmp[i], &tmp[i+1],
+ (*num_streams - i - 1) * sizeof(struct stream_struct));
+ }
+
+ *num_streams -= 1;
+ return true;
+}
+
static bool del_fruit_stream(TALLOC_CTX *mem_ctx, unsigned int *num_streams,
struct stream_struct **streams,
const char *name)
@@ -1561,16 +1797,29 @@
return true;
}
-static bool empty_finderinfo(const struct adouble *ad)
+static bool ad_empty_finderinfo(const struct adouble *ad)
{
-
+ int cmp;
char emptybuf[ADEDLEN_FINDERI] = {0};
- if (memcmp(emptybuf,
- ad_entry(ad, ADEID_FINDERI),
- ADEDLEN_FINDERI) == 0) {
- return true;
+ char *fi = NULL;
+
+ fi = ad_get_entry(ad, ADEID_FINDERI);
+ if (fi == NULL) {
+ DBG_ERR("Missing FinderInfo in struct adouble [%p]\n", ad);
+ return false;
}
- return false;
+
+ cmp = memcmp(emptybuf, fi, ADEDLEN_FINDERI);
+ return (cmp == 0);
+}
+
+static bool ai_empty_finderinfo(const AfpInfo *ai)
+{
+ int cmp;
+ char emptybuf[ADEDLEN_FINDERI] = {0};
+
+ cmp = memcmp(emptybuf, &ai->afpi_FinderInfo[0], ADEDLEN_FINDERI);
+ return (cmp == 0);
}
/**
@@ -1582,6 +1831,21 @@
uint32_t t;
struct timespec creation_time = {0};
struct adouble *ad;
+ struct fruit_config_data *config = NULL;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
+ return);
+
+ switch (config->meta) {
+ case FRUIT_META_STREAM:
+ return;
+ case FRUIT_META_NETATALK:
+ /* Handled below */
+ break;
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", config->meta);
+ return;
+ }
ad = ad_get(talloc_tos(), handle, smb_fname->base_name, ADOUBLE_META);
if (ad == NULL) {
@@ -1697,6 +1961,8 @@
struct byte_range_lock *br_lck = NULL;
bool open_for_reading, open_for_writing, deny_read, deny_write;
off_t off;
+ bool have_read = false;
+ int flags;
/* FIXME: hardcoded data fork, add resource fork */
enum apple_fork fork_type = APPLE_FORK_DATA;
@@ -1708,6 +1974,26 @@
deny_mode & DENY_READ ? "DENY_READ" : "-",
deny_mode & DENY_WRITE ? "DENY_WRITE" : "-"));
+ if (fsp->fh->fd == -1) {
+ return NT_STATUS_OK;
+ }
+
+ flags = fcntl(fsp->fh->fd, F_GETFL);
+ if (flags == -1) {
+ DBG_ERR("fcntl get flags [%s] fd [%d] failed [%s]\n",
+ fsp_str_dbg(fsp), fsp->fh->fd, strerror(errno));
+ return map_nt_error_from_unix(errno);
+ }
+
+ if (flags & (O_RDONLY|O_RDWR)) {
+ /*
+ * Applying fcntl read locks requires an fd opened for
+ * reading. This means we won't be applying locks for
+ * files openend write-only, but what can we do...
+ */
+ have_read = true;
+ }
+
/*
* Check read access and deny read mode
*/
@@ -1729,7 +2015,7 @@
}
/* Set locks */
- if (access_mask & FILE_READ_DATA) {
+ if ((access_mask & FILE_READ_DATA) && have_read) {
off = access_to_netatalk_brl(fork_type, FILE_READ_DATA);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@@ -1743,7 +2029,7 @@
TALLOC_FREE(br_lck);
}
- if (deny_mode & DENY_READ) {
+ if ((deny_mode & DENY_READ) && have_read) {
off = denymode_to_netatalk_brl(fork_type, DENY_READ);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@@ -1779,7 +2065,7 @@
}
/* Set locks */
- if (access_mask & FILE_WRITE_DATA) {
+ if ((access_mask & FILE_WRITE_DATA) && have_read) {
off = access_to_netatalk_brl(fork_type, FILE_WRITE_DATA);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@@ -1793,7 +2079,7 @@
TALLOC_FREE(br_lck);
}
- if (deny_mode & DENY_WRITE) {
+ if ((deny_mode & DENY_WRITE) && have_read) {
off = denymode_to_netatalk_brl(fork_type, DENY_WRITE);
br_lck = do_lock(
handle->conn->sconn->msg_ctx, fsp,
@@ -1934,20 +2220,257 @@
SMB2_CREATE_TAG_AAPL,
blob);
if (NT_STATUS_IS_OK(status)) {
- config->nego_aapl = true;
+ global_fruit_config.nego_aapl = true;
}
return status;
}
+static bool readdir_attr_meta_finderi_stream(
+ struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ AfpInfo *ai)
+{
+ struct smb_filename *stream_name = NULL;
+ files_struct *fsp = NULL;
+ ssize_t nread;
+ NTSTATUS status;
+ int ret;
+ bool ok;
+ uint8_t buf[AFP_INFO_SIZE];
+
+ stream_name = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ AFPINFO_STREAM_NAME,
+ NULL, smb_fname->flags);
+ if (stream_name == NULL) {
+ return false;
+ }
+
+ ret = SMB_VFS_STAT(handle->conn, stream_name);
+ if (ret != 0) {
+ return false;
+ }
+
+ status = SMB_VFS_CREATE_FILE(
+ handle->conn, /* conn */
+ NULL, /* req */
+ 0, /* root_dir_fid */
+ stream_name, /* fname */
+ FILE_READ_DATA, /* access_mask */
+ (FILE_SHARE_READ | FILE_SHARE_WRITE | /* share_access */
+ FILE_SHARE_DELETE),
+ FILE_OPEN, /* create_disposition*/
+ 0, /* create_options */
+ 0, /* file_attributes */
+ INTERNAL_OPEN_ONLY, /* oplock_request */
+ NULL, /* lease */
+ 0, /* allocation_size */
+ 0, /* private_flags */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ NULL, NULL); /* create context */
+
+ TALLOC_FREE(stream_name);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ nread = SMB_VFS_PREAD(fsp, &buf[0], AFP_INFO_SIZE, 0);
+ if (nread != AFP_INFO_SIZE) {
+ DBG_ERR("short read [%s] [%zd/%d]\n",
+ smb_fname_str_dbg(stream_name), nread, AFP_INFO_SIZE);
+ ok = false;
+ goto fail;
+ }
+
+ memcpy(&ai->afpi_FinderInfo[0], &buf[AFP_OFF_FinderInfo],
+ AFP_FinderSize);
+
+ ok = true;
+
+fail:
+ if (fsp != NULL) {
+ close_file(NULL, fsp, NORMAL_CLOSE);
+ }
+
+ return ok;
+}
+
+static bool readdir_attr_meta_finderi_netatalk(
+ struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ AfpInfo *ai)
+{
+ struct adouble *ad = NULL;
+ char *p = NULL;
+
+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name, ADOUBLE_META);
+ if (ad == NULL) {
+ return false;
+ }
+
+ p = ad_get_entry(ad, ADEID_FINDERI);
+ if (p == NULL) {
+ DBG_ERR("No ADEID_FINDERI for [%s]\n", smb_fname->base_name);
+ TALLOC_FREE(ad);
+ return false;
+ }
+
+ memcpy(&ai->afpi_FinderInfo[0], p, AFP_FinderSize);
+ TALLOC_FREE(ad);
+ return true;
+}
+
+static bool readdir_attr_meta_finderi(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ struct readdir_attr_data *attr_data)
+{
+ struct fruit_config_data *config = NULL;
+ uint32_t date_added;
+ AfpInfo ai = {0};
+ bool ok;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data,
+ return false);
+
+ switch (config->meta) {
+ case FRUIT_META_NETATALK:
+ ok = readdir_attr_meta_finderi_netatalk(
+ handle, smb_fname, &ai);
+ break;
+
+ case FRUIT_META_STREAM:
+ ok = readdir_attr_meta_finderi_stream(
+ handle, smb_fname, &ai);
+ break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", config->meta);
+ return false;
+ }
+
+ if (!ok) {
+ /* Don't bother with errors, it's likely ENOENT */
+ return true;
+ }
+
+ if (S_ISREG(smb_fname->st.st_ex_mode)) {
+ /* finder_type */
+ memcpy(&attr_data->attr_data.aapl.finder_info[0],
+ &ai.afpi_FinderInfo[0], 4);
+
+ /* finder_creator */
+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 4,
+ &ai.afpi_FinderInfo[4], 4);
+ }
+
+ /* finder_flags */
+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 8,
+ &ai.afpi_FinderInfo[8], 2);
+
+ /* finder_ext_flags */
+ memcpy(&attr_data->attr_data.aapl.finder_info[0] + 10,
+ &ai.afpi_FinderInfo[24], 2);
+
+ /* creation date */
+ date_added = convert_time_t_to_uint32_t(
+ smb_fname->st.st_ex_btime.tv_sec - AD_DATE_DELTA);
+
+ RSIVAL(&attr_data->attr_data.aapl.finder_info[0], 12, date_added);
+
+ return true;
+}
+
+static uint64_t readdir_attr_rfork_size_adouble(
+ struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ struct adouble *ad = NULL;
+ uint64_t rfork_size;
+
+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
+ ADOUBLE_RSRC);
+ if (ad == NULL) {
+ return 0;
+ }
+
+ rfork_size = ad_getentrylen(ad, ADEID_RFORK);
+ TALLOC_FREE(ad);
+
+ return rfork_size;
+}
+
+static uint64_t readdir_attr_rfork_size_stream(
+ struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ struct smb_filename *stream_name = NULL;
+ int ret;
+ uint64_t rfork_size;
+
+ stream_name = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ AFPRESOURCE_STREAM_NAME,
+ NULL, 0);
+ if (stream_name == NULL) {
+ return 0;
+ }
+
+ ret = SMB_VFS_STAT(handle->conn, stream_name);
+ if (ret != 0) {
+ TALLOC_FREE(stream_name);
+ return 0;
+ }
+
+ rfork_size = stream_name->st.st_ex_size;
+ TALLOC_FREE(stream_name);
+
+ return rfork_size;
+}
+
+static uint64_t readdir_attr_rfork_size(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ struct fruit_config_data *config = NULL;
+ uint64_t rfork_size;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data,
+ return 0);
+
+ switch (config->rsrc) {
+ case FRUIT_RSRC_ADFILE:
+ case FRUIT_RSRC_XATTR:
+ rfork_size = readdir_attr_rfork_size_adouble(handle,
+ smb_fname);
+ break;
+
+ case FRUIT_META_STREAM:
+ rfork_size = readdir_attr_rfork_size_stream(handle,
+ smb_fname);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", config->rsrc);
+ rfork_size = 0;
+ break;
+ }
+
+ return rfork_size;
+}
+
static NTSTATUS readdir_attr_macmeta(struct vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
struct readdir_attr_data *attr_data)
{
NTSTATUS status = NT_STATUS_OK;
- uint32_t date_added;
- struct adouble *ad = NULL;
struct fruit_config_data *config = NULL;
+ bool ok;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data,
@@ -1962,13 +2485,10 @@
*/
if (config->readdir_attr_rsize) {
- ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
- ADOUBLE_RSRC);
- if (ad) {
- attr_data->attr_data.aapl.rfork_size = ad_getentrylen(
- ad, ADEID_RFORK);
- TALLOC_FREE(ad);
- }
+ uint64_t rfork_size;
+
+ rfork_size = readdir_attr_rfork_size(handle, smb_fname);
+ attr_data->attr_data.aapl.rfork_size = rfork_size;
}
/*
@@ -1976,37 +2496,12 @@
*/
if (config->readdir_attr_finder_info) {
- ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
- ADOUBLE_META);
- if (ad) {
- if (S_ISREG(smb_fname->st.st_ex_mode)) {
- /* finder_type */
- memcpy(&attr_data->attr_data.aapl.finder_info[0],
- ad_entry(ad, ADEID_FINDERI), 4);
-
- /* finder_creator */
- memcpy(&attr_data->attr_data.aapl.finder_info[0] + 4,
- ad_entry(ad, ADEID_FINDERI) + 4, 4);
- }
-
- /* finder_flags */
- memcpy(&attr_data->attr_data.aapl.finder_info[0] + 8,
- ad_entry(ad, ADEID_FINDERI) + 8, 2);
-
- /* finder_ext_flags */
- memcpy(&attr_data->attr_data.aapl.finder_info[0] + 10,
- ad_entry(ad, ADEID_FINDERI) + 24, 2);
-
- /* creation date */
- date_added = convert_time_t_to_uint32_t(
- smb_fname->st.st_ex_btime.tv_sec - AD_DATE_DELTA);
- RSIVAL(&attr_data->attr_data.aapl.finder_info[0], 12, date_added);
-
- TALLOC_FREE(ad);
+ ok = readdir_attr_meta_finderi(handle, smb_fname, attr_data);
+ if (!ok) {
+ status = NT_STATUS_INTERNAL_ERROR;
}
}
- TALLOC_FREE(ad);
return status;
}
@@ -2116,25 +2611,81 @@
return rc;
}
-static int fruit_open_meta(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- files_struct *fsp, int flags, mode_t mode)
+static int fruit_open_meta_stream(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+ AfpInfo *ai = NULL;
+ char afpinfo_buf[AFP_INFO_SIZE];
+ ssize_t len, written;
+ int hostfd = -1;
+ int rc = -1;
+
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ if (hostfd == -1) {
+ return -1;
+ }
+
+ if (!(flags & (O_CREAT | O_TRUNC))) {
+ return hostfd;
+ }
+
+ ai = afpinfo_new(talloc_tos());
+ if (ai == NULL) {
+ rc = -1;
+ goto fail;
+ }
+
+ len = afpinfo_pack(ai, afpinfo_buf);
+ if (len != AFP_INFO_SIZE) {
+ rc = -1;
+ goto fail;
+ }
+
+ /* Set fd, needed in SMB_VFS_NEXT_PWRITE() */
+ fsp->fh->fd = hostfd;
+
+ written = SMB_VFS_NEXT_PWRITE(handle, fsp, afpinfo_buf,
+ AFP_INFO_SIZE, 0);
+ fsp->fh->fd = -1;
+ if (written != AFP_INFO_SIZE) {
+ DBG_ERR("bad write [%zd/%d]\n", written, AFP_INFO_SIZE);
+ rc = -1;
+ goto fail;
+ }
+
+ rc = 0;
+
+fail:
+ DBG_DEBUG("rc=%d, fd=%d\n", rc, hostfd);
+
+ if (rc != 0) {
+ int saved_errno = errno;
+ if (hostfd >= 0) {
+ fsp->fh->fd = hostfd;
+ SMB_VFS_NEXT_CLOSE(handle, fsp);
+ }
+ hostfd = -1;
+ errno = saved_errno;
+ }
+ return hostfd;
+}
+
+static int fruit_open_meta_netatalk(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
{
int rc = 0;
- struct fruit_config_data *config = NULL;
struct smb_filename *smb_fname_base = NULL;
int baseflags;
int hostfd = -1;
struct adouble *ad = NULL;
- DEBUG(10, ("fruit_open_meta for %s\n", smb_fname_str_dbg(smb_fname)));
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
-
- if (config->meta == FRUIT_META_STREAM) {
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- }
+ DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
/* Create an smb_filename with stream_name == NULL. */
smb_fname_base = synthetic_smb_fname(talloc_tos(),
@@ -2158,8 +2709,8 @@
baseflags &= ~O_EXCL;
baseflags &= ~O_CREAT;
- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
- baseflags, mode);
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
+ baseflags, mode);
/*
* It is legit to open a stream on a directory, but the base
@@ -2168,8 +2719,8 @@
if ((hostfd == -1) && (errno == EISDIR)) {
baseflags &= ~O_ACCMODE;
baseflags |= O_RDONLY;
- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
- baseflags, mode);
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
+ baseflags, mode);
}
TALLOC_FREE(smb_fname_base);
@@ -2184,29 +2735,22 @@
* The attribute does not exist or needs to be truncated,
* create an AppleDouble EA
*/
- ad = ad_init(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- handle, ADOUBLE_META, fsp);
+ ad = ad_init(fsp, handle, ADOUBLE_META);
if (ad == NULL) {
rc = -1;
goto exit;
}
- rc = ad_write(ad, smb_fname->base_name);
+ fsp->fh->fd = hostfd;
+
+ rc = ad_fset(ad, fsp);
+ fsp->fh->fd = -1;
if (rc != 0) {
rc = -1;
goto exit;
}
- } else {
- ad = ad_alloc(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- handle, ADOUBLE_META, fsp);
- if (ad == NULL) {
- rc = -1;
- goto exit;
- }
- if (ad_read(ad, smb_fname->base_name) == -1) {
- rc = -1;
- goto exit;
- }
+
+ TALLOC_FREE(ad);
}
exit:
@@ -2220,7 +2764,7 @@
* full fsp yet
*/
fsp->fh->fd = hostfd;
- SMB_VFS_CLOSE(fsp);
+ SMB_VFS_NEXT_CLOSE(handle, fsp);
}
hostfd = -1;
errno = saved_errno;
@@ -2228,56 +2772,67 @@
return hostfd;
}
-static int fruit_open_rsrc(vfs_handle_struct *handle,
+static int fruit_open_meta(vfs_handle_struct *handle,
struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- int rc = 0;
+ int fd;
struct fruit_config_data *config = NULL;
- struct adouble *ad = NULL;
- struct smb_filename *smb_fname_base = NULL;
- char *adpath = NULL;
- int hostfd = -1;
+ struct fio *fio = NULL;
- DEBUG(10, ("fruit_open_rsrc for %s\n", smb_fname_str_dbg(smb_fname)));
+ DBG_DEBUG("path [%s]\n", smb_fname_str_dbg(smb_fname));
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- switch (config->rsrc) {
- case FRUIT_RSRC_STREAM:
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- case FRUIT_RSRC_XATTR:
-#ifdef HAVE_ATTROPEN
- hostfd = attropen(smb_fname->base_name,
- AFPRESOURCE_EA_NETATALK, flags, mode);
- if (hostfd == -1) {
- return -1;
- }
- ad = ad_init(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- handle, ADOUBLE_RSRC, fsp);
- if (ad == NULL) {
- rc = -1;
- goto exit;
- }
- goto exit;
-#else
- errno = ENOTSUP;
- return -1;
-#endif
- default:
+ switch (config->meta) {
+ case FRUIT_META_STREAM:
+ fd = fruit_open_meta_stream(handle, smb_fname,
+ fsp, flags, mode);
+ break;
+
+ case FRUIT_META_NETATALK:
+ fd = fruit_open_meta_netatalk(handle, smb_fname,
+ fsp, flags, mode);
break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", config->meta);
+ return -1;
}
- if (!(flags & O_CREAT) && !VALID_STAT(smb_fname->st)) {
- rc = SMB_VFS_NEXT_STAT(handle, smb_fname);
- if (rc != 0) {
- rc = -1;
- goto exit;
- }
+ DBG_DEBUG("path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
+
+ if (fd == -1) {
+ return -1;
}
- if (VALID_STAT(smb_fname->st) && S_ISDIR(smb_fname->st.st_ex_mode)) {
+ fio = (struct fio *)VFS_ADD_FSP_EXTENSION(handle, fsp, struct fio, NULL);
+ fio->type = ADOUBLE_META;
+ fio->config = config;
+
+ return fd;
+}
+
+static int fruit_open_rsrc_adouble(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+ int rc = 0;
+ struct adouble *ad = NULL;
+ struct smb_filename *smb_fname_base = NULL;
+ struct fruit_config_data *config = NULL;
+ char *adpath = NULL;
+ int hostfd = -1;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ if ((!(flags & O_CREAT)) &&
+ S_ISDIR(fsp->base_fsp->fsp_name->st.st_ex_mode))
+ {
/* sorry, but directories don't habe a resource fork */
rc = -1;
goto exit;
@@ -2307,39 +2862,29 @@
flags |= O_RDWR;
}
- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
- flags, mode);
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
+ flags, mode);
if (hostfd == -1) {
rc = -1;
goto exit;
}
- /* REVIEW: we need this in ad_write() */
- fsp->fh->fd = hostfd;
-
if (flags & (O_CREAT | O_TRUNC)) {
- ad = ad_init(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- handle, ADOUBLE_RSRC, fsp);
+ ad = ad_init(fsp, handle, ADOUBLE_RSRC);
if (ad == NULL) {
rc = -1;
goto exit;
}
- rc = ad_write(ad, smb_fname->base_name);
+
+ fsp->fh->fd = hostfd;
+
+ rc = ad_fset(ad, fsp);
+ fsp->fh->fd = -1;
if (rc != 0) {
rc = -1;
goto exit;
}
- } else {
- ad = ad_alloc(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- handle, ADOUBLE_RSRC, fsp);
- if (ad == NULL) {
- rc = -1;
- goto exit;
- }
- if (ad_read(ad, smb_fname->base_name) == -1) {
- rc = -1;
- goto exit;
- }
+ TALLOC_FREE(ad);
}
exit:
@@ -2365,24 +2910,100 @@
return hostfd;
}
+static int fruit_open_rsrc_xattr(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp,
+ int flags,
+ mode_t mode)
+{
+#ifdef HAVE_ATTROPEN
+ int fd = -1;
+
+ fd = attropen(smb_fname->base_name,
+ AFPRESOURCE_EA_NETATALK,
+ flags,
+ mode);
+ if (fd == -1) {
+ return -1;
+ }
+
+ return fd;
+
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int fruit_open_rsrc(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ files_struct *fsp, int flags, mode_t mode)
+{
+ int fd;
+ struct fruit_config_data *config = NULL;
+ struct fio *fio = NULL;
+
+ DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ switch (config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ fd = fruit_open_rsrc_adouble(handle, smb_fname,
+ fsp, flags, mode);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ fd = fruit_open_rsrc_xattr(handle, smb_fname,
+ fsp, flags, mode);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", config->rsrc);
+ return -1;
+ }
+
+ DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
+
+ if (fd == -1) {
+ return -1;
+ }
+
+ fio = (struct fio *)VFS_ADD_FSP_EXTENSION(handle, fsp, struct fio, NULL);
+ fio->type = ADOUBLE_RSRC;
+ fio->config = config;
+
+ return fd;
+}
+
static int fruit_open(vfs_handle_struct *handle,
struct smb_filename *smb_fname,
files_struct *fsp, int flags, mode_t mode)
{
- DEBUG(10, ("fruit_open called for %s\n",
- smb_fname_str_dbg(smb_fname)));
+ int fd;
+
+ DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
if (!is_ntfs_stream_smb_fname(smb_fname)) {
return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
if (is_afpinfo_stream(smb_fname)) {
- return fruit_open_meta(handle, smb_fname, fsp, flags, mode);
+ fd = fruit_open_meta(handle, smb_fname, fsp, flags, mode);
} else if (is_afpresource_stream(smb_fname)) {
- return fruit_open_rsrc(handle, smb_fname, fsp, flags, mode);
+ fd = fruit_open_rsrc(handle, smb_fname, fsp, flags, mode);
+ } else {
+ fd = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
}
- return SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
+ DBG_DEBUG("Path [%s] fd [%d]\n", smb_fname_str_dbg(smb_fname), fd);
+
+ return fd;
}
static int fruit_rename(struct vfs_handle_struct *handle,
@@ -2393,19 +3014,27 @@
char *src_adouble_path = NULL;
char *dst_adouble_path = NULL;
struct fruit_config_data *config = NULL;
+ struct smb_filename *src_adp_smb_fname = NULL;
+ struct smb_filename *dst_adp_smb_fname = NULL;
- rc = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
- if (!VALID_STAT(smb_fname_src->st)
- || !S_ISREG(smb_fname_src->st.st_ex_mode)) {
- return rc;
+ if (!VALID_STAT(smb_fname_src->st)) {
+ DBG_ERR("Need valid stat for [%s]\n",
+ smb_fname_str_dbg(smb_fname_src));
+ return -1;
}
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+ rc = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
+ if (rc != 0) {
+ return -1;
+ }
- if (config->rsrc == FRUIT_RSRC_XATTR) {
- return rc;
+ if ((config->rsrc != FRUIT_RSRC_ADFILE) ||
+ (!S_ISREG(smb_fname_src->st.st_ex_mode)))
+ {
+ return 0;
}
rc = adouble_path(talloc_tos(), smb_fname_src->base_name,
@@ -2413,46 +3042,99 @@
if (rc != 0) {
goto done;
}
+ src_adp_smb_fname = synthetic_smb_fname(talloc_tos(),
+ src_adouble_path,
+ NULL, NULL,
+ smb_fname_src->flags);
+ TALLOC_FREE(src_adouble_path);
+ if (src_adp_smb_fname == NULL) {
+ rc = -1;
+ goto done;
+ }
+
rc = adouble_path(talloc_tos(), smb_fname_dst->base_name,
&dst_adouble_path);
if (rc != 0) {
goto done;
}
+ dst_adp_smb_fname = synthetic_smb_fname(talloc_tos(),
+ dst_adouble_path,
+ NULL, NULL,
+ smb_fname_dst->flags);
+ TALLOC_FREE(dst_adouble_path);
+ if (dst_adp_smb_fname == NULL) {
+ rc = -1;
+ goto done;
+ }
- DEBUG(10, ("fruit_rename: %s -> %s\n",
- src_adouble_path, dst_adouble_path));
+ DBG_DEBUG("%s -> %s\n",
+ smb_fname_str_dbg(src_adp_smb_fname),
+ smb_fname_str_dbg(dst_adp_smb_fname));
- rc = rename(src_adouble_path, dst_adouble_path);
+ rc = SMB_VFS_NEXT_RENAME(handle, src_adp_smb_fname, dst_adp_smb_fname);
if (errno == ENOENT) {
rc = 0;
}
- TALLOC_FREE(src_adouble_path);
- TALLOC_FREE(dst_adouble_path);
-
done:
+ TALLOC_FREE(src_adp_smb_fname);
+ TALLOC_FREE(dst_adp_smb_fname);
return rc;
}
-static int fruit_unlink(vfs_handle_struct *handle,
- const struct smb_filename *smb_fname)
+static int fruit_unlink_meta_stream(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+}
+
+static int fruit_unlink_meta_netatalk(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ return SMB_VFS_REMOVEXATTR(handle->conn,
+ smb_fname->base_name,
+ AFPINFO_EA_NETATALK);
+}
+
+static int fruit_unlink_meta(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
{
- int rc = -1;
struct fruit_config_data *config = NULL;
+ int rc;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- if (!is_ntfs_stream_smb_fname(smb_fname)) {
- char *adp = NULL;
+ switch (config->meta) {
+ case FRUIT_META_STREAM:
+ rc = fruit_unlink_meta_stream(handle, smb_fname);
+ break;
- rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
- if (rc != 0) {
- return -1;
- }
+ case FRUIT_META_NETATALK:
+ rc = fruit_unlink_meta_netatalk(handle, smb_fname);
+ break;
- if (config->rsrc != FRUIT_RSRC_ADFILE) {
- return 0;
+ default:
+ DBG_ERR("Unsupported meta config [%d]\n", config->meta);
+ return -1;
+ }
+
+ return rc;
+}
+
+static int fruit_unlink_rsrc_stream(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
+{
+ int ret;
+
+ if (!force_unlink) {
+ struct smb_filename *smb_fname_cp = NULL;
+ off_t size;
+
+ smb_fname_cp = cp_smb_filename(talloc_tos(), smb_fname);
+ if (smb_fname_cp == NULL) {
+ return -1;
}
/*
@@ -2460,46 +3142,176 @@
* vfs_streaminfo, as a result stream cleanup/deletion of file
* deletion doesn't remove the resourcefork stream.
*/
- rc = adouble_path(talloc_tos(),
- smb_fname->base_name, &adp);
- if (rc != 0) {
+
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname_cp);
+ if (ret != 0) {
+ TALLOC_FREE(smb_fname_cp);
+ DBG_ERR("stat [%s] failed [%s]\n",
+ smb_fname_str_dbg(smb_fname_cp), strerror(errno));
return -1;
}
- /* FIXME: direct unlink(), missing smb_fname */
- DBG_DEBUG("fruit_unlink: %s\n", adp);
- rc = unlink(adp);
- if ((rc == -1) && (errno == ENOENT)) {
- rc = 0;
+ size = smb_fname_cp->st.st_ex_size;
+ TALLOC_FREE(smb_fname_cp);
+
+ if (size > 0) {
+ /* OS X ignores resource fork stream delete requests */
+ return 0;
}
+ }
- TALLOC_FREE(adp);
- return 0;
+ ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ if ((ret != 0) && (errno == ENOENT) && force_unlink) {
+ ret = 0;
}
- if (is_afpinfo_stream(smb_fname)) {
- if (config->meta == FRUIT_META_STREAM) {
- rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
- } else {
- rc = SMB_VFS_REMOVEXATTR(handle->conn,
- smb_fname->base_name,
- AFPINFO_EA_NETATALK);
+ return ret;
+}
+
+static int fruit_unlink_rsrc_adouble(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
+{
+ int rc;
+ char *adp = NULL;
+ struct adouble *ad = NULL;
+ struct smb_filename *adp_smb_fname = NULL;
+
+ if (!force_unlink) {
+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
+ ADOUBLE_RSRC);
+ if (ad == NULL) {
+ errno = ENOENT;
+ return -1;
}
- return rc;
+
+ /*
+ * 0 byte resource fork streams are not listed by
+ * vfs_streaminfo, as a result stream cleanup/deletion of file
+ * deletion doesn't remove the resourcefork stream.
+ */
+
+ if (ad_getentrylen(ad, ADEID_RFORK) > 0) {
+ /* OS X ignores resource fork stream delete requests */
+ TALLOC_FREE(ad);
+ return 0;
+ }
+
+ TALLOC_FREE(ad);
}
- if (is_afpresource_stream(smb_fname)) {
- /* OS X ignores deletes on the AFP_Resource stream */
- return 0;
+ rc = adouble_path(talloc_tos(), smb_fname->base_name, &adp);
+ if (rc != 0) {
+ return -1;
}
- return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ adp_smb_fname = synthetic_smb_fname(talloc_tos(), adp,
+ NULL, NULL,
+ smb_fname->flags);
+ TALLOC_FREE(adp);
+ if (adp_smb_fname == NULL) {
+ return -1;
+ }
+
+ rc = SMB_VFS_NEXT_UNLINK(handle, adp_smb_fname);
+ TALLOC_FREE(adp_smb_fname);
+ if ((rc != 0) && (errno == ENOENT) && force_unlink) {
+ rc = 0;
+ }
+ return rc;
+}
+static int fruit_unlink_rsrc_xattr(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
+{
+ /*
+ * OS X ignores resource fork stream delete requests, so nothing to do
+ * here. Removing the file will remove the xattr anyway, so we don't
+ * have to take care of removing 0 byte resource forks that could be
+ * left behind.
+ */
return 0;
}
+static int fruit_unlink_rsrc(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ bool force_unlink)
+{
+ struct fruit_config_data *config = NULL;
+ int rc;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ switch (config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ rc = fruit_unlink_rsrc_stream(handle, smb_fname, force_unlink);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ rc = fruit_unlink_rsrc_adouble(handle, smb_fname, force_unlink);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ rc = fruit_unlink_rsrc_xattr(handle, smb_fname, force_unlink);
+ break;
+
+ default:
+ DBG_ERR("Unsupported rsrc config [%d]\n", config->rsrc);
+ return -1;
+ }
+
+ return rc;
+}
+
+static int fruit_unlink(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname)
+{
+ int rc;
+ struct fruit_config_data *config = NULL;
+ struct smb_filename *rsrc_smb_fname = NULL;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ if (is_afpinfo_stream(smb_fname)) {
+ return fruit_unlink_meta(handle, smb_fname);
+ } else if (is_afpresource_stream(smb_fname)) {
+ return fruit_unlink_rsrc(handle, smb_fname, false);
+ } if (is_ntfs_stream_smb_fname(smb_fname)) {
+ return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+ }
+
+ /*
+ * A request to delete the base file. Because 0 byte resource
+ * fork streams are not listed by fruit_streaminfo,
+ * delete_all_streams() can't remove 0 byte resource fork
+ * streams, so we have to cleanup this here.
+ */
+ rsrc_smb_fname = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ AFPRESOURCE_STREAM_NAME,
+ NULL,
+ smb_fname->flags);
+ if (rsrc_smb_fname == NULL) {
+ return -1;
+ }
+
+ rc = fruit_unlink_rsrc(handle, rsrc_smb_fname, true);
+ if ((rc != 0) && (errno != ENOENT)) {
+ DBG_ERR("Forced unlink of [%s] failed [%s]\n",
+ smb_fname_str_dbg(rsrc_smb_fname), strerror(errno));
+ TALLOC_FREE(rsrc_smb_fname);
+ return -1;
+ }
+ TALLOC_FREE(rsrc_smb_fname);
+
+ return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
+}
+
static int fruit_chmod(vfs_handle_struct *handle,
const struct smb_filename *smb_fname,
mode_t mode)
@@ -2507,7 +3319,6 @@
int rc = -1;
char *adp = NULL;
struct fruit_config_data *config = NULL;
- SMB_STRUCT_STAT sb;
const char *path = smb_fname->base_name;
struct smb_filename *smb_fname_adp = NULL;
@@ -2519,14 +3330,16 @@
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- if (config->rsrc == FRUIT_RSRC_XATTR) {
+ if (config->rsrc != FRUIT_RSRC_ADFILE) {
return 0;
}
- /* FIXME: direct sys_lstat(), missing smb_fname */
- rc = sys_lstat(path, &sb, false);
- if (rc != 0 || !S_ISREG(sb.st_ex_mode)) {
- return rc;
+ if (!VALID_STAT(smb_fname->st)) {
+ return 0;
+ }
+
+ if (!S_ISREG(smb_fname->st.st_ex_mode)) {
+ return 0;
}
rc = adouble_path(talloc_tos(), path, &adp);
@@ -2566,7 +3379,6 @@
char *adp = NULL;
struct fruit_config_data *config = NULL;
struct smb_filename *adp_smb_fname = NULL;
- SMB_STRUCT_STAT sb;
rc = SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid);
if (rc != 0) {
@@ -2576,14 +3388,16 @@
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- if (config->rsrc == FRUIT_RSRC_XATTR) {
- return rc;
+ if (config->rsrc != FRUIT_RSRC_ADFILE) {
+ return 0;
}
- /* FIXME: direct sys_lstat(), need non-const smb_fname */
- rc = sys_lstat(smb_fname->base_name, &sb, false);
- if (rc != 0 || !S_ISREG(sb.st_ex_mode)) {
- return rc;
+ if (!VALID_STAT(smb_fname->st)) {
+ return 0;
+ }
+
+ if (!S_ISREG(smb_fname->st.st_ex_mode)) {
+ return 0;
}
rc = adouble_path(talloc_tos(), smb_fname->base_name, &adp);
@@ -2621,12 +3435,11 @@
DIR *dh = NULL;
struct dirent *de;
struct fruit_config_data *config;
- const char *path = smb_fname->base_name;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct fruit_config_data, return -1);
- if (!handle->conn->cwd || !path || (config->rsrc == FRUIT_RSRC_XATTR)) {
+ if (config->rsrc != FRUIT_RSRC_ADFILE) {
goto exit_rmdir;
}
@@ -2634,24 +3447,58 @@
* Due to there is no way to change bDeleteVetoFiles variable
* from this module, need to clean up ourselves
*/
- dh = opendir(path);
+
+ dh = SMB_VFS_OPENDIR(handle->conn, smb_fname, NULL, 0);
if (dh == NULL) {
goto exit_rmdir;
}
- while ((de = readdir(dh)) != NULL) {
- if ((strncmp(de->d_name,
- ADOUBLE_NAME_PREFIX,
- strlen(ADOUBLE_NAME_PREFIX))) == 0) {
- char *p = talloc_asprintf(talloc_tos(),
- "%s/%s",
- path, de->d_name);
- if (p == NULL) {
- goto exit_rmdir;
- }
- DEBUG(10, ("fruit_rmdir: delete %s\n", p));
- (void)unlink(p);
+ while ((de = SMB_VFS_READDIR(handle->conn, dh, NULL)) != NULL) {
+ int match;
+ struct adouble *ad = NULL;
+ char *p = NULL;
+ struct smb_filename *ad_smb_fname = NULL;
+ int ret;
+
+ match = strncmp(de->d_name,
+ ADOUBLE_NAME_PREFIX,
+ strlen(ADOUBLE_NAME_PREFIX));
+ if (match != 0) {
+ continue;
+ }
+
+ p = talloc_asprintf(talloc_tos(), "%s/%s",
+ smb_fname->base_name, de->d_name);
+ if (p == NULL) {
+ DBG_ERR("talloc_asprintf failed\n");
+ return -1;
+ }
+
+ /*
+ * Check whether it's a valid AppleDouble file, if
+ * yes, delete it, ignore it otherwise.
+ */
+ ad = ad_get(talloc_tos(), handle, p, ADOUBLE_RSRC);
+ if (ad == NULL) {
TALLOC_FREE(p);
+ continue;
+ }
+ TALLOC_FREE(ad);
+
+ ad_smb_fname = synthetic_smb_fname(talloc_tos(), p,
+ NULL, NULL,
+ smb_fname->flags);
+ TALLOC_FREE(p);
+ if (ad_smb_fname == NULL) {
+ DBG_ERR("synthetic_smb_fname failed\n");
+ return -1;
+ }
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, ad_smb_fname);
+ TALLOC_FREE(ad_smb_fname);
+ if (ret != 0) {
+ DBG_ERR("Deleting [%s] failed\n",
+ smb_fname_str_dbg(ad_smb_fname));
}
}
@@ -2662,245 +3509,426 @@
return SMB_VFS_NEXT_RMDIR(handle, smb_fname);
}
-static ssize_t fruit_pread(vfs_handle_struct *handle,
- files_struct *fsp, void *data,
- size_t n, off_t offset)
+static ssize_t fruit_pread_meta_stream(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
{
- int rc = 0;
- struct adouble *ad = (struct adouble *)VFS_FETCH_FSP_EXTENSION(
- handle, fsp);
- struct fruit_config_data *config = NULL;
- AfpInfo *ai = NULL;
- ssize_t len = -1;
- char *name = NULL;
- char *tmp_base_name = NULL;
- NTSTATUS status;
+ ssize_t nread;
+ int ret;
- DEBUG(10, ("fruit_pread: offset=%d, size=%d\n", (int)offset, (int)n));
+ nread = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- if (!fsp->base_fsp) {
- return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+ if (nread == n) {
+ return nread;
}
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+ DBG_ERR("Removing [%s] after short read [%zd]\n",
+ fsp_str_dbg(fsp), nread);
- /* fsp_name is not converted with vfs_catia */
- tmp_base_name = fsp->base_fsp->fsp_name->base_name;
- status = SMB_VFS_TRANSLATE_NAME(handle->conn,
- fsp->base_fsp->fsp_name->base_name,
- vfs_translate_to_unix,
- talloc_tos(), &name);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- name = talloc_strdup(talloc_tos(), tmp_base_name);
- if (name == NULL) {
- rc = -1;
- goto exit;
- }
- } else if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- rc = -1;
- goto exit;
+ ret = SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name);
+ if (ret != 0) {
+ DBG_ERR("Removing [%s] failed\n", fsp_str_dbg(fsp));
+ return -1;
+ }
+
+ errno = EINVAL;
+ return -1;
+}
+
+static ssize_t fruit_pread_meta_adouble(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ AfpInfo *ai = NULL;
+ struct adouble *ad = NULL;
+ char afpinfo_buf[AFP_INFO_SIZE];
+ char *p = NULL;
+ ssize_t nread;
+
+ ai = afpinfo_new(talloc_tos());
+ if (ai == NULL) {
+ return -1;
}
- fsp->base_fsp->fsp_name->base_name = name;
+ ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_META);
if (ad == NULL) {
- len = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
- if (len == -1) {
- rc = -1;
- goto exit;
- }
- goto exit;
+ nread = -1;
+ goto fail;
}
- if (!fruit_fsp_recheck(ad, fsp)) {
- rc = -1;
- goto exit;
+ p = ad_get_entry(ad, ADEID_FINDERI);
+ if (p == NULL) {
+ DBG_ERR("No ADEID_FINDERI for [%s]\n", fsp_str_dbg(fsp));
+ nread = -1;
+ goto fail;
}
- if (ad->ad_type == ADOUBLE_META) {
- char afpinfo_buf[AFP_INFO_SIZE];
- size_t to_return;
+ memcpy(&ai->afpi_FinderInfo[0], p, ADEDLEN_FINDERI);
- /*
- * OS X has a off-by-1 error in the offset calculation, so we're
- * bug compatible here. It won't hurt, as any relevant real
- * world read requests from the AFP_AfpInfo stream will be
- * offset=0 n=60. offset is ignored anyway, see below.
- */
- if ((offset < 0) || (offset >= AFP_INFO_SIZE + 1)) {
- len = 0;
- rc = 0;
- goto exit;
- }
+ nread = afpinfo_pack(ai, afpinfo_buf);
+ if (nread != AFP_INFO_SIZE) {
+ nread = -1;
+ goto fail;
+ }
- to_return = MIN(n, AFP_INFO_SIZE);
+ memcpy(data, afpinfo_buf, n);
+ nread = n;
- ai = afpinfo_new(talloc_tos());
- if (ai == NULL) {
- rc = -1;
- goto exit;
- }
+fail:
+ TALLOC_FREE(ai);
+ return nread;
+}
- len = ad_read(ad, fsp->base_fsp->fsp_name->base_name);
- if (len == -1) {
- rc = -1;
- goto exit;
- }
+static ssize_t fruit_pread_meta(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nread;
+ ssize_t to_return;
- memcpy(&ai->afpi_FinderInfo[0],
- ad_entry(ad, ADEID_FINDERI),
- ADEDLEN_FINDERI);
- len = afpinfo_pack(ai, afpinfo_buf);
- if (len != AFP_INFO_SIZE) {
- rc = -1;
- goto exit;
- }
+ /*
+ * OS X has a off-by-1 error in the offset calculation, so we're
+ * bug compatible here. It won't hurt, as any relevant real
+ * world read requests from the AFP_AfpInfo stream will be
+ * offset=0 n=60. offset is ignored anyway, see below.
+ */
+ if ((offset < 0) || (offset >= AFP_INFO_SIZE + 1)) {
+ return 0;
+ }
- /*
- * OS X ignores offset when reading from AFP_AfpInfo stream!
- */
- memcpy(data, afpinfo_buf, to_return);
- len = to_return;
- } else {
- len = SMB_VFS_NEXT_PREAD(
- handle, fsp, data, n,
- offset + ad_getentryoff(ad, ADEID_RFORK));
- if (len == -1) {
- rc = -1;
- goto exit;
- }
+ /* Yes, macOS always reads from offset 0 */
+ offset = 0;
+ to_return = MIN(n, AFP_INFO_SIZE);
+
+ switch (fio->config->meta) {
+ case FRUIT_META_STREAM:
+ nread = fruit_pread_meta_stream(handle, fsp, data,
+ to_return, offset);
+ break;
+
+ case FRUIT_META_NETATALK:
+ nread = fruit_pread_meta_adouble(handle, fsp, data,
+ to_return, offset);
+ break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", fio->config->meta);
+ return -1;
}
-exit:
- fsp->base_fsp->fsp_name->base_name = tmp_base_name;
- TALLOC_FREE(name);
- TALLOC_FREE(ai);
- if (rc != 0) {
- len = -1;
+
+ return nread;
+}
+
+static ssize_t fruit_pread_rsrc_stream(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+}
+
+static ssize_t fruit_pread_rsrc_xattr(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+}
+
+static ssize_t fruit_pread_rsrc_adouble(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ struct adouble *ad = NULL;
+ ssize_t nread;
+
+ ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_RSRC);
+ if (ad == NULL) {
+ return -1;
}
- DEBUG(10, ("fruit_pread: rc=%d, len=%zd\n", rc, len));
- return len;
+
+ nread = SMB_VFS_NEXT_PREAD(handle, fsp, data, n,
+ offset + ad_getentryoff(ad, ADEID_RFORK));
+
+ TALLOC_FREE(ad);
+ return nread;
}
-static ssize_t fruit_pwrite(vfs_handle_struct *handle,
- files_struct *fsp, const void *data,
- size_t n, off_t offset)
+static ssize_t fruit_pread_rsrc(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nread;
+
+ switch (fio->config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ nread = fruit_pread_rsrc_stream(handle, fsp, data, n, offset);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ nread = fruit_pread_rsrc_adouble(handle, fsp, data, n, offset);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ nread = fruit_pread_rsrc_xattr(handle, fsp, data, n, offset);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", fio->config->rsrc);
+ return -1;
+ }
+
+ return nread;
+}
+
+static ssize_t fruit_pread(vfs_handle_struct *handle,
+ files_struct *fsp, void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nread;
+
+ DBG_DEBUG("Path [%s] offset=%zd, size=%zd\n",
+ fsp_str_dbg(fsp), offset, n);
+
+ if (fio == NULL) {
+ return SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
+ }
+
+ if (fio->type == ADOUBLE_META) {
+ nread = fruit_pread_meta(handle, fsp, data, n, offset);
+ } else {
+ nread = fruit_pread_rsrc(handle, fsp, data, n, offset);
+ }
+
+ DBG_DEBUG("Path [%s] nread [%zd]\n", fsp_str_dbg(fsp), nread);
+ return nread;
+}
+
+static ssize_t fruit_pwrite_meta_stream(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
{
- int rc = 0;
- struct adouble *ad = (struct adouble *)VFS_FETCH_FSP_EXTENSION(
- handle, fsp);
- struct fruit_config_data *config = NULL;
AfpInfo *ai = NULL;
- ssize_t len;
- char *name = NULL;
- char *tmp_base_name = NULL;
- NTSTATUS status;
+ int ret;
- DEBUG(10, ("fruit_pwrite: offset=%d, size=%d\n", (int)offset, (int)n));
+ ai = afpinfo_unpack(talloc_tos(), data);
+ if (ai == NULL) {
+ return -1;
+ }
- if (!fsp->base_fsp) {
- return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+ if (ai_empty_finderinfo(ai)) {
+ ret = SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name);
+ if (ret != 0 && errno != ENOENT && errno != ENOATTR) {
+ DBG_ERR("Can't delete metadata for %s: %s\n",
+ fsp_str_dbg(fsp), strerror(errno));
+ TALLOC_FREE(ai);
+ return -1;
+ }
+
+ return n;
}
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+ return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+}
- tmp_base_name = fsp->base_fsp->fsp_name->base_name;
- status = SMB_VFS_TRANSLATE_NAME(handle->conn,
- fsp->base_fsp->fsp_name->base_name,
- vfs_translate_to_unix,
- talloc_tos(), &name);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- name = talloc_strdup(talloc_tos(), tmp_base_name);
- if (name == NULL) {
- rc = -1;
- goto exit;
+static ssize_t fruit_pwrite_meta_netatalk(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct adouble *ad = NULL;
+ AfpInfo *ai = NULL;
+ char *p = NULL;
+ int ret;
+
+ ai = afpinfo_unpack(talloc_tos(), data);
+ if (ai == NULL) {
+ return -1;
+ }
+
+ if (ai_empty_finderinfo(ai)) {
+ ret = SMB_VFS_REMOVEXATTR(handle->conn,
+ fsp->fsp_name->base_name,
+ AFPINFO_EA_NETATALK);
+
+ if (ret != 0 && errno != ENOENT && errno != ENOATTR) {
+ DBG_ERR("Can't delete metadata for %s: %s\n",
+ fsp_str_dbg(fsp), strerror(errno));
+ return -1;
}
- } else if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- rc = -1;
- goto exit;
+
+ return n;
}
- fsp->base_fsp->fsp_name->base_name = name;
+ ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_META);
if (ad == NULL) {
- len = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
- if (len != n) {
- rc = -1;
- goto exit;
+ ad = ad_init(talloc_tos(), handle, ADOUBLE_META);
+ if (ad == NULL) {
+ return -1;
}
- goto exit;
+ }
+ p = ad_get_entry(ad, ADEID_FINDERI);
+ if (p == NULL) {
+ DBG_ERR("No ADEID_FINDERI for [%s]\n", fsp_str_dbg(fsp));
+ TALLOC_FREE(ad);
+ return -1;
}
- if (!fruit_fsp_recheck(ad, fsp)) {
- rc = -1;
- goto exit;
+ memcpy(p, &ai->afpi_FinderInfo[0], ADEDLEN_FINDERI);
+
+ ret = ad_fset(ad, fsp);
+ if (ret != 0) {
+ DBG_ERR("ad_pwrite [%s] failed\n", fsp_str_dbg(fsp));
+ TALLOC_FREE(ad);
+ return -1;
}
- if (ad->ad_type == ADOUBLE_META) {
- if (n != AFP_INFO_SIZE || offset != 0) {
- DEBUG(1, ("unexpected offset=%jd or size=%jd\n",
- (intmax_t)offset, (intmax_t)n));
- rc = -1;
- goto exit;
- }
- ai = afpinfo_unpack(talloc_tos(), data);
- if (ai == NULL) {
- rc = -1;
- goto exit;
- }
- memcpy(ad_entry(ad, ADEID_FINDERI),
- &ai->afpi_FinderInfo[0], ADEDLEN_FINDERI);
- if (empty_finderinfo(ad)) {
- /* Discard metadata */
- if (config->meta == FRUIT_META_STREAM) {
- rc = SMB_VFS_FTRUNCATE(fsp, 0);
- } else {
- rc = SMB_VFS_REMOVEXATTR(handle->conn,
- fsp->fsp_name->base_name,
- AFPINFO_EA_NETATALK);
- }
- if (rc != 0 && errno != ENOENT && errno != ENOATTR) {
- DBG_WARNING("Can't delete metadata for %s: %s\n",
- fsp->fsp_name->base_name, strerror(errno));
- goto exit;
- }
- rc = 0;
- goto exit;
- }
- rc = ad_write(ad, name);
- } else {
- len = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n,
- offset + ad_getentryoff(ad, ADEID_RFORK));
- if (len != n) {
- rc = -1;
- goto exit;
- }
+ TALLOC_FREE(ad);
+ return n;
+}
- if (config->rsrc == FRUIT_RSRC_ADFILE) {
- rc = ad_read(ad, name);
- if (rc == -1) {
- goto exit;
- }
- rc = 0;
+static ssize_t fruit_pwrite_meta(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nwritten;
- if ((len + offset) > ad_getentrylen(ad, ADEID_RFORK)) {
- ad_setentrylen(ad, ADEID_RFORK, len + offset);
- rc = ad_write(ad, name);
- }
- }
+ /*
+ * Writing an all 0 blob to the metadata stream
+ * results in the stream being removed on a macOS
+ * server. This ensures we behave the same and it
+ * verified by the "delete AFP_AfpInfo by writing all
+ * 0" test.
+ */
+ if (n != AFP_INFO_SIZE || offset != 0) {
+ DBG_ERR("unexpected offset=%jd or size=%jd\n",
+ (intmax_t)offset, (intmax_t)n);
+ return -1;
}
-exit:
- fsp->base_fsp->fsp_name->base_name = tmp_base_name;
- TALLOC_FREE(name);
- TALLOC_FREE(ai);
- if (rc != 0) {
+ switch (fio->config->meta) {
+ case FRUIT_META_STREAM:
+ nwritten = fruit_pwrite_meta_stream(handle, fsp, data,
+ n, offset);
+ break;
+
+ case FRUIT_META_NETATALK:
+ nwritten = fruit_pwrite_meta_netatalk(handle, fsp, data,
+ n, offset);
+ break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", fio->config->meta);
+ return -1;
+ }
+
+ return nwritten;
+}
+
+static ssize_t fruit_pwrite_rsrc_stream(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+}
+
+static ssize_t fruit_pwrite_rsrc_xattr(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+}
+
+static ssize_t fruit_pwrite_rsrc_adouble(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct adouble *ad = NULL;
+ ssize_t nwritten;
+ int ret;
+
+ ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_RSRC);
+ if (ad == NULL) {
+ DBG_ERR("ad_get [%s] failed\n", fsp_str_dbg(fsp));
+ return -1;
+ }
+
+ nwritten = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n,
+ offset + ad_getentryoff(ad, ADEID_RFORK));
+ if (nwritten != n) {
+ DBG_ERR("Short write on [%s] [%zd/%zd]\n",
+ fsp_str_dbg(fsp), nwritten, n);
+ TALLOC_FREE(ad);
return -1;
}
+
+ if ((n + offset) > ad_getentrylen(ad, ADEID_RFORK)) {
+ ad_setentrylen(ad, ADEID_RFORK, n + offset);
+ ret = ad_fset(ad, fsp);
+ if (ret != 0) {
+ DBG_ERR("ad_pwrite [%s] failed\n", fsp_str_dbg(fsp));
+ TALLOC_FREE(ad);
+ return -1;
+ }
+ }
+
+ TALLOC_FREE(ad);
return n;
}
+static ssize_t fruit_pwrite_rsrc(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nwritten;
+
+ switch (fio->config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ nwritten = fruit_pwrite_rsrc_stream(handle, fsp, data, n, offset);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ nwritten = fruit_pwrite_rsrc_adouble(handle, fsp, data, n, offset);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ nwritten = fruit_pwrite_rsrc_xattr(handle, fsp, data, n, offset);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", fio->config->rsrc);
+ return -1;
+ }
+
+ return nwritten;
+}
+
+static ssize_t fruit_pwrite(vfs_handle_struct *handle,
+ files_struct *fsp, const void *data,
+ size_t n, off_t offset)
+{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ ssize_t nwritten;
+
+ DBG_DEBUG("Path [%s] offset=%zd, size=%zd\n",
+ fsp_str_dbg(fsp), offset, n);
+
+ if (fio == NULL) {
+ return SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
+ }
+
+ if (fio->type == ADOUBLE_META) {
+ nwritten = fruit_pwrite_meta(handle, fsp, data, n, offset);
+ } else {
+ nwritten = fruit_pwrite_rsrc(handle, fsp, data, n, offset);
+ }
+
+ DBG_DEBUG("Path [%s] nwritten=%zd\n", fsp_str_dbg(fsp), nwritten);
+ return nwritten;
+}
+
/**
* Helper to stat/lstat the base file of an smb_fname.
*/
@@ -2922,9 +3950,24 @@
return rc;
}
-static int fruit_stat_meta(vfs_handle_struct *handle,
- struct smb_filename *smb_fname,
- bool follow_links)
+static int fruit_stat_meta_stream(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
+{
+ int ret;
+
+ if (follow_links) {
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ } else {
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+ }
+
+ return ret;
+}
+
+static int fruit_stat_meta_netatalk(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
{
struct adouble *ad = NULL;
@@ -2947,15 +3990,39 @@
return 0;
}
-static int fruit_stat_rsrc(vfs_handle_struct *handle,
+static int fruit_stat_meta(vfs_handle_struct *handle,
struct smb_filename *smb_fname,
bool follow_links)
+{
+ struct fruit_config_data *config = NULL;
+ int ret;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ switch (config->meta) {
+ case FRUIT_META_STREAM:
+ ret = fruit_stat_meta_stream(handle, smb_fname, follow_links);
+ break;
+
+ case FRUIT_META_NETATALK:
+ ret = fruit_stat_meta_netatalk(handle, smb_fname, follow_links);
+ break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", config->meta);
+ return -1;
+ }
+
+ return ret;
+}
+static int fruit_stat_rsrc_netatalk(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
{
struct adouble *ad = NULL;
-
- DEBUG(10, ("fruit_stat_rsrc called for %s\n",
- smb_fname_str_dbg(smb_fname)));
+ int ret;
ad = ad_get(talloc_tos(), handle, smb_fname->base_name, ADOUBLE_RSRC);
if (ad == NULL) {
@@ -2964,7 +4031,8 @@
}
/* Populate the stat struct with info from the base file. */
- if (fruit_stat_base(handle, smb_fname, follow_links) == -1) {
+ ret = fruit_stat_base(handle, smb_fname, follow_links);
+ if (ret != 0) {
TALLOC_FREE(ad);
return -1;
}
@@ -2976,6 +4044,96 @@
return 0;
}
+static int fruit_stat_rsrc_stream(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
+{
+ int ret;
+
+ if (follow_links) {
+ ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
+ } else {
+ ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
+ }
+
+ return ret;
+}
+
+static int fruit_stat_rsrc_xattr(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
+{
+#ifdef HAVE_ATTROPEN
+ int ret;
+ int fd = -1;
+
+ /* Populate the stat struct with info from the base file. */
+ ret = fruit_stat_base(handle, smb_fname, follow_links);
+ if (ret != 0) {
+ return -1;
+ }
+
+ fd = attropen(smb_fname->base_name,
+ AFPRESOURCE_EA_NETATALK,
+ O_RDONLY);
+ if (fd == -1) {
+ return 0;
+ }
+
+ ret = sys_fstat(fd, &smb_fname->st, false);
+ if (ret != 0) {
+ close(fd);
+ DBG_ERR("fstat [%s:%s] failed\n", smb_fname->base_name,
+ AFPRESOURCE_EA_NETATALK);
+ return -1;
+ }
+ close(fd);
+ fd = -1;
+
+ smb_fname->st.st_ex_ino = fruit_inode(&smb_fname->st,
+ smb_fname->stream_name);
+
+ return ret;
+
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int fruit_stat_rsrc(vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ bool follow_links)
+{
+ struct fruit_config_data *config = NULL;
+ int ret;
+
+ DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct fruit_config_data, return -1);
+
+ switch (config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ ret = fruit_stat_rsrc_stream(handle, smb_fname, follow_links);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ ret = fruit_stat_rsrc_xattr(handle, smb_fname, follow_links);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ ret = fruit_stat_rsrc_netatalk(handle, smb_fname, follow_links);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", config->rsrc);
+ return -1;
+ }
+
+ return ret;
+}
+
static int fruit_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
@@ -3053,17 +4211,24 @@
return rc;
}
-static int fruit_fstat_meta(vfs_handle_struct *handle,
- files_struct *fsp,
- SMB_STRUCT_STAT *sbuf)
+static int fruit_fstat_meta_stream(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+}
+
+static int fruit_fstat_meta_netatalk(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
{
- DEBUG(10, ("fruit_fstat_meta called for %s\n",
- smb_fname_str_dbg(fsp->base_fsp->fsp_name)));
+ int ret;
- /* Populate the stat struct with info from the base file. */
- if (fruit_stat_base(handle, fsp->base_fsp->fsp_name, false) == -1) {
+ ret = fruit_stat_base(handle, fsp->base_fsp->fsp_name, false);
+ if (ret != 0) {
return -1;
}
+
*sbuf = fsp->base_fsp->fsp_name->st;
sbuf->st_ex_size = AFP_INFO_SIZE;
sbuf->st_ex_ino = fruit_inode(sbuf, fsp->fsp_name->stream_name);
@@ -3071,113 +4236,418 @@
return 0;
}
-static int fruit_fstat_rsrc(vfs_handle_struct *handle, files_struct *fsp,
- SMB_STRUCT_STAT *sbuf)
+static int fruit_fstat_meta(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf,
+ struct fio *fio)
{
- struct fruit_config_data *config;
- struct adouble *ad = (struct adouble *)VFS_FETCH_FSP_EXTENSION(
- handle, fsp);
+ int ret;
- DEBUG(10, ("fruit_fstat_rsrc called for %s\n",
- smb_fname_str_dbg(fsp->base_fsp->fsp_name)));
+ DBG_DEBUG("Path [%s]\n", fsp_str_dbg(fsp));
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+ switch (fio->config->meta) {
+ case FRUIT_META_STREAM:
+ ret = fruit_fstat_meta_stream(handle, fsp, sbuf);
+ break;
- if (config->rsrc == FRUIT_RSRC_STREAM) {
- return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+ case FRUIT_META_NETATALK:
+ ret = fruit_fstat_meta_netatalk(handle, fsp, sbuf);
+ break;
+
+ default:
+ DBG_ERR("Unexpected meta config [%d]\n", fio->config->meta);
+ return -1;
}
+ DBG_DEBUG("Path [%s] ret [%d]\n", fsp_str_dbg(fsp), ret);
+ return ret;
+}
+
+static int fruit_fstat_rsrc_xattr(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+}
+
+static int fruit_fstat_rsrc_stream(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+}
+
+static int fruit_fstat_rsrc_adouble(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf)
+{
+ struct adouble *ad = NULL;
+ int ret;
+
/* Populate the stat struct with info from the base file. */
- if (fruit_stat_base(handle, fsp->base_fsp->fsp_name, false) == -1) {
+ ret = fruit_stat_base(handle, fsp->base_fsp->fsp_name, false);
+ if (ret == -1) {
+ return -1;
+ }
+
+ ad = ad_get(talloc_tos(), handle,
+ fsp->base_fsp->fsp_name->base_name,
+ ADOUBLE_RSRC);
+ if (ad == NULL) {
+ DBG_ERR("ad_get [%s] failed [%s]\n",
+ fsp_str_dbg(fsp), strerror(errno));
return -1;
}
+
*sbuf = fsp->base_fsp->fsp_name->st;
sbuf->st_ex_size = ad_getentrylen(ad, ADEID_RFORK);
sbuf->st_ex_ino = fruit_inode(sbuf, fsp->fsp_name->stream_name);
- DEBUG(10, ("fruit_fstat_rsrc %s, size: %zd\n",
- smb_fname_str_dbg(fsp->fsp_name),
- (ssize_t)sbuf->st_ex_size));
-
+ TALLOC_FREE(ad);
return 0;
}
+static int fruit_fstat_rsrc(vfs_handle_struct *handle, files_struct *fsp,
+ SMB_STRUCT_STAT *sbuf, struct fio *fio)
+{
+ int ret;
+
+ switch (fio->config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ ret = fruit_fstat_rsrc_stream(handle, fsp, sbuf);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ ret = fruit_fstat_rsrc_adouble(handle, fsp, sbuf);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ ret = fruit_fstat_rsrc_xattr(handle, fsp, sbuf);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", fio->config->rsrc);
+ return -1;
+ }
+
+ return ret;
+}
+
static int fruit_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
{
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
int rc;
- char *name = NULL;
- char *tmp_base_name = NULL;
- NTSTATUS status;
- struct adouble *ad = (struct adouble *)
- VFS_FETCH_FSP_EXTENSION(handle, fsp);
- DEBUG(10, ("fruit_fstat called for %s\n",
- smb_fname_str_dbg(fsp->fsp_name)));
+ if (fio == NULL) {
+ return SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
+ }
- if (fsp->base_fsp) {
- tmp_base_name = fsp->base_fsp->fsp_name->base_name;
- /* fsp_name is not converted with vfs_catia */
- status = SMB_VFS_TRANSLATE_NAME(
- handle->conn,
- fsp->base_fsp->fsp_name->base_name,
- vfs_translate_to_unix,
- talloc_tos(), &name);
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
- name = talloc_strdup(talloc_tos(), tmp_base_name);
- if (name == NULL) {
- rc = -1;
- goto exit;
- }
- } else if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- rc = -1;
- goto exit;
+ DBG_DEBUG("Path [%s]\n", fsp_str_dbg(fsp));
+
+ if (fio->type == ADOUBLE_META) {
+ rc = fruit_fstat_meta(handle, fsp, sbuf, fio);
+ } else {
+ rc = fruit_fstat_rsrc(handle, fsp, sbuf, fio);
+ }
+
+ if (rc == 0) {
+ sbuf->st_ex_mode &= ~S_IFMT;
+ sbuf->st_ex_mode |= S_IFREG;
+ sbuf->st_ex_blocks = sbuf->st_ex_size / STAT_ST_BLOCKSIZE + 1;
+ }
+
+ DBG_DEBUG("Path [%s] rc [%d] size [%zd]\n",
+ fsp_str_dbg(fsp), rc, sbuf->st_ex_size);
+ return rc;
+}
+
+static NTSTATUS fruit_streaminfo_meta_stream(
+ vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ struct stream_struct *stream = *pstreams;
+ unsigned int num_streams = *pnum_streams;
+ struct smb_filename *sname = NULL;
+ int i;
+ int ret;
+ bool ok;
+
+ for (i = 0; i < num_streams; i++) {
+ if (strequal_m(stream[i].name, AFPINFO_STREAM)) {
+ break;
}
- fsp->base_fsp->fsp_name->base_name = name;
}
- if (ad == NULL || fsp->base_fsp == NULL) {
- rc = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- goto exit;
+ if (i == num_streams) {
+ return NT_STATUS_OK;
}
- if (!fruit_fsp_recheck(ad, fsp)) {
- rc = -1;
- goto exit;
+ if (stream[i].size == AFP_INFO_SIZE) {
+ return NT_STATUS_OK;
}
- switch (ad->ad_type) {
- case ADOUBLE_META:
- rc = fruit_fstat_meta(handle, fsp, sbuf);
+ DBG_ERR("Removing invalid AFPINFO_STREAM size [%zd] from [%s]\n",
+ stream[i].size, smb_fname_str_dbg(smb_fname));
+
+ ok = del_fruit_stream(mem_ctx, pnum_streams, pstreams, AFPINFO_STREAM);
+ if (!ok) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ sname = synthetic_smb_fname(talloc_tos(),
+ smb_fname->base_name,
+ AFPINFO_STREAM_NAME,
+ NULL, 0);
+ if (sname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ret = SMB_VFS_NEXT_UNLINK(handle, sname);
+ TALLOC_FREE(sname);
+ if (ret != 0) {
+ DBG_ERR("Removing [%s] failed\n", smb_fname_str_dbg(sname));
+ return map_nt_error_from_unix(errno);
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS fruit_streaminfo_meta_netatalk(
+ vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ struct stream_struct *stream = *pstreams;
+ unsigned int num_streams = *pnum_streams;
+ struct adouble *ad = NULL;
+ bool is_fi_empty;
+ int i;
+ bool ok;
+
+ /* Remove the Netatalk xattr from the list */
+ ok = del_fruit_stream(mem_ctx, pnum_streams, pstreams,
+ ":" NETATALK_META_XATTR ":$DATA");
+ if (!ok) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /*
+ * Check if there's a AFPINFO_STREAM from the VFS streams
+ * backend and if yes, remove it from the list
+ */
+ for (i = 0; i < num_streams; i++) {
+ if (strequal_m(stream[i].name, AFPINFO_STREAM)) {
+ break;
+ }
+ }
+
+ if (i < num_streams) {
+ DBG_WARNING("Unexpected AFPINFO_STREAM on [%s]\n",
+ smb_fname_str_dbg(smb_fname));
+
+ ok = del_fruit_stream(mem_ctx, pnum_streams, pstreams,
+ AFPINFO_STREAM);
+ if (!ok) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ }
+
+ ad = ad_get(talloc_tos(), handle,
+ smb_fname->base_name, ADOUBLE_META);
+ if (ad == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ is_fi_empty = ad_empty_finderinfo(ad);
+ TALLOC_FREE(ad);
+
+ if (is_fi_empty) {
+ return NT_STATUS_OK;
+ }
+
+ ok = add_fruit_stream(mem_ctx, pnum_streams, pstreams,
+ AFPINFO_STREAM_NAME, AFP_INFO_SIZE,
+ smb_roundup(handle->conn, AFP_INFO_SIZE));
+ if (!ok) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS fruit_streaminfo_meta(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ struct fruit_config_data *config = NULL;
+ NTSTATUS status;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
+ return NT_STATUS_INTERNAL_ERROR);
+
+ switch (config->meta) {
+ case FRUIT_META_NETATALK:
+ status = fruit_streaminfo_meta_netatalk(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams,
+ pstreams);
break;
- case ADOUBLE_RSRC:
- rc = fruit_fstat_rsrc(handle, fsp, sbuf);
+
+ case FRUIT_META_STREAM:
+ status = fruit_streaminfo_meta_stream(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams,
+ pstreams);
break;
+
default:
- DEBUG(10, ("fruit_fstat %s: bad type\n",
- smb_fname_str_dbg(fsp->fsp_name)));
- rc = -1;
- goto exit;
+ return NT_STATUS_INTERNAL_ERROR;
}
- if (rc == 0) {
- sbuf->st_ex_mode &= ~S_IFMT;
- sbuf->st_ex_mode |= S_IFREG;
- sbuf->st_ex_blocks = sbuf->st_ex_size / STAT_ST_BLOCKSIZE + 1;
+ return status;
+}
+
+static NTSTATUS fruit_streaminfo_rsrc_stream(
+ vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ bool ok;
+
+ ok = filter_empty_rsrc_stream(pnum_streams, pstreams);
+ if (!ok) {
+ DBG_ERR("Filtering resource stream failed\n");
+ return NT_STATUS_INTERNAL_ERROR;
}
+ return NT_STATUS_OK;
+}
-exit:
- DEBUG(10, ("fruit_fstat %s, size: %zd\n",
- smb_fname_str_dbg(fsp->fsp_name),
- (ssize_t)sbuf->st_ex_size));
- if (tmp_base_name) {
- fsp->base_fsp->fsp_name->base_name = tmp_base_name;
+static NTSTATUS fruit_streaminfo_rsrc_xattr(
+ vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ bool ok;
+
+ ok = filter_empty_rsrc_stream(pnum_streams, pstreams);
+ if (!ok) {
+ DBG_ERR("Filtering resource stream failed\n");
+ return NT_STATUS_INTERNAL_ERROR;
}
- TALLOC_FREE(name);
- return rc;
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS fruit_streaminfo_rsrc_adouble(
+ vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ struct stream_struct *stream = *pstreams;
+ unsigned int num_streams = *pnum_streams;
+ struct adouble *ad = NULL;
+ bool ok;
+ size_t rlen;
+ int i;
+
+ /*
+ * Check if there's a AFPRESOURCE_STREAM from the VFS streams backend
+ * and if yes, remove it from the list
+ */
+ for (i = 0; i < num_streams; i++) {
+ if (strequal_m(stream[i].name, AFPRESOURCE_STREAM)) {
+ break;
+ }
+ }
+
+ if (i < num_streams) {
+ DBG_WARNING("Unexpected AFPRESOURCE_STREAM on [%s]\n",
+ smb_fname_str_dbg(smb_fname));
+
+ ok = del_fruit_stream(mem_ctx, pnum_streams, pstreams,
+ AFPRESOURCE_STREAM);
+ if (!ok) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ }
+
+ ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
+ ADOUBLE_RSRC);
+ if (ad == NULL) {
+ return NT_STATUS_OK;
+ }
+
+ rlen = ad_getentrylen(ad, ADEID_RFORK);
+ TALLOC_FREE(ad);
+
+ if (rlen == 0) {
+ return NT_STATUS_OK;
+ }
+
+ ok = add_fruit_stream(mem_ctx, pnum_streams, pstreams,
+ AFPRESOURCE_STREAM_NAME, rlen,
+ smb_roundup(handle->conn, rlen));
+ if (!ok) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS fruit_streaminfo_rsrc(vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ const struct smb_filename *smb_fname,
+ TALLOC_CTX *mem_ctx,
+ unsigned int *pnum_streams,
+ struct stream_struct **pstreams)
+{
+ struct fruit_config_data *config = NULL;
+ NTSTATUS status;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
+ return NT_STATUS_INTERNAL_ERROR);
+
+ switch (config->rsrc) {
+ case FRUIT_RSRC_STREAM:
+ status = fruit_streaminfo_rsrc_stream(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams,
+ pstreams);
+ break;
+
+ case FRUIT_RSRC_XATTR:
+ status = fruit_streaminfo_rsrc_xattr(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams,
+ pstreams);
+ break;
+
+ case FRUIT_RSRC_ADFILE:
+ status = fruit_streaminfo_rsrc_adouble(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams,
+ pstreams);
+ break;
+
+ default:
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ return status;
}
static NTSTATUS fruit_streaminfo(vfs_handle_struct *handle,
@@ -3188,46 +4658,12 @@
struct stream_struct **pstreams)
{
struct fruit_config_data *config = NULL;
- struct adouble *ad = NULL;
NTSTATUS status;
SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
return NT_STATUS_UNSUCCESSFUL);
- DEBUG(10, ("fruit_streaminfo called for %s\n", smb_fname->base_name));
-
- if (config->meta == FRUIT_META_NETATALK) {
- ad = ad_get(talloc_tos(), handle,
- smb_fname->base_name, ADOUBLE_META);
- if (ad && !empty_finderinfo(ad)) {
- if (!add_fruit_stream(
- mem_ctx, pnum_streams, pstreams,
- AFPINFO_STREAM_NAME, AFP_INFO_SIZE,
- smb_roundup(handle->conn,
- AFP_INFO_SIZE))) {
- TALLOC_FREE(ad);
- return NT_STATUS_NO_MEMORY;
- }
- }
- TALLOC_FREE(ad);
- }
- if (config->rsrc != FRUIT_RSRC_STREAM) {
- ad = ad_get(talloc_tos(), handle, smb_fname->base_name,
- ADOUBLE_RSRC);
- if (ad && (ad_getentrylen(ad, ADEID_RFORK) > 0)) {
- if (!add_fruit_stream(
- mem_ctx, pnum_streams, pstreams,
- AFPRESOURCE_STREAM_NAME,
- ad_getentrylen(ad, ADEID_RFORK),
- smb_roundup(handle->conn,
- ad_getentrylen(
- ad, ADEID_RFORK)))) {
- TALLOC_FREE(ad);
- return NT_STATUS_NO_MEMORY;
- }
- }
- TALLOC_FREE(ad);
- }
+ DBG_DEBUG("Path [%s]\n", smb_fname_str_dbg(smb_fname));
status = SMB_VFS_NEXT_STREAMINFO(handle, fsp, smb_fname, mem_ctx,
pnum_streams, pstreams);
@@ -3235,13 +4671,16 @@
return status;
}
- if (config->meta == FRUIT_META_NETATALK) {
- /* Remove the Netatalk xattr from the list */
- if (!del_fruit_stream(mem_ctx, pnum_streams, pstreams,
- ":" NETATALK_META_XATTR ":$DATA")) {
- TALLOC_FREE(ad);
- return NT_STATUS_NO_MEMORY;
- }
+ status = fruit_streaminfo_meta(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams, pstreams);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = fruit_streaminfo_rsrc(handle, fsp, smb_fname,
+ mem_ctx, pnum_streams, pstreams);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
return NT_STATUS_OK;
@@ -3253,9 +4692,15 @@
{
int rc = 0;
struct adouble *ad = NULL;
+ struct fruit_config_data *config = NULL;
- if (null_timespec(ft->create_time)) {
- goto exit;
+ SMB_VFS_HANDLE_GET_DATA(handle, config, struct fruit_config_data,
+ return -1);
+
+ if ((config->meta != FRUIT_META_NETATALK) ||
+ null_timespec(ft->create_time))
+ {
+ return SMB_VFS_NEXT_NTIMES(handle, smb_fname, ft);
}
DEBUG(10,("set btime for %s to %s\n", smb_fname_str_dbg(smb_fname),
@@ -3269,7 +4714,7 @@
ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX,
convert_time_t_to_uint32_t(ft->create_time.tv_sec));
- rc = ad_write(ad, smb_fname->base_name);
+ rc = ad_set(ad, smb_fname->base_name);
exit:
@@ -3287,79 +4732,123 @@
off_t offset,
off_t len)
{
- struct adouble *ad =
- (struct adouble *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
- if (ad == NULL) {
+ if (fio == NULL) {
return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
}
- if (!fruit_fsp_recheck(ad, fsp)) {
- return -1;
- }
-
/* Let the pwrite code path handle it. */
errno = ENOSYS;
return -1;
}
-static int fruit_ftruncate_meta(struct vfs_handle_struct *handle,
- struct files_struct *fsp,
- off_t offset,
- struct adouble *ad)
+static int fruit_ftruncate_rsrc_xattr(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ off_t offset)
{
- struct fruit_config_data *config;
+ if (offset == 0) {
+ return SMB_VFS_FREMOVEXATTR(fsp, AFPRESOURCE_EA_NETATALK);
+ }
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+#ifdef HAVE_ATTROPEN
+ return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
+#endif
+ return 0;
+}
- if (offset > 60) {
- DBG_WARNING("ftruncate %s to %jd",
- fsp_str_dbg(fsp), (intmax_t)offset);
- /* OS X returns NT_STATUS_ALLOTTED_SPACE_EXCEEDED */
- errno = EOVERFLOW;
+static int fruit_ftruncate_rsrc_adouble(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ off_t offset)
+{
+ int rc;
+ struct adouble *ad = NULL;
+ off_t ad_off;
+
+ ad = ad_fget(talloc_tos(), handle, fsp, ADOUBLE_RSRC);
+ if (ad == NULL) {
+ DBG_DEBUG("ad_get [%s] failed [%s]\n",
+ fsp_str_dbg(fsp), strerror(errno));
return -1;
}
- DBG_WARNING("ignoring ftruncate %s to %jd",
- fsp_str_dbg(fsp), (intmax_t)offset);
- /* OS X returns success but does nothing */
+ ad_off = ad_getentryoff(ad, ADEID_RFORK);
+
+ rc = SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset + ad_off);
+ if (rc != 0) {
+ TALLOC_FREE(ad);
+ return -1;
+ }
+
+ ad_setentrylen(ad, ADEID_RFORK, offset);
+
+ rc = ad_fset(ad, fsp);
+ if (rc != 0) {
+ DBG_ERR("ad_fset [%s] failed [%s]\n",
+ fsp_str_dbg(fsp), strerror(errno));
+ TALLOC_FREE(ad);
+ return -1;
+ }
+
+ TALLOC_FREE(ad);
return 0;
}
+static int fruit_ftruncate_rsrc_stream(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ off_t offset)
+{
+ if (offset == 0) {
+ return SMB_VFS_NEXT_UNLINK(handle, fsp->fsp_name);
+ }
+
+ return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
+}
+
static int fruit_ftruncate_rsrc(struct vfs_handle_struct *handle,
struct files_struct *fsp,
- off_t offset,
- struct adouble *ad)
+ off_t offset)
{
- int rc;
- struct fruit_config_data *config;
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ int ret;
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct fruit_config_data, return -1);
+ switch (fio->config->rsrc) {
+ case FRUIT_RSRC_XATTR:
+ ret = fruit_ftruncate_rsrc_xattr(handle, fsp, offset);
+ break;
- if (config->rsrc == FRUIT_RSRC_XATTR && offset == 0) {
- return SMB_VFS_FREMOVEXATTR(fsp,
- AFPRESOURCE_EA_NETATALK);
- }
+ case FRUIT_RSRC_ADFILE:
+ ret = fruit_ftruncate_rsrc_adouble(handle, fsp, offset);
+ break;
- rc = SMB_VFS_NEXT_FTRUNCATE(
- handle, fsp,
- offset + ad_getentryoff(ad, ADEID_RFORK));
- if (rc != 0) {
+ case FRUIT_RSRC_STREAM:
+ ret = fruit_ftruncate_rsrc_stream(handle, fsp, offset);
+ break;
+
+ default:
+ DBG_ERR("Unexpected rsrc config [%d]\n", fio->config->rsrc);
return -1;
}
- if (config->rsrc == FRUIT_RSRC_ADFILE) {
- ad_setentrylen(ad, ADEID_RFORK, offset);
- rc = ad_write(ad, NULL);
- if (rc != 0) {
- return -1;
- }
- DEBUG(10, ("fruit_ftruncate_rsrc file %s offset %jd\n",
- fsp_str_dbg(fsp), (intmax_t)offset));
+
+ return ret;
+}
+
+static int fruit_ftruncate_meta(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ off_t offset)
+{
+ if (offset > 60) {
+ DBG_WARNING("ftruncate %s to %jd",
+ fsp_str_dbg(fsp), (intmax_t)offset);
+ /* OS X returns NT_STATUS_ALLOTTED_SPACE_EXCEEDED */
+ errno = EOVERFLOW;
+ return -1;
}
+ /* OS X returns success but does nothing */
+ DBG_INFO("ignoring ftruncate %s to %jd\n",
+ fsp_str_dbg(fsp), (intmax_t)offset);
return 0;
}
@@ -3367,35 +4856,23 @@
struct files_struct *fsp,
off_t offset)
{
- int rc = 0;
- struct adouble *ad =
- (struct adouble *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ struct fio *fio = (struct fio *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+ int ret;
- DBG_DEBUG("fruit_ftruncate called for file %s offset %.0f\n",
- fsp_str_dbg(fsp), (double)offset);
+ DBG_DEBUG("Path [%s] offset [%zd]\n", fsp_str_dbg(fsp), offset);
- if (ad == NULL) {
+ if (fio == NULL) {
return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
}
- if (!fruit_fsp_recheck(ad, fsp)) {
- return -1;
- }
-
- switch (ad->ad_type) {
- case ADOUBLE_META:
- rc = fruit_ftruncate_meta(handle, fsp, offset, ad);
- break;
-
- case ADOUBLE_RSRC:
- rc = fruit_ftruncate_rsrc(handle, fsp, offset, ad);
- break;
-
- default:
- return -1;
+ if (fio->type == ADOUBLE_META) {
+ ret = fruit_ftruncate_meta(handle, fsp, offset);
+ } else {
+ ret = fruit_ftruncate_rsrc(handle, fsp, offset);
}
- return rc;
+ DBG_DEBUG("Path [%s] result [%d]\n", fsp_str_dbg(fsp), ret);
+ return ret;
}
static NTSTATUS fruit_create_file(vfs_handle_struct *handle,
@@ -3445,7 +4922,7 @@
fsp = *result;
- if (config->nego_aapl) {
+ if (global_fruit_config.nego_aapl) {
if (config->copyfile_enabled) {
/*
* Set a flag in the fsp. Gets used in
@@ -3522,7 +4999,7 @@
struct fruit_config_data,
return NT_STATUS_UNSUCCESSFUL);
- if (!config->use_aapl) {
+ if (!global_fruit_config.nego_aapl) {
return SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data);
}
diff -Nru samba-4.5.5+dfsg/source3/modules/vfs_shadow_copy2.c samba-4.5.6+dfsg/source3/modules/vfs_shadow_copy2.c
--- samba-4.5.5+dfsg/source3/modules/vfs_shadow_copy2.c 2016-09-13 10:21:35.000000000 +0200
+++ samba-4.5.6+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-09 10:21:43.000000000 +0100
@@ -35,6 +35,7 @@
#include "system/filesys.h"
#include "include/ntioctl.h"
#include "util_tdb.h"
+#include "lib/util_path.h"
struct shadow_copy2_config {
char *gmt_format;
@@ -74,6 +75,11 @@
struct shadow_copy2_private {
struct shadow_copy2_config *config;
struct shadow_copy2_snaplist_info *snaps;
+ char *shadow_cwd; /* Absolute $cwd path. */
+ /* Absolute connectpath - can vary depending on $cwd. */
+ char *shadow_connectpath;
+ /* malloc'ed realpath return. */
+ char *shadow_realpath;
};
static int shadow_copy2_get_shadow_copy_data(
@@ -404,79 +410,254 @@
return result;
}
+static char *make_path_absolute(TALLOC_CTX *mem_ctx,
+ struct shadow_copy2_private *priv,
+ const char *name)
+{
+ char *newpath = NULL;
+ char *abs_path = NULL;
+
+ if (name[0] != '/') {
+ newpath = talloc_asprintf(mem_ctx,
+ "%s/%s",
+ priv->shadow_cwd,
+ name);
+ if (newpath == NULL) {
+ return NULL;
+ }
+ name = newpath;
+ }
+ abs_path = canonicalize_absolute_path(mem_ctx, name);
+ TALLOC_FREE(newpath);
+ return abs_path;
+}
+
+/* Return a $cwd-relative path. */
+static bool make_relative_path(const char *cwd, char *abs_path)
+{
+ size_t cwd_len = strlen(cwd);
+ size_t abs_len = strlen(abs_path);
+
+ if (abs_len < cwd_len) {
+ return false;
+ }
+ if (memcmp(abs_path, cwd, cwd_len) != 0) {
+ return false;
+ }
+ if (abs_path[cwd_len] != '/' && abs_path[cwd_len] != '\0') {
+ return false;
+ }
+ if (abs_path[cwd_len] == '/') {
+ cwd_len++;
+ }
+ memmove(abs_path, &abs_path[cwd_len], abs_len + 1 - cwd_len);
+ return true;
+}
+
+static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle,
+ const char *name,
+ char *gmt, size_t gmt_len);
+
+/*
+ * Check if an incoming filename is already a snapshot converted pathname.
+ *
+ * If so, it returns the pathname truncated at the snapshot point which
+ * will be used as the connectpath.
+ */
+
+static int check_for_converted_path(TALLOC_CTX *mem_ctx,
+ struct vfs_handle_struct *handle,
+ struct shadow_copy2_private *priv,
+ char *abs_path,
+ bool *ppath_already_converted,
+ char **pconnectpath)
+{
+ size_t snapdirlen = 0;
+ char *p = strstr_m(abs_path, priv->config->snapdir);
+ char *q = NULL;
+ char *connect_path = NULL;
+ char snapshot[GMT_NAME_LEN+1];
+
+ *ppath_already_converted = false;
+
+ if (p == NULL) {
+ /* Must at least contain shadow:snapdir. */
+ return 0;
+ }
+
+ if (priv->config->snapdir[0] == '/' &&
+ p != abs_path) {
+ /* Absolute shadow:snapdir must be at the start. */
+ return 0;
+ }
+
+ snapdirlen = strlen(priv->config->snapdir);
+ if (p[snapdirlen] != '/') {
+ /* shadow:snapdir must end as a separate component. */
+ return 0;
+ }
+
+ if (p > abs_path && p[-1] != '/') {
+ /* shadow:snapdir must start as a separate component. */
+ return 0;
+ }
+
+ p += snapdirlen;
+ p++; /* Move past the / */
+
+ /*
+ * Need to return up to the next path
+ * component after the time.
+ * This will be used as the connectpath.
+ */
+ q = strchr(p, '/');
+ if (q == NULL) {
+ /*
+ * No next path component.
+ * Use entire string.
+ */
+ connect_path = talloc_strdup(mem_ctx,
+ abs_path);
+ } else {
+ connect_path = talloc_strndup(mem_ctx,
+ abs_path,
+ q - abs_path);
+ }
+ if (connect_path == NULL) {
+ return ENOMEM;
+ }
+
+ /*
+ * Point p at the same offset in connect_path as
+ * it is in abs_path.
+ */
+
+ p = &connect_path[p - abs_path];
+
+ /*
+ * Now ensure there is a time string at p.
+ * The SMB-format @GMT-token string is returned
+ * in snapshot.
+ */
+
+ if (!shadow_copy2_snapshot_to_gmt(handle,
+ p,
+ snapshot,
+ sizeof(snapshot))) {
+ TALLOC_FREE(connect_path);
+ return 0;
+ }
+
+ if (pconnectpath != NULL) {
+ *pconnectpath = connect_path;
+ }
+
+ *ppath_already_converted = true;
+
+ DBG_DEBUG("path |%s| is already converted. "
+ "connect path = |%s|\n",
+ abs_path,
+ connect_path);
+
+ return 0;
+}
+
/**
- * Strip a snapshot component from a filename as
- * handed in via the smb layer.
- * Returns the parsed timestamp and the stripped filename.
+ * This function does two things.
+ *
+ * 1). Checks if an incoming filename is already a
+ * snapshot converted pathname.
+ * If so, it returns the pathname truncated
+ * at the snapshot point which will be used
+ * as the connectpath, and then does an early return.
+ *
+ * 2). Checks if an incoming filename contains an
+ * SMB-layer @GMT- style timestamp.
+ * If so, it strips the timestamp, and returns
+ * both the timestamp and the stripped path
+ * (making it cwd-relative).
*/
-static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
+
+static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx,
struct vfs_handle_struct *handle,
- const char *name,
+ const char *orig_name,
time_t *ptimestamp,
- char **pstripped)
+ char **pstripped,
+ char **psnappath)
{
struct tm tm;
- time_t timestamp;
+ time_t timestamp = 0;
const char *p;
char *q;
- char *stripped;
+ char *stripped = NULL;
size_t rest_len, dst_len;
struct shadow_copy2_private *priv;
- const char *snapdir;
- ssize_t snapdirlen;
ptrdiff_t len_before_gmt;
+ const char *name = orig_name;
+ char *abs_path = NULL;
+ bool ret = true;
+ bool already_converted = false;
+ int err = 0;
SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
return false);
DEBUG(10, (__location__ ": enter path '%s'\n", name));
+ abs_path = make_path_absolute(mem_ctx, priv, name);
+ if (abs_path == NULL) {
+ ret = false;
+ goto out;
+ }
+ name = abs_path;
+
+ DEBUG(10, (__location__ ": abs path '%s'\n", name));
+
+ err = check_for_converted_path(mem_ctx,
+ handle,
+ priv,
+ abs_path,
+ &already_converted,
+ psnappath);
+ if (err != 0) {
+ /* error in conversion. */
+ ret = false;
+ goto out;
+ }
+
+ if (already_converted) {
+ goto out;
+ }
+
+ /*
+ * From here we're only looking to strip an
+ * SMB-layer @GMT- token.
+ */
+
p = strstr_m(name, "@GMT-");
if (p == NULL) {
DEBUG(11, ("@GMT not found\n"));
- goto no_snapshot;
+ goto out;
}
if ((p > name) && (p[-1] != '/')) {
/* the GMT-token does not start a path-component */
DEBUG(10, ("not at start, p=%p, name=%p, p[-1]=%d\n",
p, name, (int)p[-1]));
- goto no_snapshot;
+ goto out;
}
- /*
- * Figure out whether we got an already converted string. One
- * case where this happens is in a smb2 create call with the
- * mxac create blob set. We do the get_acl call on
- * fsp->fsp_name, which is already converted. We are converted
- * if we got a file name of the form ".snapshots/@GMT-",
- * i.e. ".snapshots/" precedes "p".
- */
-
- snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir",
- ".snapshots");
- snapdirlen = strlen(snapdir);
len_before_gmt = p - name;
- if ((len_before_gmt >= (snapdirlen + 1)) && (p[-1] == '/')) {
- const char *parent_snapdir = p - (snapdirlen+1);
-
- DEBUG(10, ("parent_snapdir = %s\n", parent_snapdir));
-
- if (strncmp(parent_snapdir, snapdir, snapdirlen) == 0) {
- DEBUG(10, ("name=%s is already converted\n", name));
- goto no_snapshot;
- }
- }
q = strptime(p, GMT_FORMAT, &tm);
if (q == NULL) {
DEBUG(10, ("strptime failed\n"));
- goto no_snapshot;
+ goto out;
}
tm.tm_isdst = -1;
timestamp = timegm(&tm);
if (timestamp == (time_t)-1) {
DEBUG(10, ("timestamp==-1\n"));
- goto no_snapshot;
+ goto out;
}
if (q[0] == '\0') {
/*
@@ -496,12 +677,24 @@
stripped = talloc_strndup(mem_ctx, name,
len_before_gmt);
if (stripped == NULL) {
- return false;
+ ret = false;
+ goto out;
+ }
+ if (orig_name[0] != '/') {
+ if (make_relative_path(priv->shadow_cwd,
+ stripped) == false) {
+ DEBUG(10, (__location__ ": path '%s' "
+ "doesn't start with cwd '%s\n",
+ stripped, priv->shadow_cwd));
+ ret = false;
+ errno = ENOENT;
+ goto out;
+ }
}
*pstripped = stripped;
}
*ptimestamp = timestamp;
- return true;
+ goto out;
}
if (q[0] != '/') {
/*
@@ -509,75 +702,18 @@
* component continues after the gmt-token.
*/
DEBUG(10, ("q[0] = %d\n", (int)q[0]));
- goto no_snapshot;
+ goto out;
}
q += 1;
rest_len = strlen(q);
dst_len = len_before_gmt + rest_len;
- if (priv->config->snapdirseverywhere) {
- char *insert;
- bool have_insert;
- insert = shadow_copy2_insert_string(talloc_tos(), handle,
- timestamp);
- if (insert == NULL) {
- errno = ENOMEM;
- return false;
- }
-
- DEBUG(10, (__location__ ": snapdirseverywhere mode.\n"
- "path '%s'.\n"
- "insert string '%s'\n", name, insert));
-
- have_insert = (strstr(name, insert+1) != NULL);
- DEBUG(10, ("have_insert=%d, name=%s, insert+1=%s\n",
- (int)have_insert, name, insert+1));
- if (have_insert) {
- DEBUG(10, (__location__ ": insert string '%s' found in "
- "path '%s' found in snapdirseverywhere mode "
- "==> already converted\n", insert, name));
- TALLOC_FREE(insert);
- goto no_snapshot;
- }
- TALLOC_FREE(insert);
- } else {
- char *snapshot_path;
- char *s;
-
- snapshot_path = shadow_copy2_snapshot_path(talloc_tos(),
- handle,
- timestamp);
- if (snapshot_path == NULL) {
- errno = ENOMEM;
- return false;
- }
-
- DEBUG(10, (__location__ " path: '%s'.\n"
- "snapshot path: '%s'\n", name, snapshot_path));
-
- s = strstr(name, snapshot_path);
- if (s == name) {
- /*
- * this starts with "snapshot_basepath/GMT-Token"
- * so it is already a converted absolute
- * path. Don't process further.
- */
- DEBUG(10, (__location__ ": path '%s' starts with "
- "snapshot path '%s' (not in "
- "snapdirseverywhere mode) ==> "
- "already converted\n", name, snapshot_path));
- talloc_free(snapshot_path);
- goto no_snapshot;
- }
- talloc_free(snapshot_path);
- }
-
if (pstripped != NULL) {
stripped = talloc_array(mem_ctx, char, dst_len+1);
if (stripped == NULL) {
- errno = ENOMEM;
- return false;
+ ret = false;
+ goto out;
}
if (p > name) {
memcpy(stripped, name, len_before_gmt);
@@ -586,13 +722,39 @@
memcpy(stripped + len_before_gmt, q, rest_len);
}
stripped[dst_len] = '\0';
+ if (orig_name[0] != '/') {
+ if (make_relative_path(priv->shadow_cwd,
+ stripped) == false) {
+ DEBUG(10, (__location__ ": path '%s' "
+ "doesn't start with cwd '%s\n",
+ stripped, priv->shadow_cwd));
+ ret = false;
+ errno = ENOENT;
+ goto out;
+ }
+ }
*pstripped = stripped;
}
*ptimestamp = timestamp;
- return true;
-no_snapshot:
- *ptimestamp = 0;
- return true;
+ ret = true;
+
+ out:
+ TALLOC_FREE(abs_path);
+ return ret;
+}
+
+static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx,
+ struct vfs_handle_struct *handle,
+ const char *orig_name,
+ time_t *ptimestamp,
+ char **pstripped)
+{
+ return shadow_copy2_strip_snapshot_internal(mem_ctx,
+ handle,
+ orig_name,
+ ptimestamp,
+ pstripped,
+ NULL);
}
static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx,
@@ -646,7 +808,8 @@
char *insert = NULL;
char *converted = NULL;
size_t insertlen, connectlen = 0;
- int i, saved_errno;
+ int saved_errno = 0;
+ int i;
size_t min_offset;
struct shadow_copy2_config *config;
struct shadow_copy2_private *priv;
@@ -832,12 +995,16 @@
errno = ENOENT;
}
fail:
- saved_errno = errno;
+ if (result == NULL) {
+ saved_errno = errno;
+ }
TALLOC_FREE(converted);
TALLOC_FREE(insert);
TALLOC_FREE(slashes);
TALLOC_FREE(path);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return result;
}
@@ -893,10 +1060,10 @@
const char *mask,
uint32_t attr)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
DIR *ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
struct smb_filename *conv_smb_fname = NULL;
@@ -925,10 +1092,14 @@
return NULL;
}
ret = SMB_VFS_NEXT_OPENDIR(handle, conv_smb_fname, mask, attr);
- saved_errno = errno;
+ if (ret == NULL) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
TALLOC_FREE(conv_smb_fname);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -936,16 +1107,19 @@
const struct smb_filename *smb_fname_src,
const struct smb_filename *smb_fname_dst)
{
- time_t timestamp_src, timestamp_dst;
+ time_t timestamp_src = 0;
+ time_t timestamp_dst = 0;
+ char *snappath_src = NULL;
+ char *snappath_dst = NULL;
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle,
smb_fname_src->base_name,
- ×tamp_src, NULL)) {
+ ×tamp_src, NULL, &snappath_src)) {
return -1;
}
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle,
smb_fname_dst->base_name,
- ×tamp_dst, NULL)) {
+ ×tamp_dst, NULL, &snappath_dst)) {
return -1;
}
if (timestamp_src != 0) {
@@ -956,55 +1130,88 @@
errno = EROFS;
return -1;
}
+ /*
+ * Don't allow rename on already converted paths.
+ */
+ if (snappath_src != NULL) {
+ errno = EXDEV;
+ return -1;
+ }
+ if (snappath_dst != NULL) {
+ errno = EROFS;
+ return -1;
+ }
return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
}
static int shadow_copy2_symlink(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
- time_t timestamp_old, timestamp_new;
+ time_t timestamp_old = 0;
+ time_t timestamp_new = 0;
+ char *snappath_old = NULL;
+ char *snappath_new = NULL;
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname,
- ×tamp_old, NULL)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
+ ×tamp_old, NULL, &snappath_old)) {
return -1;
}
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname,
- ×tamp_new, NULL)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
+ ×tamp_new, NULL, &snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
+ /*
+ * Don't allow symlinks on already converted paths.
+ */
+ if ((snappath_old != NULL) || (snappath_new != NULL)) {
+ errno = EROFS;
+ return -1;
+ }
return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname);
}
static int shadow_copy2_link(vfs_handle_struct *handle,
const char *oldname, const char *newname)
{
- time_t timestamp_old, timestamp_new;
+ time_t timestamp_old = 0;
+ time_t timestamp_new = 0;
+ char *snappath_old = NULL;
+ char *snappath_new = NULL;
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname,
- ×tamp_old, NULL)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname,
+ ×tamp_old, NULL, &snappath_old)) {
return -1;
}
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname,
- ×tamp_new, NULL)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname,
+ ×tamp_new, NULL, &snappath_new)) {
return -1;
}
if ((timestamp_old != 0) || (timestamp_new != 0)) {
errno = EROFS;
return -1;
}
+ /*
+ * Don't allow links on already converted paths.
+ */
+ if ((snappath_old != NULL) || (snappath_new != NULL)) {
+ errno = EROFS;
+ return -1;
+ }
return SMB_VFS_NEXT_LINK(handle, oldname, newname);
}
static int shadow_copy2_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- time_t timestamp;
- char *stripped, *tmp;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ char *tmp;
+ int saved_errno = 0;
+ int ret;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
smb_fname->base_name,
@@ -1026,7 +1233,9 @@
}
ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(smb_fname->base_name);
smb_fname->base_name = tmp;
@@ -1034,16 +1243,20 @@
if (ret == 0) {
convert_sbuf(handle, smb_fname->base_name, &smb_fname->st);
}
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_lstat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- time_t timestamp;
- char *stripped, *tmp;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ char *tmp;
+ int saved_errno = 0;
+ int ret;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
smb_fname->base_name,
@@ -1065,7 +1278,9 @@
}
ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(smb_fname->base_name);
smb_fname->base_name = tmp;
@@ -1073,14 +1288,16 @@
if (ret == 0) {
convert_sbuf(handle, smb_fname->base_name, &smb_fname->st);
}
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
{
- time_t timestamp;
+ time_t timestamp = 0;
int ret;
ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
@@ -1102,9 +1319,11 @@
struct smb_filename *smb_fname, files_struct *fsp,
int flags, mode_t mode)
{
- time_t timestamp;
- char *stripped, *tmp;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ char *tmp;
+ int saved_errno = 0;
+ int ret;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
smb_fname->base_name,
@@ -1126,21 +1345,26 @@
}
ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(smb_fname->base_name);
smb_fname->base_name = tmp;
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_unlink(vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
struct smb_filename *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
@@ -1163,9 +1387,13 @@
return -1;
}
ret = SMB_VFS_NEXT_UNLINK(handle, conv);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -1173,9 +1401,10 @@
const struct smb_filename *smb_fname,
mode_t mode)
{
- time_t timestamp;
+ time_t timestamp = 0;
char *stripped = NULL;
- int ret, saved_errno;
+ int saved_errno = 0;
+ int ret;
char *conv = NULL;
struct smb_filename *conv_smb_fname;
@@ -1207,10 +1436,14 @@
}
ret = SMB_VFS_NEXT_CHMOD(handle, conv_smb_fname, mode);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
TALLOC_FREE(conv_smb_fname);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -1219,9 +1452,10 @@
uid_t uid,
gid_t gid)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv = NULL;
struct smb_filename *conv_smb_fname = NULL;
@@ -1251,37 +1485,96 @@
return -1;
}
ret = SMB_VFS_NEXT_CHOWN(handle, conv_smb_fname, uid, gid);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
TALLOC_FREE(conv_smb_fname);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
+static void store_cwd_data(vfs_handle_struct *handle,
+ const char *connectpath)
+{
+ struct shadow_copy2_private *priv = NULL;
+ char *cwd = NULL;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
+ return);
+
+ TALLOC_FREE(priv->shadow_cwd);
+ cwd = SMB_VFS_NEXT_GETWD(handle);
+ if (cwd == NULL) {
+ smb_panic("getwd failed\n");
+ }
+ DBG_DEBUG("shadow cwd = %s\n", cwd);
+ priv->shadow_cwd = talloc_strdup(priv, cwd);
+ SAFE_FREE(cwd);
+ if (priv->shadow_cwd == NULL) {
+ smb_panic("talloc failed\n");
+ }
+ TALLOC_FREE(priv->shadow_connectpath);
+ if (connectpath) {
+ DBG_DEBUG("shadow conectpath = %s\n", connectpath);
+ priv->shadow_connectpath = talloc_strdup(priv, connectpath);
+ if (priv->shadow_connectpath == NULL) {
+ smb_panic("talloc failed\n");
+ }
+ }
+}
+
static int shadow_copy2_chdir(vfs_handle_struct *handle,
const char *fname)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
- char *conv;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ char *snappath = NULL;
+ int ret = -1;
+ int saved_errno = 0;
+ char *conv = NULL;
+ size_t rootpath_len = 0;
- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
- ×tamp, &stripped)) {
+ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, fname,
+ ×tamp, &stripped, &snappath)) {
return -1;
}
- if (timestamp == 0) {
- return SMB_VFS_NEXT_CHDIR(handle, fname);
+ if (stripped != NULL) {
+ conv = shadow_copy2_do_convert(talloc_tos(),
+ handle,
+ stripped,
+ timestamp,
+ &rootpath_len);
+ TALLOC_FREE(stripped);
+ if (conv == NULL) {
+ return -1;
+ }
+ fname = conv;
}
- conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
- TALLOC_FREE(stripped);
- if (conv == NULL) {
- return -1;
+
+ ret = SMB_VFS_NEXT_CHDIR(handle, fname);
+ if (ret == -1) {
+ saved_errno = errno;
}
- ret = SMB_VFS_NEXT_CHDIR(handle, conv);
- saved_errno = errno;
+
+ if (ret == 0) {
+ if (conv != NULL && rootpath_len != 0) {
+ conv[rootpath_len] = '\0';
+ } else if (snappath != 0) {
+ TALLOC_FREE(conv);
+ conv = snappath;
+ }
+ store_cwd_data(handle, conv);
+ }
+
+ TALLOC_FREE(stripped);
TALLOC_FREE(conv);
- errno = saved_errno;
+
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -1289,9 +1582,10 @@
const struct smb_filename *smb_fname,
struct smb_file_time *ft)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
struct smb_filename *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle,
@@ -1314,18 +1608,23 @@
return -1;
}
ret = SMB_VFS_NEXT_NTIMES(handle, conv, ft);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_readlink(vfs_handle_struct *handle,
const char *fname, char *buf, size_t bufsiz)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -1341,18 +1640,23 @@
return -1;
}
ret = SMB_VFS_NEXT_READLINK(handle, conv, buf, bufsiz);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_mknod(vfs_handle_struct *handle,
const char *fname, mode_t mode, SMB_DEV_T dev)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -1368,20 +1672,24 @@
return -1;
}
ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static char *shadow_copy2_realpath(vfs_handle_struct *handle,
const char *fname)
{
- time_t timestamp;
+ time_t timestamp = 0;
char *stripped = NULL;
char *tmp = NULL;
char *result = NULL;
- int saved_errno;
+ int saved_errno = 0;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
×tamp, &stripped)) {
@@ -1399,10 +1707,14 @@
result = SMB_VFS_NEXT_REALPATH(handle, tmp);
done:
- saved_errno = errno;
+ if (result == NULL) {
+ saved_errno = errno;
+ }
TALLOC_FREE(tmp);
TALLOC_FREE(stripped);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return result;
}
@@ -1805,8 +2117,8 @@
TALLOC_CTX *mem_ctx,
struct security_descriptor **ppdesc)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
NTSTATUS status;
char *conv;
struct smb_filename *smb_fname = NULL;
@@ -1849,8 +2161,8 @@
TALLOC_CTX *mem_ctx,
struct security_descriptor **ppdesc)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
NTSTATUS status;
char *conv;
struct smb_filename *conv_smb_fname = NULL;
@@ -1891,9 +2203,10 @@
const struct smb_filename *smb_fname,
mode_t mode)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
struct smb_filename *conv_smb_fname = NULL;
@@ -1922,19 +2235,24 @@
return -1;
}
ret = SMB_VFS_NEXT_MKDIR(handle, conv_smb_fname, mode);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
TALLOC_FREE(conv_smb_fname);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_rmdir(vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
struct smb_filename *conv_smb_fname = NULL;
@@ -1963,19 +2281,24 @@
return -1;
}
ret = SMB_VFS_NEXT_RMDIR(handle, conv_smb_fname);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv_smb_fname);
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname,
unsigned int flags)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -1991,9 +2314,13 @@
return -1;
}
ret = SMB_VFS_NEXT_CHFLAGS(handle, conv, flags);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2001,10 +2328,10 @@
const char *fname, const char *aname,
void *value, size_t size)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -2021,9 +2348,13 @@
return -1;
}
ret = SMB_VFS_NEXT_GETXATTR(handle, conv, aname, value, size);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2031,10 +2362,10 @@
const char *fname,
char *list, size_t size)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -2050,18 +2381,23 @@
return -1;
}
ret = SMB_VFS_NEXT_LISTXATTR(handle, conv, list, size);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static int shadow_copy2_removexattr(vfs_handle_struct *handle,
const char *fname, const char *aname)
{
- time_t timestamp;
- char *stripped;
- int ret, saved_errno;
+ time_t timestamp = 0;
+ char *stripped = NULL;
+ int saved_errno = 0;
+ int ret;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -2077,9 +2413,13 @@
return -1;
}
ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv, aname);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2088,10 +2428,10 @@
const char *aname, const void *value,
size_t size, int flags)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
@@ -2108,9 +2448,13 @@
return -1;
}
ret = SMB_VFS_NEXT_SETXATTR(handle, conv, aname, value, size, flags);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2118,10 +2462,10 @@
const struct smb_filename *smb_fname,
mode_t mode)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv = NULL;
struct smb_filename *conv_smb_fname = NULL;
@@ -2151,10 +2495,14 @@
return -1;
}
ret = SMB_VFS_NEXT_CHMOD_ACL(handle, conv_smb_fname, mode);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
TALLOC_FREE(conv_smb_fname);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2164,10 +2512,10 @@
TALLOC_CTX *mem_ctx,
char **found_name)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
DEBUG(10, ("shadow_copy2_get_real_filename called for path=[%s], "
@@ -2194,25 +2542,39 @@
ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, conv, name,
mem_ctx, found_name);
DEBUG(10, ("NEXT_REAL_FILE_NAME returned %d\n", (int)ret));
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
const char *fname)
{
- time_t timestamp;
+ time_t timestamp = 0;
char *stripped = NULL;
char *tmp = NULL;
char *result = NULL;
char *parent_dir = NULL;
- int saved_errno;
+ int saved_errno = 0;
size_t rootpath_len = 0;
+ struct shadow_copy2_private *priv = NULL;
+
+ SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
+ return NULL);
DBG_DEBUG("Calc connect path for [%s]\n", fname);
+ if (priv->shadow_connectpath != NULL) {
+ DBG_DEBUG("cached connect path is [%s]\n",
+ priv->shadow_connectpath);
+ return priv->shadow_connectpath;
+ }
+
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
×tamp, &stripped)) {
goto done;
@@ -2263,14 +2625,25 @@
goto done;
}
+ /*
+ * SMB_VFS_NEXT_REALPATH returns a malloc'ed string.
+ * Don't leak memory.
+ */
+ SAFE_FREE(priv->shadow_realpath);
+ priv->shadow_realpath = result;
+
DBG_DEBUG("connect path is [%s]\n", result);
done:
- saved_errno = errno;
+ if (result == NULL) {
+ saved_errno = errno;
+ }
TALLOC_FREE(tmp);
TALLOC_FREE(stripped);
TALLOC_FREE(parent_dir);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return result;
}
@@ -2278,10 +2651,10 @@
const char *path, uint64_t *bsize,
uint64_t *dfree, uint64_t *dsize)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
ssize_t ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path,
@@ -2301,9 +2674,13 @@
ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
@@ -2312,10 +2689,10 @@
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *dq)
{
- time_t timestamp;
- char *stripped;
+ time_t timestamp = 0;
+ char *stripped = NULL;
int ret;
- int saved_errno;
+ int saved_errno = 0;
char *conv;
if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path, ×tamp,
@@ -2334,13 +2711,23 @@
ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv, qtype, id, dq);
- saved_errno = errno;
+ if (ret == -1) {
+ saved_errno = errno;
+ }
TALLOC_FREE(conv);
- errno = saved_errno;
+ if (saved_errno != 0) {
+ errno = saved_errno;
+ }
return ret;
}
+static int shadow_copy2_private_destructor(struct shadow_copy2_private *priv)
+{
+ SAFE_FREE(priv->shadow_realpath);
+ return 0;
+}
+
static int shadow_copy2_connect(struct vfs_handle_struct *handle,
const char *service, const char *user)
{
@@ -2372,6 +2759,8 @@
return -1;
}
+ talloc_set_destructor(priv, shadow_copy2_private_destructor);
+
priv->snaps = talloc_zero(priv, struct shadow_copy2_snaplist_info);
if (priv->snaps == NULL) {
DBG_ERR("talloc_zero() failed\n");
@@ -2398,6 +2787,15 @@
return -1;
}
+ /* config->gmt_format must not contain a path separator. */
+ if (strchr(config->gmt_format, '/') != NULL) {
+ DEBUG(0, ("shadow:format %s must not contain a /"
+ "character. Unable to initialize module.\n",
+ config->gmt_format));
+ errno = EINVAL;
+ return -1;
+ }
+
config->use_sscanf = lp_parm_bool(SNUM(handle->conn),
"shadow", "sscanf", false);
@@ -2582,7 +2980,7 @@
}
if (config->rel_connectpath == NULL &&
- strlen(basedir) != strlen(handle->conn->connectpath)) {
+ strlen(basedir) < strlen(handle->conn->connectpath)) {
config->rel_connectpath = talloc_strdup(config,
handle->conn->connectpath + strlen(basedir));
if (config->rel_connectpath == NULL) {
@@ -2620,6 +3018,11 @@
}
}
+ trim_string(config->mount_point, NULL, "/");
+ trim_string(config->rel_connectpath, "/", "/");
+ trim_string(config->snapdir, NULL, "/");
+ trim_string(config->snapshot_basepath, NULL, "/");
+
DEBUG(10, ("shadow_copy2_connect: configuration:\n"
" share root: '%s'\n"
" mountpoint: '%s'\n"
diff -Nru samba-4.5.5+dfsg/source3/modules/vfs_streams_xattr.c samba-4.5.6+dfsg/source3/modules/vfs_streams_xattr.c
--- samba-4.5.5+dfsg/source3/modules/vfs_streams_xattr.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source3/modules/vfs_streams_xattr.c 2017-03-09 10:21:43.000000000 +0100
@@ -264,7 +264,7 @@
return -1;
}
- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp,
+ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp,
io->base, io->xattr_name);
if (sbuf->st_ex_size == -1) {
return -1;
@@ -399,6 +399,7 @@
char *xattr_name = NULL;
int baseflags;
int hostfd = -1;
+ int ret;
DEBUG(10, ("streams_xattr_open called for %s with flags 0x%x\n",
smb_fname_str_dbg(smb_fname), flags));
@@ -410,7 +411,6 @@
/* If the default stream is requested, just open the base file. */
if (is_ntfs_default_stream_smb_fname(smb_fname)) {
char *tmp_stream_name;
- int ret;
tmp_stream_name = smb_fname->stream_name;
smb_fname->stream_name = NULL;
@@ -449,10 +449,8 @@
baseflags &= ~O_EXCL;
baseflags &= ~O_CREAT;
- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname_base, fsp,
- baseflags, mode);
-
- TALLOC_FREE(smb_fname_base);
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp,
+ baseflags, mode);
/* It is legit to open a stream on a directory, but the base
* fd has to be read-only.
@@ -460,10 +458,12 @@
if ((hostfd == -1) && (errno == EISDIR)) {
baseflags &= ~O_ACCMODE;
baseflags |= O_RDONLY;
- hostfd = SMB_VFS_OPEN(handle->conn, smb_fname, fsp, baseflags,
- mode);
+ hostfd = SMB_VFS_NEXT_OPEN(handle, smb_fname_base, fsp, baseflags,
+ mode);
}
+ TALLOC_FREE(smb_fname_base);
+
if (hostfd == -1) {
goto fail;
}
@@ -500,20 +500,13 @@
DEBUG(10, ("creating or truncating attribute %s on file %s\n",
xattr_name, smb_fname->base_name));
- if (fsp->base_fsp->fh->fd != -1) {
- if (SMB_VFS_FSETXATTR(
- fsp->base_fsp, xattr_name,
+ fsp->fh->fd = hostfd;
+ ret = SMB_VFS_FSETXATTR(fsp, xattr_name,
&null, sizeof(null),
- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
- goto fail;
- }
- } else {
- if (SMB_VFS_SETXATTR(
- handle->conn, smb_fname->base_name,
- xattr_name, &null, sizeof(null),
- flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
- goto fail;
- }
+ flags & O_EXCL ? XATTR_CREATE : 0);
+ fsp->fh->fd = -1;
+ if (ret != 0) {
+ goto fail;
}
}
@@ -527,8 +520,15 @@
sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
xattr_name);
+ /*
+ * so->base needs to be a copy of fsp->fsp_name->base_name,
+ * making it identical to streams_xattr_recheck(). If the
+ * open is changing directories, fsp->fsp_name->base_name
+ * will be the full path from the share root, whilst
+ * smb_fname will be relative to the $cwd.
+ */
sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp),
- smb_fname->base_name);
+ fsp->fsp_name->base_name);
sio->fsp_name_ptr = fsp->fsp_name;
sio->handle = handle;
sio->fsp = fsp;
@@ -547,7 +547,7 @@
* we don't have a full fsp yet
*/
fsp->fh->fd = hostfd;
- SMB_VFS_CLOSE(fsp);
+ SMB_VFS_NEXT_CLOSE(handle, fsp);
}
return -1;
@@ -961,7 +961,7 @@
return -1;
}
- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
sio->base, sio->xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
return -1;
@@ -985,13 +985,13 @@
memcpy(ea.value.data + offset, data, n);
- if (fsp->base_fsp->fh->fd != -1) {
- ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
+ if (fsp->fh->fd != -1) {
+ ret = SMB_VFS_FSETXATTR(fsp,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
ret = SMB_VFS_SETXATTR(fsp->conn,
- fsp->base_fsp->fsp_name->base_name,
+ fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
@@ -1025,7 +1025,7 @@
return -1;
}
- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
sio->base, sio->xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
return -1;
@@ -1070,7 +1070,7 @@
return -1;
}
- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp,
+ status = get_ea_value(talloc_tos(), handle->conn, fsp,
sio->base, sio->xattr_name, &ea);
if (!NT_STATUS_IS_OK(status)) {
return -1;
@@ -1095,13 +1095,13 @@
ea.value.length = offset + 1;
ea.value.data[offset] = 0;
- if (fsp->base_fsp->fh->fd != -1) {
- ret = SMB_VFS_FSETXATTR(fsp->base_fsp,
+ if (fsp->fh->fd != -1) {
+ ret = SMB_VFS_FSETXATTR(fsp,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
} else {
ret = SMB_VFS_SETXATTR(fsp->conn,
- fsp->base_fsp->fsp_name->base_name,
+ fsp->fsp_name->base_name,
sio->xattr_name,
ea.value.data, ea.value.length, 0);
}
diff -Nru samba-4.5.5+dfsg/source3/passdb/passdb.c samba-4.5.6+dfsg/source3/passdb/passdb.c
--- samba-4.5.5+dfsg/source3/passdb/passdb.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/passdb/passdb.c 2017-03-09 10:21:43.000000000 +0100
@@ -2621,6 +2621,19 @@
status = NT_STATUS_NO_MEMORY;
goto fail;
}
+
+ /*
+ * It's not possible to use NTLMSSP with a domain trust account.
+ */
+ cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
+ } else {
+ /*
+ * We can't use kerberos against an NT4 domain.
+ *
+ * We should have a mode that also disallows NTLMSSP here,
+ * as only NETLOGON SCHANNEL is possible.
+ */
+ cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
}
ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
@@ -2635,6 +2648,10 @@
status = NT_STATUS_NO_MEMORY;
goto fail;
}
+ /*
+ * We currently can't do kerberos just with an NTHASH.
+ */
+ cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
goto done;
}
diff -Nru samba-4.5.5+dfsg/source3/rpc_client/cli_pipe.c samba-4.5.6+dfsg/source3/rpc_client/cli_pipe.c
--- samba-4.5.5+dfsg/source3/rpc_client/cli_pipe.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/rpc_client/cli_pipe.c 2017-03-09 10:21:43.000000000 +0100
@@ -948,8 +948,7 @@
status = dcerpc_pull_ncacn_packet(state->pkt,
&state->incoming_frag,
- state->pkt,
- !state->endianess);
+ state->pkt);
if (!NT_STATUS_IS_OK(status)) {
/*
* TODO: do a real async disconnect ...
diff -Nru samba-4.5.5+dfsg/source3/rpc_server/mdssvc/sparql_mapping.c samba-4.5.6+dfsg/source3/rpc_server/mdssvc/sparql_mapping.c
--- samba-4.5.5+dfsg/source3/rpc_server/mdssvc/sparql_mapping.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/rpc_server/mdssvc/sparql_mapping.c 2017-03-09 10:21:43.000000000 +0100
@@ -133,6 +133,11 @@
.type = ssmt_type,
.sparql_attr = NULL,
},
+ {
+ .spotlight_attr = "kMDItemContentType",
+ .type = ssmt_type,
+ .sparql_attr = NULL,
+ },
/* Image metadata */
{
diff -Nru samba-4.5.5+dfsg/source3/rpc_server/rpc_service_setup.c samba-4.5.6+dfsg/source3/rpc_server/rpc_service_setup.c
--- samba-4.5.5+dfsg/source3/rpc_server/rpc_service_setup.c 2016-09-13 10:21:35.000000000 +0200
+++ samba-4.5.6+dfsg/source3/rpc_server/rpc_service_setup.c 2017-03-09 10:21:43.000000000 +0100
@@ -535,18 +535,15 @@
/* Initialize shared modules */
mod_init_fns = load_samba_modules(tmp_ctx, "rpc");
- if (mod_init_fns == NULL) {
- if (errno != ENOENT) {
- /*
- * ENOENT means the directory doesn't exist
- * which can happen if all modules are
- * static. So ENOENT is ok, everything else is
- * not ok.
- */
- DBG_ERR("Loading shared RPC modules failed [%s]\n",
- strerror(errno));
- ok = false;
- }
+ if ((mod_init_fns == NULL) && (errno != ENOENT)) {
+ /*
+ * ENOENT means the directory doesn't exist which can happen if
+ * all modules are static. So ENOENT is ok, everything else is
+ * not ok.
+ */
+ DBG_ERR("Loading shared RPC modules failed [%s]\n",
+ strerror(errno));
+ ok = false;
goto done;
}
diff -Nru samba-4.5.5+dfsg/source3/rpc_server/wscript_build samba-4.5.6+dfsg/source3/rpc_server/wscript_build
--- samba-4.5.5+dfsg/source3/rpc_server/wscript_build 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/rpc_server/wscript_build 2017-03-09 10:21:43.000000000 +0100
@@ -39,6 +39,10 @@
NDR_NAMED_PIPE_AUTH
''')
+bld.SAMBA3_SUBSYSTEM('RPC_MODULES',
+ source='rpc_modules.c',
+ deps='samba-util')
+
### RPC_SERVICES
bld.SAMBA3_SUBSYSTEM('RPC_DSSETUP',
source='''dssetup/srv_dssetup_nt.c
@@ -150,11 +154,12 @@
deps='samba-util')
bld.SAMBA3_SUBSYSTEM('RPC_SERVICE',
- source='rpc_service_setup.c rpc_modules.c',
+ source='rpc_service_setup.c',
deps='''
rpc
RPC_SERVER
RPC_SERVER_REGISTER
+ RPC_MODULES
RPC_SAMR
RPC_LSARPC
RPC_WINREG
@@ -192,6 +197,6 @@
deps='samba-util')
bld.SAMBA3_SUBSYSTEM('MDSSD',
- source='mdssd.c rpc_modules.c',
- deps='RPC_SOCK_HELPER samba-util',
+ source='mdssd.c',
+ deps='RPC_SOCK_HELPER RPC_MODULES samba-util',
enabled=bld.env.with_spotlight)
diff -Nru samba-4.5.5+dfsg/source3/script/tests/test_smbclient_encryption_off.sh samba-4.5.6+dfsg/source3/script/tests/test_smbclient_encryption_off.sh
--- samba-4.5.5+dfsg/source3/script/tests/test_smbclient_encryption_off.sh 1970-01-01 01:00:00.000000000 +0100
+++ samba-4.5.6+dfsg/source3/script/tests/test_smbclient_encryption_off.sh 2017-03-09 10:21:43.000000000 +0100
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+if [ $# -lt 4 ]; then
+cat <<EOF
+Usage: test_smbclient_encryption_off.sh USERNAME PASSWORD SERVER SMBCLIENT
+EOF
+exit 1;
+fi
+
+USERNAME="$1"
+PASSWORD="$2"
+SERVER="$3"
+SMBCLIENT="$VALGRIND $4"
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+#
+# Let me introduce you to the shares used in this test:
+#
+# "tmp" has the default "smb encrypt" (which is "enabled")
+# "tmpenc" has "smb encrypt = required"
+# "enc_desired" has "smb encrypt = desired"
+#
+
+# Unencrypted connections should work of course, let's test em to be sure...
+
+# SMB1
+testit "smbclient //$SERVER/enc_desired" $SMBCLIENT -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit || failed=`expr $failed + 1`
+testit "smbclient //$SERVER/tmp" $SMBCLIENT -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit || failed=`expr $failed + 1`
+# SMB3_02
+testit "smbclient -m smb3_02 //$SERVER/enc_desired" $SMBCLIENT -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit || failed=`expr $failed + 1`
+testit "smbclient -m smb3_02 //$SERVER/tmp" $SMBCLIENT -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit || failed=`expr $failed + 1`
+# SMB3_11
+testit "smbclient -m smb3_11 //$SERVER/enc_desired" $SMBCLIENT -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit || failed=`expr $failed + 1`
+testit "smbclient -m smb3_11 //$SERVER/tmp" $SMBCLIENT -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit || failed=`expr $failed + 1`
+
+# These tests must fail, as encryption is globally off and in combination with "smb
+# encrypt=required" on the share "tmpenc" the server *must* reject the tcon.
+
+# SMB1
+testit_expect_failure "smbclient //$SERVER/tmpenc" $SMBCLIENT -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e //$SERVER/tmpenc" $SMBCLIENT -e -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+# SMB3_02
+testit_expect_failure "smbclient -m smb3_02 //$SERVER/tmpenc" $SMBCLIENT -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e -m smb3_02 //$SERVER/tmpenc" $SMBCLIENT -e -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+# SMB3_11
+testit_expect_failure "smbclient -m smb3_11 //$SERVER/tmpenc" $SMBCLIENT -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e -m smb3_11 //$SERVER/tmpenc" $SMBCLIENT -e -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/tmpenc -c quit && failed=`expr $failed + 1`
+
+# These tests must fail, as the client requires encryption and it's off on the server
+
+# SMB1
+testit_expect_failure "smbclient -e //$SERVER/enc_desired" $SMBCLIENT -e -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e //$SERVER/tmp" $SMBCLIENT -e -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit && failed=`expr $failed + 1`
+# SMB3_02
+testit_expect_failure "smbclient -e -m smb3_02 //$SERVER/enc_desired" $SMBCLIENT -e -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e -m smb3_02 //$SERVER/tmp" $SMBCLIENT -e -m smb3_02 -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit && failed=`expr $failed + 1`
+# SMB3_11
+testit_expect_failure "smbclient -e -m smb3_11 //$SERVER/enc_desired" $SMBCLIENT -e -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/enc_desired -c quit && failed=`expr $failed + 1`
+testit_expect_failure "smbclient -e -m smb3_11 //$SERVER/tmp" $SMBCLIENT -e -m smb3_11 -U $USERNAME%$PASSWORD //$SERVER/tmp -c quit && failed=`expr $failed + 1`
+
+testok $0 $failed
diff -Nru samba-4.5.5+dfsg/source3/selftest/tests.py samba-4.5.6+dfsg/source3/selftest/tests.py
--- samba-4.5.5+dfsg/source3/selftest/tests.py 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source3/selftest/tests.py 2017-03-09 10:21:43.000000000 +0100
@@ -84,7 +84,7 @@
plantestsuite("samba3.smbtorture_s3.vfs_aio_fork(simpleserver).%s" % t, "simpleserver", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/vfs_aio_fork', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA", "POSIX-OFD-LOCK",
- "POSIX-STREAM-DELETE" ]
+ "POSIX-STREAM-DELETE", "WINDOWS-BAD-SYMLINK" ]
for t in posix_tests:
plantestsuite("samba3.smbtorture_s3.plain(nt4_dc).%s" % t, "nt4_dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, '//$SERVER_IP/posix_share', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l $LOCAL_PATH"])
@@ -119,6 +119,7 @@
"LOCAL-MESSAGING-FDPASS2",
"LOCAL-MESSAGING-FDPASS2a",
"LOCAL-MESSAGING-FDPASS2b",
+ "LOCAL-CANONICALIZE-PATH",
"LOCAL-hex_encode_buf",
"LOCAL-remove_duplicate_addrs2"]
@@ -274,7 +275,7 @@
#smbtorture4 tests
-base = ["base.attr", "base.charset", "base.chkpath", "base.defer_open", "base.delaywrite", "base.delete",
+base = ["base.attr", "base.charset", "base.chkpath", "base.createx_access", "base.defer_open", "base.delaywrite", "base.delete",
"base.deny1", "base.deny2", "base.deny3", "base.denydos", "base.dir1", "base.dir2",
"base.disconnect", "base.fdpass", "base.lock",
"base.mangle", "base.negnowait", "base.ntdeny1",
@@ -323,13 +324,15 @@
libsmbclient = ["libsmbclient"]
-vfs = ["vfs.fruit", "vfs.acl_xattr"]
+vfs = ["vfs.fruit", "vfs.acl_xattr", "vfs.fruit_netatalk"]
tests= base + raw + smb2 + rpc + unix + local + rap + nbt + libsmbclient + idmap + vfs
for t in tests:
if t == "base.delaywrite":
plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900')
+ if t == "base.createx_access":
+ plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD -k yes --maximum-runtime=900')
elif t == "rap.sam":
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=doscharset=ISO-8859-1')
plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD --option=doscharset=ISO-8859-1')
@@ -404,8 +407,11 @@
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmpsort -U$USERNAME%$PASSWORD')
plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
elif t == "vfs.fruit":
+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share --option=torture:share2=vfs_wo_fruit', 'metadata_netatalk')
+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_metadata_stream --option=torture:share2=vfs_wo_fruit -U$USERNAME%$PASSWORD', 'metadata_stream')
+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_stream_depot --option=torture:share2=vfs_wo_fruit_stream_depot -U$USERNAME%$PASSWORD', 'streams_depot')
+ elif t == "vfs.fruit_netatalk":
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share')
- plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/vfs_fruit -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/ad_dc/share')
elif t == "rpc.schannel_anon_setpw":
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$%', description="anonymous password set")
plansmbtorture4testsuite(t, "nt4_dc_schannel", '//$SERVER_IP/tmp -U$%', description="anonymous password set (schannel enforced server-side)")
@@ -442,8 +448,12 @@
# We should try more combinations in future, but this is all
# the pre-calculated credentials cache supports at the moment
+ #
+ # As the ktest env requires SMB3_00 we need to use "smb2" until
+ # dcerpc client code in smbtorture support autonegotiation
+ # of any smb dialect.
e = ""
- a = ""
+ a = "smb2"
binding_string = "ncacn_np:$SERVER[%s%s%s]" % (a, s, e)
options = binding_string + " -k yes --krb5-ccache=$PREFIX/ktest/krb5_ccache-2"
plansmbtorture4testsuite(test, "ktest", options, 'krb5 with old ccache ncacn_np with [%s%s%s] ' % (a, s, e))
@@ -483,6 +493,11 @@
"$USERNAME", "$PASSWORD", "$SERVER",
os.path.join(bindir(), "rpcclient")])
+plantestsuite("samba3.blackbox.smbclient.encryption_off", "simpleserver",
+ [os.path.join(samba3srcdir, "script/tests/test_smbclient_encryption_off.sh"),
+ "$USERNAME", "$PASSWORD", "$SERVER",
+ smbclient3])
+
options_list = ["", "-e"]
for options in options_list:
plantestsuite("samba3.blackbox.smbclient_krb5 old ccache %s" % options, "ktest:local",
diff -Nru samba-4.5.5+dfsg/source3/smbd/filename.c samba-4.5.6+dfsg/source3/smbd/filename.c
--- samba-4.5.5+dfsg/source3/smbd/filename.c 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/source3/smbd/filename.c 2017-03-09 10:21:43.000000000 +0100
@@ -220,6 +220,148 @@
return NT_STATUS_OK;
}
+/*
+ * Re-order a known good @GMT-token path.
+ */
+
+static NTSTATUS rearrange_snapshot_path(struct smb_filename *smb_fname,
+ char *startp,
+ char *endp)
+{
+ size_t endlen = 0;
+ size_t gmt_len = endp - startp;
+ char gmt_store[gmt_len + 1];
+ char *parent = NULL;
+ const char *last_component = NULL;
+ char *newstr;
+ bool ret;
+
+ DBG_DEBUG("|%s| -> ", smb_fname->base_name);
+
+ /* Save off the @GMT-token. */
+ memcpy(gmt_store, startp, gmt_len);
+ gmt_store[gmt_len] = '\0';
+
+ if (*endp == '/') {
+ /* Remove any trailing '/' */
+ endp++;
+ }
+
+ if (*endp == '\0') {
+ /*
+ * @GMT-token was at end of path.
+ * Remove any preceeding '/'
+ */
+ if (startp > smb_fname->base_name && startp[-1] == '/') {
+ startp--;
+ }
+ }
+
+ /* Remove @GMT-token from the path. */
+ endlen = strlen(endp);
+ memmove(startp, endp, endlen + 1);
+
+ /* Split the remaining path into components. */
+ ret = parent_dirname(smb_fname,
+ smb_fname->base_name,
+ &parent,
+ &last_component);
+ if (ret == false) {
+ /* Must terminate debug with \n */
+ DBG_DEBUG("NT_STATUS_NO_MEMORY\n");
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (ISDOT(parent)) {
+ if (last_component[0] == '\0') {
+ newstr = talloc_strdup(smb_fname,
+ gmt_store);
+ } else {
+ newstr = talloc_asprintf(smb_fname,
+ "%s/%s",
+ gmt_store,
+ last_component);
+ }
+ } else {
+ newstr = talloc_asprintf(smb_fname,
+ "%s/%s/%s",
+ gmt_store,
+ parent,
+ last_component);
+ }
+
+ TALLOC_FREE(parent);
+ TALLOC_FREE(smb_fname->base_name);
+ smb_fname->base_name = newstr;
+
+ DBG_DEBUG("|%s|\n", newstr);
+
+ return NT_STATUS_OK;
+}
+
+/*
+ * Canonicalize any incoming pathname potentially containining
+ * a @GMT-token into a path that looks like:
+ *
+ * @GMT-YYYY-MM-DD-HH-MM-SS/path/name/components/last_component
+ *
+ * Leaves single path @GMT-token -component alone:
+ *
+ * @GMT-YYYY-MM-DD-HH-MM-SS -> @GMT-YYYY-MM-DD-HH-MM-SS
+ *
+ * Eventually when struct smb_filename is updated and the VFS
+ * ABI is changed this will remove the @GMT-YYYY-MM-DD-HH-MM-SS
+ * and store in the struct smb_filename as a struct timeval field
+ * instead.
+ */
+
+static NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname)
+{
+ char *startp = strchr_m(smb_fname->base_name, '@');
+ char *endp = NULL;
+ struct tm tm;
+
+ if (startp == NULL) {
+ /* No @ */
+ return NT_STATUS_OK;
+ }
+
+ startp = strstr_m(startp, "@GMT-");
+ if (startp == NULL) {
+ /* No @ */
+ return NT_STATUS_OK;
+ }
+
+ if ((startp > smb_fname->base_name) && (startp[-1] != '/')) {
+ /* the GMT-token does not start a path-component */
+ return NT_STATUS_OK;
+ }
+
+ endp = strptime(startp, GMT_FORMAT, &tm);
+ if (endp == NULL) {
+ /* Not a valid timestring. */
+ return NT_STATUS_OK;
+ }
+
+ if ( endp[0] == '\0') {
+ return rearrange_snapshot_path(smb_fname,
+ startp,
+ endp);
+ }
+
+ if (endp[0] != '/') {
+ /*
+ * It is not a complete path component, i.e. the path
+ * component continues after the gmt-token.
+ */
+ return NT_STATUS_OK;
+ }
+
+ return rearrange_snapshot_path(smb_fname,
+ startp,
+ endp);
+}
+
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format changes,
@@ -356,6 +498,14 @@
goto err;
}
+ /* Canonicalize any @GMT- paths. */
+ if (posix_pathnames == false) {
+ status = canonicalize_snapshot_path(smb_fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err;
+ }
+ }
+
/*
* Large directory fix normalization. If we're case sensitive, and
* the case preserving parameters are set to "no", normalize the case of
diff -Nru samba-4.5.5+dfsg/source3/smbd/negprot.c samba-4.5.6+dfsg/source3/smbd/negprot.c
--- samba-4.5.5+dfsg/source3/smbd/negprot.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/negprot.c 2017-03-09 10:21:43.000000000 +0100
@@ -544,6 +544,8 @@
struct smbXsrv_connection *xconn = req->xconn;
struct smbd_server_connection *sconn = req->sconn;
bool signing_required = true;
+ int max_proto;
+ int min_proto;
START_PROFILE(SMBnegprot);
@@ -688,11 +690,28 @@
FLAG_MSG_GENERAL|FLAG_MSG_SMBD
|FLAG_MSG_PRINT_GENERAL);
+ /*
+ * Anything higher than PROTOCOL_SMB2_10 still
+ * needs to go via "SMB 2.???", which is marked
+ * as PROTOCOL_SMB2_10.
+ *
+ * The real negotiation happens via reply_smb20ff()
+ * using SMB2 Negotiation.
+ */
+ max_proto = lp_server_max_protocol();
+ if (max_proto > PROTOCOL_SMB2_10) {
+ max_proto = PROTOCOL_SMB2_10;
+ }
+ min_proto = lp_server_min_protocol();
+ if (min_proto > PROTOCOL_SMB2_10) {
+ min_proto = PROTOCOL_SMB2_10;
+ }
+
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
i = 0;
- if ((supported_protocols[protocol].protocol_level <= lp_server_max_protocol()) &&
- (supported_protocols[protocol].protocol_level >= lp_server_min_protocol()))
+ if ((supported_protocols[protocol].protocol_level <= max_proto) &&
+ (supported_protocols[protocol].protocol_level >= min_proto))
while (i < num_cliprotos) {
if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
choice = i;
diff -Nru samba-4.5.5+dfsg/source3/smbd/open.c samba-4.5.6+dfsg/source3/smbd/open.c
--- samba-4.5.5+dfsg/source3/smbd/open.c 2017-01-17 20:55:44.000000000 +0100
+++ samba-4.5.6+dfsg/source3/smbd/open.c 2017-03-09 10:21:43.000000000 +0100
@@ -639,7 +639,9 @@
bool *file_created)
{
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS retry_status;
bool file_existed = VALID_STAT(fsp->fsp_name->st);
+ int curr_flags;
*file_created = false;
@@ -671,59 +673,65 @@
* we can never call O_CREAT without O_EXCL. So if
* we think the file existed, try without O_CREAT|O_EXCL.
* If we think the file didn't exist, try with
- * O_CREAT|O_EXCL. Keep bouncing between these two
- * requests until either the file is created, or
- * opened. Either way, we keep going until we get
- * a returnable result (error, or open/create).
+ * O_CREAT|O_EXCL.
+ *
+ * The big problem here is dangling symlinks. Opening
+ * without O_NOFOLLOW means both bad symlink
+ * and missing path return -1, ENOENT from open(). As POSIX
+ * is pathname based it's not possible to tell
+ * the difference between these two cases in a
+ * non-racy way, so change to try only two attempts before
+ * giving up.
+ *
+ * We don't have this problem for the O_NOFOLLOW
+ * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
+ * mapped from the ELOOP POSIX error.
*/
- while(1) {
- int curr_flags = flags;
+ curr_flags = flags;
- if (file_existed) {
- /* Just try open, do not create. */
- curr_flags &= ~(O_CREAT);
- status = fd_open(conn, fsp, curr_flags, mode);
- if (NT_STATUS_EQUAL(status,
- NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
- /*
- * Someone deleted it in the meantime.
- * Retry with O_EXCL.
- */
- file_existed = false;
- DEBUG(10,("fd_open_atomic: file %s existed. "
- "Retry.\n",
- smb_fname_str_dbg(fsp->fsp_name)));
- continue;
- }
- } else {
- /* Try create exclusively, fail if it exists. */
- curr_flags |= O_EXCL;
- status = fd_open(conn, fsp, curr_flags, mode);
- if (NT_STATUS_EQUAL(status,
- NT_STATUS_OBJECT_NAME_COLLISION)) {
- /*
- * Someone created it in the meantime.
- * Retry without O_CREAT.
- */
- file_existed = true;
- DEBUG(10,("fd_open_atomic: file %s "
- "did not exist. Retry.\n",
- smb_fname_str_dbg(fsp->fsp_name)));
- continue;
- }
- if (NT_STATUS_IS_OK(status)) {
- /*
- * Here we've opened with O_CREAT|O_EXCL
- * and got success. We *know* we created
- * this file.
- */
- *file_created = true;
- }
+ if (file_existed) {
+ curr_flags &= ~(O_CREAT);
+ retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ } else {
+ curr_flags |= O_EXCL;
+ retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ status = fd_open(conn, fsp, curr_flags, mode);
+ if (NT_STATUS_IS_OK(status)) {
+ if (!file_existed) {
+ *file_created = true;
}
- /* Create is done, or failed. */
- break;
+ return NT_STATUS_OK;
+ }
+ if (!NT_STATUS_EQUAL(status, retry_status)) {
+ return status;
+ }
+
+ curr_flags = flags;
+
+ /*
+ * Keep file_existed up to date for clarity.
+ */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ file_existed = false;
+ curr_flags |= O_EXCL;
+ DBG_DEBUG("file %s did not exist. Retry.\n",
+ smb_fname_str_dbg(fsp->fsp_name));
+ } else {
+ file_existed = true;
+ curr_flags &= ~(O_CREAT);
+ DBG_DEBUG("file %s existed. Retry.\n",
+ smb_fname_str_dbg(fsp->fsp_name));
}
+
+ status = fd_open(conn, fsp, curr_flags, mode);
+
+ if (NT_STATUS_IS_OK(status) && (!file_existed)) {
+ *file_created = true;
+ }
+
return status;
}
@@ -2274,6 +2282,12 @@
uint32_t orig_access_mask = access_mask;
uint32_t rejected_share_access;
+ if (access_mask & SEC_MASK_INVALID) {
+ DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
+ access_mask);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
/*
* Convert GENERIC bits to specific bits.
*/
diff -Nru samba-4.5.5+dfsg/source3/smbd/posix_acls.c samba-4.5.6+dfsg/source3/smbd/posix_acls.c
--- samba-4.5.5+dfsg/source3/smbd/posix_acls.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/posix_acls.c 2017-03-09 10:21:43.000000000 +0100
@@ -2700,9 +2700,9 @@
.attr = ALLOW_ACE,
.trustee = sid,
.unix_ug = unix_ug,
- .owner_type = owner_type,
- .ace_flags = get_pai_flags(pal, ace, is_default_acl)
+ .owner_type = owner_type
};
+ ace->ace_flags = get_pai_flags(pal, ace, is_default_acl);
DLIST_ADD(l_head, ace);
}
diff -Nru samba-4.5.5+dfsg/source3/smbd/service.c samba-4.5.6+dfsg/source3/smbd/service.c
--- samba-4.5.5+dfsg/source3/smbd/service.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/service.c 2017-03-09 10:21:43.000000000 +0100
@@ -31,6 +31,7 @@
#include "lib/param/loadparm.h"
#include "messages.h"
#include "lib/afs/afs_funcs.h"
+#include "lib/util_path.h"
static bool canonicalize_connect_path(connection_struct *conn)
{
@@ -47,118 +48,20 @@
/****************************************************************************
Ensure when setting connectpath it is a canonicalized (no ./ // or ../)
absolute path stating in / and not ending in /.
- Observent people will notice a similarity between this and check_path_syntax :-).
****************************************************************************/
bool set_conn_connectpath(connection_struct *conn, const char *connectpath)
{
char *destname;
- char *d;
- const char *s = connectpath;
- bool start_of_name_component = true;
if (connectpath == NULL || connectpath[0] == '\0') {
return false;
}
- /* Allocate for strlen + '\0' + possible leading '/' */
- destname = (char *)talloc_size(conn, strlen(connectpath) + 2);
- if (!destname) {
+ destname = canonicalize_absolute_path(conn, connectpath);
+ if (destname == NULL) {
return false;
}
- d = destname;
-
- *d++ = '/'; /* Always start with root. */
-
- while (*s) {
- if (*s == '/') {
- /* Eat multiple '/' */
- while (*s == '/') {
- s++;
- }
- if ((d > destname + 1) && (*s != '\0')) {
- *d++ = '/';
- }
- start_of_name_component = True;
- continue;
- }
-
- if (start_of_name_component) {
- if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
- /* Uh oh - "/../" or "/..\0" ! */
-
- /* Go past the ../ or .. */
- if (s[2] == '/') {
- s += 3;
- } else {
- s += 2; /* Go past the .. */
- }
-
- /* If we just added a '/' - delete it */
- if ((d > destname) && (*(d-1) == '/')) {
- *(d-1) = '\0';
- d--;
- }
-
- /* Are we at the start ? Can't go back further if so. */
- if (d <= destname) {
- *d++ = '/'; /* Can't delete root */
- continue;
- }
- /* Go back one level... */
- /* Decrement d first as d points to the *next* char to write into. */
- for (d--; d > destname; d--) {
- if (*d == '/') {
- break;
- }
- }
- /* We're still at the start of a name component, just the previous one. */
- continue;
- } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) {
- /* Component of pathname can't be "." only - skip the '.' . */
- if (s[1] == '/') {
- s += 2;
- } else {
- s++;
- }
- continue;
- }
- }
-
- if (!(*s & 0x80)) {
- *d++ = *s++;
- } else {
- size_t siz;
- /* Get the size of the next MB character. */
- next_codepoint(s,&siz);
- switch(siz) {
- case 5:
- *d++ = *s++;
- /*fall through*/
- case 4:
- *d++ = *s++;
- /*fall through*/
- case 3:
- *d++ = *s++;
- /*fall through*/
- case 2:
- *d++ = *s++;
- /*fall through*/
- case 1:
- *d++ = *s++;
- break;
- default:
- break;
- }
- }
- start_of_name_component = false;
- }
- *d = '\0';
-
- /* And must not end in '/' */
- if (d > destname + 1 && (*(d-1) == '/')) {
- *(d-1) = '\0';
- }
DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n",
lp_servicename(talloc_tos(), SNUM(conn)), destname ));
@@ -623,6 +526,18 @@
conn->short_case_preserve = lp_short_preserve_case(snum);
conn->encrypt_level = lp_smb_encrypt(snum);
+ if (conn->encrypt_level > SMB_SIGNING_OFF) {
+ if (lp_smb_encrypt(-1) == SMB_SIGNING_OFF) {
+ if (conn->encrypt_level == SMB_SIGNING_REQUIRED) {
+ DBG_ERR("Service [%s] requires encryption, but "
+ "it is disabled globally!\n",
+ lp_servicename(talloc_tos(), snum));
+ status = NT_STATUS_ACCESS_DENIED;
+ goto err_root_exit;
+ }
+ conn->encrypt_level = SMB_SIGNING_OFF;
+ }
+ }
conn->veto_list = NULL;
conn->hide_list = NULL;
diff -Nru samba-4.5.5+dfsg/source3/smbd/smb2_negprot.c samba-4.5.6+dfsg/source3/smbd/smb2_negprot.c
--- samba-4.5.5+dfsg/source3/smbd/smb2_negprot.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/smb2_negprot.c 2017-03-09 10:21:43.000000000 +0100
@@ -441,7 +441,7 @@
req->preauth = &req->xconn->smb2.preauth;
}
- if (in_cipher != NULL) {
+ if ((capabilities & SMB2_CAP_ENCRYPTION) && (in_cipher != NULL)) {
size_t needed = 2;
uint16_t cipher_count;
const uint8_t *p;
diff -Nru samba-4.5.5+dfsg/source3/smbd/smb2_server.c samba-4.5.6+dfsg/source3/smbd/smb2_server.c
--- samba-4.5.5+dfsg/source3/smbd/smb2_server.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/smb2_server.c 2017-03-09 10:21:43.000000000 +0100
@@ -3566,6 +3566,7 @@
int ret;
int err;
bool retry;
+ NTSTATUS status;
if (xconn->smb2.send_queue == NULL) {
TEVENT_FD_NOT_WRITEABLE(xconn->transport.fde);
@@ -3577,11 +3578,12 @@
bool ok;
if (e->sendfile_header != NULL) {
- NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
size_t size = 0;
size_t i = 0;
uint8_t *buf;
+ status = NT_STATUS_INTERNAL_ERROR;
+
for (i=0; i < e->count; i++) {
size += e->vector[i].iov_len;
}
@@ -3653,6 +3655,16 @@
talloc_free(e->mem_ctx);
}
+ /*
+ * Restart reads if we were blocked on
+ * draining the send queue.
+ */
+
+ status = smbd_smb2_request_next_incoming(xconn);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
return NT_STATUS_OK;
}
diff -Nru samba-4.5.5+dfsg/source3/smbd/smb2_tcon.c samba-4.5.6+dfsg/source3/smbd/smb2_tcon.c
--- samba-4.5.5+dfsg/source3/smbd/smb2_tcon.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/smbd/smb2_tcon.c 2017-03-09 10:21:43.000000000 +0100
@@ -268,7 +268,8 @@
}
if ((lp_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) &&
- (conn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
+ (conn->smb2.server.cipher != 0))
+ {
encryption_desired = true;
}
diff -Nru samba-4.5.5+dfsg/source3/torture/torture.c samba-4.5.6+dfsg/source3/torture/torture.c
--- samba-4.5.5+dfsg/source3/torture/torture.c 2017-01-17 20:55:44.000000000 +0100
+++ samba-4.5.6+dfsg/source3/torture/torture.c 2017-03-09 10:21:43.000000000 +0100
@@ -9501,6 +9501,106 @@
return success;
}
+/*
+ Test Windows open on a bad POSIX symlink.
+ */
+static bool run_symlink_open_test(int dummy)
+{
+ static struct cli_state *cli;
+ const char *fname = "non_existant_file";
+ const char *sname = "dangling_symlink";
+ uint16_t fnum = (uint16_t)-1;
+ bool correct = false;
+ NTSTATUS status;
+ TALLOC_CTX *frame = NULL;
+
+ frame = talloc_stackframe();
+
+ printf("Starting Windows bad symlink open test\n");
+
+ if (!torture_open_connection(&cli, 0)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ smbXcli_conn_set_sockopt(cli->conn, sockops);
+
+ status = torture_setup_unix_extensions(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(frame);
+ return false;
+ }
+
+ /* Ensure nothing exists. */
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+
+ /* Create a symlink pointing nowhere. */
+ status = cli_posix_symlink(cli, fname, sname);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_posix_symlink of %s -> %s failed (%s)\n",
+ sname,
+ fname,
+ nt_errstr(status));
+ goto out;
+ }
+
+ /* Now ensure that a Windows open doesn't hang. */
+ status = cli_ntcreate(cli,
+ sname,
+ 0,
+ FILE_READ_DATA|FILE_WRITE_DATA,
+ 0,
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+ FILE_OPEN_IF,
+ 0x0,
+ 0x0,
+ &fnum,
+ NULL);
+
+ /*
+ * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
+ * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
+ * we use O_NOFOLLOW on the server or not.
+ */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
+ {
+ correct = true;
+ } else {
+ printf("cli_ntcreate of %s returned %s - should return"
+ " either (%s) or (%s)\n",
+ sname,
+ nt_errstr(status),
+ nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
+ nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
+ goto out;
+ }
+
+ correct = true;
+
+ out:
+
+ if (fnum != (uint16_t)-1) {
+ cli_close(cli, fnum);
+ fnum = (uint16_t)-1;
+ }
+
+ cli_setatr(cli, sname, 0, 0);
+ cli_posix_unlink(cli, sname);
+ cli_setatr(cli, fname, 0, 0);
+ cli_posix_unlink(cli, fname);
+
+ if (!torture_close_connection(cli)) {
+ correct = false;
+ }
+
+ TALLOC_FREE(frame);
+ return correct;
+}
+
static bool run_local_substitute(int dummy)
{
bool ok = true;
@@ -10878,6 +10978,49 @@
return true;
}
+static bool run_local_canonicalize_path(int dummy)
+{
+ const char *src[] = {
+ "/foo/..",
+ "/..",
+ "/foo/bar/../baz",
+ "/foo/././",
+ "/../foo",
+ ".././././",
+ ".././././../../../boo",
+ "./..",
+ NULL
+ };
+ const char *dst[] = {
+ "/",
+ "/",
+ "/foo/baz",
+ "/foo",
+ "/foo",
+ "/",
+ "/boo",
+ "/",
+ NULL
+ };
+ unsigned int i;
+
+ for (i = 0; src[i] != NULL; i++) {
+ char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
+ if (d == NULL) {
+ perror("talloc fail\n");
+ return false;
+ }
+ if (strcmp(d, dst[i]) != 0) {
+ d_fprintf(stderr,
+ "canonicalize missmatch %s -> %s != %s",
+ src[i], d, dst[i]);
+ return false;
+ }
+ talloc_free(d);
+ }
+ return true;
+}
+
static double create_procs(bool (*fn)(int), bool *result)
{
int i, status;
@@ -11020,6 +11163,7 @@
{"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
{"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
{"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
+ {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
{"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
{"ASYNC-ECHO", run_async_echo, 0},
{ "UID-REGRESSION-TEST", run_uid_regression_test, 0},
@@ -11112,6 +11256,7 @@
{ "local-tdb-writer", run_local_tdb_writer, 0 },
{ "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
{ "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
+ { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
{ "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
{NULL, NULL, 0}};
diff -Nru samba-4.5.5+dfsg/source3/utils/net_rpc_trust.c samba-4.5.6+dfsg/source3/utils/net_rpc_trust.c
--- samba-4.5.5+dfsg/source3/utils/net_rpc_trust.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/utils/net_rpc_trust.c 2017-03-09 10:21:43.000000000 +0100
@@ -518,9 +518,9 @@
}
DEBUG(0, ("Using random trust password.\n"));
- trust_pw = generate_random_password(mem_ctx,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
- DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ trust_pw = trust_pw_new_value(mem_ctx,
+ SEC_CHAN_DOMAIN,
+ SEC_DOMAIN);
if (trust_pw == NULL) {
DEBUG(0, ("generate_random_password failed.\n"));
goto done;
diff -Nru samba-4.5.5+dfsg/source3/winbindd/idmap_ad.c samba-4.5.6+dfsg/source3/winbindd/idmap_ad.c
--- samba-4.5.5+dfsg/source3/winbindd/idmap_ad.c 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/source3/winbindd/idmap_ad.c 2017-03-09 10:21:43.000000000 +0100
@@ -22,7 +22,7 @@
#include "idmap.h"
#include "tldap_gensec_bind.h"
#include "tldap_util.h"
-#include "secrets.h"
+#include "passdb.h"
#include "lib/param/param.h"
#include "utils/net.h"
#include "auth/gensec/gensec.h"
@@ -243,7 +243,6 @@
const char *domname,
struct tldap_context **pld)
{
- struct db_context *db_ctx;
struct netr_DsRGetDCNameInfo *dcinfo;
struct sockaddr_storage dcaddr;
struct cli_credentials *creds;
@@ -294,11 +293,19 @@
return NT_STATUS_NO_MEMORY;
}
- creds = cli_credentials_init(dcinfo);
- if (creds == NULL) {
- DBG_DEBUG("cli_credentials_init failed\n");
+ /*
+ * Here we use or own machine account as
+ * we run as domain member.
+ */
+ status = pdb_get_trust_credentials(lp_workgroup(),
+ lp_realm(),
+ dcinfo,
+ &creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_DEBUG("pdb_get_trust_credentials() failed - %s\n",
+ nt_errstr(status));
TALLOC_FREE(dcinfo);
- return NT_STATUS_NO_MEMORY;
+ return status;
}
lp_ctx = loadparm_init_s3(dcinfo, loadparm_s3_helpers());
@@ -308,23 +315,6 @@
return NT_STATUS_NO_MEMORY;
}
- cli_credentials_set_conf(creds, lp_ctx);
-
- db_ctx = secrets_db_ctx();
- if (db_ctx == NULL) {
- DBG_DEBUG("Failed to open secrets.tdb.\n");
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- status = cli_credentials_set_machine_account_db_ctx(creds, lp_ctx,
- db_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DBG_DEBUG("cli_credentials_set_machine_account "
- "failed: %s\n", nt_errstr(status));
- TALLOC_FREE(dcinfo);
- return status;
- }
-
rc = tldap_gensec_bind(ld, creds, "ldap", dcinfo->dc_unc, NULL, lp_ctx,
GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL);
if (!TLDAP_RC_IS_SUCCESS(rc)) {
diff -Nru samba-4.5.5+dfsg/source3/winbindd/winbindd_ads.c samba-4.5.6+dfsg/source3/winbindd/winbindd_ads.c
--- samba-4.5.5+dfsg/source3/winbindd/winbindd_ads.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/winbindd/winbindd_ads.c 2017-03-09 10:21:43.000000000 +0100
@@ -119,6 +119,8 @@
ads->auth.renewable = renewable;
ads->auth.password = password;
+ ads->auth.flags |= ADS_AUTH_ALLOW_NTLMSSP;
+
ads->auth.realm = SMB_STRDUP(auth_realm);
if (!strupper_m(ads->auth.realm)) {
ads_destroy(&ads);
@@ -1700,6 +1702,14 @@
}
TALLOC_FREE(parent);
+ /*
+ * We need to pass the modified properties
+ * to the caller.
+ */
+ trust->trust_flags = d.domain_flags;
+ trust->trust_type = d.domain_type;
+ trust->trust_attributes = d.domain_trust_attribs;
+
wcache_tdc_add_domain( &d );
ret_count++;
}
diff -Nru samba-4.5.5+dfsg/source3/winbindd/winbindd_cm.c samba-4.5.6+dfsg/source3/winbindd/winbindd_cm.c
--- samba-4.5.5+dfsg/source3/winbindd/winbindd_cm.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source3/winbindd/winbindd_cm.c 2017-03-09 10:21:43.000000000 +0100
@@ -903,7 +903,6 @@
struct cli_credentials *creds;
NTSTATUS status;
bool force_machine_account = false;
- bool ok;
/* If we are a DC and this is not our own domain */
@@ -937,24 +936,7 @@
goto ipc_fallback;
}
- if (domain->primary && lp_security() == SEC_ADS) {
- cli_credentials_set_kerberos_state(creds,
- CRED_AUTO_USE_KERBEROS);
- } else if (domain->active_directory) {
- cli_credentials_set_kerberos_state(creds,
- CRED_MUST_USE_KERBEROS);
- } else {
- cli_credentials_set_kerberos_state(creds,
- CRED_DONT_USE_KERBEROS);
- }
-
- /*
- * When we contact our own domain and get a list of the trusted domain
- * we have the information if we are able to contact the DC with
- * with our machine account password.
- */
- ok = winbindd_can_contact_domain(domain);
- if (!ok) {
+ if (creds_domain != domain) {
/*
* We can only use schannel against a direct trust
*/
@@ -1002,6 +984,8 @@
struct named_mutex *mutex;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ NTSTATUS tmp_status;
+ NTSTATUS tcon_status = NT_STATUS_NETWORK_NAME_DELETED;
enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing();
@@ -1103,6 +1087,10 @@
}
}
+ if (cli_credentials_is_anonymous(creds)) {
+ goto anon_fallback;
+ }
+
krb5_state = cli_credentials_get_kerberos_state(creds);
machine_krb5_principal = cli_credentials_get_principal(creds,
@@ -1138,8 +1126,10 @@
goto session_setup_done;
}
- DEBUG(4,("failed kerberos session setup with %s\n",
- nt_errstr(result)));
+ DEBUG(1, ("Failed to use kerberos connecting to %s from %s "
+ "with kerberos principal [%s]\n",
+ controller, lp_netbios_name(),
+ machine_krb5_principal));
}
if (krb5_state != CRED_MUST_USE_KERBEROS) {
@@ -1157,10 +1147,15 @@
machine_password,
strlen(machine_password)+1,
machine_domain);
- }
- if (NT_STATUS_IS_OK(result)) {
- goto session_setup_done;
+ if (NT_STATUS_IS_OK(result)) {
+ goto session_setup_done;
+ }
+
+ DEBUG(1, ("Failed to use NTLMSSP connecting to %s from %s "
+ "with username [%s]\\[%s]\n",
+ controller, lp_netbios_name(),
+ machine_domain, machine_account));
}
/*
@@ -1174,10 +1169,6 @@
|| NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
|| NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
{
- if (cli_credentials_is_anonymous(creds)) {
- goto done;
- }
-
if (!cm_is_ipc_credentials(creds)) {
goto ipc_fallback;
}
@@ -1189,19 +1180,22 @@
goto anon_fallback;
}
- DEBUG(4, ("authenticated session setup failed with %s\n",
- nt_errstr(result)));
+ DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
+ controller,
+ cli_credentials_get_unparsed_name(creds, talloc_tos()),
+ nt_errstr(result)));
goto done;
ipc_fallback:
- result = cm_get_ipc_credentials(talloc_tos(), &creds);
- if (!NT_STATUS_IS_OK(result)) {
+ TALLOC_FREE(creds);
+ tmp_status = cm_get_ipc_credentials(talloc_tos(), &creds);
+ if (!NT_STATUS_IS_OK(tmp_status)) {
+ result = tmp_status;
goto done;
}
if (cli_credentials_is_anonymous(creds)) {
- TALLOC_FREE(creds);
goto anon_fallback;
}
@@ -1228,6 +1222,11 @@
goto session_setup_done;
}
+ DEBUG(1, ("Failed to use NTLMSSP connecting to %s from %s "
+ "with username "
+ "[%s]\\[%s]\n", controller, lp_netbios_name(),
+ machine_domain, machine_account));
+
/*
* If we are not going to validiate the conneciton
* with SMB signing, then allow us to fall back to
@@ -1242,19 +1241,22 @@
goto anon_fallback;
}
- DEBUG(4, ("authenticated session setup failed with %s\n",
- nt_errstr(result)));
+ DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
+ controller,
+ cli_credentials_get_unparsed_name(creds, talloc_tos()),
+ nt_errstr(result)));
goto done;
anon_fallback:
+ TALLOC_FREE(creds);
if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
goto done;
}
/* Fall back to anonymous connection, this might fail later */
- DEBUG(10,("cm_prepare_connection: falling back to anonymous "
+ DEBUG(5,("cm_prepare_connection: falling back to anonymous "
"connection for DC %s\n",
controller ));
@@ -1266,6 +1268,9 @@
goto session_setup_done;
}
+ DEBUG(1, ("anonymous session setup to %s failed with %s\n",
+ controller, nt_errstr(result)));
+
/* We can't session setup */
goto done;
@@ -1283,11 +1288,11 @@
}
result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0);
-
if (!NT_STATUS_IS_OK(result)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
goto done;
}
+ tcon_status = result;
/* cache the server name for later connections */
@@ -1306,7 +1311,13 @@
done:
TALLOC_FREE(mutex);
+ if (NT_STATUS_IS_OK(result)) {
+ result = tcon_status;
+ }
+
if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
+ controller, nt_errstr(result)));
winbind_add_failed_connection_entry(domain, controller, result);
if ((*cli) != NULL) {
cli_shutdown(*cli);
@@ -3293,9 +3304,28 @@
sec_chan_type = cli_credentials_get_secure_channel_type(creds);
if (sec_chan_type == SEC_CHAN_NULL) {
- DBG_WARNING("get_secure_channel_type gave SEC_CHAN_NULL for %s\n",
- domain->name);
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ if (transport == NCACN_IP_TCP) {
+ DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
+ " deny NCACN_IP_TCP and let the caller fallback to NCACN_NP.\n",
+ domain->name);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
+ "fallback to noauth on NCACN_NP.\n",
+ domain->name);
+
+ result = cli_rpc_pipe_open_noauth_transport(conn->cli,
+ transport,
+ &ndr_table_netlogon,
+ &conn->netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
+ invalidate_cm_connection(domain);
+ return result;
+ }
+
+ *cli = conn->netlogon_pipe;
+ return NT_STATUS_OK;
}
result = rpccli_create_netlogon_creds_with_creds(creds,
@@ -3334,11 +3364,6 @@
conn->netlogon_flags = netlogon_creds->negotiate_flags;
TALLOC_FREE(netlogon_creds);
- /*
- * FIXME: Document in which case we are not able to contact
- * a DC without schannel. Which information do we try to get
- * from this DC?
- */
if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
result = NT_STATUS_DOWNGRADE_DETECTED;
diff -Nru samba-4.5.5+dfsg/source3/winbindd/winbindd_util.c samba-4.5.6+dfsg/source3/winbindd/winbindd_util.c
--- samba-4.5.5+dfsg/source3/winbindd/winbindd_util.c 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/source3/winbindd/winbindd_util.c 2017-03-09 10:21:43.000000000 +0100
@@ -345,6 +345,20 @@
char *p;
struct winbindd_tdc_domain trust_params = {0};
ptrdiff_t extra_len;
+ bool within_forest = false;
+
+ /*
+ * Only when we enumerate our primary domain
+ * or our forest root domain, we should keep
+ * the NETR_TRUST_FLAG_IN_FOREST flag, in
+ * all other cases we need to clear it as the domain
+ * is not part of our forest.
+ */
+ if (state->domain->primary) {
+ within_forest = true;
+ } else if (domain_is_forest_root(state->domain)) {
+ within_forest = true;
+ }
res = wb_domain_request_recv(req, state, &response, &err);
if ((res == -1) || (response->result != WINBINDD_OK)) {
@@ -430,6 +444,14 @@
trust_params.trust_attribs = (uint32_t)strtoul(q, NULL, 10);
+ if (!within_forest) {
+ trust_params.trust_flags &= ~NETR_TRUST_FLAG_IN_FOREST;
+ }
+
+ if (!state->domain->primary) {
+ trust_params.trust_flags &= ~NETR_TRUST_FLAG_PRIMARY;
+ }
+
/*
* We always call add_trusted_domain() cause on an existing
* domain structure, it will update the SID if necessary.
diff -Nru samba-4.5.5+dfsg/source3/wscript_build samba-4.5.6+dfsg/source3/wscript_build
--- samba-4.5.5+dfsg/source3/wscript_build 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/source3/wscript_build 2017-03-09 10:21:43.000000000 +0100
@@ -455,7 +455,7 @@
libads/ldap_schema.c
libads/util.c
libads/ndr.c''',
- deps='cli-ldap-common krb5samba ldap lber KRBCLIENT param LIBNMB libsmb DCUTIL smbldap',
+ deps='cli-ldap-common krb5samba ldap lber KRBCLIENT param LIBNMB libsmb DCUTIL smbldap trusts_util',
private_library=True)
bld.SAMBA3_SUBSYSTEM('LIBADS_SERVER',
diff -Nru samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/password_hash.c samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/password_hash.c
--- samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/password_hash.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/password_hash.c 2017-03-09 10:21:43.000000000 +0100
@@ -35,6 +35,7 @@
#include "includes.h"
#include "ldb_module.h"
#include "libcli/auth/libcli_auth.h"
+#include "libcli/security/dom_sid.h"
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
#include "dsdb/samdb/samdb.h"
@@ -125,6 +126,7 @@
const char *sAMAccountName;
const char *user_principal_name;
bool is_computer;
+ bool is_krbtgt;
uint32_t restrictions;
} u;
@@ -2793,6 +2795,8 @@
ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
int ret;
const struct ldb_message *info_msg = NULL;
+ struct dom_sid *account_sid = NULL;
+ int rodc_krbtgt = 0;
ZERO_STRUCTP(io);
@@ -2837,6 +2841,26 @@
"userPrincipalName", NULL);
io->u.is_computer = ldb_msg_check_string_attribute(info_msg, "objectClass", "computer");
+ /* Ensure it has an objectSID too */
+ account_sid = samdb_result_dom_sid(ac, info_msg, "objectSid");
+ if (account_sid != NULL) {
+ NTSTATUS status;
+ uint32_t rid = 0;
+
+ status = dom_sid_split_rid(account_sid, account_sid, NULL, &rid);
+ if (NT_STATUS_IS_OK(status)) {
+ if (rid == DOMAIN_RID_KRBTGT) {
+ io->u.is_krbtgt = true;
+ }
+ }
+ }
+
+ rodc_krbtgt = ldb_msg_find_attr_as_int(info_msg,
+ "msDS-SecondaryKrbTgtNumber", 0);
+ if (rodc_krbtgt != 0) {
+ io->u.is_krbtgt = true;
+ }
+
if (io->u.sAMAccountName == NULL) {
ldb_asprintf_errstring(ldb,
"setup_io: sAMAccountName attribute is missing on %s for attempted password set/change",
@@ -2867,6 +2891,12 @@
& (UF_INTERDOMAIN_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT
| UF_SERVER_TRUST_ACCOUNT));
+ if (io->u.is_krbtgt) {
+ io->u.restrictions = 0;
+ io->ac->status->domain_data.pwdHistoryLength =
+ MAX(io->ac->status->domain_data.pwdHistoryLength, 3);
+ }
+
if (ac->userPassword) {
ret = msg_find_old_and_new_pwd_val(client_msg, "userPassword",
ac->req->operation,
@@ -3172,6 +3202,59 @@
return ldb_operr(ldb);
}
+ if (io->u.is_krbtgt) {
+ size_t min = 196;
+ size_t max = 255;
+ size_t diff = max - min;
+ size_t len = max;
+ struct ldb_val *krbtgt_utf16 = NULL;
+
+ if (!ac->pwd_reset) {
+ return dsdb_module_werror(ac->module,
+ LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS,
+ WERR_DS_ATT_ALREADY_EXISTS,
+ "Password change on krbtgt not permitted!");
+ }
+
+ if (io->n.cleartext_utf16 == NULL) {
+ return dsdb_module_werror(ac->module,
+ LDB_ERR_UNWILLING_TO_PERFORM,
+ WERR_DS_INVALID_ATTRIBUTE_SYNTAX,
+ "Password reset on krbtgt requires UTF16!");
+ }
+
+ /*
+ * Instead of taking the callers value,
+ * we just generate a new random value here.
+ *
+ * Include null termination in the array.
+ */
+ if (diff > 0) {
+ size_t tmp;
+
+ generate_random_buffer((uint8_t *)&tmp, sizeof(tmp));
+
+ tmp %= diff;
+
+ len = min + tmp;
+ }
+
+ krbtgt_utf16 = talloc_zero(io->ac, struct ldb_val);
+ if (krbtgt_utf16 == NULL) {
+ return ldb_oom(ldb);
+ }
+
+ *krbtgt_utf16 = data_blob_talloc_zero(krbtgt_utf16,
+ (len+1)*2);
+ if (krbtgt_utf16->data == NULL) {
+ return ldb_oom(ldb);
+ }
+ krbtgt_utf16->length = len * 2;
+ generate_secret_buffer(krbtgt_utf16->data,
+ krbtgt_utf16->length);
+ io->n.cleartext_utf16 = krbtgt_utf16;
+ }
+
if (existing_msg != NULL) {
NTSTATUS status;
@@ -4055,6 +4138,7 @@
"badPasswordTime",
"badPwdCount",
"lockoutTime",
+ "msDS-SecondaryKrbTgtNumber",
NULL };
struct ldb_request *search_req;
int ret;
diff -Nru samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/repl_meta_data.c samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/repl_meta_data.c
--- samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 2016-10-24 21:37:30.000000000 +0200
+++ samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/repl_meta_data.c 2017-03-09 10:21:43.000000000 +0100
@@ -1446,15 +1446,21 @@
NTTIME now,
bool is_schema_nc)
{
+ const char *rdn_name = ldb_dn_get_rdn_name(msg->dn);
+ const struct dsdb_attribute *rdn_attr =
+ dsdb_attribute_by_lDAPDisplayName(ar->schema, rdn_name);
+ const char *attr_name = rdn_attr != NULL ?
+ rdn_attr->lDAPDisplayName :
+ rdn_name;
struct ldb_message_element new_el = {
.flags = LDB_FLAG_MOD_REPLACE,
- .name = ldb_dn_get_rdn_name(msg->dn),
+ .name = attr_name,
.num_values = 1,
.values = discard_const_p(struct ldb_val, rdn_new)
};
struct ldb_message_element old_el = {
.flags = LDB_FLAG_MOD_REPLACE,
- .name = ldb_dn_get_rdn_name(msg->dn),
+ .name = attr_name,
.num_values = rdn_old ? 1 : 0,
.values = discard_const_p(struct ldb_val, rdn_old)
};
diff -Nru samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/samba_dsdb.c samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
--- samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/samba_dsdb.c 2016-08-11 09:51:04.000000000 +0200
+++ samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/samba_dsdb.c 2017-03-09 10:21:43.000000000 +0100
@@ -231,7 +231,7 @@
static int samba_dsdb_init(struct ldb_module *module)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
- int ret, len, i;
+ int ret, len, i, j;
TALLOC_CTX *tmp_ctx = talloc_new(module);
struct ldb_result *res;
struct ldb_message *rootdse_msg = NULL, *partition_msg;
@@ -317,11 +317,15 @@
static const char *openldap_backend_modules[] = {
"dsdb_flags_ignore", "entryuuid", "simple_dn", NULL };
- static const char *samba_dsdb_attrs[] = { "backendType", NULL };
+ static const char *samba_dsdb_attrs[] = { "backendType",
+ SAMBA_COMPATIBLE_FEATURES_ATTR,
+ SAMBA_REQUIRED_FEATURES_ATTR, NULL };
static const char *partition_attrs[] = { "ldapBackend", NULL };
const char *backendType, *backendUrl;
bool use_sasl_external = false;
+ const char *current_supportedFeatures[] = {};
+
if (!tmp_ctx) {
return ldb_oom(ldb);
}
@@ -357,7 +361,77 @@
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
backendType = "ldb";
} else if (ret == LDB_SUCCESS) {
+ struct ldb_message_element *requiredFeatures;
+ struct ldb_message_element *old_compatibleFeatures;
+
backendType = ldb_msg_find_attr_as_string(res->msgs[0], "backendType", "ldb");
+
+ requiredFeatures = ldb_msg_find_element(res->msgs[0], SAMBA_REQUIRED_FEATURES_ATTR);
+ if (requiredFeatures != NULL) {
+ ldb_set_errstring(ldb, "This Samba database was created with "
+ "a newer Samba version and is marked with "
+ "requiredFeatures in @SAMBA_DSDB. "
+ "This database can not safely be read by this Samba version");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ old_compatibleFeatures = ldb_msg_find_element(res->msgs[0],
+ SAMBA_COMPATIBLE_FEATURES_ATTR);
+
+ if (old_compatibleFeatures) {
+ struct ldb_message *features_msg;
+ struct ldb_message_element *features_el;
+
+ features_msg = ldb_msg_new(res);
+ if (features_msg == NULL) {
+ return ldb_module_operr(module);
+ }
+ features_msg->dn = samba_dsdb_dn;
+
+ ldb_msg_add_empty(features_msg, SAMBA_COMPATIBLE_FEATURES_ATTR,
+ LDB_FLAG_MOD_DELETE, &features_el);
+
+ for (i = 0;
+ old_compatibleFeatures && i < old_compatibleFeatures->num_values;
+ i++) {
+ for (j = 0;
+ j < ARRAY_SIZE(current_supportedFeatures); j++) {
+ if (strcmp((char *)old_compatibleFeatures->values[i].data,
+ current_supportedFeatures[j]) == 0) {
+ break;
+ }
+ }
+ if (j == ARRAY_SIZE(current_supportedFeatures)) {
+ /*
+ * Add to list of features to remove
+ * (rather than all features)
+ */
+ ret = ldb_msg_add_value(features_msg, SAMBA_COMPATIBLE_FEATURES_ATTR,
+ &old_compatibleFeatures->values[i],
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+ if (features_el->num_values > 0) {
+ /* Delete by list */
+ ret = ldb_next_start_trans(module);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ ret = dsdb_module_modify(module, features_msg, DSDB_FLAG_NEXT_MODULE, NULL);
+ if (ret != LDB_SUCCESS) {
+ ldb_next_del_trans(module);
+ return ret;
+ }
+ ret = ldb_next_end_trans(module);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+ }
+
} else {
talloc_free(tmp_ctx);
return ret;
diff -Nru samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c
--- samba-4.5.5+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/source4/dsdb/samdb/ldb_modules/samldb.c 2017-03-09 10:21:43.000000000 +0100
@@ -386,7 +386,6 @@
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
uint32_t krbtgt_number, i_start, i;
int ret;
- char *newpass;
struct ldb_val newpass_utf16;
/* find a unused msDC-SecondaryKrbTgtNumber */
@@ -432,21 +431,17 @@
return ldb_operr(ldb);
}
- newpass = generate_random_password(ac->msg, 128, 255);
- if (newpass == NULL) {
- return ldb_operr(ldb);
- }
-
- if (!convert_string_talloc(ac,
- CH_UNIX, CH_UTF16,
- newpass, strlen(newpass),
- (void *)&newpass_utf16.data,
- &newpass_utf16.length)) {
- ldb_asprintf_errstring(ldb,
- "samldb_rodc_add: "
- "failed to generate UTF16 password from random password");
- return LDB_ERR_OPERATIONS_ERROR;
- }
+ newpass_utf16 = data_blob_talloc_zero(ac->module, 256);
+ if (newpass_utf16.data == NULL) {
+ return ldb_oom(ldb);
+ }
+ /*
+ * Note that the password_hash module will ignore
+ * this value and use it's own generate_secret_buffer()
+ * that's why we can just use generate_random_buffer()
+ * here.
+ */
+ generate_random_buffer(newpass_utf16.data, newpass_utf16.length);
ret = ldb_msg_add_steal_value(ac->msg, "clearTextPassword", &newpass_utf16);
if (ret != LDB_SUCCESS) {
return ldb_operr(ldb);
diff -Nru samba-4.5.5+dfsg/source4/dsdb/samdb/samdb.h samba-4.5.6+dfsg/source4/dsdb/samdb/samdb.h
--- samba-4.5.5+dfsg/source4/dsdb/samdb/samdb.h 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/source4/dsdb/samdb/samdb.h 2017-03-09 10:21:43.000000000 +0100
@@ -314,4 +314,6 @@
*/
#define DSDB_FLAG_INTERNAL_FORCE_META_DATA 0x10000
+#define SAMBA_COMPATIBLE_FEATURES_ATTR "compatibleFeatures"
+#define SAMBA_REQUIRED_FEATURES_ATTR "requiredFeatures"
#endif /* __SAMDB_H__ */
diff -Nru samba-4.5.5+dfsg/source4/ldap_server/ldap_bind.c samba-4.5.6+dfsg/source4/ldap_server/ldap_bind.c
--- samba-4.5.5+dfsg/source4/ldap_server/ldap_bind.c 2016-08-11 09:51:05.000000000 +0200
+++ samba-4.5.6+dfsg/source4/ldap_server/ldap_bind.c 2017-03-09 10:21:43.000000000 +0100
@@ -29,6 +29,37 @@
#include "param/param.h"
#include "../lib/util/tevent_ntstatus.h"
+static char *ldapsrv_bind_error_msg(TALLOC_CTX *mem_ctx,
+ HRESULT hresult,
+ uint32_t DSID,
+ NTSTATUS status)
+{
+ WERROR werr;
+ char *msg = NULL;
+
+ status = nt_status_squash(status);
+ werr = ntstatus_to_werror(status);
+
+ /*
+ * There are 4 lower case hex digits following 'v' at the end,
+ * but different Windows Versions return different values:
+ *
+ * Windows 2008R2 uses 'v1db1'
+ * Windows 2012R2 uses 'v2580'
+ *
+ * We just match Windows 2008R2 as that's what was referenced
+ * in https://bugzilla.samba.org/show_bug.cgi?id=9048
+ */
+ msg = talloc_asprintf(mem_ctx, "%08X: LdapErr: DSID-%08X, comment: "
+ "AcceptSecurityContext error, data %x, v1db1",
+ (unsigned)HRES_ERROR_V(hresult),
+ (unsigned)DSID,
+ (unsigned)W_ERROR_V(werr));
+
+ return msg;
+}
+
+
static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
{
struct ldap_BindRequest *req = &call->request->r.BindRequest;
@@ -95,7 +126,8 @@
status = nt_status_squash(status);
result = LDAP_INVALID_CREDENTIALS;
- errstr = talloc_asprintf(reply, "Simple Bind Failed: %s", nt_errstr(status));
+ errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_INVALID_TOKEN,
+ 0x0C0903A9, status);
}
do_reply:
@@ -346,7 +378,8 @@
status = nt_status_squash(status);
if (result == 0) {
result = LDAP_INVALID_CREDENTIALS;
- errstr = talloc_asprintf(reply, "SASL:[%s]: %s", req->creds.SASL.mechanism, nt_errstr(status));
+ errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
+ 0x0C0904DC, status);
}
talloc_unlink(conn, conn->gensec);
conn->gensec = NULL;
diff -Nru samba-4.5.5+dfsg/source4/libcli/raw/smb.h samba-4.5.6+dfsg/source4/libcli/raw/smb.h
--- samba-4.5.5+dfsg/source4/libcli/raw/smb.h 2016-08-11 09:51:05.000000000 +0200
+++ samba-4.5.6+dfsg/source4/libcli/raw/smb.h 2017-03-09 10:21:43.000000000 +0100
@@ -297,13 +297,6 @@
#define UID_FIELD_INVALID 0
-/* The maximum length of a trust account password.
- Used when we randomly create it, 15 char passwords
- exceed NT4's max password length */
-
-#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
-
-
/*
filesystem attribute bits
*/
diff -Nru samba-4.5.5+dfsg/source4/libnet/libnet_vampire.c samba-4.5.6+dfsg/source4/libnet/libnet_vampire.c
--- samba-4.5.5+dfsg/source4/libnet/libnet_vampire.c 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/source4/libnet/libnet_vampire.c 2017-03-09 10:21:43.000000000 +0100
@@ -160,7 +160,7 @@
settings.realm = s->realm;
settings.domain = s->domain_name;
settings.server_dn_str = p->dest_dsa->server_dn_str;
- settings.machine_password = generate_random_password(s, 16, 255);
+ settings.machine_password = generate_random_machine_password(s, 128, 255);
settings.targetdir = s->targetdir;
settings.use_ntvfs = true;
status = provision_bare(s, s->lp_ctx, &settings, &result);
diff -Nru samba-4.5.5+dfsg/source4/scripting/bin/renamedc samba-4.5.6+dfsg/source4/scripting/bin/renamedc
--- samba-4.5.5+dfsg/source4/scripting/bin/renamedc 2016-08-11 09:51:05.000000000 +0200
+++ samba-4.5.6+dfsg/source4/scripting/bin/renamedc 2017-03-09 10:21:43.000000000 +0100
@@ -95,7 +95,7 @@
# Then change password and samaccountname and dnshostname
msg = ldb.Message(newdn)
- machinepass = samba.generate_random_password(128, 255)
+ machinepass = samba.generate_random_machine_password(128, 255)
mputf16 = machinepass.encode('utf-16-le')
account = "%s$" % opts.newname.upper()
diff -Nru samba-4.5.5+dfsg/source4/selftest/tests.py samba-4.5.6+dfsg/source4/selftest/tests.py
--- samba-4.5.5+dfsg/source4/selftest/tests.py 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/source4/selftest/tests.py 2017-03-09 10:21:43.000000000 +0100
@@ -625,6 +625,11 @@
plantestsuite("samba4.blackbox.samba3dump", "none", [os.path.join(samba4srcdir, "selftest/test_samba3dump.sh")])
plantestsuite("samba4.blackbox.upgrade", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_s3upgrade.sh"), '$PREFIX/provision'])
plantestsuite("samba4.blackbox.provision.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_provision.sh"), '$PREFIX/provision'])
+plantestsuite("samba4.blackbox.supported_features", "none",
+ ["PYTHON=%s" % python,
+ os.path.join(samba4srcdir,
+ "setup/tests/blackbox_supported_features.sh"),
+ '$PREFIX/provision'])
plantestsuite("samba4.blackbox.upgradeprovision.current", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_upgradeprovision.sh"), '$PREFIX/provision'])
plantestsuite("samba4.blackbox.setpassword.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_setpassword.sh"), '$PREFIX/provision'])
plantestsuite("samba4.blackbox.newuser.py", "none", ["PYTHON=%s" % python, os.path.join(samba4srcdir, "setup/tests/blackbox_newuser.sh"), '$PREFIX/provision'])
diff -Nru samba-4.5.5+dfsg/source4/setup/tests/blackbox_supported_features.sh samba-4.5.6+dfsg/source4/setup/tests/blackbox_supported_features.sh
--- samba-4.5.5+dfsg/source4/setup/tests/blackbox_supported_features.sh 1970-01-01 01:00:00.000000000 +0100
+++ samba-4.5.6+dfsg/source4/setup/tests/blackbox_supported_features.sh 2017-03-09 10:21:43.000000000 +0100
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+if [ $# -lt 1 ]; then
+cat <<EOF
+Usage: blackbox_supported_features.sh PREFIX
+EOF
+exit 1;
+fi
+
+PREFIX="$1"
+shift 1
+
+DBPATH=$PREFIX/supported-features
+
+. `dirname $0`/../../../testprogs/blackbox/subunit.sh
+
+ldbmodify="ldbmodify"
+if [ -x "$BINDIR/ldbmodify" ]; then
+ ldbmodify="$BINDIR/ldbmodify"
+fi
+
+ldbdel="ldbdel"
+if [ -x "$BINDIR/ldbdel" ]; then
+ ldbdel="$BINDIR/ldbdel"
+fi
+
+ldbsearch="ldbsearch"
+if [ -x "$BINDIR/ldbsearch" ]; then
+ ldbsearch="$BINDIR/ldbsearch"
+fi
+
+testit "provision" $PYTHON $BINDIR/samba-tool domain provision \
+ --domain=FOO --realm=foo.example.com \
+ --targetdir=$DBPATH --use-ntvfs
+
+testit "add-compatible-feature" $ldbmodify \
+ -H tdb://$DBPATH/private/sam.ldb <<EOF
+dn: @SAMBA_DSDB
+changetype: modify
+add: compatibleFeatures
+compatibleFeatures: non-existent-feature
+-
+
+EOF
+
+# The non-existent feature is not compatible with this version, so it
+# should not be listed in compatibleFeatures even though we tried to
+# put it there.
+
+ldb_search_fail() {
+ $ldbsearch -H tdb://$DBPATH/private/sam.ldb \
+ -s base -b "$1" "$2" \
+ | grep -q "$3"
+}
+
+
+testit_expect_failure "find-compatible-feature" \
+ ldb_search_fail '@SAMBA_DSDB' 'compatibleFeatures' non-existent-feature
+
+
+# just make sure the thing we're using is normally findable
+testit "find-test-feature" \
+ $ldbsearch -H tdb://$DBPATH/private/sam.ldb \
+ -b 'CN=LostAndFound,DC=foo,DC=example,DC=com'
+
+
+testit "add-required-feature" $ldbmodify \
+ -H tdb://$DBPATH/private/sam.ldb <<EOF
+dn: @SAMBA_DSDB
+changetype: modify
+add: requiredFeatures
+requiredFeatures: futuristic-feature
+-
+
+EOF
+
+# The futuristic-feature is not implemented in this version, but it is
+# required by this database. A search for anything should fail.
+
+testit_expect_failure "find-required-feature" \
+ $ldbsearch -H tdb://$DBPATH/private/sam.ldb \
+ -b 'CN=LostAndFound,DC=foo,DC=example,DC=com'
+
+rm -rf $DBPATH
+
+exit $failed
diff -Nru samba-4.5.5+dfsg/source4/torture/vfs/fruit.c samba-4.5.6+dfsg/source4/torture/vfs/fruit.c
--- samba-4.5.5+dfsg/source4/torture/vfs/fruit.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source4/torture/vfs/fruit.c 2017-03-09 10:21:43.000000000 +0100
@@ -2451,6 +2451,7 @@
struct srv_copychunk_rsp cc_rsp;
enum ndr_err_code ndr_ret;
bool ok;
+ const char *sname = ":foo" "\xef\x80\xa2" "bar:$DATA";
/*
* First test a copy_chunk with a 0 chunk count without having
@@ -2521,6 +2522,11 @@
torture_fail(torture, "setup stream error");
}
+ ok = write_stream(tree, __location__, torture, tmp_ctx,
+ FNAME_CC_SRC, sname,
+ 10, 10, "abcdefghij");
+ torture_assert_goto(torture, ok == true, ok, done, "write_stream failed\n");
+
ok = test_setup_copy_chunk(torture, tree, tmp_ctx,
0, /* 0 chunks, copyfile semantics */
&src_h, 4096, /* fill 4096 byte src file */
@@ -2573,6 +2579,11 @@
torture_fail_goto(torture, done, "inconsistent stream data");
}
+ ok = check_stream(tree, __location__, torture, tmp_ctx,
+ FNAME_CC_DST, sname,
+ 0, 20, 10, 10, "abcdefghij");
+ torture_assert_goto(torture, ok == true, ok, done, "check_stream failed\n");
+
done:
smb2_util_close(tree, src_h);
smb2_util_close(tree, dest_h);
@@ -3527,6 +3538,383 @@
}
/*
+ * This tests that right after creating the AFP_AfpInfo stream,
+ * reading from the stream returns an empty, default metadata blob of
+ * 60 bytes.
+ *
+ * NOTE: against OS X SMB server this only works if the read request
+ * is compounded with the create that created the stream, is fails
+ * otherwise. We don't care...
+ */
+static bool test_null_afpinfo(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const char *fname = "test_null_afpinfo";
+ const char *sname = "test_null_afpinfo" AFPINFO_STREAM_NAME;
+ NTSTATUS status;
+ bool ret = true;
+ struct smb2_request *req[3];
+ struct smb2_handle handle;
+ struct smb2_create create;
+ struct smb2_read read;
+ AfpInfo *afpinfo = NULL;
+ char *afpinfo_buf = NULL;
+ const char *type_creator = "SMB,OLE!";
+
+ torture_comment(tctx, "Checking create of AfpInfo stream\n");
+
+ smb2_util_unlink(tree, fname);
+
+ ret = torture_setup_file(mem_ctx, tree, fname, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA;
+ create.in.share_access = FILE_SHARE_READ | FILE_SHARE_DELETE;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+ create.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+ create.in.fname = sname;
+
+ smb2_transport_compound_start(tree->session->transport, 2);
+
+ req[0] = smb2_create_send(tree, &create);
+
+ handle.data[0] = UINT64_MAX;
+ handle.data[1] = UINT64_MAX;
+
+ smb2_transport_compound_set_related(tree->session->transport, true);
+
+ ZERO_STRUCT(read);
+ read.in.file.handle = handle;
+ read.in.length = AFP_INFO_SIZE;
+ req[1] = smb2_read_send(tree, &read);
+
+ status = smb2_create_recv(req[0], tree, &create);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_recv failed");
+
+ handle = create.out.file.handle;
+
+ status = smb2_read_recv(req[1], tree, &read);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read_recv failed");
+
+ afpinfo = torture_afpinfo_new(mem_ctx);
+ torture_assert_goto(tctx, afpinfo != NULL, ret, done, "torture_afpinfo_new failed");
+
+ memcpy(afpinfo->afpi_FinderInfo, type_creator, 8);
+
+ afpinfo_buf = torture_afpinfo_pack(tctx, afpinfo);
+ torture_assert_goto(tctx, afpinfo_buf != NULL, ret, done, "torture_afpinfo_new failed");
+
+ status = smb2_util_write(tree, handle, afpinfo_buf, 0, AFP_INFO_SIZE);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_write failed");
+
+ smb2_util_close(tree, handle);
+
+ ret = check_stream(tree, __location__, tctx, mem_ctx, fname, AFPINFO_STREAM,
+ 0, 60, 16, 8, type_creator);
+ torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed");
+
+done:
+ smb2_util_unlink(tree, fname);
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+static bool test_delete_file_with_rfork(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ const char *fname = "torture_write_rfork_io";
+ const char *rfork_content = "1234567890";
+ NTSTATUS status;
+ bool ret = true;
+
+ smb2_util_unlink(tree, fname);
+
+ torture_comment(tctx, "Test deleting file with resource fork\n");
+
+ ret = torture_setup_file(tctx, tree, fname, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed\n");
+
+ ret = write_stream(tree, __location__, tctx, tctx,
+ fname, AFPRESOURCE_STREAM_NAME,
+ 10, 10, rfork_content);
+ torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed\n");
+
+ ret = check_stream(tree, __location__, tctx, tctx,
+ fname, AFPRESOURCE_STREAM_NAME,
+ 0, 20, 10, 10, rfork_content);
+ torture_assert_goto(tctx, ret == true, ret, done, "check_stream failed\n");
+
+ status = smb2_util_unlink(tree, fname);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "check_stream failed\n");
+
+done:
+ return ret;
+}
+
+static bool test_rename_and_read_rsrc(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ bool ret = true;
+ NTSTATUS status;
+ struct smb2_create create, create2;
+ struct smb2_handle h1, h2;
+ const char *fname = "test_rename_openfile";
+ const char *sname = "test_rename_openfile" AFPRESOURCE_STREAM_NAME;
+ const char *fname_renamed = "test_rename_openfile_renamed";
+ const char *data = "1234567890";
+ union smb_setfileinfo sinfo;
+ struct smb2_read r;
+
+ ret = enable_aapl(tctx, tree);
+ torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
+
+ torture_comment(tctx, "Create file with resource fork\n");
+
+ ret = torture_setup_file(tctx, tree, fname, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
+
+ ret = write_stream(tree, __location__, tctx, tctx,
+ fname, AFPRESOURCE_STREAM_NAME, 0, 10, data);
+ torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
+
+ torture_comment(tctx, "Open resource fork\n");
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_FILE_ALL;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+ create.in.fname = sname;
+
+ status = smb2_create(tree, tctx, &create);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
+
+ h1 = create.out.file.handle;
+
+ torture_comment(tctx, "Rename base file\n");
+
+ ZERO_STRUCT(create2);
+ create2.in.desired_access = SEC_FILE_ALL;
+ create2.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create2.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+ create2.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create2.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+ create2.in.fname = fname;
+
+ status = smb2_create(tree, tctx, &create2);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
+
+ h2 = create2.out.file.handle;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.handle = h2;
+ sinfo.rename_information.in.overwrite = 0;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = fname_renamed;
+
+ status = smb2_setinfo_file(tree, &sinfo);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file failed");
+
+ smb2_util_close(tree, h2);
+
+ ZERO_STRUCT(r);
+ r.in.file.handle = h1;
+ r.in.length = 10;
+ r.in.offset = 0;
+
+ torture_comment(tctx, "Read resource fork of renamed file\n");
+
+ status = smb2_read(tree, tree, &r);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_read failed");
+
+ smb2_util_close(tree, h1);
+
+ torture_assert_goto(tctx, r.out.data.length == 10, ret, done,
+ talloc_asprintf(tctx, "smb2_read returned %jd bytes, expected 10\n",
+ (intmax_t)r.out.data.length));
+
+ torture_assert_goto(tctx, memcmp(r.out.data.data, data, 10) == 0, ret, done,
+ talloc_asprintf(tctx, "Bad data in stream\n"));
+
+done:
+ smb2_util_unlink(tree, fname);
+ smb2_util_unlink(tree, fname_renamed);
+
+ return ret;
+}
+
+static bool test_readdir_attr_illegal_ntfs(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ const char *name = "test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
+ const char *fname = BASEDIR "\\test" "\xef\x80\xa2" "aapl"; /* "test:aapl" */
+ NTSTATUS status;
+ struct smb2_handle testdirh;
+ bool ret = true;
+ struct smb2_create io;
+ AfpInfo *info;
+ const char *type_creator = "SMB,OLE!";
+ struct smb2_find f;
+ unsigned int count;
+ union smb_search_data *d;
+ uint64_t rfork_len;
+ int i;
+
+ smb2_deltree(tree, BASEDIR);
+
+ status = torture_smb2_testdir(tree, BASEDIR, &testdirh);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir failed");
+ smb2_util_close(tree, testdirh);
+
+ torture_comment(tctx, "Enabling AAPL\n");
+
+ ret = enable_aapl(tctx, tree);
+ torture_assert_goto(tctx, ret == true, ret, done, "enable_aapl failed");
+
+ /*
+ * Now that Requested AAPL extensions are enabled, setup some
+ * Mac files with metadata and resource fork
+ */
+
+ torture_comment(tctx, "Preparing file\n");
+
+ ret = torture_setup_file(mem_ctx, tree, fname, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file failed");
+
+ info = torture_afpinfo_new(mem_ctx);
+ torture_assert_not_null_goto(tctx, info, ret, done, "torture_afpinfo_new failed");
+
+ memcpy(info->afpi_FinderInfo, type_creator, 8);
+ ret = torture_write_afpinfo(tree, tctx, mem_ctx, fname, info);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_write_afpinfo failed");
+
+ ret = write_stream(tree, __location__, tctx, mem_ctx,
+ fname, AFPRESOURCE_STREAM_NAME,
+ 0, 3, "foo");
+ torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
+
+ /*
+ * Ok, file is prepared, now call smb2/find
+ */
+
+ torture_comment(tctx, "Issue find\n");
+
+ ZERO_STRUCT(io);
+ io.in.desired_access = SEC_RIGHTS_DIR_READ;
+ io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ io.in.share_access = (NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE);
+ io.in.create_disposition = NTCREATEX_DISP_OPEN;
+ io.in.fname = BASEDIR;
+ status = smb2_create(tree, tctx, &io);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed");
+
+ ZERO_STRUCT(f);
+ f.in.file.handle = io.out.file.handle;
+ f.in.pattern = "*";
+ f.in.max_response_size = 0x1000;
+ f.in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO;
+
+ status = smb2_find_level(tree, tree, &f, &count, &d);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_find_level failed");
+
+ status = smb2_util_close(tree, io.out.file.handle);
+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed");
+
+ torture_comment(tctx, "Checking find response with enriched macOS metadata\n");
+
+ for (i = 0; i < count; i++) {
+ const char *found = d[i].id_both_directory_info.name.s;
+
+ if (!strcmp(found, ".") || !strcmp(found, ".."))
+ continue;
+ break;
+ }
+
+ torture_assert_str_equal_goto(tctx,
+ d[i].id_both_directory_info.name.s, name,
+ ret, done, "bad name");
+
+ rfork_len = BVAL(d[i].id_both_directory_info.short_name_buf, 0);
+ torture_assert_int_equal_goto(tctx, rfork_len, 3, ret, done, "bad resource fork length");
+
+ torture_assert_mem_equal_goto(tctx, type_creator,
+ d[i].id_both_directory_info.short_name_buf + 8,
+ 8, ret, done, "Bad FinderInfo");
+done:
+ smb2_util_unlink(tree, fname);
+ smb2_deltree(tree, BASEDIR);
+ talloc_free(mem_ctx);
+ return ret;
+}
+
+static bool test_invalid_afpinfo(struct torture_context *tctx,
+ struct smb2_tree *tree1,
+ struct smb2_tree *tree2)
+{
+ const char *fname = "filtest_invalid_afpinfo";
+ const char *sname = "filtest_invalid_afpinfo" AFPINFO_STREAM_NAME;
+ struct smb2_create create;
+ const char *streams_basic[] = {
+ "::$DATA"
+ };
+ const char *streams_afpinfo[] = {
+ "::$DATA",
+ AFPINFO_STREAM
+ };
+ NTSTATUS status;
+ bool ret = true;
+
+ if (tree2 == NULL) {
+ torture_skip_goto(tctx, done, "need second share without fruit\n");
+ }
+
+ torture_comment(tctx, "Testing invalid AFP_AfpInfo stream\n");
+
+ ret = torture_setup_file(tctx, tree2, fname, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "torture_setup_file");
+
+ ret = write_stream(tree2, __location__, tctx, tctx,
+ fname, AFPINFO_STREAM_NAME,
+ 0, 3, "foo");
+ torture_assert_goto(tctx, ret == true, ret, done, "write_stream failed");
+
+ ret = check_stream_list(tree2, tctx, fname, 2, streams_afpinfo, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
+
+ torture_comment(tctx, "Listing streams, bad AFPINFO stream must not be present\n");
+
+ ret = check_stream_list(tree1, tctx, fname, 1, streams_basic, false);
+ torture_assert_goto(tctx, ret == true, ret, done, "Bad streams");
+
+ torture_comment(tctx, "Try to open AFPINFO stream, must fail\n");
+
+ ZERO_STRUCT(create);
+ create.in.desired_access = SEC_FILE_ALL;
+ create.in.share_access = NTCREATEX_SHARE_ACCESS_MASK;
+ create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ create.in.create_disposition = NTCREATEX_DISP_OPEN;
+ create.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION;
+ create.in.fname = sname;
+
+ status = smb2_create(tree1, tctx, &create);
+ torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ ret, done, "Stream still around?");
+
+done:
+ smb2_util_unlink(tree1, fname);
+ return ret;
+}
+
+/*
* Note: This test depends on "vfs objects = catia fruit streams_xattr". For
* some tests torture must be run on the host it tests and takes an additional
* argument with the local path to the share:
@@ -3542,11 +3930,9 @@
suite->description = talloc_strdup(suite, "vfs_fruit tests");
torture_suite_add_1smb2_test(suite, "copyfile", test_copyfile);
- torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
torture_suite_add_1smb2_test(suite, "read metadata", test_read_afpinfo);
torture_suite_add_1smb2_test(suite, "write metadata", test_write_atalk_metadata);
torture_suite_add_1smb2_test(suite, "resource fork IO", test_write_atalk_rfork_io);
- torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
torture_suite_add_1smb2_test(suite, "SMB2/CREATE context AAPL", test_aapl);
torture_suite_add_1smb2_test(suite, "stream names", test_stream_names);
torture_suite_add_1smb2_test(suite, "truncate resource fork to 0 bytes", test_rfork_truncate);
@@ -3560,6 +3946,25 @@
torture_suite_add_1smb2_test(suite, "create delete-on-close AFP_AfpResource", test_create_delete_on_close_resource);
torture_suite_add_1smb2_test(suite, "setinfo delete-on-close AFP_AfpResource", test_setinfo_delete_on_close_resource);
torture_suite_add_1smb2_test(suite, "setinfo eof AFP_AfpResource", test_setinfo_eof_resource);
+ torture_suite_add_1smb2_test(suite, "null afpinfo", test_null_afpinfo);
+ torture_suite_add_1smb2_test(suite, "delete", test_delete_file_with_rfork);
+ torture_suite_add_1smb2_test(suite, "read open rsrc after rename", test_rename_and_read_rsrc);
+ torture_suite_add_1smb2_test(suite, "readdir_attr with names with illegal ntfs characters", test_readdir_attr_illegal_ntfs);
+
+ torture_suite_add_2ns_smb2_test(suite, "invalid AFP_AfpInfo", test_invalid_afpinfo);
+
+ return suite;
+}
+
+struct torture_suite *torture_vfs_fruit_netatalk(void)
+{
+ struct torture_suite *suite = torture_suite_create(
+ talloc_autofree_context(), "fruit_netatalk");
+
+ suite->description = talloc_strdup(suite, "vfs_fruit tests for Netatalk interop that require fruit:metadata=netatalk");
+
+ torture_suite_add_1smb2_test(suite, "read netatalk metadata", test_read_netatalk_metadata);
+ torture_suite_add_1smb2_test(suite, "OS X AppleDouble file conversion", test_adouble_conversion);
return suite;
}
diff -Nru samba-4.5.5+dfsg/source4/torture/vfs/vfs.c samba-4.5.6+dfsg/source4/torture/vfs/vfs.c
--- samba-4.5.5+dfsg/source4/torture/vfs/vfs.c 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/source4/torture/vfs/vfs.c 2017-03-09 10:21:43.000000000 +0100
@@ -38,42 +38,44 @@
struct torture_test *test)
{
bool (*fn) (struct torture_context *, struct smb2_tree *, struct smb2_tree *);
- bool ret = false;
+ bool ok;
- struct smb2_tree *tree1;
- struct smb2_tree *tree2;
+ struct smb2_tree *tree1 = NULL;
+ struct smb2_tree *tree2 = NULL;
TALLOC_CTX *mem_ctx = talloc_new(torture_ctx);
- if (!torture_smb2_con_sopt(torture_ctx, "share1", &tree1)) {
+ if (!torture_smb2_connection(torture_ctx, &tree1)) {
torture_fail(torture_ctx,
- "Establishing SMB2 connection failed\n");
- goto done;
+ "Establishing SMB2 connection failed\n");
+ return false;
}
+ /*
+ * This is a trick:
+ * The test might close the connection. If we steal the tree context
+ * before that and free the parent instead of tree directly, we avoid
+ * a double free error.
+ */
talloc_steal(mem_ctx, tree1);
- if (!torture_smb2_con_sopt(torture_ctx, "share2", &tree2)) {
- torture_fail(torture_ctx,
- "Establishing SMB2 connection failed\n");
- goto done;
+ ok = torture_smb2_con_sopt(torture_ctx, "share2", &tree2);
+ if (ok) {
+ talloc_steal(mem_ctx, tree2);
}
- talloc_steal(mem_ctx, tree2);
-
fn = test->fn;
- ret = fn(torture_ctx, tree1, tree2);
+ ok = fn(torture_ctx, tree1, tree2);
-done:
/* the test may already have closed some of the connections */
talloc_free(mem_ctx);
- return ret;
+ return ok;
}
/*
- * Run a test with 2 connected trees, Share names to connect are taken
- * from option strings "torture:share1" and "torture:share2"
+ * Run a test with 2 connected trees, the default share and another
+ * taken from option strings "torture:share2"
*/
struct torture_test *torture_suite_add_2ns_smb2_test(struct torture_suite *suite,
const char *name,
@@ -107,6 +109,7 @@
suite->description = talloc_strdup(suite, "VFS modules tests");
torture_suite_add_suite(suite, torture_vfs_fruit());
+ torture_suite_add_suite(suite, torture_vfs_fruit_netatalk());
torture_suite_add_suite(suite, torture_acl_xattr());
torture_register_suite(suite);
diff -Nru samba-4.5.5+dfsg/testprogs/blackbox/dbcheck-links.sh samba-4.5.6+dfsg/testprogs/blackbox/dbcheck-links.sh
--- samba-4.5.5+dfsg/testprogs/blackbox/dbcheck-links.sh 2016-12-05 09:18:44.000000000 +0100
+++ samba-4.5.6+dfsg/testprogs/blackbox/dbcheck-links.sh 2017-03-09 10:21:43.000000000 +0100
@@ -91,6 +91,41 @@
fi
}
+add_dangling_link() {
+ ldif=$release_dir/add-dangling-forwardlink-user.ldif
+ TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+
+ ldif=$release_dir/add-initially-normal-link.ldif
+ TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+ sleep 6
+
+ ldif=$release_dir/delete-only-backlink.ldif
+ TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+}
+
+add_dangling_backlink() {
+ ldif=$release_dir/add-dangling-backlink-user.ldif
+ TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+
+ ldif=$release_dir/add-dangling-backlink.ldif
+ TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb.d/DC%3DRELEASE-4-5-0-PRE1,DC%3DSAMBA,DC%3DCORP.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+}
+
add_two_more_users() {
ldif=$release_dir/add-two-more-users.ldif
TZ=UTC $ldbadd -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif
@@ -157,6 +192,14 @@
fi
}
+dangling_one_way() {
+ ldif=$release_dir/dangling-one-way-link.ldif
+ TZ=UTC $ldbmodify -H tdb://$PREFIX_ABS/${RELEASE}/private/sam.ldb $ldif
+ if [ "$?" != "0" ]; then
+ return 1
+ fi
+}
+
if [ -d $release_dir ]; then
testit $RELEASE undump
testit "add_two_more_users" add_two_more_users
@@ -164,11 +207,15 @@
testit "remove_one_link" remove_one_link
testit "remove_one_user" remove_one_user
testit "move_one_user" move_one_user
+ testit "add_dangling_link" add_dangling_link
+ testit "add_dangling_backlink" add_dangling_backlink
testit "dbcheck" dbcheck
testit "dbcheck_clean" dbcheck_clean
testit "check_expected_after_deleted_links" check_expected_after_deleted_links
testit "check_expected_after_links" check_expected_after_links
testit "check_expected_after_objects" check_expected_after_objects
+ testit "dangling_one_way" dangling_one_way
+ testit "dbcheck_clean" dbcheck_clean
else
subunit_start_test $RELEASE
subunit_skip_test $RELEASE <<EOF
diff -Nru samba-4.5.5+dfsg/testprogs/blackbox/renamedc.sh samba-4.5.6+dfsg/testprogs/blackbox/renamedc.sh
--- samba-4.5.5+dfsg/testprogs/blackbox/renamedc.sh 2016-08-11 09:51:05.000000000 +0200
+++ samba-4.5.6+dfsg/testprogs/blackbox/renamedc.sh 2017-03-09 10:21:43.000000000 +0100
@@ -65,8 +65,10 @@
}
dbcheck_fix() {
+ # Unlike most calls to dbcheck --fix, this will not trigger an error, as
+ # we do not flag an error count for this old DN string case.
$BINDIR/samba-tool dbcheck --cross-ncs -s $PREFIX/renamedc_test/etc/smb.conf --fix \
- --quiet --yes fix_all_string_dn_component_mismatch \
+ --quiet --yes fix_all_old_dn_string_component_mismatch \
--attrs="fsmoRoleOwner interSiteTopologyGenerator msDS-NC-Replica-Locations"
}
@@ -83,7 +85,7 @@
testit "confirmrenamedc_dNSHostName" confirmrenamedc_dNSHostName || failed=`expr $failed + 1`
testit "confirmrenamedc_rootdse_dnsHostName" confirmrenamedc_rootdse_dnsHostName || failed=`expr $failed + 1`
testit "confirmrenamedc_rootdse_dsServiceName" confirmrenamedc_rootdse_dsServiceName || failed=`expr $failed + 1`
-testit_expect_failure "dbcheck_fix" dbcheck_fix || failed=`expr $failed + 1`
+testit "dbcheck_fix" dbcheck_fix || failed=`expr $failed + 1`
testit "dbcheck" dbcheck || failed=`expr $failed + 1`
testit "renamedc2" testrenamedc2 || failed=`expr $failed + 1`
diff -Nru samba-4.5.5+dfsg/third_party/waf/wafadmin/Tools/config_c.py samba-4.5.6+dfsg/third_party/waf/wafadmin/Tools/config_c.py
--- samba-4.5.5+dfsg/third_party/waf/wafadmin/Tools/config_c.py 2016-08-11 09:51:05.000000000 +0200
+++ samba-4.5.6+dfsg/third_party/waf/wafadmin/Tools/config_c.py 2017-03-09 10:21:43.000000000 +0100
@@ -106,7 +106,9 @@
@conf
def validate_cfg(self, kw):
if not 'path' in kw:
- kw['path'] = 'pkg-config --errors-to-stdout --print-errors'
+ if not self.env.PKGCONFIG:
+ self.find_program('pkg-config', var='PKGCONFIG')
+ kw['path'] = self.env.PKGCONFIG
# pkg-config version
if 'atleast_pkgconfig_version' in kw:
diff -Nru samba-4.5.5+dfsg/VERSION samba-4.5.6+dfsg/VERSION
--- samba-4.5.5+dfsg/VERSION 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/VERSION 2017-03-09 10:21:43.000000000 +0100
@@ -25,7 +25,7 @@
########################################################
SAMBA_VERSION_MAJOR=4
SAMBA_VERSION_MINOR=5
-SAMBA_VERSION_RELEASE=5
+SAMBA_VERSION_RELEASE=6
########################################################
# If a official release has a serious bug #
diff -Nru samba-4.5.5+dfsg/WHATSNEW.txt samba-4.5.6+dfsg/WHATSNEW.txt
--- samba-4.5.5+dfsg/WHATSNEW.txt 2017-01-30 10:56:26.000000000 +0100
+++ samba-4.5.6+dfsg/WHATSNEW.txt 2017-03-09 10:21:43.000000000 +0100
@@ -1,4 +1,111 @@
=============================
+ Release Notes for Samba 4.5.6
+ March 9, 2017
+ =============================
+
+
+This is the latest stable release of the Samba 4.5 release series.
+
+
+Changes since 4.5.5:
+--------------------
+
+o Jeremy Allison <jra at samba.org>
+ * BUG 12499: s3: vfs: dirsort doesn't handle opendir of "." correctly.
+ * BUG 12531: vfs_shadow_copy2 doesn't cope with server changing directories.
+ * BUG 12546: vfs_streams_xattr doesn't cope with server changing directories.
+ * BUG 12572: s3: smbd: Don't loop infinitely on bad-symlink resolution.
+ * BUG 12608: s3: smbd: Restart reading the incoming SMB2 fd when the send
+ queue is drained.
+
+o Andrew Bartlett <abartlet at samba.org>
+ * BUG 12573: Samba < 4.7 does not know about compatibleFeatures and
+ requiredFeatures.
+
+o Ralph Boehme <slow at samba.org>
+ * BUG 12184: s3/rpc_server: Shared rpc modules loading.
+ * BUG 12427: vfs_fruit doesn't work with fruit:metadata=stream.
+ * BUG 12520: Ensure global "smb encrypt = off" is effective.
+ * BUG 12524: s3/rpc_server: move rpc_modules.c to its own subsystem.
+ * BUG 12536: s3/smbd: check for invalid access_mask
+ smbd_calculate_access_mask().
+ * BUG 12541: vfs_fruit: checks wrong AAPL config state and so always uses
+ readdirattr.
+ * BUG 12545: s3/rpc_server/mdssvc: add attribute "kMDItemContentType".
+ * BUG 12591: vfs_streams_xattr: use fsp, not base_fsp.
+ * BUG 12604: vfs_fruit: Enabling AAPL extensions must be a global switch.
+
+o Amitay Isaacs <amitay at gmail.com>
+ * BUG 12469: ctdb-tests: Use replace headers instead of system headers.
+ * BUG 12547: ctdb-build: Install CTDB tests correctly from toplevel.
+ * BUG 12580: ctdb-common: Fix use-after-free error in comm_fd_handler().
+
+o Volker Lendecke <vl at samba.org>
+ * BUG 12551: smbd: Fix "map acl inherit" = yes.
+
+o Stefan Metzmacher <metze at samba.org>
+ * BUG 9048: s4:ldap_server: Match Windows in the error messages of failing
+ LDAP Bind requests.
+ * BUG 11830: s3:winbindd: Try a NETLOGON connection with noauth over NCACN_NP
+ against trusted domains.
+ * BUG 12262: 'net ads testjoin' and smb access fails after winbindd changed the
+ trust password.
+ * BUG 12399: s4:repl_meta_data: Normalize rdn attribute name via the schema.
+ * BUG 12540: s3:smbd: Allow "server min protocol = SMB3_00" to go via "SMB
+ 2.???" negprot.
+ * BUG 12581: smbclient fails on bad endianess when listing shares from
+ Solaris kernel SMB server on SPARC.
+ * BUG 12585: librpc/rpc: fix regression in
+ NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE error mapping.
+ * BUG 12586: libcli/auth: Use the correct creds value against servers without
+ LogonSamLogonEx.
+ * BUG 12587: winbindd child segfaults on connect to an NT4 domain.
+ * BUG 12588: cm_prepare_connection may return NT_STATUS_OK without a valid
+ connection.
+ * BUG 12598: winbindd (as member) requires Kerberos against trusted ad
+ domain, while it shouldn't.
+ * BUG 12605: s3:winbindd: Fix endless forest trust scan.
+
+o Garming Sam <garming at catalyst.net.nz>
+ * BUG 12577: dbcheck-links: Test that dbcheck against one-way links does not
+ error.
+ * BUG 12600: dbchecker: Stop ignoring linked cases where both objects are
+ alive.
+
+o Andreas Schneider <asn at samba.org>
+ * BUG 12571: s3-vfs: Only walk the directory once in open_and_sort_dir().
+
+o Martin Schwenke <martin at meltin.net>
+ * BUG 12589: ctdb-scripts: Initialise CTDB_NFS_CALLOUT in statd-callout.
+
+o Uri Simchoni <uri at samba.org>
+ * BUG 12529: waf: backport finding of pkg-config.
+
+
+#######################################
+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.5
January 30, 2017
=============================
@@ -22,7 +129,7 @@
o Martin Schwenke <martin at meltin.net>
* BUG 12512: ctdb-scripts: Fix remaining uses of "ctdb gratiousarp".
- * BUG 12516: /etc/iproute2/rt_tables gets populated with multiple
+ * BUG 12516: ctdb-scripts: /etc/iproute2/rt_tables gets populated with multiple
'default' entries.
@@ -46,8 +153,8 @@
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
=============================
Release Notes for Samba 4.5.4
More information about the Pkg-samba-maint
mailing list