1 diff -ur ../smb3.0a20.orig/source/include/smb.h ./source/include/smb.h
2 --- ../smb3.0a20.orig/source/include/smb.h Mon Jan 6 18:04:22 2003
3 +++ ./source/include/smb.h Fri Jun 4 05:34:14 2004
6 extern struct poptOption popt_common_debug[];
10 + SMB_BIG_UINT allocation_size;
15 diff -ur ../smb3.0a20.orig/source/include/smb_macros.h ./source/include/smb_macros.h
16 --- ../smb3.0a20.orig/source/include/smb_macros.h Mon Jan 6 18:04:22 2003
17 +++ ./source/include/smb_macros.h Fri Jun 4 18:24:20 2004
20 #define vfs_chdir(conn,fname) ((conn)->vfs_ops.chdir((conn),fname))
22 +/*******************************************************************
23 + A wrapper for vfs_listads().
24 +********************************************************************/
25 +#define vfs_listads(conn,path,list,size) ((conn)->vfs_ops.listads((conn),(path),(list),(size)))
26 #endif /* _SMB_MACROS_H */
27 diff -ur ../smb3.0a20.orig/source/include/vfs.h ./source/include/vfs.h
28 --- ../smb3.0a20.orig/source/include/vfs.h Mon Jan 6 18:04:23 2003
29 +++ ./source/include/vfs.h Fri Jun 4 16:30:14 2004
31 /* Changed to version 3 for POSIX acl extensions. JRA. */
32 /* Changed to version 4 for cascaded VFS interface. Alexander Bokovoy. */
33 /* Changed to version 5 for sendfile addition. JRA. */
34 -#define SMB_VFS_INTERFACE_VERSION 5
35 +/* Changed to version 11 to include alternate data streams. */
36 +#define SMB_VFS_INTERFACE_VERSION 11
39 /* Version of supported cascaded interface backward copmatibility.
41 int (*sys_acl_free_text)(struct connection_struct *conn, char *text);
42 int (*sys_acl_free_acl)(struct connection_struct *conn, SMB_ACL_T posix_acl);
43 int (*sys_acl_free_qualifier)(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype);
45 + /* alternate stream operations. */
46 + ssize_t (*listads)(/* struct vfs_handle_struct *handle, */ struct connection_struct *conn,const char *path, char *list, size_t size);
51 SMB_VFS_OP_SYS_ACL_FREE_ACL,
52 SMB_VFS_OP_SYS_ACL_FREE_QUALIFIER,
54 + /* alternate stream */
57 /* This should always be last enum value */
60 diff -ur ../smb3.0a20.orig/source/smbd/nttrans.c ./source/smbd/nttrans.c
61 --- ../smb3.0a20.orig/source/smbd/nttrans.c Mon Jan 6 18:05:44 2003
62 +++ ./source/smbd/nttrans.c Fri Jul 2 07:38:38 2004
67 +#define SMB_VFS_LISTADS vfs_listads
69 /****************************************************************************
70 Send the required number of replies back.
71 We assume all fields other than the data fields are
73 * Check to see if this is a mac fork of some kind.
76 - if( strchr_m(fname, ':')) {
77 + if( !strchr_m(fname, ':')) {
78 + /* it's not an alternate stream */
79 + END_PROFILE(SMBntcreateX);
80 + return(ERROR_DOS(ERRDOS,ERRbadfid));
82 + else if (-1 == SMB_VFS_LISTADS(conn, NULL, NULL, 0)) {
83 + /* fs have no support for alternate streams */
84 END_PROFILE(SMBntcreateX);
85 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
87 - END_PROFILE(SMBntcreateX);
88 - return(ERROR_DOS(ERRDOS,ERRbadfid));
92 - * Copy in the base directory name.
95 + * Copy in the base name.
97 + pstrcpy( fname, dir_fsp->fsp_name );
98 + dir_name_len = strlen(fname);
100 + else { /* it's a dir */
102 + * Copy in the base directory name.
105 - pstrcpy( fname, dir_fsp->fsp_name );
106 - dir_name_len = strlen(fname);
107 + pstrcpy( fname, dir_fsp->fsp_name );
108 + dir_name_len = strlen(fname);
111 - * Ensure it ends in a '\'.
114 - if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
115 - pstrcat(fname, "\\");
119 + * Ensure it ends in a '\'.
122 + if(fname[dir_name_len-1] != '\\' && fname[dir_name_len-1] != '/') {
123 + pstrcat(fname, "\\");
127 srvstr_pull_buf(inbuf, &fname[dir_name_len], smb_buf(inbuf), sizeof(fname)-dir_name_len, STR_TERMINATE);
129 srvstr_pull_buf(inbuf, fname, smb_buf(inbuf), sizeof(fname), STR_TERMINATE);
132 * Check to see if this is a mac fork of some kind.
135 - if( strchr_m(fname, ':')) {
136 + if( strchr_m(fname, ':') && -1 == SMB_VFS_LISTADS(conn, NULL, NULL, 0)) {
137 END_PROFILE(SMBntcreateX);
138 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
140 @@ -1138,12 +1149,10 @@
141 srvstr_pull(inbuf, fname, params+53, sizeof(fname), total_parameter_count-53, STR_TERMINATE);
144 - * Check to see if this is a mac fork of some kind.
145 + * Check to see if this is a mac fork of some kind. FIXME ADS
148 - if( strchr_m(fname, ':'))
149 + if( strchr_m(fname, ':') && -1 == SMB_VFS_LISTADS(conn, NULL, NULL, 0))
150 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
152 return ERROR_DOS(ERRDOS,ERRbadfid);
155 @@ -1172,7 +1181,7 @@
156 * Check to see if this is a mac fork of some kind.
159 - if( strchr_m(fname, ':'))
160 + if( strchr_m(fname, ':') && -1 == SMB_VFS_LISTADS(conn, NULL, NULL, 0))
161 return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
164 diff -ur ../smb3.0a20.orig/source/smbd/trans2.c ./source/smbd/trans2.c
165 --- ../smb3.0a20.orig/source/smbd/trans2.c Mon Jan 6 18:05:48 2003
166 +++ ./source/smbd/trans2.c Thu Jul 1 03:06:42 2004
171 +#define SMB_VFS_STAT vfs_stat
172 +#define SMB_VFS_LISTADS vfs_listads
174 +/****************************************************************************
175 + ****************************************************************************
176 + Return a linked list of the alternate streams Plus the total size
177 +****************************************************************************/
179 + struct ads_list *next, *prev;
180 + struct ads_struct ads;
183 +static struct ads_list *get_ads_list(TALLOC_CTX *mem_ctx, connection_struct *conn, files_struct *fsp, const char *fname, size_t *pads_total_len)
185 + /* Get a list of all ads with size, lax namesize is 64k. */
186 + size_t ads_namelist_size = 4096;
187 + char *ads_namelist;
191 + struct ads_list *ads_list_head = NULL;
193 + *pads_total_len = 0;
195 + DEBUG(10,("get_ads_list\n" ));
197 + for (i = 0, ads_namelist = talloc(mem_ctx, ads_namelist_size); i < 6;
198 + ads_namelist = talloc_realloc(mem_ctx, ads_namelist, ads_namelist_size), i++) {
200 + sizeret = SMB_VFS_LISTADS(conn, fname, ads_namelist, ads_namelist_size);
201 + if (sizeret == -1 && errno == ERANGE) {
202 + ads_namelist_size *= 2;
211 + DEBUG(10,("get_ads_list: ads_namelist size = %d\n", sizeret ));
214 + for (p = ads_namelist; p - ads_namelist < sizeret; p += strlen(p) +1) {
215 + struct ads_list *listp, *tmp;
216 + SMB_STRUCT_STAT sbuf;
219 + listp = talloc(mem_ctx, sizeof(struct ads_list));
223 + listp->ads.name = talloc_strdup(mem_ctx, p);
224 + if (!listp->ads.name)
227 + listp->ads.size = 0;
228 + listp->ads.allocation_size = 0;
230 + t = talloc_asprintf(mem_ctx, "%s%s", fname, p);
233 + if (!SMB_VFS_STAT(conn, t ,&sbuf)) {
234 + listp->ads.size = get_file_size(sbuf);
235 + listp->ads.allocation_size = get_allocation_size(NULL,&sbuf);
237 + /* FIXME get ride of this */
239 + fstring dos_ads_name;
241 + push_ascii_fstring(dos_ads_name, listp->ads.name);
242 + *pads_total_len += strlen(dos_ads_name) + 1 + 24;
243 + DEBUG(10,("get_ads_list: total_len = %u, %s, size = %llu\n",
244 + *pads_total_len, dos_ads_name, listp->ads.size ));
246 + DLIST_ADD_END(ads_list_head, listp, tmp);
250 + DEBUG(10,("get_ads_list: total_len = %u\n", *pads_total_len));
251 + return ads_list_head;
254 +/****************************************************************************
255 + Fill a qfilepathinfo buffer with alternate streams.
256 + Returns the length of the buffer that was filled.
257 +****************************************************************************/
259 +static unsigned int fill_ads_buffer(char *pdata, unsigned int total_data_size,
260 + connection_struct *conn, files_struct *fsp, const char *fname)
262 + unsigned int ret_data_size = 0;
264 + size_t total_ads_len;
265 + TALLOC_CTX *mem_ctx;
266 + struct ads_list *ads_list;
268 + SMB_ASSERT(total_data_size >= 24);
270 + mem_ctx = talloc_init(/*"fill_ads_buffer"*/);
275 + ads_list = get_ads_list(mem_ctx, conn, fsp, fname, &total_ads_len);
277 + talloc_destroy(mem_ctx);
281 + if (total_ads_len > total_data_size) {
282 + talloc_destroy(mem_ctx);
286 + for (p = pdata; ads_list; ads_list = ads_list->next) {
288 + size_t dos_namelen;
289 + fstring dos_ads_name;
291 + push_ascii_fstring(dos_ads_name, ads_list->ads.name);
292 + dos_namelen = strlen(dos_ads_name);
293 + if (dos_namelen > 255 || dos_namelen == 0) {
296 + if (dos_namelen + 24 > total_data_size) {
300 + /* We know we have room. */
301 + size_t byte_len = dos_PutUniCode(p +24, ads_list->ads.name, -1, False);
302 + size_t off = SMB_ROUNDUP(24 +byte_len, 8);
304 + SIVAL(p,0,0); /* from ethereal next entry offset */
305 + SIVAL(p,4, byte_len); /* Byte length of unicode string :filename:$DATA */
306 + SOFF_T(p,8, ads_list->ads.size);
307 + SOFF_T(p,16, ads_list->ads.allocation_size);
308 + if (ads_list->next) {
312 + /* don't pad the last one */
313 + off = 24 +byte_len;
316 + total_data_size -= off;
320 + ret_data_size = PTR_DIFF(p, pdata);
321 + DEBUG(10,("fill_ads_buffer: data_size = %u, total_ads_len = %u\n",
322 + ret_data_size, total_ads_len ));
323 + talloc_destroy(mem_ctx);
324 + return ret_data_size;
327 /****************************************************************************
328 Send the required number of replies back.
329 We assume all fields other than the data fields are
330 @@ -1934,7 +2090,7 @@
337 * NT4 server just returns "invalid query" to this - if we try to answer
338 * it then NTws gets a BSOD! (tridge).
339 @@ -1943,16 +2099,24 @@
340 case SMB_QUERY_FILE_STREAM_INFO:
342 case SMB_FILE_STREAM_INFORMATION:
346 - size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
347 - SIVAL(pdata,0,0); /* ??? */
348 - SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
349 - SOFF_T(pdata,8,file_size);
350 - SIVAL(pdata,16,allocation_size);
351 - SIVAL(pdata,20,0); /* ??? */
352 - data_size = 24 + byte_len;
359 + size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", 0xE, False);
361 + off = SMB_ROUNDUP(24 +byte_len, 8); /* FIXME or 8 ? */
362 + SIVAL(pdata,0,0); /* from ethereal next entry offset */
363 + SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
364 + SOFF_T(pdata,8,file_size);
365 + SOFF_T(pdata,16,allocation_size);
367 + if ((data_size = fill_ads_buffer(pdata +off, data_size, conn, fsp, fname))) {
368 + SIVAL(pdata,0,off);
374 diff -ur ../smb3.0a20.orig/source/smbd/vfs-wrap.c ./source/smbd/vfs-wrap.c
375 --- ../smb3.0a20.orig/source/smbd/vfs-wrap.c Mon Jan 6 18:05:49 2003
376 +++ ./source/smbd/vfs-wrap.c Fri Jun 4 16:33:16 2004
379 return sys_acl_free_qualifier(qualifier, tagtype);
382 +/****************************************************************
383 + Alternate stream operations.
384 +*****************************************************************/
386 +ssize_t vfswrap_listads(/* struct vfs_handle_struct *handle, */ struct connection_struct *conn,const char *path, char *list, size_t size)
392 Only in ./source/smbd: vfs-wrap.c.orig
393 diff -ur ../smb3.0a20.orig/source/smbd/vfs.c ./source/smbd/vfs.c
394 --- ../smb3.0a20.orig/source/smbd/vfs.c Mon Jan 6 18:05:48 2003
395 +++ ./source/smbd/vfs.c Fri Jun 4 05:40:09 2004
397 vfswrap_sys_acl_get_perm,
398 vfswrap_sys_acl_free_text,
399 vfswrap_sys_acl_free_acl,
400 - vfswrap_sys_acl_free_qualifier
401 + vfswrap_sys_acl_free_qualifier,
403 + /* alternate streams operations. */
407 /****************************************************************************