-/*
+/*
Unix SMB/CIFS implementation.
VFS module tester
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "smbd/smbd.h"
+#include "smbd/globals.h"
#include "popt_common.h"
#include "vfstest.h"
#include "../libcli/smbreadline/smbreadline.h"
+#include "auth.h"
+#include "serverid.h"
+#include "messages.h"
+#include "libcli/security/security.h"
+#include "lib/smbd_shim.h"
+#include "system/filesys.h"
/* List to hold groups of commands */
static struct cmd_list {
struct cmd_set *cmd_set;
} *cmd_list;
+/* shall we do talloc_report after each command? */
+static int memreports = 0;
+
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
int i, count=0;
struct cmd_list *commands = cmd_list;
- if (start)
+ if (start)
return NULL;
/* make sure we have a list of valid commands */
- if (!commands)
+ if (!commands)
return NULL;
matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
matches[count++] = SMB_STRDUP(text);
if (!matches[0]) return NULL;
- while (commands && count < MAX_COMPLETIONS-1)
+ while (commands && count < MAX_COMPLETIONS-1)
{
if (!commands->cmd_set)
break;
-
+
for (i=0; commands->cmd_set[i].name; i++)
{
if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) &&
- commands->cmd_set[i].fn)
+ commands->cmd_set[i].fn)
{
matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
- if (!matches[count])
+ if (!matches[count])
return NULL;
count++;
}
}
-
+
commands = commands->next;
-
}
if (count == 2) {
if (p)
*p = '\0';
command = talloc_strdup(ctx, *cmdstr);
- *cmdstr = p;
+
+ /* Pass back the remaining cmdstring
+ (a trailing delimiter ";" does also work),
+ or NULL at last cmdstring.
+ */
+ *cmdstr = p ? p + 1 : p;
return command;
}
return NT_STATUS_OK;
}
- if (!lp_load(argv[1], False, True, False, True)) {
+ if (!lp_load_with_shares(argv[1])) {
printf("Error loading \"%s\"\n", argv[1]);
return NT_STATUS_OK;
}
printf("\"%s\" successfully loaded\n", argv[1]);
return NT_STATUS_OK;
}
-
+
/* Display help on commands */
static NTSTATUS cmd_help(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
int argc, const char **argv)
if (argc == 2) {
for (tmp = cmd_list; tmp; tmp = tmp->next) {
-
+
tmp_set = tmp->cmd_set;
while(tmp_set->name) {
static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
{
const char *p = cmd;
- char **argv = NULL;
+ const char **argv = NULL;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
char *buf;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- int argc = 0, i;
+ int argc = 0;
/* Count number of arguments first time through the loop then
allocate memory and strdup them. */
again:
while(next_token_talloc(mem_ctx, &p, &buf, " ")) {
if (argv) {
- argv[argc] = SMB_STRDUP(buf);
+ argv[argc] = talloc_strdup(argv, buf);
}
argc++;
}
if (!argv) {
/* Create argument list */
- argv = SMB_MALLOC_ARRAY(char *, argc);
- memset(argv, 0, sizeof(char *) * argc);
-
- if (!argv) {
+ argv = talloc_zero_array(mem_ctx, const char *, argc);
+ if (argv == NULL) {
fprintf(stderr, "out of memory\n");
result = NT_STATUS_NO_MEMORY;
goto done;
/* Cleanup */
if (argv) {
- for (i = 0; i < argc; i++)
- SAFE_FREE(argv[i]);
-
- SAFE_FREE(argv);
+ char **_argv = discard_const_p(char *, argv);
+ TALLOC_FREE(_argv);
+ argv = NULL;
}
+ if (memreports != 0) {
+ talloc_report_full(mem_ctx, stdout);
+ }
TALLOC_FREE(mem_ctx);
return result;
}
}
}
-void exit_server(const char *reason)
+static void vfstest_exit_server(const char * const reason) _NORETURN_;
+static void vfstest_exit_server(const char * const reason)
{
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
exit(0);
}
-void exit_server_cleanly(const char *const reason)
+static void vfstest_exit_server_cleanly(const char * const reason) _NORETURN_;
+static void vfstest_exit_server_cleanly(const char * const reason)
{
- exit_server("normal exit");
+ vfstest_exit_server("normal exit");
}
-int last_message = -1;
+struct smb_request *vfstest_get_smbreq(TALLOC_CTX *mem_ctx,
+ struct vfs_state *vfs)
+{
+ struct smb_request *result;
+ uint8_t *inbuf;
+
+ result = talloc_zero(mem_ctx, struct smb_request);
+ if (result == NULL) {
+ return NULL;
+ }
+ result->sconn = vfs->conn->sconn;
+ result->mid = ++vfs->mid;
+
+ inbuf = talloc_array(result, uint8_t, smb_size);
+ if (inbuf == NULL) {
+ goto fail;
+ }
+ SSVAL(inbuf, smb_mid, result->mid);
+ smb_setlen(inbuf, smb_size-4);
+ result->inbuf = inbuf;
+ return result;
+fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
/* Main function */
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
{
- static char *cmdstr = NULL;
- struct cmd_set **cmd_set;
- static struct vfs_state vfs;
+ char *cmdstr = NULL;
+ struct cmd_set **cmd_set;
+ struct vfs_state *vfs;
int i;
- static char *filename = NULL;
+ char *filename = NULL;
+ char cwd[MAXPATHLEN];
TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev;
+ struct auth_session_info *session_info = NULL;
+ NTSTATUS status = NT_STATUS_OK;
/* make sure the vars that get altered (4th field) are in
a fixed location or certain compilers complain */
POPT_AUTOHELP
{"file", 'f', POPT_ARG_STRING, &filename, 0, },
{"command", 'c', POPT_ARG_STRING, &cmdstr, 0, "Execute specified list of commands" },
+ {"memreport", 'm', POPT_ARG_INT, &memreports, 0,
+ "Report memory left on talloc stackframe after each command" },
POPT_COMMON_SAMBA
POPT_TABLEEND
};
+ static const struct smbd_shim vfstest_shim_fns =
+ {
+ .exit_server = vfstest_exit_server,
+ .exit_server_cleanly = vfstest_exit_server_cleanly,
+ };
- load_case_tables();
+ smb_init_locale();
setlinebuf(stdout);
- pc = poptGetContext("vfstest", argc, (const char **) argv,
- long_options, 0);
-
+ pc = poptGetContext("vfstest", argc, argv, long_options, 0);
+
while(poptGetNextOpt(pc) != -1);
poptFreeContext(pc);
+ /* we want total control over the permissions on created files,
+ so set our umask to 0 */
+ umask(0);
+
lp_load_initial_only(get_dyn_CONFIGFILE());
/* TODO: check output */
- reload_services(smbd_messaging_context(), -1, False);
+ reload_services(NULL, NULL, false);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
setup_logging("vfstest", DEBUG_STDOUT);
-
+
+ set_smbd_shim(&vfstest_shim_fns);
+
/* Load command lists */
cmd_set = vfstest_command_list;
/* some basic initialization stuff */
sec_init();
- vfs.conn = TALLOC_ZERO_P(NULL, connection_struct);
- vfs.conn->params = TALLOC_P(vfs.conn, struct share_params);
+ init_guest_info();
+ locking_init();
+ vfs = talloc_zero(NULL, struct vfs_state);
+ if (vfs == NULL) {
+ return 1;
+ }
+ status = make_session_info_guest(vfs, &session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return 1;
+ }
+
+ ev = server_event_context();
+
+ status = create_conn_struct(vfs,
+ ev,
+ server_messaging_context(),
+ &vfs->conn,
+ -1,
+ getcwd(cwd, sizeof(cwd)),
+ session_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return 1;
+ }
+
+ vfs->conn->share_access = FILE_GENERIC_ALL;
+ vfs->conn->read_only = false;
+
+ file_init(vfs->conn->sconn);
for (i=0; i < 1024; i++)
- vfs.files[i] = NULL;
+ vfs->files[i] = NULL;
- /* some advanced initiliazation stuff */
- smbd_vfs_init(vfs.conn);
+ if (!posix_locking_init(false)) {
+ return 1;
+ }
/* Do we have a file input? */
if (filename && filename[0]) {
- process_file(&vfs, filename);
+ process_file(vfs, filename);
return 0;
}
char *p = cmdstr;
while((cmd=next_command(frame, &p)) != NULL) {
- process_cmd(&vfs, cmd);
+ status = process_cmd(vfs, cmd);
}
TALLOC_FREE(cmd);
- return 0;
+ return NT_STATUS_IS_OK(status) ? 0 : 1;
}
/* Loop around accepting commands */
}
if (line[0] != '\n') {
- process_cmd(&vfs, line);
+ status = process_cmd(vfs, line);
}
SAFE_FREE(line);
}
- TALLOC_FREE(vfs.conn);
+ TALLOC_FREE(vfs);
TALLOC_FREE(frame);
- return 0;
+ return NT_STATUS_IS_OK(status) ? 0 : 1;
}