diff options
author | Luke Leighton <lkcl@samba.org> | 2000-01-20 05:01:18 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 2000-01-20 05:01:18 +0000 |
commit | 6507c2530ba26fdf8e685c912b6fff17158960bb (patch) | |
tree | bece5b56fe0e35bb9120ae9fa8baa35a2fd44714 | |
parent | 2cfef8aedab054372aacea5a9d5c22d9328072ea (diff) | |
download | samba-6507c2530ba26fdf8e685c912b6fff17158960bb.tar.gz samba-6507c2530ba26fdf8e685c912b6fff17158960bb.tar.xz samba-6507c2530ba26fdf8e685c912b6fff17158960bb.zip |
moved some functions only used by smbd/filename.c into filename.c
-rw-r--r-- | source/include/proto.h | 3 | ||||
-rw-r--r-- | source/lib/util.c | 272 | ||||
-rw-r--r-- | source/smbd/filename.c | 184 |
3 files changed, 184 insertions, 275 deletions
diff --git a/source/include/proto.h b/source/include/proto.h index efcdd597549..430b9b60751 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -486,9 +486,6 @@ int smb_buflen(char *buf); char *smb_buf(char *buf); int smb_offset(char *p,char *buf); void dos_clean_name(char *s); -void unix_clean_name(char *s); -BOOL reduce_name(char *s,char *dir,BOOL widelinks); -void expand_mask(char *Mask,BOOL doext); void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date); void close_low_fds(void); int set_blocking(int fd, BOOL set); diff --git a/source/lib/util.c b/source/lib/util.c index c7c26b29a0b..6c84c192de6 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -83,8 +83,6 @@ pstring global_myname = ""; fstring global_myworkgroup = ""; char **my_netbios_names; -static char *filename_dos(char *path,char *buf); - char *daynames[] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; char *daynames_short[] = {"M", "Tu", "W", "Th", "F", "Sa", "Su"}; @@ -638,260 +636,6 @@ void dos_clean_name(char *s) string_sub(s, "\\.\\", "\\"); } -/******************************************************************* -reduce a file name, removing .. elements. -********************************************************************/ -void unix_clean_name(char *s) -{ - char *p=NULL; - - DEBUG(3,("unix_clean_name [%s]\n",s)); - - /* remove any double slashes */ - string_sub(s, "//","/"); - - /* Remove leading ./ characters */ - if(strncmp(s, "./", 2) == 0) { - trim_string(s, "./", NULL); - if(*s == 0) - pstrcpy(s,"./"); - } - - while ((p = strstr(s,"/../")) != NULL) - { - pstring s1; - - *p = 0; - pstrcpy(s1,p+3); - - if ((p=strrchr(s,'/')) != NULL) - *p = 0; - else - *s = 0; - pstrcat(s,s1); - } - - trim_string(s,NULL,"/.."); -} - -/******************************************************************* -reduce a file name, removing .. elements and checking that -it is below dir in the heirachy. This uses GetWd() and so must be run -on the system that has the referenced file system. - -widelinks are allowed if widelinks is true -********************************************************************/ - -BOOL reduce_name(char *s,char *dir,BOOL widelinks) -{ -#ifndef REDUCE_PATHS - return True; -#else - pstring dir2; - pstring wd; - pstring base_name; - pstring newname; - char *p=NULL; - BOOL relative = (*s != '/'); - - *dir2 = *wd = *base_name = *newname = 0; - - if (widelinks) - { - unix_clean_name(s); - /* can't have a leading .. */ - if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) - { - DEBUG(3,("Illegal file name? (%s)\n",s)); - return(False); - } - - if (strlen(s) == 0) - pstrcpy(s,"./"); - - return(True); - } - - DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); - - /* remove any double slashes */ - string_sub(s,"//","/"); - - pstrcpy(base_name,s); - p = strrchr(base_name,'/'); - - if (!p) - return(True); - - if (!dos_GetWd(wd)) - { - DEBUG(0,("couldn't getwd for %s %s\n",s,dir)); - return(False); - } - - if (dos_ChDir(dir) != 0) - { - DEBUG(0,("couldn't chdir to %s\n",dir)); - return(False); - } - - if (!dos_GetWd(dir2)) - { - DEBUG(0,("couldn't getwd for %s\n",dir)); - dos_ChDir(wd); - return(False); - } - - - if (p && (p != base_name)) - { - *p = 0; - if (strcmp(p+1,".")==0) - p[1]=0; - if (strcmp(p+1,"..")==0) - *p = '/'; - } - - if (dos_ChDir(base_name) != 0) - { - dos_ChDir(wd); - DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name)); - return(False); - } - - if (!dos_GetWd(newname)) - { - dos_ChDir(wd); - DEBUG(2,("couldn't get wd for %s %s\n",s,dir2)); - return(False); - } - - if (p && (p != base_name)) - { - pstrcat(newname,"/"); - pstrcat(newname,p+1); - } - - { - size_t l = strlen(dir2); - if (dir2[l-1] == '/') - l--; - - if (strncmp(newname,dir2,l) != 0) - { - dos_ChDir(wd); - DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l)); - return(False); - } - - if (relative) - { - if (newname[l] == '/') - pstrcpy(s,newname + l + 1); - else - pstrcpy(s,newname+l); - } - else - pstrcpy(s,newname); - } - - dos_ChDir(wd); - - if (strlen(s) == 0) - pstrcpy(s,"./"); - - DEBUG(3,("reduced to %s\n",s)); - return(True); -#endif -} - -/**************************************************************************** -expand some *s -****************************************************************************/ -static void expand_one(char *Mask,int len) -{ - char *p1; - while ((p1 = strchr(Mask,'*')) != NULL) - { - int lfill = (len+1) - strlen(Mask); - int l1= (p1 - Mask); - pstring tmp; - pstrcpy(tmp,Mask); - memset(tmp+l1,'?',lfill); - pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); - pstrcpy(Mask,tmp); - } -} - -/**************************************************************************** -parse out a directory name from a path name. Assumes dos style filenames. -****************************************************************************/ -static void dirname_dos(char *path,char *buf) -{ - split_at_last_component(path, buf, '\\', NULL); -} - - -/**************************************************************************** -expand a wildcard expression, replacing *s with ?s -****************************************************************************/ -void expand_mask(char *Mask,BOOL doext) -{ - pstring mbeg,mext; - pstring dirpart; - pstring filepart; - BOOL hasdot = False; - char *p1; - BOOL absolute = (*Mask == '\\'); - - *mbeg = *mext = *dirpart = *filepart = 0; - - /* parse the directory and filename */ - if (strchr(Mask,'\\')) - dirname_dos(Mask,dirpart); - - filename_dos(Mask,filepart); - - pstrcpy(mbeg,filepart); - if ((p1 = strchr(mbeg,'.')) != NULL) - { - hasdot = True; - *p1 = 0; - p1++; - pstrcpy(mext,p1); - } - else - { - pstrcpy(mext,""); - if (strlen(mbeg) > 8) - { - pstrcpy(mext,mbeg + 8); - mbeg[8] = 0; - } - } - - if (*mbeg == 0) - pstrcpy(mbeg,"????????"); - if ((*mext == 0) && doext && !hasdot) - pstrcpy(mext,"???"); - - if (strequal(mbeg,"*") && *mext==0) - pstrcpy(mext,"*"); - - /* expand *'s */ - expand_one(mbeg,8); - if (*mext) - expand_one(mext,3); - - pstrcpy(Mask,dirpart); - if (*dirpart || absolute) pstrcat(Mask,"\\"); - pstrcat(Mask,mbeg); - pstrcat(Mask,"."); - pstrcat(Mask,mext); - - DEBUG(6,("Mask expanded to [%s]\n",Mask)); -} - /**************************************************************************** @@ -1711,22 +1455,6 @@ this is a version of setbuffer() for those machines that only have setvbuf #endif -/**************************************************************************** -parse out a filename from a path name. Assumes dos style filenames. -****************************************************************************/ -static char *filename_dos(char *path,char *buf) -{ - char *p = strrchr(path,'\\'); - - if (!p) - pstrcpy(buf,path); - else - pstrcpy(buf,p+1); - - return(buf); -} - - /**************************************************************************** expand a pointer to be a particular size diff --git a/source/smbd/filename.c b/source/smbd/filename.c index 1d9c5ef754e..cd37ea39b31 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -338,6 +338,42 @@ BOOL unix_dfs_convert(char *name,connection_struct *conn, return unix_convert(name, conn, saved_last_component, bad_path, pst); } + +/******************************************************************* +reduce a file name, removing .. elements. +********************************************************************/ +static void unix_clean_name(char *s) +{ + char *p=NULL; + + DEBUG(3,("unix_clean_name [%s]\n",s)); + + /* remove any double slashes */ + string_sub(s, "//","/"); + + /* Remove leading ./ characters */ + if(strncmp(s, "./", 2) == 0) { + trim_string(s, "./", NULL); + if(*s == 0) + pstrcpy(s,"./"); + } + + while ((p = strstr(s,"/../")) != NULL) + { + pstring s1; + + *p = 0; + pstrcpy(s1,p+3); + + if ((p=strrchr(s,'/')) != NULL) + *p = 0; + else + *s = 0; + pstrcat(s,s1); + } + + trim_string(s,NULL,"/.."); +} /**************************************************************************** This routine is called to convert names from the dos namespace to unix namespace. It needs to handle any case conversions, mangling, format @@ -665,6 +701,154 @@ BOOL unix_convert(char *name,connection_struct *conn, return(True); } +/******************************************************************* +reduce a file name, removing .. elements and checking that +it is below dir in the hierarchy. This uses GetWd() and so must be run +on the system that has the referenced file system. + +widelinks are allowed if widelinks is true +********************************************************************/ + +static BOOL reduce_name(char *s,char *dir,BOOL widelinks) +{ +#ifndef REDUCE_PATHS + return True; +#else + pstring dir2; + pstring wd; + pstring base_name; + pstring newname; + char *p=NULL; + BOOL relative = (*s != '/'); + + *dir2 = *wd = *base_name = *newname = 0; + + if (widelinks) + { + unix_clean_name(s); + /* can't have a leading .. */ + if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/')) + { + DEBUG(3,("Illegal file name? (%s)\n",s)); + return(False); + } + + if (strlen(s) == 0) + pstrcpy(s,"./"); + + return(True); + } + + DEBUG(3,("reduce_name [%s] [%s]\n",s,dir)); + + /* remove any double slashes */ + string_sub(s,"//","/"); + + pstrcpy(base_name,s); + p = strrchr(base_name,'/'); + + if (!p) + return(True); + + if (!dos_GetWd(wd)) + { + DEBUG(0,("couldn't getwd for %s %s\n",s,dir)); + return(False); + } + + if (dos_ChDir(dir) != 0) + { + DEBUG(0,("couldn't chdir to %s\n",dir)); + return(False); + } + + if (!dos_GetWd(dir2)) + { + DEBUG(0,("couldn't getwd for %s\n",dir)); + dos_ChDir(wd); + return(False); + } + + + if (p && (p != base_name)) + { + *p = 0; + if (strcmp(p+1,".")==0) + p[1]=0; + if (strcmp(p+1,"..")==0) + *p = '/'; + } + + if (dos_ChDir(base_name) != 0) + { + dos_ChDir(wd); + DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name)); + return(False); + } + + if (!dos_GetWd(newname)) + { + dos_ChDir(wd); + DEBUG(2,("couldn't get wd for %s %s\n",s,dir2)); + return(False); + } + + if (p && (p != base_name)) + { + pstrcat(newname,"/"); + pstrcat(newname,p+1); + } + + { + size_t l = strlen(dir2); + if (dir2[l-1] == '/') + l--; + + if (strncmp(newname,dir2,l) != 0) + { + dos_ChDir(wd); + DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l)); + return(False); + } + + if (relative) + { + if (newname[l] == '/') + pstrcpy(s,newname + l + 1); + else + pstrcpy(s,newname+l); + } + else + pstrcpy(s,newname); + } + + dos_ChDir(wd); + + if (strlen(s) == 0) + pstrcpy(s,"./"); + + DEBUG(3,("reduced to %s\n",s)); + return(True); +#endif +} + +/**************************************************************************** +expand some *s +****************************************************************************/ +static void expand_one(char *Mask,int len) +{ + char *p1; + while ((p1 = strchr(Mask,'*')) != NULL) + { + int lfill = (len+1) - strlen(Mask); + int l1= (p1 - Mask); + pstring tmp; + pstrcpy(tmp,Mask); + memset(tmp+l1,'?',lfill); + pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); + pstrcpy(Mask,tmp); + } +} /**************************************************************************** check a filename - possibly caling reducename |