Changeset 444 for branches/client-1.6/src/smbwrp.c
- Timestamp:
- Apr 22, 2010, 6:20:08 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/client-1.6/src/smbwrp.c
r443 r444 21 21 #include "includes.h" 22 22 #include "smbwrp.h" 23 /**************************************************************************** 24 Calculate a safe next_entry_offset. 25 ****************************************************************************/ 26 27 static size_t calc_next_entry_offset(const char *base, const char *pdata_end) 28 { 29 size_t next_entry_offset = (size_t)IVAL(base,0); 30 31 if (next_entry_offset == 0 || 32 base + next_entry_offset < base || 33 base + next_entry_offset > pdata_end) { 34 next_entry_offset = pdata_end - base; 35 } 36 return next_entry_offset; 37 } 23 38 24 39 void smbwrp_Logging() … … 1069 1084 // in the longrun we should switch to file_info struct instead of our own smbwrp_fileinfo 1070 1085 1071 static size_t _os2_interpret_long_filename( struct cli_state *cli,1072 int level,c har *p, smbwrp_fileinfo *finfo,1073 uint32 *p_resume_key, DATA_BLOB *p_last_name_raw , uint32 *p_last_name_raw_len)1086 static size_t _os2_interpret_long_filename(TALLOC_CTX *ctx, struct cli_state *cli, 1087 int level,const char *p, const char *pdata_end, smbwrp_fileinfo *finfo, 1088 uint32 *p_resume_key, DATA_BLOB *p_last_name_raw) 1074 1089 { 1075 1090 int len; 1076 c har *base = p;1077 s mbwrp_fileinfo finfo1;1091 const char *base = p; 1092 size_t ret; 1078 1093 1079 if (!finfo) finfo = &finfo1;1094 data_blob_free(p_last_name_raw); 1080 1095 1081 1096 if (p_resume_key) { … … 1083 1098 } 1084 1099 1085 ZERO_STRUCT(finfo);1100 // ZERO_STRUCTP(finfo); 1086 1101 debuglocal(9,"fname %s (serverzone %d, level %d)\n",finfo->fname, cli->serverzone, level); 1087 1102 … … 1090 1105 /* these dates are converted to GMT by 1091 1106 make_unix_date */ 1107 if (pdata_end - base < 27) { 1108 return pdata_end - base; 1109 } 1092 1110 finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone; 1093 1111 finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone; … … 1098 1116 p += 27; 1099 1117 p += clistr_align_in(cli, p, 0); 1118 1119 /* We can safely use len here (which is required by OS/2) 1120 * and the NAS-BASIC server instead of +2 or +1 as the 1121 * STR_TERMINATE flag below is 1122 * actually used as the length calculation. 1123 * The len is merely an upper bound. 1124 * Due to the explicit 2 byte null termination 1125 * in cli_receive_trans/cli_receive_nt_trans 1126 * we know this is safe. JRA + kukks 1127 */ 1128 1129 if (p + len > pdata_end) { 1130 return pdata_end - base; 1131 } 1132 1100 1133 /* the len+2 below looks strange but it is 1101 1134 important to cope with the differences 1102 1135 between win2000 and win9x for this call 1103 1136 (tridge) */ 1104 p += clistr_pull(cli, finfo->fname, p, 1105 sizeof(finfo->fname), 1137 ret = clistr_pull_talloc(ctx, cli, &finfo->fname, p, 1106 1138 len+2, 1107 1139 STR_TERMINATE); 1140 if (ret == (size_t)-1) { 1141 return pdata_end - base; 1142 } 1143 p += ret; 1108 1144 finfo->easize = -1; 1109 1145 return PTR_DIFF(p, base); … … 1112 1148 /* these dates are converted to GMT by 1113 1149 make_unix_date */ 1150 if (pdata_end - base < 31) { 1151 return pdata_end - base; 1152 } 1114 1153 finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone; 1115 1154 finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone; … … 1121 1160 p += 31; 1122 1161 /* check for unisys! */ 1123 p += clistr_pull(cli, finfo->fname, p, 1124 sizeof(finfo->fname), 1162 if (p + len + 1 > pdata_end) { 1163 return pdata_end - base; 1164 } 1165 ret = clistr_pull_talloc(ctx, cli, &finfo->fname, p, 1125 1166 len, 1126 1167 STR_NOALIGN); 1168 if (ret == (size_t)-1) { 1169 return pdata_end - base; 1170 } 1171 p += ret; 1127 1172 return PTR_DIFF(p, base) + 1; 1128 1173 … … 1130 1175 { 1131 1176 size_t namelen, slen; 1177 1178 if (pdata_end - base < 94) { 1179 return pdata_end - base; 1180 } 1181 1132 1182 p += 4; /* next entry offset */ 1183 1133 1184 if (p_resume_key) { 1134 1185 *p_resume_key = IVAL(p,0); … … 1155 1206 p += 4; /* EA size */ 1156 1207 slen = SVAL(p, 0); 1208 if (slen > 24) { 1209 /* Bad short name length. */ 1210 return pdata_end - base; 1211 } 1157 1212 p += 2; 1158 1213 #if 0 … … 1166 1221 } 1167 1222 #endif 1168 p += 24; /* short name? */ 1169 clistr_pull(cli, finfo->fname, p, 1170 sizeof(finfo->fname), 1223 p += 24; /* short name? */ 1224 if (p + namelen < p || p + namelen > pdata_end) { 1225 return pdata_end - base; 1226 } 1227 ret = clistr_pull_talloc(ctx, cli, &finfo->fname, p, 1171 1228 namelen, 0); 1229 if (ret == (size_t)-1) { 1230 return pdata_end - base; 1231 } 1172 1232 1173 1233 /* To be robust in the face of unicode conversion failures … … 1176 1236 copy it here. */ 1177 1237 #if 0 1178 if (p_last_name_raw && p_last_name_raw_len) { 1179 if (namelen + 2 > p_last_name_raw->length) { 1180 memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); 1181 *p_last_name_raw_len = 0; 1182 } else { 1183 memcpy(p_last_name_raw->data, p, namelen); 1184 SSVAL(p_last_name_raw->data, namelen, 0); 1185 *p_last_name_raw_len = namelen + 2; 1186 } 1238 if (p_last_name_raw) { 1239 *p_last_name_raw = data_blob(NULL, namelen+2); 1240 memcpy(p_last_name_raw->data, p, namelen); 1241 SSVAL(p_last_name_raw->data, namelen, 0); 1187 1242 } 1188 1243 #endif 1189 return (size_t)IVAL(base, 0);1244 return calc_next_entry_offset(base, pdata_end); 1190 1245 } 1191 1246 } 1192 1247 1193 1248 debuglocal(1,"Unknown long filename format %d\n",level); 1194 return (size_t)IVAL(base,0);1249 return calc_next_entry_offset(base, pdata_end); 1195 1250 } 1196 1251 … … 1227 1282 const char *mnt; 1228 1283 uint32 resume_key = 0; 1229 uint32 last_name_raw_len = 0;1284 TALLOC_CTX *frame = talloc_stackframe(); 1230 1285 DATA_BLOB last_name_raw = data_blob(NULL, 0); 1231 1286 … … 1234 1289 1235 1290 debuglocal(4,"list_files level %d. mask <%s>\n", info_level, Mask); 1236 1237 /* when getting a directory listing from a 2k dfs root share, 1238 we have to include the full path (\server\share\mask) here */ 1239 1240 if ( cli->dfsroot ) { 1241 mask = talloc_asprintf(mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask ); 1242 } else { 1243 mask = SMB_STRDUP(Mask); 1244 if (!mask) { 1245 return -1; 1246 } 1291 1292 mask = SMB_STRDUP(Mask); 1293 if (!mask) { 1294 TALLOC_FREE(frame); 1295 return -1; 1247 1296 } 1248 1297 1249 1298 while (ff_eos == 0) { 1299 size_t nlen = 2*(strlen(mask)+1); 1300 1250 1301 loop_count++; 1251 1302 if (loop_count > 200) { … … 1254 1305 } 1255 1306 1256 size_t nlen = 2*(strlen(mask)+1);1257 1307 param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2); 1258 1308 if (!param) { … … 1306 1356 )) { 1307 1357 SAFE_FREE(param); 1358 TALLOC_FREE(frame); 1308 1359 break; 1309 1360 } … … 1391 1442 SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); 1392 1443 } 1393 p2 += _os2_interpret_long_filename( cli,info_level,p2,&finfo,1394 &resume_key, &last_name_raw,&last_name_raw.length);1444 p2 += _os2_interpret_long_filename(frame, cli, info_level, p2, rdata_end, &finfo, 1445 &resume_key, &last_name_raw); 1395 1446 1396 1447 if (!finfo.fname) { … … 1456 1507 } else { 1457 1508 /* no connection problem. let user function add each entry */ 1509 rdata_end = dirlist + dirlist_len; 1458 1510 for (p=dirlist,i=0;i<total_received;i++) { 1459 p += _os2_interpret_long_filename(cli, info_level, p, 1460 &finfo,NULL,NULL,NULL); 1511 p += _os2_interpret_long_filename(frame, cli, info_level, p, rdata_end, 1512 &finfo,NULL,NULL); 1513 if (!finfo.fname) { 1514 debuglocal(0,"list_new: unable to parse name from info level %d\n", 1515 info_level); 1516 break; 1517 } 1461 1518 fn( mnt,&finfo, Mask, state ); 1462 1519 } … … 1465 1522 /* free up the dirlist buffer and last name raw blob */ 1466 1523 SAFE_FREE(dirlist); 1524 data_blob_free(&last_name_raw); 1467 1525 SAFE_FREE(mask); 1468 data_blob_free(&last_name_raw);1526 TALLOC_FREE(frame); 1469 1527 return(total_received); 1470 1528 }
Note:
See TracChangeset
for help on using the changeset viewer.