s4-dns: dlz_bind9: Fix ipv6 updates
[samba.git] / source3 / torture / vfstest.c
index 53b5ee99d9d68bcaf1480757d173cb1fe3bdca1d..b039ac408bee5df424cfcf596eb0ea0bf4e73aef 100644 (file)
@@ -33,6 +33,8 @@
 #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 {
@@ -40,6 +42,9 @@ 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
 ****************************************************************************/
@@ -103,7 +108,12 @@ static char *next_command(TALLOC_CTX *ctx, char **cmdstr)
        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;
 }
@@ -266,11 +276,11 @@ static void add_command_set(struct cmd_set *cmd_set)
 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. */
@@ -278,7 +288,7 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
  again:
        while(next_token_talloc(mem_ctx, &p, &buf, " ")) {
                if (argv) {
-                       argv[argc] = SMB_STRDUP(buf);
+                       argv[argc] = talloc_strdup(argv, buf);
                }
                argc++;
        }
@@ -286,10 +296,8 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
        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;
@@ -316,12 +324,14 @@ static NTSTATUS do_cmd(struct vfs_state *vfs, struct cmd_set *cmd_entry, char *c
        /* 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;
 }
@@ -405,21 +415,24 @@ static void process_file(struct vfs_state *pvfs, char *filename) {
        }
 }
 
-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");
 }
 
 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) {
@@ -428,12 +441,13 @@ struct smb_request *vfstest_get_smbreq(TALLOC_CTX *mem_ctx,
        result->sconn = vfs->conn->sconn;
        result->mid = ++vfs->mid;
 
-       result->inbuf = talloc_array(result, uint8_t, smb_size);
-       if (result->inbuf == NULL) {
+       inbuf = talloc_array(result, uint8_t, smb_size);
+       if (inbuf == NULL) {
                goto fail;
        }
-       SSVAL(result->inbuf, smb_mid, result->mid);
-       smb_setlen(result->inbuf, smb_size-4);
+       SSVAL(inbuf, smb_mid, result->mid);
+       smb_setlen(inbuf, smb_size-4);
+       result->inbuf = inbuf;
        return result;
 fail:
        TALLOC_FREE(result);
@@ -442,16 +456,18 @@ fail:
 
 /* Main function */
 
-int main(int argc, char *argv[])
+int main(int argc, const char *argv[])
 {
        char *cmdstr = NULL;
        struct cmd_set  **cmd_set;
-       struct vfs_state vfs = { 0, };
+       struct vfs_state *vfs;
        int i;
        char *filename = NULL;
        char cwd[MAXPATHLEN];
        TALLOC_CTX *frame = talloc_stackframe();
-       struct tevent_context *ev = tevent_context_init(NULL);
+       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 */
@@ -460,22 +476,32 @@ int main(int argc, char *argv[])
                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();
 
        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 */
@@ -485,6 +511,8 @@ int main(int argc, char *argv[])
           facilities.  See lib/debug.c */
        setup_logging("vfstest", DEBUG_STDOUT);
 
+       set_smbd_shim(&vfstest_shim_fns);
+
        /* Load command lists */
 
        cmd_set = vfstest_command_list;
@@ -500,21 +528,35 @@ int main(int argc, char *argv[])
        init_guest_info();
        locking_init();
        serverid_parent_init(NULL);
-       vfs.conn = talloc_zero(NULL, 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 = 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;
+       }
 
-       /* some advanced initialization stuff */
-       smbd_vfs_init(vfs.conn);
+       vfs->conn->share_access = FILE_GENERIC_ALL;
+       vfs->conn->read_only = false;
+
+       serverid_register(messaging_server_id(vfs->conn->sconn->msg_ctx), 0);
+       file_init(vfs->conn->sconn);
+       for (i=0; i < 1024; i++)
+               vfs->files[i] = NULL;
 
        if (!posix_locking_init(false)) {
                return 1;
@@ -522,7 +564,7 @@ int main(int argc, char *argv[])
 
        /* Do we have a file input? */
        if (filename && filename[0]) {
-               process_file(&vfs, filename);
+               process_file(vfs, filename);
                return 0;
        }
 
@@ -532,11 +574,11 @@ int main(int argc, char *argv[])
                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 */
@@ -551,12 +593,12 @@ int main(int argc, char *argv[])
                }
 
                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;
 }