2 Unix SMB/CIFS implementation.
3 SMB torture tester utility functions
4 Copyright (C) Andrew Tridgell 2003
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.
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.
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.
24 static struct timeval tp1,tp2;
26 void start_timer(void)
28 gettimeofday(&tp1,NULL);
31 double end_timer(void)
33 gettimeofday(&tp2,NULL);
34 return((tp2.tv_sec - tp1.tv_sec) +
35 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
40 create a directory, returning a handle to it
42 int create_directory_handle(struct cli_tree *tree, const char *dname)
48 mem_ctx = talloc_init("create_directory_handle");
50 io.generic.level = RAW_OPEN_NTCREATEX;
51 io.ntcreatex.in.root_fid = 0;
52 io.ntcreatex.in.flags = 0;
53 io.ntcreatex.in.access_mask = SA_RIGHT_FILE_ALL_ACCESS;
54 io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
55 io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
56 io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
57 io.ntcreatex.in.alloc_size = 0;
58 io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
59 io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
60 io.ntcreatex.in.security_flags = 0;
61 io.ntcreatex.in.fname = dname;
63 status = smb_raw_open(tree, mem_ctx, &io);
64 if (!NT_STATUS_IS_OK(status)) {
65 talloc_destroy(mem_ctx);
69 talloc_destroy(mem_ctx);
70 return io.ntcreatex.out.fnum;
74 sometimes we need a fairly complex file to work with, so we can test
75 all possible attributes.
77 int create_complex_file(struct cli_state *cli, TALLOC_CTX *mem_ctx, const char *fname)
81 union smb_setfileinfo setfile;
82 union smb_fileinfo fileinfo;
83 time_t t = (time(NULL) & ~1);
86 cli_unlink(cli->tree, fname);
87 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
88 FILE_ATTRIBUTE_NORMAL,
89 NTCREATEX_SHARE_ACCESS_DELETE|
90 NTCREATEX_SHARE_ACCESS_READ|
91 NTCREATEX_SHARE_ACCESS_WRITE,
92 NTCREATEX_DISP_OVERWRITE_IF,
94 if (fnum == -1) return -1;
96 cli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
99 setfile.generic.level = RAW_SFILEINFO_EA_SET;
100 setfile.generic.file.fnum = fnum;
101 setfile.ea_set.in.ea.flags = 0;
102 setfile.ea_set.in.ea.name.s = "EAONE";
103 setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "VALUE1", 6);
105 status = smb_raw_setfileinfo(cli->tree, &setfile);
106 if (!NT_STATUS_IS_OK(status)) {
107 printf("Failed to setup EAs\n");
110 setfile.ea_set.in.ea.name.s = "SECONDEA";
111 setfile.ea_set.in.ea.value = data_blob_talloc(mem_ctx, "ValueTwo", 8);
112 status = smb_raw_setfileinfo(cli->tree, &setfile);
113 if (!NT_STATUS_IS_OK(status)) {
114 printf("Failed to setup EAs\n");
117 /* make sure all the timestamps aren't the same, and are also
118 in different DST zones*/
119 setfile.generic.level = RAW_SFILEINFO_SETATTRE;
120 setfile.generic.file.fnum = fnum;
122 setfile.setattre.in.create_time = t + 9*30*24*60*60;
123 setfile.setattre.in.access_time = t + 6*30*24*60*60;
124 setfile.setattre.in.write_time = t + 3*30*24*60*60;
126 status = smb_raw_setfileinfo(cli->tree, &setfile);
127 if (!NT_STATUS_IS_OK(status)) {
128 printf("Failed to setup file times - %s\n", nt_errstr(status));
131 /* make sure all the timestamps aren't the same */
132 fileinfo.generic.level = RAW_FILEINFO_GETATTRE;
133 fileinfo.generic.in.fnum = fnum;
135 status = smb_raw_fileinfo(cli->tree, mem_ctx, &fileinfo);
136 if (!NT_STATUS_IS_OK(status)) {
137 printf("Failed to query file times - %s\n", nt_errstr(status));
140 if (setfile.setattre.in.create_time != fileinfo.getattre.out.create_time) {
141 printf("create_time not setup correctly\n");
143 if (setfile.setattre.in.access_time != fileinfo.getattre.out.access_time) {
144 printf("access_time not setup correctly\n");
146 if (setfile.setattre.in.write_time != fileinfo.getattre.out.write_time) {
147 printf("write_time not setup correctly\n");
155 /* return a pointer to a anonymous shared memory segment of size "size"
156 which will persist across fork() but will disappear when all processes
159 The memory is not zeroed
161 This function uses system5 shared memory. It takes advantage of a property
162 that the memory is not destroyed if it is attached when the id is removed
164 void *shm_setup(int size)
169 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
171 printf("can't get shared memory\n");
174 ret = (void *)shmat(shmid, 0, 0);
175 if (!ret || ret == (void *)-1) {
176 printf("can't attach to shared memory\n");
179 /* the following releases the ipc, but note that this process
180 and all its children will still have access to the memory, its
181 just that the shmid is no longer valid for other shm calls. This
182 means we don't leave behind lots of shm segments after we exit
184 See Stevens "advanced programming in unix env" for details
186 shmctl(shmid, IPC_RMID, 0);
193 check that a wire string matches the flags specified
194 not 100% accurate, but close enough for testing
196 BOOL wire_bad_flags(WIRE_STRING *str, int flags)
199 if (!str || !str->s) return True;
200 len = strlen(str->s);
201 if (flags & STR_TERMINATE) len++;
202 if ((flags & STR_UNICODE) || !getenv("CLI_FORCE_ASCII")) {
204 } else if (flags & STR_TERMINATE_ASCII) {
207 if (str->private_length != len) {
208 printf("Expected wire_length %d but got %d for '%s'\n",
209 len, str->private_length, str->s);
216 check if 2 NTTIMEs are equal
218 BOOL nt_time_equal(NTTIME *t1, NTTIME *t2)
224 dump a all_info QFILEINFO structure
226 void dump_all_info(TALLOC_CTX *mem_ctx, union smb_fileinfo *finfo)
228 d_printf("\tcreate_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.create_time));
229 d_printf("\taccess_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.access_time));
230 d_printf("\twrite_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.write_time));
231 d_printf("\tchange_time: %s\n", nt_time_string(mem_ctx, finfo->all_info.out.change_time));
232 d_printf("\tattrib: 0x%x\n", finfo->all_info.out.attrib);
233 d_printf("\talloc_size: %llu\n", (unsigned long long)finfo->all_info.out.alloc_size);
234 d_printf("\tsize: %llu\n", (unsigned long long)finfo->all_info.out.size);
235 d_printf("\tnlink: %u\n", finfo->all_info.out.nlink);
236 d_printf("\tdelete_pending: %u\n", finfo->all_info.out.delete_pending);
237 d_printf("\tdirectory: %u\n", finfo->all_info.out.directory);
238 d_printf("\tea_size: %u\n", finfo->all_info.out.ea_size);
239 d_printf("\tfname: '%s'\n", finfo->all_info.out.fname.s);
243 dump file infor by name
245 void torture_all_info(struct cli_tree *tree, const char *fname)
247 TALLOC_CTX *mem_ctx = talloc_init(fname);
248 union smb_fileinfo finfo;
251 finfo.generic.level = RAW_FILEINFO_ALL_INFO;
252 finfo.generic.in.fname = fname;
253 status = smb_raw_pathinfo(tree, mem_ctx, &finfo);
254 if (!NT_STATUS_IS_OK(status)) {
255 d_printf("%s - %s\n", fname, nt_errstr(status));
259 d_printf("%s:\n", fname);
260 dump_all_info(mem_ctx, &finfo);
261 talloc_destroy(mem_ctx);
266 split a UNC name into server and share names
268 BOOL split_unc_name(const char *unc, char **server, char **share)
270 char *p = strdup(unc);
271 if (!p) return False;
272 all_string_sub(p, "\\", "/", 0);
273 if (strncmp(p, "//", 2) != 0) return False;
276 p = strchr(*server, '/');
277 if (!p) return False;
286 split a USER%PASS pair into username and password
288 BOOL split_username(const char *pair, char **user, char **pass)
290 char *p = strdup(pair);
291 if (!p) return False;
295 p = strchr(*user, '%');
296 if (!p) return False;
305 set a attribute on a file
307 BOOL torture_set_file_attribute(struct cli_tree *tree, const char *fname, uint16 attrib)
309 union smb_setfileinfo sfinfo;
312 sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
313 sfinfo.generic.file.fname = fname;
315 ZERO_STRUCT(sfinfo.basic_info.in);
316 sfinfo.basic_info.in.attrib = attrib;
317 status = smb_raw_setpathinfo(tree, &sfinfo);
318 return NT_STATUS_IS_OK(status);
323 set a file descriptor as sparse
325 NTSTATUS torture_set_sparse(struct cli_tree *tree, int fnum)
331 mem_ctx = talloc_init("torture_set_sparse");
333 return NT_STATUS_NO_MEMORY;
336 nt.ntioctl.level = RAW_IOCTL_NTIOCTL;
337 nt.ntioctl.in.function = 0x900c4;
338 nt.ntioctl.in.fnum = fnum;
339 nt.ntioctl.in.fsctl = True;
340 nt.ntioctl.in.filter = 0;
342 status = smb_raw_ioctl(tree, mem_ctx, &nt);
344 talloc_destroy(mem_ctx);