<docbook><section><title>VOSStubDETAPI</title><programlisting>--
--  $Id: DET_Stub.sql,v 1.3 2009/02/12 18:11:42 ddimitrov Exp $
--
--  This file is part of the OpenLink Software Virtuoso Open-Source (VOS)
--  project.
--
--  Copyright (C) 1998-2006 OpenLink Software
--
--  This project is free software; you can redistribute it and/or modify it
--  under the terms of the GNU General Public License as published by the
--  Free Software Foundation; only version 2 of the License, dated June 1991.
--
--  This program is distributed in the hope that it will be useful, but
--  WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
--  General Public License for more details.
--
--  You should have received a copy of the GNU General Public License along
--  with this program; if not, write to the Free Software Foundation, Inc.,
--  51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
--

use DB
;

--| This matches DAV_AUTHENTICATE (in id any, in what char(1), in req varchar, in a_uname varchar, in a_pwd varchar, in a_uid integer := null)
--| The difference is that the DET function should not check whether the pair of name and password is valid; the auth_uid is not a null already.
create function &quot;Stub_DAV_AUTHENTICATE&quot; (in id any, in what char(1), in req varchar, in auth_uname varchar, in auth_pwd varchar, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;Stub_DAV_AUTHENTICATE (&#39;, id, what, req, auth_uname, auth_pwd, auth_uid, &#39;)&#39;);
  if (auth_uid &gt;= 0)
    return auth_uid;
  return -12;
}
;

--| This exactly matches DAV_AUTHENTICATE_HTTP (in id any, in what char(1), in req varchar, in can_write_http integer, inout a_lines any, inout a_uname varchar, inout a_pwd varchar, inout a_uid integer, inout a_gid integer, inout _perms varchar) returns integer
--| The function should fully check access because DAV_AUTHENTICATE_HTTP do nothing with auth data either before or after calling this DET function.
--| Unlike DAV_AUTHENTICATE, user name passed to DAV_AUTHENTICATE_HTTP header may not match real DAV user.
--| If DET call is successful, DAV_AUTHENTICATE_HTTP checks whether the user have read permission on mount point collection.
--| Thus even if DET function allows anonymous access, the whole request may fail if mountpoint is not readable by public.
create function &quot;Stub_DAV_AUTHENTICATE_HTTP&quot; (in id any, in what char(1), in req varchar, in can_write_http integer, inout a_lines any, inout a_uname varchar, inout a_pwd varchar, inout a_uid integer, inout a_gid integer, inout _perms varchar) returns integer
{
  declare rc integer;
  declare puid, pgid integer;
  declare u_password, pperms varchar;
  declare allow_anon integer;
  if (length (req) &lt;&gt; 3)
    return -15;

  whenever not found goto nf_col_or_res;
  puid := http_dav_uid();
  pgid := coalesce (
    ( select G_ID from WS.WS.SYS_DAV_GROUP
      where G_NAME = &#39;Stub_&#39; || coalesce ((select COL_NAME from WS.WS.SYS_DAV_COL where COL_ID=id[1] and COL_DET=&#39;HostFs&#39;), &#39;&#39;)
      ), puid+1);
  pperms := &#39;110100100NN&#39;;
  if ((what &lt;&gt; &#39;r&#39;) and (what &lt;&gt; &#39;c&#39;))
    return -14;
  allow_anon := WS.WS.PERM_COMP (substring (cast (pperms as varchar), 7, 3), req);
  if (a_uid is null)
    {
      if ((not allow_anon) or (&#39;&#39; &lt;&gt; WS.WS.FINDPARAM (a_lines, &#39;Authorization:&#39;)))
      rc := WS.WS.GET_DAV_AUTH (a_lines, allow_anon, can_write_http, a_uname, u_password, a_uid, a_gid, _perms);
      if (rc &lt; 0)
        return rc;
    }
  if (isinteger (a_uid))
    {
      if (a_uid &lt; 0)
	return a_uid;
     if (a_uid = 1) -- Anonymous FTP
	{
          a_uid := http_nobody_uid ();
          a_gid := http_nogroup_gid ();
	}
    }
  if (DAV_CHECK_PERM (pperms, req, a_uid, a_gid, pgid, puid))
    return a_uid;
  return -13;

nf_col_or_res:
  return -1;
}
;


--| This should return ID of the collection that contains resource or collection with given ID,
--| Possible ambiguity (such as symlinks etc.) should be resolved by using path.
--| This matches DAV_GET_PARENT (in id any, in st char(1), in path varchar) returns any
create function &quot;Stub_DAV_GET_PARENT&quot; (in id any, in st char(1), in path varchar) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_GET_PARENT (&#39;, id, st, path, &#39;)&#39;);
  return -20;
}
;

--| When DAV_COL_CREATE_INT calls DET function, authentication, check for lock and check for overwrite are passed, uid and gid are translated from strings to IDs.
--| Check for overwrite, but the deletion of previously existing collection should be made by DET function.
create function &quot;Stub_DAV_COL_CREATE&quot; (in detcol_id any, in path_parts any, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_COL_CREATE (&#39;, detcol_id, path_parts, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| It looks like that this is redundant and should be removed at all.
create function &quot;Stub_DAV_COL_MOUNT&quot; (in detcol_id any, in path_parts any, in full_mount_path varchar, in mount_det varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_COL_MOUNT (&#39;, detcol_id, path_parts, full_mount_path, mount_det, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| It looks like that this is redundant and should be removed at all.
create function &quot;Stub_DAV_COL_MOUNT_HERE&quot; (in parent_id any, in full_mount_path varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_COL_MOUNT_HERE (&#39;, parent_id, full_mount_path, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


--| When DAV_DELETE_INT calls DET function, authentication and check for lock are passed.
create function &quot;Stub_DAV_DELETE&quot; (in detcol_id any, in path_parts any, in what char(1), in silent integer, in auth_uid integer) returns integer
{
  -- dbg_obj_princ (&#39;Stub_DAV_DELETE (&#39;, detcol_id, path_parts, what, silent, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| When DAV_RES_UPLOAD_STRSES_INT calls DET function, authentication and check for locks are performed before the call.
--| There&#39;s a special problem, known as &#39;Transaction deadlock after reading from HTTP session&#39;.
--| The DET function should do only one INSERT of the &#39;content&#39; into the table and do it as late as possible.
--| The function should return -29 if deadlocked or otherwise broken after reading blob from HTTP.
create function &quot;Stub_DAV_RES_UPLOAD&quot; (in detcol_id any, in path_parts any, inout content any, in type varchar, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_RES_UPLOAD (&#39;, detcol_id, path_parts, &#39;, [content], &#39;, type, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;


--| When DAV_PROP_REMOVE_INT calls DET function, authentication and check for locks are performed before the call.
--| The check whether it&#39;s a system name or not (when an error in returned if name is system) is _not_ permitted.
--| It should delete any dead property even if the name looks like system name.
create function &quot;Stub_DAV_PROP_REMOVE&quot; (in id any, in what char(0), in propname varchar, in silent integer, in auth_uid integer) returns integer
{
  -- dbg_obj_princ (&#39;Stub_DAV_PROP_REMOVE (&#39;, id, what, propname, silent, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| When DAV_PROP_SET_INT calls DET function, authentication and check for locks are performed before the call.
--| The check whether it&#39;s a system property or not is _not_ permitted and the function should return -16 for live system properties.
create function &quot;Stub_DAV_PROP_SET&quot; (in id any, in what char(0), in propname varchar, in propvalue any, in overwrite integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_PROP_SET (&#39;, id, what, propname, propvalue, overwrite, auth_uid, &#39;)&#39;);
  if (propname[0] = 58)
    {
      return -16;
    }
  return -20;
}
;

--| When DAV_PROP_GET_INT calls DET function, authentication and check whether it&#39;s a system property are performed before the call.
create function &quot;Stub_DAV_PROP_GET&quot; (in id any, in what char(0), in propname varchar, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;Stub_DAV_PROP_GET (&#39;, id, what, propname, auth_uid, &#39;)&#39;);
  return -11;
}
;

--| When DAV_PROP_LIST_INT calls DET function, authentication is performed before the call.
--| The returned list should contain only user properties.
create function &quot;Stub_DAV_PROP_LIST&quot; (in id any, in what char(0), in propmask varchar, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;Stub_DAV_PROP_LIST (&#39;, id, what, propmask, auth_uid, &#39;)&#39;);
  return vector ();
}
;

--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function &quot;Stub_DAV_DIR_SINGLE&quot; (in id any, in what char(0), in path any, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_DIR_SINGLE (&#39;, id, what, path, auth_uid, &#39;)&#39;);
  return vector();
}
;

--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function &quot;Stub_DAV_DIR_LIST&quot; (in detcol_id any, in path_parts any, in detcol_path varchar, in name_mask varchar, in recursive integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_DIR_LIST (&#39;, detcol_id, path_parts, detcol_path, name_mask, recursive, auth_uid, &#39;)&#39;);
  return vector();
}
;

--| When DAV_DIR_FILTER_INT calls DET function, authentication is performed before the call and compilation is initialized.
create function &quot;CatFilter_DAV_DIR_FILTER&quot; (in detcol_id any, in path_parts any, in detcol_path varchar, inout compilation any, in recursive integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_DIR_FILTER (&#39;, detcol_id, path_parts, detcol_path, compilation, recursive, auth_uid, &#39;)&#39;);
  return vector();
}
;

--| When DAV_PROP_GET_INT or DAV_DIR_LIST_INT calls DET function, authentication is performed before the call.
create function &quot;Stub_DAV_SEARCH_ID&quot; (in detcol_id any, in path_parts any, in what char(1)) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_SEARCH_ID (&#39;, detcol_id, path_parts, what, &#39;)&#39;);
  return -20;
}
;

--| When DAV_SEARCH_PATH_INT calls DET function, authentication is performed before the call.
create function &quot;Stub_DAV_SEARCH_PATH&quot; (in id any, in what char(1)) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_SEARCH_PATH (&#39;, id, what, &#39;)&#39;);
  return NULL;
}
;

--| When DAV_COPY_INT calls DET function, authentication and check for locks are performed before the call, but no check for existing/overwrite.
create function &quot;Stub_DAV_RES_UPLOAD_COPY&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite_flags integer, in permissions varchar, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_RES_UPLOAD_COPY (&#39;, detcol_id, path_parts, source_id, what, overwrite, permissions, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| When DAV_COPY_INT calls DET function, authentication and check for locks are performed before the call, but no check for existing/overwrite.
create function &quot;Stub_DAV_RES_UPLOAD_MOVE&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite_flags integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_RES_UPLOAD_MOVE (&#39;, detcol_id, path_parts, source_id, what, overwrite, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| When DAV_RES_CONTENT or DAV_RES_COPY_INT or DAV_RES_MOVE_INT calls DET function, authentication is made.
--| If content_mode is 1 then content is a valid output stream before the call.
create function &quot;Stub_DAV_RES_CONTENT&quot; (in id any, inout content any, out type varchar, in content_mode integer) returns integer
{
  -- dbg_obj_princ (&#39;Stub_DAV_RES_CONTENT (&#39;, id, &#39;, [content], [type], &#39;, content_mode, &#39;)&#39;);
  return -20;
}
;

--| This adds an extra access path to the existing resource or collection.
create function &quot;Stub_DAV_SYMLINK&quot; (in detcol_id any, in path_parts any, in source_id any, in what char(1), in overwrite integer, in uid integer, in gid integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_SYMLINK (&#39;, detcol_id, path_parts, source_id, overwrite, uid, gid, auth_uid, &#39;)&#39;);
  return -20;
}
;

--| This gets a list of resources and/or collections as it is returned by DAV_DIR_LIST and and writes the list of quads (old_id, &#39;what&#39;, old_full_path, dereferenced_id, dereferenced_full_path).
create function &quot;Stub_DAV_DEREFERENCE_LIST&quot; (in detcol_id any, inout report_array) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_DEREFERENCE_LIST (&#39;, detcol_id, report_array, &#39;)&#39;);
  return -20;
}
;

--| This gets one of reference quads returned by ..._DAV_REREFERENCE_LIST() and returns a record (new_full_path, new_dereferenced_full_path, name_may_vary).
create function &quot;Stub_DAV_RESOLVE_PATH&quot; (in detcol_id any, inout reference_item any, inout old_base varchar, inout new_base varchar) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_RESOLVE_PATH (&#39;, detcol_id, reference_item, old_base, new_base, &#39;)&#39;);
  return -20;
}
;

--| There&#39;s no API function to lock for a while (do we need such?) The &quot;LOCK&quot; DAV method checks that all parameters are valid but does not check for existing locks.
create function &quot;Stub_DAV_LOCK&quot; (in path any, in id any, in type char(1), inout locktype varchar, inout scope varchar, in token varchar, inout owner_name varchar, inout owned_tokens varchar, in depth varchar, in timeout_sec integer, in auth_uid integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_LOCK (&#39;, path, id, type, locktype, scope, token, owner_name, owned_tokens, depth, timeout_sec, auth_uid, &#39;)&#39;);
  return -20;
}
;


--| There&#39;s no API function to unlock for a while (do we need such?) The &quot;UNLOCK&quot; DAV method checks that all parameters are valid but does not check for existing locks.
create function &quot;Stub_DAV_UNLOCK&quot; (in id any, in type char(1), in token varchar, in auth_uid integer)
{
  -- dbg_obj_princ (&#39;Stub_DAV_UNLOCK (&#39;, id, type, token, auth_uid, &#39;)&#39;);
  return -27;
}
;

--| The caller does not check if id is valid.
--| This returns -1 if id is not valid, 0 if all existing locks are listed in owned_tokens whitespace-delimited list, 1 for soft 2 for hard lock.
create function &quot;Stub_DAV_IS_LOCKED&quot; (inout id any, inout type char(1), in owned_tokens varchar) returns integer
{
  -- dbg_obj_princ (&#39;Stub_DAV_IS_LOCKED (&#39;, id, type, owned_tokens, &#39;)&#39;);
  return 0;
}
;


--| The caller does not check if id is valid.
--| This returns -1 if id is not valid, list of tuples (LOCK_TYPE, LOCK_SCOPE, LOCK_TOKEN, LOCK_TIMEOUT, LOCK_OWNER, LOCK_OWNER_INFO) otherwise.
create function &quot;Stub_DAV_LIST_LOCKS&quot; (in id any, in type char(1), in recursive integer) returns any
{
  -- dbg_obj_princ (&#39;Stub_DAV_LIST_LOCKS&quot; (&#39;, id, type, recursive);
  return vector ();
}
;

</programlisting></section></docbook>