2005-07-11 03:25:42 +04:00
/*
Unix SMB / CIFS implementation .
ejs auth functions
Copyright ( C ) Simo Sorce 2005
Copyright ( C ) Andrew Tridgell 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-07-11 03:25:42 +04:00
( at your option ) any later version .
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
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-07-11 03:25:42 +04:00
*/
# include "includes.h"
2005-07-13 04:06:38 +04:00
# include "lib/appweb/ejs/ejs.h"
2005-07-11 03:25:42 +04:00
# include "auth/auth.h"
2006-11-07 03:48:36 +03:00
# include "auth/credentials/credentials.h"
2005-07-11 03:25:42 +04:00
# include "scripting/ejs/smbcalls.h"
2006-01-18 14:25:30 +03:00
# include "lib/events/events.h"
2006-07-31 18:05:08 +04:00
# include "lib/messaging/irpc.h"
2007-07-19 11:48:26 +04:00
# include "libcli/security/security.h"
2005-07-11 03:25:42 +04:00
2005-12-14 10:22:25 +03:00
static int ejs_doauth ( MprVarHandle eid ,
2007-10-01 22:52:55 +04:00
TALLOC_CTX * tmp_ctx , struct MprVar * auth ,
const char * username , const char * password ,
const char * domain , const char * workstation ,
struct socket_address * remote_host ,
const char * * auth_types )
2005-07-11 03:25:42 +04:00
{
struct auth_usersupplied_info * user_info = NULL ;
struct auth_serversupplied_info * server_info = NULL ;
2005-12-14 10:22:25 +03:00
struct auth_session_info * session_info = NULL ;
2005-07-11 03:25:42 +04:00
struct auth_context * auth_context ;
2006-01-10 13:35:47 +03:00
struct MprVar * session_info_obj ;
2005-07-11 03:25:42 +04:00
NTSTATUS nt_status ;
2007-07-19 11:48:26 +04:00
bool set ;
2005-07-11 03:25:42 +04:00
2006-07-31 17:34:00 +04:00
struct smbcalls_context * c ;
struct event_context * ev ;
2006-07-31 18:05:08 +04:00
struct messaging_context * msg ;
2006-07-31 17:34:00 +04:00
/* Hope we can find an smbcalls_context somewhere up there... */
c = talloc_find_parent_bytype ( tmp_ctx , struct smbcalls_context ) ;
if ( c ) {
ev = c - > event_ctx ;
2006-07-31 18:05:08 +04:00
msg = c - > msg_ctx ;
2006-07-31 17:34:00 +04:00
} else {
/* Hope we can find the event context somewhere up there... */
ev = event_context_find ( tmp_ctx ) ;
2008-02-21 20:21:44 +03:00
msg = messaging_client_init ( tmp_ctx , lp_messaging_path ( tmp_ctx , mprLpCtx ( ) ) ,
lp_iconv_convenience ( mprLpCtx ( ) ) , ev ) ;
2006-07-31 17:34:00 +04:00
}
2006-01-18 14:25:30 +03:00
2007-07-12 08:56:33 +04:00
if ( auth_types ) {
2008-02-21 20:21:44 +03:00
nt_status = auth_context_create_methods ( tmp_ctx , auth_types , ev , msg , mprLpCtx ( ) , & auth_context ) ;
2007-07-12 08:56:33 +04:00
} else {
2008-02-21 20:21:44 +03:00
nt_status = auth_context_create ( tmp_ctx , ev , msg , mprLpCtx ( ) , & auth_context ) ;
2007-07-12 08:56:33 +04:00
}
2005-07-11 03:25:42 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2005-07-12 09:53:51 +04:00
mprSetPropertyValue ( auth , " report " , mprString ( " Auth System Failure " ) ) ;
2005-07-11 03:25:42 +04:00
goto done ;
}
2005-07-22 08:10:07 +04:00
user_info = talloc ( tmp_ctx , struct auth_usersupplied_info ) ;
if ( ! user_info ) {
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2005-07-22 08:10:07 +04:00
mprSetPropertyValue ( auth , " report " , mprString ( " talloc failed " ) ) ;
goto done ;
}
2007-10-07 02:28:14 +04:00
user_info - > mapped_state = true ;
2005-07-22 08:10:07 +04:00
user_info - > client . account_name = username ;
user_info - > mapped . account_name = username ;
user_info - > client . domain_name = domain ;
user_info - > mapped . domain_name = domain ;
2006-01-10 01:12:53 +03:00
user_info - > workstation_name = workstation ;
2005-07-22 08:10:07 +04:00
2006-01-10 12:21:13 +03:00
user_info - > remote_host = remote_host ;
2005-07-22 08:10:07 +04:00
user_info - > password_state = AUTH_PASSWORD_PLAIN ;
user_info - > password . plaintext = talloc_strdup ( user_info , password ) ;
user_info - > flags = USER_INFO_CASE_INSENSITIVE_USERNAME |
USER_INFO_DONT_CHECK_UNIX_ACCOUNT ;
2005-11-01 16:32:09 +03:00
user_info - > logon_parameters = 0 ;
2005-07-11 03:25:42 +04:00
nt_status = auth_check_password ( auth_context , tmp_ctx , user_info , & server_info ) ;
2006-01-14 01:55:23 +03:00
/* Don't give the game away (any difference between no such
* user and wrong password ) */
nt_status = auth_nt_status_squash ( nt_status ) ;
2005-07-11 03:25:42 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2006-01-10 12:21:13 +03:00
mprSetPropertyValue ( auth , " report " ,
2006-01-14 10:46:04 +03:00
mprString ( talloc_strdup ( mprMemCtx ( ) , get_friendly_nt_error_msg ( nt_status ) ) ) ) ;
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2005-12-14 10:22:25 +03:00
goto done ;
}
2008-02-21 20:21:44 +03:00
nt_status = auth_generate_session_info ( tmp_ctx , mprLpCtx ( ) , server_info , & session_info ) ;
2005-12-14 10:22:25 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
mprSetPropertyValue ( auth , " report " , mprString ( " Session Info generation failed " ) ) ;
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2005-07-11 03:25:42 +04:00
goto done ;
}
2007-07-19 11:48:26 +04:00
if ( security_token_has_nt_authenticated_users ( session_info - > security_token ) ) {
mprSetPropertyValue ( auth , " user_class " , mprString ( " USER " ) ) ;
set = true ;
}
if ( security_token_has_builtin_administrators ( session_info - > security_token ) ) {
mprSetPropertyValue ( auth , " user_class " , mprString ( " ADMINISTRATOR " ) ) ;
set = true ;
}
if ( security_token_is_system ( session_info - > security_token ) ) {
mprSetPropertyValue ( auth , " user_class " , mprString ( " SYSTEM " ) ) ;
set = true ;
}
if ( security_token_is_anonymous ( session_info - > security_token ) ) {
mprSetPropertyValue ( auth , " report " , mprString ( " Anonymous login not permitted " ) ) ;
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2007-07-19 11:48:26 +04:00
goto done ;
}
if ( ! set ) {
mprSetPropertyValue ( auth , " report " , mprString ( " Session Info generation failed " ) ) ;
2007-10-07 02:28:14 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( false ) ) ;
2007-07-19 11:48:26 +04:00
}
2006-01-10 13:35:47 +03:00
session_info_obj = mprInitObject ( eid , " session_info " , 0 , NULL ) ;
mprSetPtrChild ( session_info_obj , " session_info " , session_info ) ;
2005-12-14 10:22:25 +03:00
talloc_steal ( mprMemCtx ( ) , session_info ) ;
2006-01-10 13:35:47 +03:00
mprSetProperty ( auth , " session_info " , session_info_obj ) ;
2005-07-11 03:25:42 +04:00
mprSetPropertyValue ( auth , " result " , mprCreateBoolVar ( server_info - > authenticated ) ) ;
2005-07-12 09:53:51 +04:00
mprSetPropertyValue ( auth , " username " , mprString ( server_info - > account_name ) ) ;
mprSetPropertyValue ( auth , " domain " , mprString ( server_info - > domain_name ) ) ;
2005-07-11 03:25:42 +04:00
done :
return 0 ;
}
/*
perform user authentication , returning an array of results
*/
static int ejs_userAuth ( MprVarHandle eid , int argc , struct MprVar * * argv )
{
TALLOC_CTX * tmp_ctx ;
const char * username ;
const char * password ;
const char * domain ;
2006-01-10 01:12:53 +03:00
const char * workstation ;
2005-08-23 06:05:53 +04:00
struct MprVar auth ;
2005-08-22 18:32:58 +04:00
struct cli_credentials * creds ;
2006-01-10 12:21:13 +03:00
struct socket_address * remote_host ;
2006-01-18 14:25:30 +03:00
const char * auth_types_unix [ ] = { " unix " , NULL } ;
2005-07-11 03:25:42 +04:00
2006-01-10 12:21:13 +03:00
if ( argc ! = 2 | | argv [ 0 ] - > type ! = MPR_TYPE_OBJECT | | argv [ 1 ] - > type ! = MPR_TYPE_OBJECT ) {
2005-07-11 03:25:42 +04:00
ejsSetErrorMsg ( eid , " userAuth invalid arguments, this function requires an object. " ) ;
return - 1 ;
}
2005-08-22 18:32:58 +04:00
/* get credential values from credentials object */
creds = mprGetPtr ( argv [ 0 ] , " creds " ) ;
2005-08-23 06:05:53 +04:00
if ( creds = = NULL ) {
2006-01-10 12:21:13 +03:00
ejsSetErrorMsg ( eid , " userAuth requires a 'creds' first parameter " ) ;
return - 1 ;
}
2007-09-08 17:27:14 +04:00
remote_host = ( struct socket_address * ) mprGetPtr ( argv [ 1 ] , " socket_address " ) ;
2006-01-10 12:21:13 +03:00
if ( remote_host = = NULL ) {
ejsSetErrorMsg ( eid , " userAuth requires a socket address second parameter " ) ;
2005-08-23 06:05:53 +04:00
return - 1 ;
}
2005-08-29 23:08:18 +04:00
tmp_ctx = talloc_new ( mprMemCtx ( ) ) ;
2005-09-22 05:50:58 +04:00
username = cli_credentials_get_username ( creds ) ;
2005-08-22 18:32:58 +04:00
password = cli_credentials_get_password ( creds ) ;
domain = cli_credentials_get_domain ( creds ) ;
2006-01-10 01:12:53 +03:00
workstation = cli_credentials_get_workstation ( creds ) ;
2005-07-11 03:25:42 +04:00
2005-07-20 09:41:29 +04:00
if ( username = = NULL | | password = = NULL | | domain = = NULL ) {
mpr_Return ( eid , mprCreateUndefinedVar ( ) ) ;
2005-08-29 23:08:18 +04:00
talloc_free ( tmp_ctx ) ;
2005-07-20 09:41:29 +04:00
return 0 ;
}
2005-07-11 14:18:26 +04:00
auth = mprObject ( " auth " ) ;
2005-07-11 03:25:42 +04:00
2006-01-10 12:21:13 +03:00
if ( domain & & ( strcmp ( " SYSTEM USER " , domain ) = = 0 ) ) {
2006-01-18 14:25:30 +03:00
ejs_doauth ( eid , tmp_ctx , & auth , username , password , domain , workstation , remote_host , auth_types_unix ) ;
2005-07-20 08:27:09 +04:00
} else {
2007-07-12 08:56:33 +04:00
ejs_doauth ( eid , tmp_ctx , & auth , username , password , domain , workstation , remote_host , NULL ) ;
2005-07-11 03:25:42 +04:00
}
mpr_Return ( eid , auth ) ;
talloc_free ( tmp_ctx ) ;
return 0 ;
}
2006-01-07 00:04:32 +03:00
/*
initialise credentials ejs object
*/
static int ejs_system_session ( MprVarHandle eid , int argc , struct MprVar * * argv )
{
struct MprVar * obj = mprInitObject ( eid , " session_info " , argc , argv ) ;
2008-02-21 20:21:44 +03:00
struct auth_session_info * session_info = system_session ( mprMemCtx ( ) , mprLpCtx ( ) ) ;
2006-01-07 00:04:32 +03:00
if ( session_info = = NULL ) {
return - 1 ;
}
mprSetPtrChild ( obj , " session_info " , session_info ) ;
return 0 ;
}
2005-07-11 03:25:42 +04:00
/*
setup C functions that be called from ejs
*/
2006-05-20 07:08:44 +04:00
NTSTATUS smb_setup_ejs_auth ( void )
2005-07-11 03:25:42 +04:00
{
ejsDefineCFunction ( - 1 , " userAuth " , ejs_userAuth , NULL , MPR_VAR_SCRIPT_HANDLE ) ;
2006-01-07 00:04:32 +03:00
ejsDefineCFunction ( - 1 , " system_session " , ejs_system_session , NULL , MPR_VAR_SCRIPT_HANDLE ) ;
2006-05-20 07:08:44 +04:00
return NT_STATUS_OK ;
2005-07-11 03:25:42 +04:00
}