Ignore:
Timestamp:
Apr 22, 2010, 6:20:08 PM (15 years ago)
Author:
Silvan Scherrer
Message:

samba client 1.6: more work

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/client-1.6/src/smbwrp.c

    r443 r444  
    2121#include "includes.h"
    2222#include "smbwrp.h"
     23/****************************************************************************
     24 Calculate a safe next_entry_offset.
     25****************************************************************************/
     26
     27static 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}
    2338
    2439void smbwrp_Logging()
     
    10691084// in the longrun we should switch to file_info struct instead of our own smbwrp_fileinfo
    10701085
    1071 static size_t _os2_interpret_long_filename(struct cli_state *cli,
    1072                                    int level,char *p, smbwrp_fileinfo *finfo,
    1073                                         uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len)
     1086static 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)
    10741089{
    10751090        int len;
    1076         char *base = p;
    1077         smbwrp_fileinfo finfo1;
     1091        const char *base = p;
     1092        size_t ret;
    10781093       
    1079         if (!finfo) finfo = &finfo1;
     1094        data_blob_free(p_last_name_raw);
    10801095
    10811096        if (p_resume_key) {
     
    10831098        }
    10841099
    1085         ZERO_STRUCT(finfo);
     1100//      ZERO_STRUCTP(finfo);
    10861101        debuglocal(9,"fname %s (serverzone %d, level %d)\n",finfo->fname, cli->serverzone, level);
    10871102       
     
    10901105                        /* these dates are converted to GMT by
    10911106                           make_unix_date */
     1107                        if (pdata_end - base < 27) {
     1108                                return pdata_end - base;
     1109                        }
    10921110                        finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone;
    10931111                        finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone;
     
    10981116                        p += 27;
    10991117                        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
    11001133                        /* the len+2 below looks strange but it is
    11011134                           important to cope with the differences
    11021135                           between win2000 and win9x for this call
    11031136                           (tridge) */
    1104                         p += clistr_pull(cli, finfo->fname, p,
    1105                                          sizeof(finfo->fname),
     1137                        ret = clistr_pull_talloc(ctx, cli, &finfo->fname, p,
    11061138                                         len+2,
    11071139                                         STR_TERMINATE);
     1140                        if (ret == (size_t)-1) {
     1141                                return pdata_end - base;
     1142                        }
     1143                        p += ret;
    11081144                        finfo->easize = -1;
    11091145                        return PTR_DIFF(p, base);
     
    11121148                        /* these dates are converted to GMT by
    11131149                           make_unix_date */
     1150                        if (pdata_end - base < 31) {
     1151                                return pdata_end - base;
     1152                        }
    11141153                        finfo->ctime = cli_make_unix_date2(cli, p+4) - cli->serverzone;
    11151154                        finfo->atime = cli_make_unix_date2(cli, p+8) - cli->serverzone;
     
    11211160                        p += 31;
    11221161                        /* 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,
    11251166                                         len,
    11261167                                         STR_NOALIGN);
     1168                        if (ret == (size_t)-1) {
     1169                                return pdata_end - base;
     1170                        }
     1171                        p += ret;
    11271172                        return PTR_DIFF(p, base) + 1;
    11281173                       
     
    11301175                {
    11311176                        size_t namelen, slen;
     1177
     1178                        if (pdata_end - base < 94) {
     1179                                return pdata_end - base;
     1180                        }
     1181
    11321182                        p += 4; /* next entry offset */
     1183
    11331184                        if (p_resume_key) {
    11341185                                *p_resume_key = IVAL(p,0);
     
    11551206                        p += 4; /* EA size */
    11561207                        slen = SVAL(p, 0);
     1208                        if (slen > 24) {
     1209                                /* Bad short name length. */
     1210                                return pdata_end - base;
     1211                        }
    11571212                        p += 2;
    11581213#if 0                   
     
    11661221                        }
    11671222#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,
    11711228                                    namelen, 0);
     1229                        if (ret == (size_t)-1) {
     1230                                return pdata_end - base;
     1231                        }
    11721232
    11731233                        /* To be robust in the face of unicode conversion failures
     
    11761236                           copy it here. */
    11771237#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);
    11871242                        }
    11881243#endif
    1189                         return (size_t)IVAL(base, 0);
     1244                        return calc_next_entry_offset(base, pdata_end);
    11901245                }
    11911246        }
    11921247       
    11931248        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);
    11951250}
    11961251
     
    12271282        const char *mnt;
    12281283        uint32 resume_key = 0;
    1229         uint32 last_name_raw_len = 0;
     1284        TALLOC_CTX *frame = talloc_stackframe();
    12301285        DATA_BLOB last_name_raw = data_blob(NULL, 0);
    12311286
     
    12341289       
    12351290        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;
    12471296        }
    12481297
    12491298        while (ff_eos == 0) {
     1299                size_t nlen = 2*(strlen(mask)+1);
     1300
    12501301                loop_count++;
    12511302                if (loop_count > 200) {
     
    12541305                }
    12551306
    1256                 size_t nlen = 2*(strlen(mask)+1);
    12571307                param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2);
    12581308                if (!param) {
     
    13061356                                    )) {
    13071357                        SAFE_FREE(param);
     1358                        TALLOC_FREE(frame);
    13081359                        break;
    13091360                }
     
    13911442                                SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
    13921443                        }
    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);
    13951446
    13961447                        if (!finfo.fname) {
     
    14561507        } else {
    14571508                /* no connection problem.  let user function add each entry */
     1509                rdata_end = dirlist + dirlist_len;
    14581510                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                        }
    14611518                        fn( mnt,&finfo, Mask, state );
    14621519                }
     
    14651522        /* free up the dirlist buffer and last name raw blob */
    14661523        SAFE_FREE(dirlist);
     1524        data_blob_free(&last_name_raw);
    14671525        SAFE_FREE(mask);
    1468         data_blob_free(&last_name_raw);
     1526        TALLOC_FREE(frame);
    14691527        return(total_received);
    14701528}
Note: See TracChangeset for help on using the changeset viewer.