The branch, master has been updated via 9089d48 s4:torture/smb2: add smb2.durable-open.delete_on_close1 via b240406 s3:move serverid_equal() to serverid.c via 73b2000 s3:util: rename procid_equal() to serverid_equal() via 0159344 s3:util: remove (now) unused cluster_id_equal() via 1eacf3a s3:smbstatus: use procid_equal() instead of equivalent cluster_id_equal() via 53cfde7 s3: Remove a user of procid_is_me via ca9a734 s3: Remove a user of procid_is_me via 6289fcf s3:util: reformat procid_equal() to adhere to coding guidelines via 3bdad95 s3:util: also compare the unique_id in procid_equal(). via e27d56c script: really sleep in "random-sleep.sh" from 17ad62b samba-tool: gpo: Fix creation of filesystem ACL from directory ACL
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 9089d487c45b7a8959de61bba11f9dd069c503eb Author: Stefan Metzmacher <me...@samba.org> Date: Wed Jun 20 22:28:54 2012 +0200 s4:torture/smb2: add smb2.durable-open.delete_on_close1 metze Autobuild-User(master): Stefan Metzmacher <me...@samba.org> Autobuild-Date(master): Thu Jun 21 10:19:00 CEST 2012 on sn-devel-104 commit b240406651b6397df912c78408e1de0f36334773 Author: Michael Adam <ob...@samba.org> Date: Sat Jun 16 00:30:55 2012 +0200 s3:move serverid_equal() to serverid.c Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 73b200064fea77037f15cceeda303469b3e78624 Author: Michael Adam <ob...@samba.org> Date: Sat Jun 16 00:26:26 2012 +0200 s3:util: rename procid_equal() to serverid_equal() Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 0159344d4c55d9bea7f7938b6a3e750177fe6108 Author: Michael Adam <ob...@samba.org> Date: Sat Jun 16 00:09:24 2012 +0200 s3:util: remove (now) unused cluster_id_equal() Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 1eacf3a66f44be94b345813ae667d5b3a36701b4 Author: Michael Adam <ob...@samba.org> Date: Sat Jun 16 00:07:16 2012 +0200 s3:smbstatus: use procid_equal() instead of equivalent cluster_id_equal() Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 53cfde7204f7bb372f62cefd827762c6880ea345 Author: Volker Lendecke <v...@samba.org> Date: Fri Jun 15 14:29:08 2012 +0200 s3: Remove a user of procid_is_me Signed-off-by: Michael Adam <ob...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit ca9a734e19e43b9e00bbb6bdd644284b351b9cde Author: Volker Lendecke <v...@samba.org> Date: Fri Jun 15 14:29:08 2012 +0200 s3: Remove a user of procid_is_me Signed-off-by: Michael Adam <ob...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 6289fcffd7de288aa67eff7bee11081aae195104 Author: Michael Adam <ob...@samba.org> Date: Fri Jun 15 13:58:20 2012 +0200 s3:util: reformat procid_equal() to adhere to coding guidelines Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 3bdad95e3b63788a071872317cc7b5d3625c4cde Author: Michael Adam <ob...@samba.org> Date: Fri Jun 15 13:56:39 2012 +0200 s3:util: also compare the unique_id in procid_equal(). Signed-off-by: Stefan Metzmacher <me...@samba.org> commit e27d56c2dae13e2ae49b02f754b3d4a2d487cd59 Author: Michael Adam <ob...@samba.org> Date: Thu Jun 21 00:39:21 2012 +0200 script: really sleep in "random-sleep.sh" Signed-off-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: script/random-sleep.sh | 2 +- selftest/knownfail | 1 + source3/include/proto.h | 4 +- source3/include/serverid.h | 2 + source3/lib/dbwrap/dbwrap_watch.c | 2 +- source3/lib/g_lock.c | 4 +- source3/lib/serverid.c | 21 +++++ source3/lib/util.c | 17 ---- source3/locking/brlock.c | 8 +- source3/locking/locking.c | 7 +- source3/locking/posix.c | 2 +- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 2 +- source3/smbd/close.c | 6 +- source3/smbd/notify_internal.c | 2 +- source3/smbd/open.c | 4 +- source3/smbd/oplock.c | 4 +- source3/smbd/sesssetup.c | 3 +- source3/utils/net_status.c | 2 +- source3/utils/status.c | 3 +- source3/web/statuspage.c | 4 +- source4/torture/smb2/durable_open.c | 128 ++++++++++++++++++++++++++++- 21 files changed, 180 insertions(+), 48 deletions(-) Changeset truncated at 500 lines: diff --git a/script/random-sleep.sh b/script/random-sleep.sh index 70b0c03..9bb866b 100755 --- a/script/random-sleep.sh +++ b/script/random-sleep.sh @@ -17,5 +17,5 @@ v=$(expr $r % $s) d=$(expr $l + $v) echo "$0: sleep $d ... start" -#sleep $d +sleep $d echo "$0: sleep $d ... end" diff --git a/selftest/knownfail b/selftest/knownfail index 35da8b3..f08b4d1 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -159,6 +159,7 @@ ^samba3.smb2.durable-open.reopen2a ^samba3.smb2.durable-open.reopen3 ^samba3.smb2.durable-open.reopen4 +^samba3.smb2.durable-open.delete_on_close1 ^samba3.smb2.durable-open.oplock ^samba3.smb2.durable-v2-open.open-oplock ^samba3.smb2.durable-v2-open.open-lease diff --git a/source3/include/proto.h b/source3/include/proto.h index a258bf3..69661bb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -470,9 +470,7 @@ void set_my_unique_id(uint64_t unique_id); struct server_id pid_to_procid(pid_t pid); struct server_id procid_self(void); struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx); -bool procid_equal(const struct server_id *p1, const struct server_id *p2); -bool cluster_id_equal(const struct server_id *id1, - const struct server_id *id2); +bool serverid_equal(const struct server_id *p1, const struct server_id *p2); bool procid_is_me(const struct server_id *pid); struct server_id interpret_pid(const char *pid_string); char *procid_str_static(const struct server_id *pid); diff --git a/source3/include/serverid.h b/source3/include/serverid.h index 1833f53..ed8d17f 100644 --- a/source3/include/serverid.h +++ b/source3/include/serverid.h @@ -75,4 +75,6 @@ bool serverid_parent_init(TALLOC_CTX *mem_ctx); */ uint64_t serverid_get_random_unique_id(void); +bool serverid_equal(const struct server_id *p1, const struct server_id *p2); + #endif diff --git a/source3/lib/dbwrap/dbwrap_watch.c b/source3/lib/dbwrap/dbwrap_watch.c index ea75427..701ac9d 100644 --- a/source3/lib/dbwrap/dbwrap_watch.c +++ b/source3/lib/dbwrap/dbwrap_watch.c @@ -166,7 +166,7 @@ static NTSTATUS dbwrap_record_del_watcher(TDB_DATA w_key, struct server_id id) num_ids = value.dsize / sizeof(struct server_id); for (i=0; i<num_ids; i++) { - if (procid_equal(&id, &ids[i])) { + if (serverid_equal(&id, &ids[i])) { ids[i] = ids[num_ids-1]; value.dsize -= sizeof(struct server_id); break; diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 06a14fa..d505b6b 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -119,7 +119,7 @@ static NTSTATUS g_lock_trylock(struct db_record *rec, struct server_id self, } for (i=0; i<num_locks; i++) { - if (procid_equal(&self, &locks[i].pid)) { + if (serverid_equal(&self, &locks[i].pid)) { status = NT_STATUS_INTERNAL_ERROR; goto done; } @@ -327,7 +327,7 @@ NTSTATUS g_lock_unlock(struct g_lock_ctx *ctx, const char *name) goto done; } for (i=0; i<num_locks; i++) { - if (procid_equal(&self, &locks[i].pid)) { + if (serverid_equal(&self, &locks[i].pid)) { break; } } diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c index 48d5b42..0033d60 100644 --- a/source3/lib/serverid.c +++ b/source3/lib/serverid.c @@ -453,3 +453,24 @@ uint64_t serverid_get_random_unique_id(void) return unique_id; } + +bool serverid_equal(const struct server_id *p1, const struct server_id *p2) +{ + if (p1->pid != p2->pid) { + return false; + } + + if (p1->task_id != p2->task_id) { + return false; + } + + if (p1->vnn != p2->vnn) { + return false; + } + + if (p1->unique_id != p2->unique_id) { + return false; + } + + return true; +} diff --git a/source3/lib/util.c b/source3/lib/util.c index 49cd771..f1b8158 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -2058,23 +2058,6 @@ struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx) return server_id; } -bool procid_equal(const struct server_id *p1, const struct server_id *p2) -{ - if (p1->pid != p2->pid) - return False; - if (p1->task_id != p2->task_id) - return False; - if (p1->vnn != p2->vnn) - return False; - return True; -} - -bool cluster_id_equal(const struct server_id *id1, - const struct server_id *id2) -{ - return procid_equal(id1, id2); -} - bool procid_is_me(const struct server_id *pid) { if (pid->pid != getpid()) diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 836bbb4..7150936 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -69,7 +69,7 @@ static void print_lock_struct(unsigned int i, struct lock_struct *pls) bool brl_same_context(const struct lock_context *ctx1, const struct lock_context *ctx2) { - return (procid_equal(&ctx1->pid, &ctx2->pid) && + return (serverid_equal(&ctx1->pid, &ctx2->pid) && (ctx1->smblctx == ctx2->smblctx) && (ctx1->tid == ctx2->tid)); } @@ -252,7 +252,7 @@ NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, bool return NT_STATUS_FILE_LOCK_CONFLICT; } - if (procid_equal(&lock->context.pid, &fsp->last_lock_failure.context.pid) && + if (serverid_equal(&lock->context.pid, &fsp->last_lock_failure.context.pid) && lock->context.tid == fsp->last_lock_failure.context.tid && lock->fnum == fsp->last_lock_failure.fnum && lock->start == fsp->last_lock_failure.start) { @@ -1509,7 +1509,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx, for (i=0; i < num_locks_copy; i++) { struct lock_struct *lock = &locks_copy[i]; - if (lock->context.tid == tid && procid_equal(&lock->context.pid, &pid) && + if (lock->context.tid == tid && serverid_equal(&lock->context.pid, &pid) && (lock->fnum == fnum)) { brl_unlock(msg_ctx, br_lck, @@ -1958,7 +1958,7 @@ void brl_revalidate(struct messaging_context *msg_ctx, ZERO_STRUCT(last_pid); for (i=0; i<state->num_pids; i++) { - if (procid_equal(&last_pid, &state->pids[i])) { + if (serverid_equal(&last_pid, &state->pids[i])) { /* * We've seen that one already */ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b3bd8dd..95e9b77 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -482,6 +482,7 @@ bool rename_share_filename(struct messaging_context *msg_ctx, int i; bool strip_two_chars = false; bool has_stream = smb_fname_dst->stream_name != NULL; + struct server_id self_pid = messaging_server_id(msg_ctx); DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n", servicepath, smb_fname_dst->base_name)); @@ -552,7 +553,7 @@ bool rename_share_filename(struct messaging_context *msg_ctx, se->name_hash = new_name_hash; /* But not to ourselves... */ - if (procid_is_me(&se->pid)) { + if (serverid_equal(&se->pid, &self_pid)) { continue; } @@ -754,7 +755,7 @@ static bool share_modes_identical(struct share_mode_entry *e1, sharing the same share mode entry may validly differ in fsp->share_access field. */ - return (procid_equal(&e1->pid, &e2->pid) && + return (serverid_equal(&e1->pid, &e2->pid) && file_id_equal(&e1->id, &e2->id) && e1->share_file_id == e2->share_file_id ); } @@ -762,7 +763,7 @@ static bool share_modes_identical(struct share_mode_entry *e1, static bool deferred_open_identical(struct share_mode_entry *e1, struct share_mode_entry *e2) { - return (procid_equal(&e1->pid, &e2->pid) && + return (serverid_equal(&e1->pid, &e2->pid) && (e1->op_mid == e2->op_mid) && file_id_equal(&e1->id, &e2->id)); } diff --git a/source3/locking/posix.c b/source3/locking/posix.c index 02d9b6d..e5320f8 100644 --- a/source3/locking/posix.c +++ b/source3/locking/posix.c @@ -777,7 +777,7 @@ static struct lock_list *posix_lock_list(TALLOC_CTX *ctx, } /* Ignore locks not owned by this process. */ - if (!procid_equal(&lock->context.pid, &lock_ctx->pid)) { + if (!serverid_equal(&lock->context.pid, &lock_ctx->pid)) { continue; } diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index d351468..6702784 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -856,7 +856,7 @@ static void sess_file_fn( const struct share_mode_entry *e, { struct sess_file_count *sess = (struct sess_file_count *)data; - if ( procid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid) ) { + if (serverid_equal(&e->pid, &sess->pid) && (sess->uid == e->uid)) { sess->count++; } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 1fb7bde..a3eedbf 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -232,7 +232,7 @@ static void notify_deferred_opens(struct smbd_server_connection *sconn, for (i=0; i<num_deferred; i++) { struct share_mode_entry *e = &deferred[i]; - if (procid_equal(&self, &e->pid)) { + if (serverid_equal(&self, &e->pid)) { /* * We need to notify ourself to retry the open. Do * this by finding the queued SMB record, moving it to @@ -427,7 +427,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } - if (procid_equal(&self, &e->pid) && + if (serverid_equal(&self, &e->pid) && (e->share_file_id == fsp->fh->gen_id)) { continue; } @@ -1103,7 +1103,7 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } - if (procid_equal(&self, &e->pid) && + if (serverid_equal(&self, &e->pid) && (e->share_file_id == fsp->fh->gen_id)) { continue; } diff --git a/source3/smbd/notify_internal.c b/source3/smbd/notify_internal.c index 9af3b45..4fb1b35 100644 --- a/source3/smbd/notify_internal.c +++ b/source3/smbd/notify_internal.c @@ -453,7 +453,7 @@ static NTSTATUS notify_del_entry(struct db_record *rec, if (e->private_data != private_data) { continue; } - if (procid_equal(&e->server, pid)) { + if (serverid_equal(&e->server, pid)) { break; } } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 26d6971..273f3b2 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -913,7 +913,7 @@ static void validate_my_share_entries(struct smbd_server_connection *sconn, struct server_id self = messaging_server_id(sconn->msg_ctx); files_struct *fsp; - if (!procid_equal(&self, &share_entry->pid)) { + if (!serverid_equal(&self, &share_entry->pid)) { return; } @@ -1363,7 +1363,7 @@ static void defer_open(struct share_mode_lock *lck, struct share_mode_entry *e = &lck->data->share_modes[i]; if (is_deferred_open_entry(e) && - procid_equal(&self, &e->pid) && + serverid_equal(&self, &e->pid) && (e->op_mid == req->mid)) { DEBUG(0, ("Trying to defer an already deferred " "request: mid=%llu, exiting\n", diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 54d95a2..406ffd1 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -564,7 +564,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, /* Need to wait before sending a break message if we sent ourselves this message. */ - if (procid_equal(&self, &src)) { + if (serverid_equal(&self, &src)) { wait_before_sending_break(); } @@ -876,7 +876,7 @@ static void do_break_to_none(struct tevent_req *req) * Bugid #5980. */ - if (procid_equal(&self, &share_entry->pid)) { + if (serverid_equal(&self, &share_entry->pid)) { struct files_struct *cur_fsp = initial_break_processing(state->sconn, share_entry->id, diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7cef733..81e56eb 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -333,6 +333,7 @@ static int shutdown_other_smbds(const struct connections_key *key, void *private_data) { struct shutdown_state *state = (struct shutdown_state *)private_data; + struct server_id self_pid = messaging_server_id(state->msg_ctx); DEBUG(10, ("shutdown_other_smbds: %s, %s\n", server_id_str(talloc_tos(), &crec->pid), crec->addr)); @@ -342,7 +343,7 @@ static int shutdown_other_smbds(const struct connections_key *key, return 0; } - if (procid_is_me(&crec->pid)) { + if (serverid_equal(&crec->pid, &self_pid)) { DEBUG(10, ("It's me\n")); return 0; } diff --git a/source3/utils/net_status.c b/source3/utils/net_status.c index 85d0235..c96730f 100644 --- a/source3/utils/net_status.c +++ b/source3/utils/net_status.c @@ -152,7 +152,7 @@ static int show_share_parseable(const struct connections_key *key, for (i=0; i<ids->num_entries; i++) { struct server_id id = ids->entries[i].pid; - if (procid_equal(&id, &crec->pid)) { + if (serverid_equal(&id, &crec->pid)) { guest = false; break; } diff --git a/source3/utils/status.c b/source3/utils/status.c index a6e8055..3d16f8e 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -88,8 +88,9 @@ static unsigned int Ucrit_checkPid(struct server_id pid) return 1; for (i=0;i<Ucrit_MaxPid;i++) { - if (cluster_id_equal(&pid, &Ucrit_pid[i])) + if (serverid_equal(&pid, &Ucrit_pid[i])) { return 1; + } } return 0; diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index dd83d15..8eac803 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -89,7 +89,7 @@ static char *mapPid2Machine (struct server_id pid) /* show machine name rather PID on table "Open Files"? */ if (PID_or_Machine) { for (map = pidmap; map != NULL; map = map->next) { - if (procid_equal(&pid, &map->pid)) { + if (serverid_equal(&pid, &map->pid)) { if (map->machine == NULL) /* no machine name */ break; /* show PID */ @@ -207,7 +207,7 @@ static int traverse_fn2(const struct connections_key *key, void *private_data) { if (crec->cnum == TID_FIELD_INVALID || !process_exists(crec->pid) || - procid_equal(&crec->pid, &smbd_pid)) + serverid_equal(&crec->pid, &smbd_pid)) return 0; addPid2Machine (crec->pid, crec->machine); diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c index 0c20f77..7e55052 100644 --- a/source4/torture/smb2/durable_open.c +++ b/source4/torture/smb2/durable_open.c @@ -30,8 +30,15 @@ #define CHECK_VAL(v, correct) do { \ if ((v) != (correct)) { \ - torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \ - __location__, #v, (int)v, (int)correct); \ + torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%llx - should be 0x%llx\n", \ + __location__, #v, (unsigned long long)v, (unsigned long long)correct); \ + ret = false; \ + }} while (0) + +#define CHECK_NOT_VAL(v, correct) do { \ + if ((v) == (correct)) { \ + torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%llx - should not be 0x%llx\n", \ + __location__, #v, (unsigned long long)v, (unsigned long long)correct); \ ret = false; \ }} while (0) @@ -699,6 +706,121 @@ done: return ret; } +bool test_durable_open_delete_on_close1(struct torture_context *tctx, + struct smb2_tree *tree) +{ + NTSTATUS status; + TALLOC_CTX *mem_ctx = talloc_new(tctx); + char fname[256]; + struct smb2_handle _h; + struct smb2_handle *h = NULL; + struct smb2_create io1, io2, io3; + bool ret = true; + struct smb2_transport *transport; + struct smb2_session *session2; + struct smb2_tree *tree2; + union smb_fileinfo info1, info2; + + /* Choose a random name in case the state is left a little funky. */ + snprintf(fname, 256, "durable_open_delete_on_close1_%s.dat", + generate_random_str(tctx, 8)); + + smb2_util_unlink(tree, fname); + + smb2_oplock_create_share(&io1, fname, + smb2_util_share_access(""), + smb2_util_oplock_level("b")); + io1.in.durable_open = true; + io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + + status = smb2_create(tree, mem_ctx, &io1); + CHECK_STATUS(status, NT_STATUS_OK); + _h = io1.out.file.handle; + h = &_h; + CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io1.out.durable_open, true); + CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); + + ZERO_STRUCT(info1); + info1.internal_information.level = RAW_FILEINFO_INTERNAL_INFORMATION; + info1.internal_information.in.file.handle = _h; + status = smb2_getinfo_file(tree, tree, &info1); + CHECK_STATUS(status, NT_STATUS_OK); + + /* + * do a session logoff, establish a new session and tree + * connect on the same transport, and try a durable reopen + */ + transport = tree->session->transport; + status = smb2_logoff(tree->session); + CHECK_STATUS(status, NT_STATUS_OK); + + if (!torture_smb2_session_setup(tctx, transport, + 0, /* previous_session_id */ + mem_ctx, &session2)) + { + torture_warning(tctx, "session setup failed.\n"); + ret = false; + goto done; + } + + /* + * the session setup has talloc-stolen the transport, + * so we can safely free the old tree+session for clarity + */ + TALLOC_FREE(tree); + + if (!torture_smb2_tree_connect(tctx, session2, mem_ctx, &tree2)) { + torture_warning(tctx, "tree connect failed.\n"); + ret = false; + goto done; + } -- Samba Shared Repository