smbtrans2set.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "headers.h"
  2. SmbProcessResult
  3. smbtrans2setfileinformation(SmbSession *s, SmbHeader *h)
  4. {
  5. SmbTree *t;
  6. ushort infolevel;
  7. SmbBuffer *b;
  8. SmbProcessResult pr;
  9. ushort fid;
  10. SmbFile *f;
  11. vlong newsize;
  12. uvlong atime, mtime;
  13. ulong attr;
  14. ulong mode;
  15. t = smbidmapfind(s->tidmap, h->tid);
  16. if (t == nil) {
  17. smbseterror(s, ERRSRV, ERRinvtid);
  18. pr = SmbProcessResultError;
  19. goto done;
  20. }
  21. b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
  22. if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) {
  23. misc:
  24. pr = SmbProcessResultMisc;
  25. goto done;
  26. }
  27. f = smbidmapfind(s->fidmap, fid);
  28. if (f == nil) {
  29. smbseterror(s, ERRDOS, ERRbadfid);
  30. pr = SmbProcessResultError;
  31. goto done;
  32. }
  33. switch (infolevel) {
  34. case SMB_SET_FILE_ALLOCATION_INFO:
  35. case SMB_SET_FILE_END_OF_FILE_INFO:
  36. if (s->transaction.in.tdcount < 8)
  37. goto misc;
  38. newsize = smbnhgetv(s->transaction.in.data);
  39. pr = smbtruncatefile(s, f, newsize);
  40. if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0))
  41. goto misc;
  42. break;
  43. case SMB_SET_FILE_BASIC_INFO:
  44. if (s->transaction.in.tdcount < 4 * 8 + 4)
  45. goto misc;
  46. atime = smbnhgetv(s->transaction.in.data + 8);
  47. mtime = smbnhgetv(s->transaction.in.data + 24);
  48. attr = smbnhgetv(s->transaction.in.data + 32);
  49. if (attr) {
  50. Dir *od = dirfstat(f->fd);
  51. if (od == nil)
  52. goto noaccess;
  53. mode = smbdosattr2plan9wstatmode(od->mode, attr);
  54. free(od);
  55. }
  56. else
  57. mode = 0xffffffff;
  58. if (atime || mtime || mode != 0xffffffff) {
  59. Dir d;
  60. memset(&d, 0xff, sizeof(d));
  61. d.name = d.uid = d.gid = d.muid = nil;
  62. if (atime)
  63. d.atime = smbtime2plan9time(atime);
  64. if (mtime)
  65. d.mtime = smbtime2plan9time(mtime);
  66. d.mode = mode;
  67. if (dirfwstat(f->fd, &d) < 0) {
  68. noaccess:
  69. smbseterror(s, ERRDOS, ERRnoaccess);
  70. pr = SmbProcessResultError;
  71. goto done;
  72. }
  73. }
  74. if (!smbbufferputs(s->transaction.out.parameters, 0))
  75. goto misc;
  76. pr = SmbProcessResultReply;
  77. break;
  78. case SMB_SET_FILE_DISPOSITION_INFO:
  79. if (s->transaction.in.tdcount < 1)
  80. goto misc;
  81. f->sf->deleteonclose = *s->transaction.in.data;
  82. if (!smbbufferputs(s->transaction.out.parameters, 0))
  83. goto misc;
  84. pr = SmbProcessResultReply;
  85. break;
  86. default:
  87. smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4ux not implemented\n", infolevel);
  88. smbseterror(s, ERRDOS, ERRunknownlevel);
  89. pr = SmbProcessResultError;
  90. break;
  91. }
  92. done:
  93. smbbufferfree(&b);
  94. return pr;
  95. }
  96. SmbProcessResult
  97. smbtrans2setpathinformation(SmbSession *s, SmbHeader *h)
  98. {
  99. char *fullpath, *path;
  100. SmbTree *t;
  101. ushort infolevel;
  102. SmbBuffer *b;
  103. SmbProcessResult pr;
  104. ushort atime, adate, mtime, mdate;
  105. ulong attr;
  106. ulong mode;
  107. ulong size;
  108. uvlong length;
  109. t = smbidmapfind(s->tidmap, h->tid);
  110. if (t == nil) {
  111. smbseterror(s, ERRSRV, ERRinvtid);
  112. pr = SmbProcessResultError;
  113. goto done;
  114. }
  115. b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
  116. path = nil;
  117. if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4)
  118. || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
  119. misc:
  120. pr = SmbProcessResultMisc;
  121. goto done;
  122. }
  123. fullpath = nil;
  124. smbstringprint(&fullpath, "%s%s", t->serv->path, path);
  125. translogprint(s->transaction.in.setup[0], "path %s\n", path);
  126. translogprint(s->transaction.in.setup[0], "infolevel 0x%.4ux\n", infolevel);
  127. translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath);
  128. switch (infolevel) {
  129. case SMB_INFO_STANDARD:
  130. if (s->transaction.in.tdcount < 6 * 4 + 2 * 2)
  131. goto misc;
  132. adate = smbnhgets(s->transaction.in.data + 6);
  133. atime = smbnhgets(s->transaction.in.data + 4);
  134. mdate = smbnhgets(s->transaction.in.data + 10);
  135. mtime = smbnhgets(s->transaction.in.data + 8);
  136. size = smbnhgetl(s->transaction.in.data + 12);
  137. attr = smbnhgets(s->transaction.in.data + 20);
  138. if (attr) {
  139. Dir *od = dirstat(fullpath);
  140. if (od == nil)
  141. goto noaccess;
  142. mode = smbdosattr2plan9wstatmode(od->mode, attr);
  143. free(od);
  144. }
  145. else
  146. mode = 0xffffffff;
  147. translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode);
  148. if (size)
  149. length = size;
  150. else
  151. length = ~0LL;
  152. translogprint(s->transaction.in.setup[0], "size %lld\n", size);
  153. translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime);
  154. translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime);
  155. if (size || adate || atime || mdate || mtime || mode != 0xffffffff) {
  156. Dir d;
  157. memset(&d, 0xff, sizeof(d));
  158. d.name = d.uid = d.gid = d.muid = nil;
  159. if (adate || atime)
  160. d.atime = smbdatetime2plan9time(adate, atime, s->tzoff);
  161. if (mdate || mtime)
  162. d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff);
  163. d.mode = mode;
  164. d.length = size;
  165. if (dirwstat(fullpath, &d) < 0) {
  166. noaccess:
  167. smbseterror(s, ERRDOS, ERRnoaccess);
  168. pr = SmbProcessResultError;
  169. goto done;
  170. }
  171. }
  172. if (!smbbufferputs(s->transaction.out.parameters, 0))
  173. goto misc;
  174. pr = SmbProcessResultReply;
  175. break;
  176. default:
  177. smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4ux not implemented\n", infolevel);
  178. smbseterror(s, ERRDOS, ERRunknownlevel);
  179. pr = SmbProcessResultError;
  180. break;
  181. }
  182. done:
  183. smbbufferfree(&b);
  184. return pr;
  185. }