Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

272 lines
7.7 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. smbcheck.c
  5. Abstract:
  6. Contains a routine for checking Server Message Block for
  7. syntactical correctness.
  8. Author:
  9. Dan Lafferty (danl) 17-Jul-1991
  10. Environment:
  11. User Mode -Win32
  12. Notes:
  13. These files assume that the buffers and strings are NOT Unicode - just
  14. straight ansi.
  15. Revision History:
  16. 17-Jul-1991 danl
  17. ported from LM2.0
  18. --*/
  19. #include <windows.h>
  20. #include <lmcons.h> // network constants and stuff
  21. #include <smbtypes.h> // needed for smb.h
  22. #include <smb.h> // Server Message Block definitions
  23. #include <string.h> // strlen
  24. #include <nb30.h> // Needed in msrv.h
  25. /*
  26. ** Msgsmbcheck - check Server Message Block for syntactical correctness
  27. **
  28. ** This function is called to verify that a Server Message Block
  29. ** is of the specified form. The function returns zero if the
  30. ** SMB is correct; if an error is detected, a non-zero value
  31. ** indicating the nature of the error is returned.
  32. **
  33. ** smbcheck (buffer, size, func, parms, fields)
  34. **
  35. ** ENTRY
  36. ** buffer - a pointer to the buffer containing the SMB
  37. ** size - the number of bytes in the buffer
  38. ** func - the expected SMB function code
  39. ** parms - the expected number of parameters
  40. ** fields - a dope vector describing the expected buffer fields
  41. ** within the SMB's buffer area (see below).
  42. **
  43. ** RETURN
  44. ** an integer status code; zero indicates no errors.
  45. **
  46. ** An SMB is a variable length structure whose exact size
  47. ** depends on the setting of certain fixed-offset fields
  48. ** and whose exact format cannot be determined except by
  49. ** examination of the whole structure. Smbcheck checks to
  50. ** see that an SMB conforms to a set of specified conditions.
  51. ** The "fields" parameter is a dope vector that describes the
  52. ** individual fields to be found in the buffer section at the
  53. ** end of the SMB. The vector is a null-terminated character
  54. ** string. Currently, the elements of the string must be as
  55. ** follows:
  56. **
  57. ** 'b' - the next element in the buffer area should be
  58. ** a variable length buffer prefixed with a byte
  59. ** containing either 1 or 5 followed by two bytes
  60. ** containing the size of the buffer.
  61. ** 'd' - the next element in the buffer area is a null-terminated
  62. ** string prefixed with a byte containing 2.
  63. ** 'p' - the next element in the buffer area is a null-terminated
  64. ** string prefixed with a byte containing 3.
  65. ** 's' - the next element in the buffer area is a null-terminated
  66. ** string prefixed with a byte containing 4.
  67. **
  68. ** SIDE EFFECTS
  69. **
  70. ** none
  71. **/
  72. int
  73. Msgsmbcheck(
  74. LPBYTE buffer, // Buffer containing SMB
  75. USHORT size, // size of SMB buffer (in bytes)
  76. UCHAR func, // Function code
  77. int parms, // Parameter count
  78. LPSTR fields // Buffer fields dope vector
  79. )
  80. {
  81. PSMB_HEADER smb; // SMB header pointer
  82. LPBYTE limit; // Upper limit
  83. int errRet = 0;
  84. smb = (PSMB_HEADER) buffer; // Overlay header with buffer
  85. //
  86. // Must be long enough for header
  87. //
  88. if(size <= sizeof(SMB_HEADER)) {
  89. return(2);
  90. }
  91. //
  92. // Message type must be 0xFF
  93. //
  94. if(smb->Protocol[0] != 0xff) {
  95. return(3);
  96. }
  97. //
  98. // Server must be "SMB"
  99. //
  100. if( smb->Protocol[1] != 'S' ||
  101. smb->Protocol[2] != 'M' ||
  102. smb->Protocol[3] != 'B') {
  103. return(4);
  104. }
  105. //
  106. // Must have proper function code
  107. //
  108. if(smb->Command != func) {
  109. return(5);
  110. }
  111. limit = &buffer[size]; // Set upper limit of SMB
  112. buffer += sizeof(SMB_HEADER); // Skip over header
  113. //
  114. // Parameter counts must match
  115. //
  116. if(*buffer++ != (BYTE)parms) {
  117. return(6);
  118. }
  119. //
  120. // Skip parameters and buffer size
  121. //
  122. buffer += (((SHORT)parms & 0xFF) + 1)*sizeof(SHORT);
  123. //
  124. // Check for overflow
  125. //
  126. if(buffer > limit) { // 342440: RC2SS:MSGSVC: Off by one error in Msgsmbcheck
  127. // JonN 8/9/99: I'm not convinced that this should be >=, if
  128. // the dope vector is empty then this is correct
  129. return(7);
  130. }
  131. //
  132. // Loop to check buffer fields
  133. //
  134. try {
  135. while(*fields) {
  136. //
  137. // Check for overflow
  138. //
  139. if(buffer >= limit) {
  140. errRet = 14;
  141. break;
  142. }
  143. //
  144. // Switch on dope vector character
  145. //
  146. switch(*fields++) {
  147. case 'b': // Variable length data block
  148. if(*buffer != '\001' && *buffer != '\005') {
  149. errRet = 8;
  150. break;
  151. }
  152. //
  153. // Check for block code
  154. //
  155. // 342440: RC2SS:MSGSVC: Off by one error in Msgsmbcheck
  156. if(buffer+3 > limit) {
  157. errRet = 15;
  158. break;
  159. }
  160. ++buffer; // Skip over block code
  161. size = (USHORT)*buffer++ & (USHORT)0xFF; // Get low-byte size
  162. size += ((USHORT)*buffer++ & (USHORT)0xFF)<< 8; // Get high-byte of buffer size
  163. buffer += size; // Increment pointer
  164. break;
  165. case 'd': // Null-terminated dialect string
  166. if(*buffer++ != '\002') { // Check for string code
  167. errRet = 9;
  168. break;
  169. }
  170. // 342440: RC2SS:MSGSVC: Off by one error in Msgsmbcheck
  171. // buffer += strlen(buffer) + 1; // Skip over the string
  172. for ( ; buffer < limit; buffer++) {
  173. if ('\0' == *buffer)
  174. break;
  175. }
  176. buffer++;
  177. break;
  178. case 'p': // Null-terminated path string
  179. if(*buffer++ != '\003') { // Check for string code
  180. errRet = 10;
  181. break;
  182. }
  183. // 342440: RC2SS:MSGSVC: Off by one error in Msgsmbcheck
  184. // buffer += strlen(buffer) + 1; // Skip over the string
  185. for ( ; buffer < limit; buffer++) {
  186. if ('\0' == *buffer)
  187. break;
  188. }
  189. buffer++;
  190. break;
  191. case 's': // Null-terminated string
  192. if(*buffer++ != '\004') { // Check for string code
  193. errRet = 11;
  194. break;
  195. }
  196. // 342440: RC2SS:MSGSVC: Off by one error in Msgsmbcheck
  197. // buffer += strlen(buffer) + 1; // Skip over the string
  198. for ( ; buffer < limit; buffer++) {
  199. if ('\0' == *buffer)
  200. break;
  201. }
  202. buffer++;
  203. break;
  204. }
  205. if ( errRet ) {
  206. break;
  207. }
  208. //
  209. // Check against end of block
  210. //
  211. if(buffer > limit) {
  212. errRet = 12;
  213. break;
  214. }
  215. }
  216. } except( EXCEPTION_EXECUTE_HANDLER ) {
  217. return(13);
  218. }
  219. return(errRet ? errRet : (buffer != limit) ); // Should be false
  220. }