-/*
+/*
Unix SMB/CIFS implementation.
VFS module tester
Copyright (C) Simo Sorce 2002
Copyright (C) Eric Lorimer 2002
- Copyright (C) Jelmer Vernooij 2002
+ Copyright (C) Jelmer Vernooij 2002,2003
Most of this code was ripped off of rpcclient.
Copyright (C) Tim Potter 2000-2001
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ 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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ 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;
-extern pstring user_socket_options;
-
/****************************************************************************
handle completion of commands for readline
****************************************************************************/
-static char **completion_fn(char *text, int start, int end)
+static char **completion_fn(const char *text, int start, int end)
{
#define MAX_COMPLETIONS 100
char **matches;
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 = (char **)malloc(sizeof(matches[0])*MAX_COMPLETIONS);
+ matches = SMB_MALLOC_ARRAY(char *, MAX_COMPLETIONS);
if (!matches) return NULL;
- matches[count++] = strdup(text);
+ 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] = strdup(commands->cmd_set[i].name);
- if (!matches[count])
+ matches[count] = SMB_STRDUP(commands->cmd_set[i].name);
+ if (!matches[count])
return NULL;
count++;
}
}
-
+
commands = commands->next;
-
}
if (count == 2) {
SAFE_FREE(matches[0]);
- matches[0] = strdup(matches[1]);
+ matches[0] = SMB_STRDUP(matches[1]);
}
matches[count] = NULL;
return matches;
}
-static char* next_command(char** cmdstr)
+static char *next_command(TALLOC_CTX *ctx, char **cmdstr)
{
- static pstring command;
- char *p;
-
+ char *command;
+ char *p;
+
if (!cmdstr || !(*cmdstr))
return NULL;
-
+
p = strchr_m(*cmdstr, ';');
if (p)
*p = '\0';
- pstrcpy(command, *cmdstr);
+ command = talloc_strdup(ctx, *cmdstr);
*cmdstr = p;
-
+
return command;
}
/* Load specified configuration file */
static NTSTATUS cmd_conf(struct vfs_state *vfs, TALLOC_CTX *mem_ctx,
- int argc, char **argv)
+ int argc, const char **argv)
{
if (argc != 2) {
printf("Usage: %s <smb.conf>\n", argv[0]);
return NT_STATUS_OK;
}
- if (!lp_load(argv[1], False, True, False)) {
+ if (!lp_load(argv[1], False, True, False, True)) {
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, char **argv)
+ int argc, const char **argv)
{
struct cmd_list *tmp;
struct cmd_set *tmp_set;
if (argc == 2) {
for (tmp = cmd_list; tmp; tmp = tmp->next) {
-
+
tmp_set = tmp->cmd_set;
while(tmp_set->name) {
}
/* Change the debug level */
-static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_debuglevel(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
if (argc > 2) {
printf("Usage: %s [debuglevel]\n", argv[0]);
}
if (argc == 2) {
- DEBUGLEVEL = atoi(argv[1]);
+ lp_set_cmdline("log level", argv[1]);
}
printf("debuglevel is %d\n", DEBUGLEVEL);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_freemem(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
/* Cleanup */
talloc_destroy(mem_ctx);
return NT_STATUS_OK;
}
-static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, char **argv)
+static NTSTATUS cmd_quit(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
/* Cleanup */
talloc_destroy(mem_ctx);
{
struct cmd_list *entry;
- if (!(entry = (struct cmd_list *)malloc(sizeof(struct cmd_list)))) {
+ if (!(entry = SMB_MALLOC_P(struct cmd_list))) {
DEBUG(0, ("out of memory\n"));
return;
}
static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *cmd)
{
- char *p = cmd, **argv = NULL;
+ const char *p = cmd;
+ char **argv = NULL;
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
- pstring buf;
- TALLOC_CTX *mem_ctx = NULL;
+ char *buf;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
int argc = 0, i;
/* Count number of arguments first time through the loop then
allocate memory and strdup them. */
again:
- while(next_token(&p, buf, " ", sizeof(buf))) {
+ while(next_token_talloc(mem_ctx, &p, &buf, " ")) {
if (argv) {
- argv[argc] = strdup(buf);
+ argv[argc] = SMB_STRDUP(buf);
}
-
argc++;
}
-
- if (!argv) {
+ if (!argv) {
/* Create argument list */
- argv = (char **)malloc(sizeof(char *) * argc);
+ argv = SMB_MALLOC_ARRAY(char *, argc);
memset(argv, 0, sizeof(char *) * argc);
if (!argv) {
result = NT_STATUS_NO_MEMORY;
goto done;
}
-
+
p = cmd;
argc = 0;
-
+
goto again;
}
/* Call the function */
if (cmd_entry->fn) {
-
- if (mem_ctx == NULL) {
- /* Create mem_ctx */
- if (!(mem_ctx = talloc_init("do_cmd"))) {
- DEBUG(0, ("talloc_init() failed\n"));
- goto done;
- }
- }
-
/* Run command */
- result = cmd_entry->fn(vfs, mem_ctx, argc, argv);
-
+ result = cmd_entry->fn(vfs, mem_ctx, argc, (const char **)argv);
} else {
fprintf (stderr, "Invalid command\n");
goto done;
}
done:
-
+
/* Cleanup */
if (argv) {
for (i = 0; i < argc; i++)
SAFE_FREE(argv[i]);
-
+
SAFE_FREE(argv);
}
-
+
+ TALLOC_FREE(mem_ctx);
return result;
}
static NTSTATUS process_cmd(struct vfs_state *vfs, char *cmd)
{
struct cmd_list *temp_list;
- BOOL found = False;
- pstring buf;
- char *p = cmd;
+ bool found = False;
+ char *buf;
+ const char *p = cmd;
NTSTATUS result = NT_STATUS_OK;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
int len = 0;
if (cmd[strlen(cmd) - 1] == '\n')
cmd[strlen(cmd) - 1] = '\0';
- if (!next_token(&p, buf, " ", sizeof(buf))) {
+ if (!next_token_talloc(mem_ctx, &p, &buf, " ")) {
+ TALLOC_FREE(mem_ctx);
return NT_STATUS_OK;
}
- /* strip the trainly \n if it exsists */
+ /* Strip the trailing \n if it exists */
len = strlen(buf);
if (buf[len-1] == '\n')
buf[len-1] = '\0';
done:
if (!found && buf[0]) {
printf("command not found: %s\n", buf);
+ TALLOC_FREE(mem_ctx);
return NT_STATUS_OK;
}
printf("result was %s\n", nt_errstr(result));
}
+ TALLOC_FREE(mem_ctx);
return result;
}
while (fgets(command, 3 * PATH_MAX, file) != NULL) {
process_cmd(pvfs, command);
}
+
+ if (file != stdin) {
+ fclose(file);
+ }
}
-void exit_server(char *reason)
+static void vfstest_exit_server(const char * const reason)
{
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
exit(0);
}
-static int server_fd = -1;
-int last_message = -1;
-
-int smbd_server_fd(void)
+static void vfstest_exit_server_cleanly(const char * const reason)
{
- return server_fd;
+ vfstest_exit_server("normal exit");
}
-/****************************************************************************
- Reload the services file.
-**************************************************************************/
-
-BOOL reload_services(BOOL test)
+struct smb_request *vfstest_get_smbreq(TALLOC_CTX *mem_ctx,
+ struct vfs_state *vfs)
{
- BOOL ret;
-
- if (lp_loaded()) {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname, NULL) &&
- !strcsequal(fname, dyn_CONFIGFILE)) {
- pstrcpy(dyn_CONFIGFILE, fname);
- test = False;
- }
- }
-
- reopen_logs();
-
- if (test && !lp_file_list_changed())
- return(True);
-
- lp_killunused(conn_snum_used);
-
- ret = lp_load(dyn_CONFIGFILE, False, False, True);
+ struct smb_request *result;
- load_printers();
-
- /* perhaps the config filename is now set */
- if (!test)
- reload_services(True);
-
- reopen_logs();
-
- load_interfaces();
-
- {
- if (smbd_server_fd() != -1) {
- set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
- set_socket_options(smbd_server_fd(), user_socket_options);
- }
+ result = talloc_zero(mem_ctx, struct smb_request);
+ if (result == NULL) {
+ return NULL;
}
+ result->sconn = vfs->conn->sconn;
+ result->mid = ++vfs->mid;
- mangle_reset_cache();
- reset_stat_cache();
-
- /* this forces service parameters to be flushed */
- set_current_service(NULL,True);
-
- return (ret);
+ result->inbuf = talloc_array(result, uint8_t, smb_size);
+ if (result->inbuf == NULL) {
+ goto fail;
+ }
+ SSVAL(result->inbuf, smb_mid, result->mid);
+ smb_setlen(result->inbuf, smb_size-4);
+ return result;
+fail:
+ TALLOC_FREE(result);
+ return NULL;
}
/* Main function */
int main(int argc, char *argv[])
{
- BOOL interactive = True;
- int opt;
- static char *cmdstr = "";
- static char *opt_logfile=NULL;
- static int opt_debuglevel;
- pstring logfile;
- struct cmd_set **cmd_set;
- extern BOOL AllowDebugChange;
- static struct vfs_state vfs;
+ char *cmdstr = NULL;
+ struct cmd_set **cmd_set;
+ struct vfs_state *vfs;
int i;
- static char *filename = "";
+ char *filename = NULL;
+ char cwd[MAXPATHLEN];
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev = tevent_context_init(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" },
- {"logfile", 'l', POPT_ARG_STRING, &opt_logfile, 'l', "Write output to specified logfile" },
- { NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_debug },
- { 0, 0, 0, 0}
+ 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();
setlinebuf(stdout);
- DEBUGLEVEL = 1;
- AllowDebugChange = False;
-
pc = poptGetContext("vfstest", argc, (const char **) argv,
long_options, 0);
-
- while((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- case 'l':
- slprintf(logfile, sizeof(logfile) - 1, "%s.client",
- opt_logfile);
- lp_set_logfile(logfile);
- interactive = False;
- break;
-
- case 'd':
- DEBUGLEVEL = opt_debuglevel;
- break;
- }
- }
+
+ 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(False);
+ reload_services(NULL, NULL, false);
/* the following functions are part of the Samba debugging
facilities. See lib/debug.c */
- setup_logging("vfstest", interactive);
- if (!interactive)
- reopen_logs();
-
+ setup_logging("vfstest", DEBUG_STDOUT);
+
+ set_smbd_shim(&vfstest_shim_fns);
+
/* Load command lists */
cmd_set = vfstest_command_list;
}
/* some basic initialization stuff */
- vfs.conn = (struct connection_struct *)malloc(sizeof(struct connection_struct));
- vfs.conn->user = "vfstest";
+ sec_init();
+ init_guest_info();
+ locking_init();
+ serverid_parent_init(NULL);
+ vfs = talloc_zero(NULL, struct vfs_state);
+ vfs->conn = talloc_zero(vfs, connection_struct);
+ vfs->conn->share_access = FILE_GENERIC_ALL;
+ vfs->conn->params = talloc_zero(vfs->conn, struct share_params);
+ vfs->conn->sconn = talloc_zero(NULL, struct smbd_server_connection);
+ vfs->conn->sconn->msg_ctx = messaging_init(vfs->conn->sconn, ev);
+ vfs->conn->sconn->ev_ctx = ev;
+ serverid_register(messaging_server_id(vfs->conn->sconn->msg_ctx), 0);
+ make_session_info_guest(NULL, &vfs->conn->session_info);
+ file_init(vfs->conn->sconn);
+ set_conn_connectpath(vfs->conn, getcwd(cwd, sizeof(cwd)));
for (i=0; i < 1024; i++)
- vfs.files[i] = NULL;
+ vfs->files[i] = NULL;
+
+ /* some advanced initialization stuff */
+ smbd_vfs_init(vfs->conn);
- /* some advanced initiliazation stuff */
- smbd_vfs_init(vfs.conn);
+ if (!posix_locking_init(false)) {
+ return 1;
+ }
/* Do we have a file input? */
- if (filename[0]) {
- process_file(&vfs, filename);
+ if (filename && filename[0]) {
+ process_file(vfs, filename);
return 0;
}
/* Do anything specified with -c */
- if (cmdstr[0]) {
+ if (cmdstr && cmdstr[0]) {
char *cmd;
char *p = cmdstr;
-
- while((cmd=next_command(&p)) != NULL) {
- process_cmd(&vfs, cmd);
+
+ while((cmd=next_command(frame, &p)) != NULL) {
+ status = process_cmd(vfs, cmd);
}
-
- return 0;
+
+ TALLOC_FREE(cmd);
+ return NT_STATUS_IS_OK(status) ? 0 : 1;
}
/* Loop around accepting commands */
while(1) {
- pstring prompt;
- char *line;
+ char *line = NULL;
- slprintf(prompt, sizeof(prompt) - 1, "vfstest $> ");
+ line = smb_readline("vfstest $> ", NULL, completion_fn);
- line = smb_readline(prompt, NULL, completion_fn);
-
- if (line == NULL)
+ if (line == NULL) {
break;
+ }
- if (line[0] != '\n')
- process_cmd(&vfs, line);
+ if (line[0] != '\n') {
+ status = process_cmd(vfs, line);
+ }
+ SAFE_FREE(line);
}
-
- free(vfs.conn);
- return 0;
+
+ TALLOC_FREE(vfs);
+ TALLOC_FREE(frame);
+ return NT_STATUS_IS_OK(status) ? 0 : 1;
}