r6633: Added "check_path_syntax_posix()" in preparation for handling
authorJeremy Allison <jra@samba.org>
Fri, 6 May 2005 13:26:54 +0000 (13:26 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:56:48 +0000 (10:56 -0500)
POSIX pathnames. Not yet used.
Jeremy.
(This used to be commit 381da9b55d6a3fda2ba4a3f12bee50853b7fd3b3)

source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/vfs.c

index d747e84a3a5ee1162cbe6ad800f5a8dbe621ffae..a37ae5548f7e849872081e69bf9ceef755e60bf4 100644 (file)
@@ -73,7 +73,6 @@ static char *nttrans_realloc(char **ptr, size_t size)
        return tptr;
 }
 
-
 /****************************************************************************
  Send the required number of replies back.
  We assume all fields other than the data fields are
@@ -262,6 +261,15 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, NTSTATUS nt_e
        return 0;
 }
 
+/****************************************************************************
+ Is it an NTFS stream name ?
+****************************************************************************/
+
+BOOL is_ntfs_stream_name(const char *fname)
+{
+       return (strchr_m(fname, ':') != NULL) ? True : False;
+}
+
 /****************************************************************************
  Save case statics.
 ****************************************************************************/
@@ -668,7 +676,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                         * Check to see if this is a mac fork of some kind.
                         */
 
-                       if( strchr_m(fname, ':')) {
+                       if( is_ntfs_stream_name(fname)) {
                                END_PROFILE(SMBntcreateX);
                                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
                        }
@@ -717,7 +725,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
                 * Check to see if this is a mac fork of some kind.
                 */
 
-               if( strchr_m(fname, ':')) {
+               if( is_ntfs_stream_name(fname)) {
                        
 #ifdef HAVE_SYS_QUOTAS
                        if ((fake_file_type=is_fake_file(fname))!=FAKE_FILE_TYPE_NONE) {
@@ -1329,8 +1337,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                         * Check to see if this is a mac fork of some kind.
                         */
 
-                       if( strchr_m(fname, ':'))
+                       if( is_ntfs_stream_name(fname)) {
                                return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+                       }
 
                        return ERROR_DOS(ERRDOS,ERRbadfid);
                }
@@ -1369,8 +1378,9 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
                 * Check to see if this is a mac fork of some kind.
                 */
 
-               if( strchr_m(fname, ':'))
+               if( is_ntfs_stream_name(fname)) {
                        return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
+               }
        }
 
        /*
@@ -1854,7 +1864,7 @@ int reply_ntrename(connection_struct *conn,
                return ERROR_NT(status);
        }
 
-       if( strchr_m(oldname, ':')) {
+       if( is_ntfs_stream_name(oldname)) {
                /* Can't rename a stream. */
                END_PROFILE(SMBntrename);
                return ERROR_NT(NT_STATUS_ACCESS_DENIED);
index 8cccd9b56837eec62aa2ba4c390cf34da1af4820..e1131c56ed59bc5c478b202b0878ac03bba5dd4c 100644 (file)
@@ -280,6 +280,100 @@ NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
        return ret;
 }
 
+/****************************************************************************
+ Check the path for a POSIX client.
+ We're assuming here that '/' is not the second byte in any multibyte char
+ set (a safe assumption).
+****************************************************************************/
+
+NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname)
+{
+       char *d = destname;
+       const char *s = srcname;
+       NTSTATUS ret = NT_STATUS_OK;
+       BOOL start_of_name_component = True;
+
+       while (*s) {
+               if (*s == '/') {
+                       /*
+                        * Safe to assume is not the second part of a mb char as this is handled below.
+                        */
+                       /* Eat multiple '/' or '\\' */
+                       while (*s == '/') {
+                               s++;
+                       }
+                       if ((d != destname) && (*s != '\0')) {
+                               /* We only care about non-leading or trailing '/' */
+                               *d++ = '/';
+                       }
+
+                       start_of_name_component = True;
+                       continue;
+               }
+
+               if (start_of_name_component) {
+                       if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) {
+                               /* Uh oh - "/../" or "/..\0" ! */
+
+                               /*
+                                * No mb char starts with '.' so we're safe checking the directory separator here.
+                                */
+
+                               /* If  we just added a '/' - delete it */
+                               if ((d > destname) && (*(d-1) == '/')) {
+                                       *(d-1) = '\0';
+                                       d--;
+                               }
+
+                               /* Are we at the start ? Can't go back further if so. */
+                               if (d <= destname) {
+                                       ret = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+                                       break;
+                               }
+                               /* Go back one level... */
+                               /* We know this is safe as '/' cannot be part of a mb sequence. */
+                               /* NOTE - if this assumption is invalid we are not in good shape... */
+                               /* Decrement d first as d points to the *next* char to write into. */
+                               for (d--; d > destname; d--) {
+                                       if (*d == '/')
+                                               break;
+                               }
+                               s += 2; /* Else go past the .. */
+                               continue;
+
+                       } else if ((s[0] == '.') && ((s[1] == '\0') || (s[1] == '/'))) {
+                               /* Eat the '.' */
+                               s++;
+                               continue;
+                       }
+               }
+
+               if (!(*s & 0x80)) {
+                       *d++ = *s++;
+               } else {
+                       switch(next_mb_char_size(s)) {
+                               case 4:
+                                       *d++ = *s++;
+                               case 3:
+                                       *d++ = *s++;
+                               case 2:
+                                       *d++ = *s++;
+                               case 1:
+                                       *d++ = *s++;
+                                       break;
+                               default:
+                                       DEBUG(0,("check_path_syntax_posix: character length assumptions invalid !\n"));
+                                       *d = '\0';
+                                       return NT_STATUS_INVALID_PARAMETER;
+                       }
+               }
+               start_of_name_component = False;
+       }
+
+       *d = '\0';
+       return ret;
+}
+
 /****************************************************************************
  Pull a string and check the path - provide for error return.
 ****************************************************************************/
@@ -3529,7 +3623,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
 
        unix_convert(directory,conn,0,&bad_path,&sbuf);
 
-       if( strchr_m(directory, ':')) {
+       if( is_ntfs_stream_name(directory)) {
                DEBUG(5,("reply_mkdir: failing create on filename %s with colon in name\n", directory));
                END_PROFILE(SMBmkdir);
                return ERROR_FORCE_DOS(ERRDOS, ERRinvalidname);
index dee29f4796548a8dad7232cee4a2f46bb663c98d..ade28f9bee9d721d137b0bfa7858b7117ea2697e 100644 (file)
@@ -227,13 +227,15 @@ BOOL vfs_init_custom(connection_struct *conn, const char *vfs_object)
                return False;
        }
 
-       if(!backends) static_init_vfs;
+       if(!backends) {
+               static_init_vfs;
+       }
 
        DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
 
        module_name = smb_xstrdup(vfs_object);
 
-       p = strchr(module_name, ':');
+       p = strchr_m(module_name, ':');
 
        if (p) {
                *p = 0;