1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester utility functions
4 Copyright (C) Jelmer Vernooij 2006
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "system/filesys.h"
23 #include "system/wait.h"
24 #include "torture/torture.h"
25 #include "libcli/raw/interfaces.h"
26 #include "libcli/raw/libcliraw.h"
27
28 /**
29 create a temporary directory.
30 */
torture_temp_dir(TALLOC_CTX * mem_ctx,const char * prefix,char ** tempdir)31 _PUBLIC_ NTSTATUS torture_temp_dir(TALLOC_CTX *mem_ctx, const char *prefix,
32 char **tempdir)
33 {
34 const char *basedir = lp_parm_string(-1, "torture", "basedir");
35 if (basedir == NULL) basedir = ".";
36 *tempdir = talloc_asprintf(mem_ctx, "%s/torture.tmp-%s.XXXXXX",
37 basedir, prefix);
38
39 if (mkdtemp(*tempdir) == NULL)
40 return NT_STATUS_UNSUCCESSFUL;
41
42 return NT_STATUS_OK;
43 }
44
45 /**
46 check if 2 NTTIMEs are equal.
47 */
nt_time_equal(NTTIME * t1,NTTIME * t2)48 BOOL nt_time_equal(NTTIME *t1, NTTIME *t2)
49 {
50 return *t1 == *t2;
51 }
52
53 /**
54 * Provision a Samba installation using @param setupdir_script and start smbd.
55 */
torture_setup_server(TALLOC_CTX * mem_ctx,const char * prefix,const char * setupdir_script,const char * smbd_path,pid_t * smbd_pid)56 NTSTATUS torture_setup_server(TALLOC_CTX *mem_ctx,
57 const char *prefix,
58 const char *setupdir_script,
59 const char *smbd_path,
60 pid_t *smbd_pid)
61 {
62 char *tempdir;
63 NTSTATUS status;
64 pid_t pid;
65 int child_status;
66 char *configfile, *configparam;
67 pid_t closed_pid;
68
69 *smbd_pid = -1;
70
71 status = torture_temp_dir(mem_ctx, prefix, &tempdir);
72 if (NT_STATUS_IS_ERR(status)) {
73 return status;
74 }
75
76 if ((pid = fork()) == 0) {
77 execl(setupdir_script, setupdir_script, tempdir, NULL);
78 exit(1);
79 } else if (pid == -1) {
80 DEBUG(0, ("Unable to fork()\n"));
81 return NT_STATUS_UNSUCCESSFUL;
82 }
83
84 closed_pid = waitpid(pid, &child_status, 0);
85
86 if (closed_pid == -1) {
87 DEBUG(1, ("Error waiting for child"));
88 return NT_STATUS_UNSUCCESSFUL;
89 }
90
91 SMB_ASSERT(closed_pid == pid);
92
93 if (!WIFEXITED(child_status) || WEXITSTATUS(child_status) != 0) {
94 DEBUG(1, ("Invalid return code from setup script %s: %d\n",
95 setupdir_script,
96 WEXITSTATUS(child_status)));
97 return NT_STATUS_UNSUCCESSFUL;
98 }
99
100 configfile = talloc_asprintf(mem_ctx, "%s/etc/smb.conf",
101 tempdir);
102 if (!file_exist(configfile)) {
103 DEBUG(1, ("Setup script didn't create %s\n", configfile));
104 return NT_STATUS_UNSUCCESSFUL;
105 }
106
107 configparam = talloc_asprintf(mem_ctx, "--configfile=%s", configfile);
108 talloc_free(configfile);
109
110 if ((pid = fork()) == 0) {
111 execl(smbd_path, smbd_path, "-i", "--model=single",
112 configparam, NULL);
113 exit(1);
114 } else if (pid == -1) {
115 DEBUG(0, ("Unable to fork()\n"));
116 return NT_STATUS_UNSUCCESSFUL;
117 }
118
119 *smbd_pid = pid;
120
121 return NT_STATUS_OK;
122 }
123
torture_second_tcon(TALLOC_CTX * mem_ctx,struct smbcli_session * session,const char * sharename,struct smbcli_tree ** res)124 NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx,
125 struct smbcli_session *session,
126 const char *sharename,
127 struct smbcli_tree **res)
128 {
129 union smb_tcon tcon;
130 struct smbcli_tree *result;
131 TALLOC_CTX *tmp_ctx;
132 NTSTATUS status;
133
134 if ((tmp_ctx = talloc_new(mem_ctx)) == NULL) {
135 return NT_STATUS_NO_MEMORY;
136 }
137
138 result = smbcli_tree_init(session, tmp_ctx, False);
139 if (result == NULL) {
140 talloc_free(tmp_ctx);
141 return NT_STATUS_NO_MEMORY;
142 }
143
144 tcon.generic.level = RAW_TCON_TCONX;
145 tcon.tconx.in.flags = 0;
146
147 /* Ignore share mode security here */
148 tcon.tconx.in.password = data_blob(NULL, 0);
149 tcon.tconx.in.path = sharename;
150 tcon.tconx.in.device = "?????";
151
152 status = smb_raw_tcon(result, tmp_ctx, &tcon);
153 if (!NT_STATUS_IS_OK(status)) {
154 talloc_free(tmp_ctx);
155 return status;
156 }
157
158 result->tid = tcon.tconx.out.tid;
159 *res = talloc_steal(mem_ctx, result);
160 talloc_free(tmp_ctx);
161 return NT_STATUS_OK;
162 }
163