s3: Always allocate memory in dptr_ReadDirName
authorAravind Srinivasan <aravind.srinivasan@isilon.com>
Mon, 11 May 2009 22:39:05 +0000 (22:39 +0000)
committerTim Prouty <tprouty@samba.org>
Tue, 19 May 2009 04:50:07 +0000 (21:50 -0700)
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 <tprouty@samba.org>
source3/include/proto.h
source3/smbd/dir.c
source3/smbd/trans2.c

index 68c312568ba7ac547a9de2af3256015277bbdaad..6f298ad9a0e4c24119efe2d5391202ca030ed952 100644 (file)
@@ -6142,7 +6142,7 @@ void dptr_SeekDir(struct dptr_struct *dptr, long offset);
 long dptr_TellDir(struct dptr_struct *dptr);
 bool dptr_has_wild(struct dptr_struct *dptr);
 int dptr_dnum(struct dptr_struct *dptr);
-const char *dptr_ReadDirName(TALLOC_CTX *ctx,
+char *dptr_ReadDirName(TALLOC_CTX *ctx,
                        struct dptr_struct *dptr,
                        long *poffset,
                        SMB_STRUCT_STAT *pst);
index e7902871d38042fd9e80e19ccd8101831755f484..ab4a0d27e375a00c22eb4df8903bcd0f83a2f924 100644 (file)
@@ -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);
index 72b4ba074276547610e85871f2632b226d70cad4..edbb0dfc4d0217950681950898899342affdf2d6 100644 (file)
@@ -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);