00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 BOOL msrpc_gen(DATA_BLOB *blob,
00044 const char *format, ...)
00045 {
00046 int i, n;
00047 va_list ap;
00048 char *s;
00049 uint8 *b;
00050 int head_size=0, data_size=0;
00051 int head_ofs, data_ofs;
00052
00053
00054 va_start(ap, format);
00055 for (i=0; format[i]; i++) {
00056 switch (format[i]) {
00057 case 'U':
00058 s = va_arg(ap, char *);
00059 head_size += 8;
00060 data_size += str_charnum(s) * 2;
00061 break;
00062 case 'A':
00063 s = va_arg(ap, char *);
00064 head_size += 8;
00065 data_size += str_ascii_charnum(s);
00066 break;
00067 case 'a':
00068 n = va_arg(ap, int);
00069 s = va_arg(ap, char *);
00070 data_size += (str_charnum(s) * 2) + 4;
00071 break;
00072 case 'B':
00073 b = va_arg(ap, uint8 *);
00074 head_size += 8;
00075 data_size += va_arg(ap, int);
00076 break;
00077 case 'b':
00078 b = va_arg(ap, uint8 *);
00079 head_size += va_arg(ap, int);
00080 break;
00081 case 'd':
00082 n = va_arg(ap, int);
00083 head_size += 4;
00084 break;
00085 case 'C':
00086 s = va_arg(ap, char *);
00087 head_size += str_charnum(s) + 1;
00088 break;
00089 }
00090 }
00091 va_end(ap);
00092
00093
00094 *blob = data_blob(NULL, head_size + data_size);
00095
00096 head_ofs = 0;
00097 data_ofs = head_size;
00098
00099 va_start(ap, format);
00100 for (i=0; format[i]; i++) {
00101 switch (format[i]) {
00102 case 'U':
00103 s = va_arg(ap, char *);
00104 n = str_charnum(s);
00105 SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
00106 SSVAL(blob->data, head_ofs, n*2); head_ofs += 2;
00107 SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
00108 push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
00109 data_ofs += n*2;
00110 break;
00111 case 'A':
00112 s = va_arg(ap, char *);
00113 n = str_ascii_charnum(s);
00114 SSVAL(blob->data, head_ofs, n); head_ofs += 2;
00115 SSVAL(blob->data, head_ofs, n); head_ofs += 2;
00116 SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
00117 push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN);
00118 data_ofs += n;
00119 break;
00120 case 'a':
00121 n = va_arg(ap, int);
00122 SSVAL(blob->data, data_ofs, n); data_ofs += 2;
00123 s = va_arg(ap, char *);
00124 n = str_charnum(s);
00125 SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
00126 if (0 < n) {
00127 push_string(NULL, blob->data+data_ofs, s, n*2,
00128 STR_UNICODE|STR_NOALIGN);
00129 }
00130 data_ofs += n*2;
00131 break;
00132
00133 case 'B':
00134 b = va_arg(ap, uint8 *);
00135 n = va_arg(ap, int);
00136 SSVAL(blob->data, head_ofs, n); head_ofs += 2;
00137 SSVAL(blob->data, head_ofs, n); head_ofs += 2;
00138 SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4;
00139 if (n && b)
00140 memcpy(blob->data+data_ofs, b, n);
00141 data_ofs += n;
00142 break;
00143 case 'd':
00144 n = va_arg(ap, int);
00145 SIVAL(blob->data, head_ofs, n); head_ofs += 4;
00146 break;
00147 case 'b':
00148 b = va_arg(ap, uint8 *);
00149 n = va_arg(ap, int);
00150 memcpy(blob->data + head_ofs, b, n);
00151 head_ofs += n;
00152 break;
00153 case 'C':
00154 s = va_arg(ap, char *);
00155 n = str_charnum(s) + 1;
00156 head_ofs += push_string(NULL, blob->data+head_ofs, s, n,
00157 STR_ASCII|STR_TERMINATE);
00158 break;
00159 }
00160 }
00161 va_end(ap);
00162
00163 return True;
00164 }
00165
00166
00167
00168 #define NEED_DATA(amount) \
00169 if ((head_ofs + amount) > blob->length) { \
00170 return False; \
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 BOOL msrpc_parse(const DATA_BLOB *blob,
00187 const char *format, ...)
00188 {
00189 int i;
00190 va_list ap;
00191 char **ps, *s;
00192 DATA_BLOB *b;
00193 size_t head_ofs = 0;
00194 uint16 len1, len2;
00195 uint32 ptr;
00196 uint32 *v;
00197 pstring p;
00198
00199 va_start(ap, format);
00200 for (i=0; format[i]; i++) {
00201 switch (format[i]) {
00202 case 'U':
00203 NEED_DATA(8);
00204 len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
00205 len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
00206 ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
00207
00208 ps = va_arg(ap, char **);
00209 if (len1 == 0 && len2 == 0) {
00210 *ps = smb_xstrdup("");
00211 } else {
00212
00213 if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
00214 return False;
00215 }
00216 if (len1 & 1) {
00217
00218 return False;
00219 }
00220 if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
00221 return False;
00222
00223 if (0 < len1) {
00224 pull_string(NULL, p, blob->data + ptr, sizeof(p),
00225 len1,
00226 STR_UNICODE|STR_NOALIGN);
00227 (*ps) = smb_xstrdup(p);
00228 } else {
00229 (*ps) = smb_xstrdup("");
00230 }
00231 }
00232 break;
00233 case 'A':
00234 NEED_DATA(8);
00235 len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
00236 len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
00237 ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
00238
00239 ps = va_arg(ap, char **);
00240
00241 if (len1 == 0 && len2 == 0) {
00242 *ps = smb_xstrdup("");
00243 } else {
00244 if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
00245 return False;
00246 }
00247
00248 if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
00249 return False;
00250
00251 if (0 < len1) {
00252 pull_string(NULL, p, blob->data + ptr, sizeof(p),
00253 len1,
00254 STR_ASCII|STR_NOALIGN);
00255 (*ps) = smb_xstrdup(p);
00256 } else {
00257 (*ps) = smb_xstrdup("");
00258 }
00259 }
00260 break;
00261 case 'B':
00262 NEED_DATA(8);
00263 len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
00264 len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
00265 ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
00266
00267 b = (DATA_BLOB *)va_arg(ap, void *);
00268 if (len1 == 0 && len2 == 0) {
00269 *b = data_blob(NULL, 0);
00270 } else {
00271
00272 if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) {
00273 return False;
00274 }
00275
00276 if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data)
00277 return False;
00278
00279 *b = data_blob(blob->data + ptr, len1);
00280 }
00281 break;
00282 case 'b':
00283 b = (DATA_BLOB *)va_arg(ap, void *);
00284 len1 = va_arg(ap, unsigned);
00285
00286 NEED_DATA(len1);
00287 if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data)
00288 return False;
00289
00290 *b = data_blob(blob->data + head_ofs, len1);
00291 head_ofs += len1;
00292 break;
00293 case 'd':
00294 v = va_arg(ap, uint32 *);
00295 NEED_DATA(4);
00296 *v = IVAL(blob->data, head_ofs); head_ofs += 4;
00297 break;
00298 case 'C':
00299 s = va_arg(ap, char *);
00300
00301 if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data)
00302 return False;
00303
00304 head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p),
00305 blob->length - head_ofs,
00306 STR_ASCII|STR_TERMINATE);
00307 if (strcmp(s, p) != 0) {
00308 return False;
00309 }
00310 break;
00311 }
00312 }
00313 va_end(ap);
00314
00315 return True;
00316 }