<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head profile="http://internetalchemy.org/2003/02/profile"> <link rel="foaf" type="application/rdf+xml" title="FOAF" href="http://www.openlinksw.com/dataspace/uda/about.rdf" /> <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" /> <meta name="dc.title" content="10. Database Event Hooks" /> <meta name="dc.subject" content="10. Database Event Hooks" /> <meta name="dc.creator" content="OpenLink Software Documentation Team ; " /> <meta name="dc.copyright" content="OpenLink Software, 1999 - 2009" /> <link rel="top" href="index.html" title="OpenLink Virtuoso Universal Server: Documentation" /> <link rel="search" href="/doc/adv_search.vspx" title="Search OpenLink Virtuoso Universal Server: Documentation" /> <link rel="parent" href="hooks.html" title="Chapter Contents" /> <link rel="prev" href="fn_dbev_connect.html" title="Database Connections" /> <link rel="next" href="fn_disconnect.html" title="Database Disconnections" /> <link rel="shortcut icon" href="../images/misc/favicon.ico" type="image/x-icon" /> <link rel="stylesheet" type="text/css" href="doc.css" /> <link rel="stylesheet" type="text/css" href="/doc/translation.css" /> <title>10. Database Event Hooks</title> <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" /> <meta name="author" content="OpenLink Software Documentation Team ; " /> <meta name="copyright" content="OpenLink Software, 1999 - 2009" /> <meta name="keywords" content="" /> <meta name="GENERATOR" content="OpenLink XSLT Team" /> </head> <body> <div id="header"> <a name="fn_logins" /> <img src="../images/misc/logo.jpg" alt="" /> <h1>10. Database Event Hooks</h1> </div> <div id="navbartop"> <div> <a class="link" href="hooks.html">Chapter Contents</a> | <a class="link" href="fn_dbev_connect.html" title="Database Connections">Prev</a> | <a class="link" href="fn_disconnect.html" title="Database Disconnections">Next</a> </div> </div> <div id="currenttoc"> <form method="post" action="/doc/adv_search.vspx"> <div class="search">Keyword Search: <br /> <input type="text" name="q" /> <input type="submit" name="go" value="Go" /> </div> </form> <div> <a href="http://www.openlinksw.com/">www.openlinksw.com</a> </div> <div> <a href="http://docs.openlinksw.com/">docs.openlinksw.com</a> </div> <br /> <div> <a href="index.html">Book Home</a> </div> <br /> <div> <a href="contents.html">Contents</a> </div> <div> <a href="preface.html">Preface</a> </div> <br /> <div class="selected"> <a href="hooks.html">Database Event Hooks</a> </div> <br /> <div> <a href="fn_dbev_startup.html">Database Startup</a> </div> <div> <a href="fn_dbev_connect.html">Database Connections</a> </div> <div class="selected"> <a href="fn_logins.html">Database Logins</a> </div> <div> <a href="fn_disconnect.html">Database Disconnections</a> </div> <div> <a href="fn_dbev_shutdown.html">Database Shutdown</a> </div> <div> <a href="fn_dbev_prepare.html">SQL Statement Preparation</a> </div> <div> <a href="sqlparsetree.html">SQL Parse Tree</a> </div> <div> <a href="fn_davlogins.html">WebDAV Logins</a> </div> <div> <a href="assocauxdata.html">Associating Auxiliary Data With A Connection</a> </div> <br /> </div> <div id="text"> <a name="fn_logins" /> <h2>10.3. Database Logins</h2> <p> <span class="computeroutput">DB.DBA.DBEV_LOGIN (<span class="paramdef">inout <span class="parameter">user_name</span> varchar</span>, <span class="paramdef">in <span class="parameter">digest</span> varchar</span>, <span class="paramdef">in <span class="parameter">session_random</span> varchar</span>); </span> </p> <p>This function, if defined, will always be called by Virtuoso just before a client is authenticated against the Virtuoso Server. Three parameters are available for audit purposes or any other pre-processing purpose totally user definable.</p> <ul> <li> <strong>user_name:</strong> <ul> <li> <strong>IN</strong> : the user name from the login data</li> <li> <strong>OUT</strong> : the user name used by Virtuoso for this connection</li> </ul> </li> <li> <strong>digest</strong> : the password digest calculated by the client (or the password itself for older clients)</li> <li> <strong>session_random</strong> : the random key used to calculate the digest</li> </ul> <p>This hook can be used to control how Virtuoso proceeds with the client login by responding to 3 possible return values:</p> <ul> <li>-1 - continue with normal verification</li> <li>0 - reject the login</li> <li>1 - allow the login (the user returned should be a valid Virtuoso local user name</li> </ul> <a name="ex_dbev_login" /> <div class="example"> <div class="exampletitle">Sample Database Login Hook</div> <div> <pre class="programlisting"> create procedure "DB"."DBA"."DBEV_LOGIN" ( inout user_name varchar, in digest varchar, in session_random varchar) { -- the hook runs as DBA dbg_obj_print ('user=', user); -- and is compiled as DBA declare uid_cnt integer; uid_cnt := 0; select count (*) into uid_cnt from SYS_USERS where U_NAME = user_name; dbg_printf ('%ld local users found with this name', uid_cnt); if (user_name = 'masterdba') { -- 'masterdba' is a valid remotely defined user -- it's password is 'masterdbapwd' -- we're going to check it's password and then map it to dba declare md5_ctx any; declare my_digest varchar; declare pwd varchar; -- this is our assumption for the user's password -- this can come from an external source as well pwd := 'masterdbapwd'; -- calculate the MD5 digest for checking the password that the client supplied. -- note that it uses the 'masterdba'/'masterdbapwd' to calculate it since we -- assume that these are the data the client supplied as user id and password -- -- The way to calculate this is FIXED. -- The ONLY variables are the user id and the password -- START of the FIXED digest calculation sequence md5_ctx := md5_init(); md5_ctx := md5_update(md5_ctx, session_random); md5_ctx := md5_update(md5_ctx, user_name); md5_ctx := md5_update(md5_ctx, pwd); -- the 0 parameter to the md5_final causes it to return the bytes -- instead of representing it as hexadecimal characters my_digest := md5_final (md5_ctx, 0); -- END of the FIXED digest calculation sequence -- now compare the calculated digest with the one supplied by the client -- note the OR here - some older clients MAY supply the password in plain text if (my_digest = digest or pwd = digest) { -- the match says that the client indeed supplied 'masterdbapwd' as a password dbg_obj_print ('masterdba validated'); -- so map it to the local 'dba' user user_name := 'dba'; -- and skip further verification return 1; } else { -- the password is not the one that we verify against dbg_obj_print ('masterdba pwd wrong'); -- not allow the login at all return 0; } } else if (user_name = 'nobody') { -- the hook can signal : -- this is equal to returning -1, but has the additional benefit of an error message printed into the log signal ('28000', 'we don''t map nobody'); } else if (user_name = 'attacker') { -- that's a way to print a message to the log and reject the login log_message ('trying invalid user'); return 0; } else { -- all local user_name/pwd are subject to normal verification dbg_obj_print (user_name); return -1; } -- note that not returning value causes the Virtuoso to print an appropriate message to the log -- and then continue with the normal verification -- same happens if the value returned is not 0, -1 or 1 }; </pre> </div> </div> <p> <span class="computeroutput">DB.DBA.USER_FIND (<span class="paramdef">in <span class="parameter">name</span> varchar</span>); </span> </p> <p>This is a user-defined PL function hook which, if it exists, will be executed before doing the SQL/ODBC login. In this hook the user can find a user account from some other server and register it in the local database. Or, this can be used to perform some pre-login actions. It is similar to the DBEV_LOGIN, but it does not change any account validation rule, it is purely for pre-processing.</p> <table border="0" width="90%" id="navbarbottom"> <tr> <td align="left" width="33%"> <a href="fn_dbev_connect.html" title="Database Connections">Previous</a> <br />Database Connections</td> <td align="center" width="34%"> <a href="hooks.html">Chapter Contents</a> </td> <td align="right" width="33%"> <a href="fn_disconnect.html" title="Database Disconnections">Next</a> <br />Database Disconnections</td> </tr> </table> </div> <div id="footer"> <div>Copyright© 1999 - 2009 OpenLink Software All rights reserved.</div> <div id="validation"> <a href="http://validator.w3.org/check/referer"> <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /> </a> <a href="http://jigsaw.w3.org/css-validator/"> <img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" /> </a> </div> </div> </body> </html>