From 1718e803dc9269f8ba0db4260cc3b8a000da248a Mon Sep 17 00:00:00 2001 From: Aravind Srinivasan Date: Mon, 11 May 2009 22:39:05 +0000 Subject: s3: Always allocate memory in dptr_ReadDirName This is a follow up to 69d61453df6019caef4e7960fa78c6a3c51f3d2a to adjust the API to allow the lower layers allocate memory. Now the memory can explicitly be freed rather than relying on talloc_tos(). Signed-off-by: Tim Prouty --- source3/smbd/dir.c | 39 ++++++++++++++++++++++++++------------- source3/smbd/trans2.c | 22 ++++++++++++++++++---- 2 files changed, 44 insertions(+), 17 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index e7902871d3..ab4a0d27e3 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -569,7 +569,7 @@ static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, Return the next visible file name, skipping veto'd and invisible files. ****************************************************************************/ -const char *dptr_ReadDirName(TALLOC_CTX *ctx, +char *dptr_ReadDirName(TALLOC_CTX *ctx, struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst) @@ -578,11 +578,14 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, char *pathreal = NULL; char *found_name = NULL; int ret; + const char *name_temp = NULL; SET_STAT_INVALID(*pst); if (dptr->has_wild || dptr->did_stat) { - return dptr_normal_ReadDirName(dptr, poffset, pst); + name_temp = dptr_normal_ReadDirName(dptr, poffset, pst); + name = talloc_strdup(ctx, name_temp); + return name; } /* If poffset is -1 then we know we returned this name before and we @@ -610,7 +613,7 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, } if (VALID_STAT(*pst)) { - name = dptr->wcard; + name = talloc_strdup(ctx, dptr->wcard); goto ret; } @@ -622,13 +625,13 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, return NULL; if (SMB_VFS_STAT(dptr->conn, pathreal, pst) == 0) { - name = dptr->wcard; + name = talloc_strdup(ctx, dptr->wcard); goto clean; } else { /* If we get any other error than ENOENT or ENOTDIR then the file exists we just can't stat it. */ if (errno != ENOENT && errno != ENOTDIR) { - name = dptr->wcard; + name = talloc_strdup(ctx, dptr->wcard); goto clean; } } @@ -659,7 +662,9 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, TALLOC_FREE(pathreal); - return dptr_normal_ReadDirName(dptr, poffset, pst); + name_temp = dptr_normal_ReadDirName(dptr, poffset, pst); + name = talloc_strdup(ctx, name_temp); + return name; clean: TALLOC_FREE(pathreal); @@ -823,11 +828,11 @@ bool get_dir_entry(TALLOC_CTX *ctx, bool check_descend, bool ask_sharemode) { - const char *dname = NULL; + char *dname = NULL; bool found = False; SMB_STRUCT_STAT sbuf; char *pathreal = NULL; - const char *filename = NULL; + char *filename = NULL; bool needslash; *pp_fname_out = NULL; @@ -863,9 +868,13 @@ bool get_dir_entry(TALLOC_CTX *ctx, if (!mangle_is_8_3(filename, False, conn->params)) { if (!name_to_8_3(filename,mname,False, conn->params)) { + TALLOC_FREE(filename); continue; } - filename = mname; + filename = talloc_strdup(ctx, mname); + if (!filename) { + return False; + } } if (needslash) { @@ -880,6 +889,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, dname); } if (!pathreal) { + TALLOC_FREE(filename); return False; } @@ -887,6 +897,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n", pathreal, strerror(errno) )); TALLOC_FREE(pathreal); + TALLOC_FREE(filename); continue; } @@ -895,6 +906,7 @@ bool get_dir_entry(TALLOC_CTX *ctx, if (!dir_check_ftype(conn,*mode,dirtype)) { DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype)); TALLOC_FREE(pathreal); + TALLOC_FREE(filename); continue; } @@ -921,14 +933,15 @@ bool get_dir_entry(TALLOC_CTX *ctx, found = True; - *pp_fname_out = talloc_strdup(ctx, filename); - if (!*pp_fname_out) { - return False; - } + SMB_ASSERT(filename != NULL); + *pp_fname_out = filename; DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff); TALLOC_FREE(pathreal); } + + if (!found) + TALLOC_FREE(filename); } return(found); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 72b4ba0742..edbb0dfc4d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1238,12 +1238,12 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, int *last_entry_off, struct ea_list *name_list) { - const char *dname; + char *dname; bool found = False; SMB_STRUCT_STAT sbuf; const char *mask = NULL; char *pathreal = NULL; - const char *fname = NULL; + char *fname = NULL; char *p, *q, *pdata = *ppdata; uint32 reskey=0; long prev_dirpos=0; @@ -1319,9 +1319,13 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, /* Mangle fname if it's an illegal name. */ if (mangle_must_mangle(dname,conn->params)) { if (!name_to_8_3(dname,mangled_name,True,conn->params)) { + TALLOC_FREE(fname); continue; /* Error - couldn't mangle. */ } - fname = mangled_name; + fname = talloc_strdup(ctx, mangled_name); + if (!fname) { + return False; + } } if(!(got_match = *got_exact_match = exact_match(conn, fname, mask))) { @@ -1338,6 +1342,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, */ /* Force the mangling into 8.3. */ if (!name_to_8_3( fname, mangled_name, False, conn->params)) { + TALLOC_FREE(fname); continue; /* Error - couldn't mangle. */ } @@ -1350,6 +1355,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, bool isdots = (ISDOT(dname) || ISDOTDOT(dname)); if (dont_descend && !isdots) { + TALLOC_FREE(fname); continue; } @@ -1367,6 +1373,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, } if (!pathreal) { + TALLOC_FREE(fname); return False; } @@ -1375,6 +1382,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, DEBUG(5,("get_lanman2_dir_entry:Couldn't lstat [%s] (%s)\n", pathreal,strerror(errno))); TALLOC_FREE(pathreal); + TALLOC_FREE(fname); continue; } } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) { @@ -1386,6 +1394,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n", pathreal,strerror(errno))); TALLOC_FREE(pathreal); + TALLOC_FREE(fname); continue; } } @@ -1399,6 +1408,7 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, if (!dir_check_ftype(conn,mode,dirtype)) { DEBUG(5,("get_lanman2_dir_entry: [%s] attribs didn't match %x\n",fname,dirtype)); TALLOC_FREE(pathreal); + TALLOC_FREE(fname); continue; } @@ -1440,6 +1450,9 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, dptr_DirCacheAdd(conn->dirptr, dname, curr_dirpos); } + + if (!found) + TALLOC_FREE(fname); } p = pdata; @@ -1833,10 +1846,11 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx, break; default: + TALLOC_FREE(fname); return(False); } - + TALLOC_FREE(fname); if (PTR_DIFF(p,pdata) > space_remaining) { /* Move the dirptr back to prev_dirpos */ dptr_SeekDir(conn->dirptr, prev_dirpos); -- cgit