diff options
-rw-r--r-- | source3/smbd/trans2.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index aca5186a5c..edfbe330a1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1130,12 +1130,12 @@ static NTSTATUS unix_perms_from_wire( connection_struct *conn, Get a level dependent lanman2 dir entry. ****************************************************************************/ -static BOOL get_lanman2_dir_entry(connection_struct *conn, - void *inbuf, char *outbuf, +static BOOL get_lanman2_dir_entry(connection_struct *conn, uint16 flags2, char *path_mask,uint32 dirtype,int info_level, int requires_resume_key, BOOL dont_descend,char **ppdata, - char *base_data, int space_remaining, + char *base_data, char *end_data, + int space_remaining, BOOL *out_of_space, BOOL *got_exact_match, int *last_entry_off, struct ea_list *name_list, TALLOC_CTX *ea_ctx) { @@ -1339,10 +1339,11 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SSVAL(p,20,mode); p += 23; nameptr = p; - p += align_string(outbuf, p, 0); - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, - fname, -1, STR_TERMINATE); - if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { + p += align_string(pdata, p, 0); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE); + if (flags2 & FLAGS2_UNICODE_STRINGS) { if (len > 2) { SCVAL(nameptr, -1, len - 2); } else { @@ -1376,10 +1377,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, } p += 27; nameptr = p - 1; - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), - p, fname, -1, + len = srvstr_push(base_data, flags2, + p, fname, PTR_DIFF(end_data, p), STR_TERMINATE | STR_NOALIGN); - if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { + if (flags2 & FLAGS2_UNICODE_STRINGS) { if (len > 2) { len -= 2; } else { @@ -1434,10 +1435,10 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, /* Push the ea_data followed by the name. */ p += fill_ea_buffer(ea_ctx, p, space_remaining, conn, name_list); nameptr = p; - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), - p + 1, fname, -1, + len = srvstr_push(base_data, flags2, + p + 1, fname, PTR_DIFF(end_data, p), STR_TERMINATE | STR_NOALIGN); - if (SVAL(outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS) { + if (flags2 & FLAGS2_UNICODE_STRINGS) { if (len > 2) { len -= 2; } else { @@ -1484,8 +1485,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, mangle_map(mangled_name,True,True, conn->params); mangled_name[12] = 0; - len = srvstr_push(outbuf, - SVAL(outbuf, smb_flg2), + len = srvstr_push(base_data, flags2, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); if (len < 24) { @@ -1496,8 +1496,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, memset(p,'\0',26); } p += 2 + 24; - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, - fname, -1, STR_TERMINATE_ASCII); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE_ASCII); SIVAL(q,0,len); p += len; SIVAL(p,0,0); /* Ensure any padding is null. */ @@ -1518,8 +1519,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SOFF_T(p,0,file_size); p += 8; SOFF_T(p,0,allocation_size); p += 8; SIVAL(p,0,nt_extmode); p += 4; - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), - p + 4, fname, -1, + len = srvstr_push(base_data, flags2, + p + 4, fname, PTR_DIFF(end_data, p), STR_TERMINATE_ASCII); SIVAL(p,0,len); p += 4 + len; @@ -1547,8 +1548,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,ea_size); /* Extended attributes */ p +=4; } - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, - fname, -1, STR_TERMINATE_ASCII); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE_ASCII); SIVAL(q, 0, len); p += len; @@ -1566,8 +1568,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, p += 4; /* this must *not* be null terminated or w2k gets in a loop trying to set an acl on a dir (tridge) */ - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), - p, fname, -1, STR_TERMINATE_ASCII); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE_ASCII); SIVAL(p, -4, len); p += len; SIVAL(p,0,0); /* Ensure any padding is null. */ @@ -1597,8 +1600,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */ SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, - fname, -1, STR_TERMINATE_ASCII); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE_ASCII); SIVAL(q, 0, len); p += len; SIVAL(p,0,0); /* Ensure any padding is null. */ @@ -1636,8 +1640,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, mangle_map(mangled_name,True,True, conn->params); mangled_name[12] = 0; - len = srvstr_push(outbuf, - SVAL(outbuf, smb_flg2), + len = srvstr_push(base_data, flags2, p+2, mangled_name, 24, STR_UPPER|STR_UNICODE); SSVAL(p, 0, len); @@ -1652,8 +1655,9 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, SSVAL(p,0,0); p += 2; /* Reserved ? */ SIVAL(p,0,sbuf.st_ino); p += 4; /* FileIndexLow */ SIVAL(p,0,sbuf.st_dev); p += 4; /* FileIndexHigh */ - len = srvstr_push(outbuf, SVAL(outbuf, smb_flg2), p, - fname, -1, STR_TERMINATE_ASCII); + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), + STR_TERMINATE_ASCII); SIVAL(q,0,len); p += len; SIVAL(p,0,0); /* Ensure any padding is null. */ @@ -1676,9 +1680,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n")); p = store_file_unix_basic(conn, p, NULL, &sbuf); - len = srvstr_push(outbuf, - SVAL(outbuf, smb_flg2), - p, fname, -1, + len = srvstr_push(base_data, flags2, p, + fname, PTR_DIFF(end_data, p), STR_TERMINATE); } else { DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n")); @@ -1686,9 +1689,8 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn, NULL, &sbuf); nameptr = p; p += 4; - len = srvstr_push(outbuf, - SVAL(outbuf, smb_flg2), - p, fname, -1, 0); + len = srvstr_push(base_data, flags2, p, fname, + PTR_DIFF(end_data, p), 0); SIVAL(nameptr, 0, len); } @@ -1739,6 +1741,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb requested. */ char *params = *pparams; char *pdata = *ppdata; + char *data_end; uint32 dirtype; int maxentries; uint16 findfirst_flags; @@ -1886,6 +1889,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd return ERROR_NT(NT_STATUS_NO_MEMORY); } pdata = *ppdata; + data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; /* Realloc the params space */ *pparams = (char *)SMB_REALLOC(*pparams, 10); @@ -1937,10 +1941,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd finished = False; } else { finished = !get_lanman2_dir_entry(conn, - inbuf, outbuf, + SVAL(outbuf, smb_flg2), mask,dirtype,info_level, requires_resume_key,dont_descend, - &p,pdata,space_remaining, &out_of_space, &got_exact_match, + &p,pdata,data_end, + space_remaining, &out_of_space, + &got_exact_match, &last_entry_off, ea_list, ea_ctx); } @@ -2034,6 +2040,7 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu requested. */ char *params = *pparams; char *pdata = *ppdata; + char *data_end; int dptr_num; int maxentries; uint16 info_level; @@ -2164,6 +2171,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } pdata = *ppdata; + data_end = pdata + max_data_bytes + DIR_ENTRY_SAFETY_MARGIN - 1; /* Realloc the params space */ *pparams = (char *)SMB_REALLOC(*pparams, 6*SIZEOFWORD); @@ -2253,10 +2261,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd finished = False; } else { finished = !get_lanman2_dir_entry(conn, - inbuf, outbuf, + SVAL(outbuf, smb_flg2), mask,dirtype,info_level, requires_resume_key,dont_descend, - &p,pdata,space_remaining, &out_of_space, &got_exact_match, + &p,pdata,data_end, + space_remaining, &out_of_space, + &got_exact_match, &last_entry_off, ea_list, ea_ctx); } |