lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>Im using lua 4 in my server appz and I would like to limit filesystem
access to a scope of certain >directory only (i.e. the server appz root
directory). Right now anybody can access whole filesystem >tree from
scripts.

Sometimes, I face a problem like yours, because some host processes must run
setuid. So I devised
a lua module to handle the question of where to write.
The main concept is that the allowed directories or folders are recorded in
a environment variable.
For me, "WriteIn" is a good name.
Follows a lua module to simplify the chore of user´s pathname validation.
---------------------- start ----------------
ut = { }

ut.pathspat = "%/"
ut.pathsstr = "/"
ut.allowedp = "/tmp:~"

ut.stripslash = function( path )
   if string.find( path, ut.pathspat, -1 ) then
      path = string.sub( path, 1, string.len( path ) - 1 )
   end
   return path
end

ut.pathsplit = function( full )
   local path
   local base
   local i = 1
   while 1 do
      local s, e
      local p
      s, e = string.find( full, ut.pathspat, i )
      if not s then
         if i <= string.len( full ) then
            base = string.sub( full, i, -1 )
         end
      else
         path = string.sub( full, 1, e )
      end
      if not s then
         break
      else
         i = e + 1
      end
   end
   return path, base
end

ut.pathtable = function( list, delim )

   if not delim then
      delim = "%:"
   end

   local t = { }
   local i = 1

   while 1 do
      local s, e
      local p
      s, e = string.find( list, delim, i )
      if not s then
         if i <= string.len( list ) then
            p = string.sub( list, i, -1 )
         else
            p = nil
         end
      else
         p = string.sub( list, i, e - 1 )
      end
      if p then
         table.insert( t, p )
      end
      if not s then
         return t
      end
      i = e + 1
   end
end

ut.allowedpath = function( path, list, delim )
   if not list then
      if posix then
         list = posix.getenv( "WriteIn" )
      end
      if not list then
         list = ut.allowedp
      end
   end
   path = ut.stripslash( path )
   local t = ut.pathtable( list, delim )
   local p
   for _, p in pairs( t ) do
      p = ut.stripslash( p )
      if p == path then
         return p
      end
   end
end

ut.solvetilde = function( )
   if posix then
      local a = posix.getpasswd( )
      if a then
         return a.dir
      end
   end
end

ut.fullpath = function( path, stem )
    local p = ut.stripslash( path )
    local s = stem
    local f
    if string.sub( stem, 1, 1 ) == ut.pathsstr then
       return string.format( "%s%s", p, s )
    else
       return string.format( "%s%s%s", p, ut.pathsstr, s )
    end
end

---------------- end --------------

This module is lua 5.0, but I think it´s not so difficult to adapt it to lua
4.x.
Mainly, it´s a question of some standard library function names (
string.find vs strfind ).
Also, I load the module using the lua 5 require function, but also can be
loaded using dofile.
Well, the full code is a mess, but you are concerned only with the entry
point
ut.allowedpath( path, pathlist, delimiter )
where pathlist and delimiter can be both nil.
If the folder part of path is the pathlist or the environment var or in the
default list,
you get a non nil result, else you get a nil retval.
As a bonus, you get a function to compose a path from a directory and a
filename, where the important question is the extra slash stripping, so one
can safely
ut.fullpath( "/mydir/", "/myfile" )
or
ut.fullpath( "/mydir", "/myfile" )
or
ut.fullpath( "/mydir", "myfile" )

ut.solvetilde may be of no usage in windows

Please note the first 3 members, they are OS dependent !!!

Hope it´s useful