0001-01-01 02:30:17 +02:30
/*
0001-01-01 02:30:17 +02:30
* Unix SMB / CIFS implementation .
0001-01-01 02:30:17 +02:30
* RPC Pipe client / server routines
* Copyright ( C ) Andrew Tridgell 1992 - 1997 ,
* Copyright ( C ) Luke Kenneth Casson Leighton 1996 - 1997 ,
* Copyright ( C ) Paul Ashton 1997.
* Copyright ( C ) Hewlett - Packard Company 1999.
* Copyright ( C ) Jeremy Allison 2001.
*
* 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
* the Free Software Foundation ; either version 2 of the License , or
* ( 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
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/* Implementation of registry functions. */
# include "includes.h"
0001-01-01 02:30:17 +02:30
struct reg_info {
/* for use by \PIPE\winreg */
fstring name ; /* name of registry key */
0001-01-01 02:30:17 +02:30
} ;
static void free_reg_info ( void * ptr )
{
struct reg_info * info = ( struct reg_info * ) ptr ;
0001-01-01 02:30:17 +02:30
SAFE_FREE ( info ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/*******************************************************************
reg_reply_unknown_1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_close ( pipes_struct * p , REG_Q_CLOSE * q_u , REG_R_CLOSE * r_u )
0001-01-01 02:30:17 +02:30
{
/* set up the REG unknown_1 response */
0001-01-01 02:30:17 +02:30
ZERO_STRUCT ( r_u - > pol ) ;
0001-01-01 02:30:17 +02:30
/* close the policy handle */
0001-01-01 02:30:17 +02:30
if ( ! close_policy_hnd ( p , & q_u - > pol ) )
0001-01-01 02:30:17 +02:30
return NT_STATUS_OBJECT_NAME_INVALID ;
0001-01-01 02:30:17 +02:30
return NT_STATUS_OK ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
reg_reply_open
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_open ( pipes_struct * p , REG_Q_OPEN_HKLM * q_u , REG_R_OPEN_HKLM * r_u )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
if ( ! create_policy_hnd ( p , & r_u - > pol , free_reg_info , NULL ) )
0001-01-01 02:30:17 +02:30
return NT_STATUS_OBJECT_NAME_NOT_FOUND ;
0001-01-01 02:30:17 +02:30
return NT_STATUS_OK ;
0001-01-01 02:30:17 +02:30
}
/*******************************************************************
reg_reply_open_entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_open_entry ( pipes_struct * p , REG_Q_OPEN_ENTRY * q_u , REG_R_OPEN_ENTRY * r_u )
0001-01-01 02:30:17 +02:30
{
POLICY_HND pol ;
fstring name ;
0001-01-01 02:30:17 +02:30
struct reg_info * info = NULL ;
0001-01-01 02:30:17 +02:30
DEBUG ( 5 , ( " reg_open_entry: %d \n " , __LINE__ ) ) ;
0001-01-01 02:30:17 +02:30
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
0001-01-01 02:30:17 +02:30
return NT_STATUS_INVALID_HANDLE ;
0001-01-01 02:30:17 +02:30
rpcstr_pull ( name , q_u - > uni_name . buffer , sizeof ( name ) , q_u - > uni_name . uni_str_len * 2 , 0 ) ;
0001-01-01 02:30:17 +02:30
DEBUG ( 5 , ( " reg_open_entry: %s \n " , name ) ) ;
/* lkcl XXXX do a check on the name, here */
if ( ! strequal ( name , " SYSTEM \\ CurrentControlSet \\ Control \\ ProductOptions " ) & &
! strequal ( name , " System \\ CurrentControlSet \\ services \\ Netlogon \\ parameters \\ " ) )
return NT_STATUS_ACCESS_DENIED ;
0001-01-01 02:30:17 +02:30
if ( ( info = ( struct reg_info * ) malloc ( sizeof ( struct reg_info ) ) ) = = NULL )
return NT_STATUS_NO_MEMORY ;
ZERO_STRUCTP ( info ) ;
fstrcpy ( info - > name , name ) ;
if ( ! create_policy_hnd ( p , & pol , free_reg_info , ( void * ) info ) )
0001-01-01 02:30:17 +02:30
return NT_STATUS_TOO_MANY_SECRETS ; /* ha ha very droll */
0001-01-01 02:30:17 +02:30
init_reg_r_open_entry ( r_u , & pol , NT_STATUS_OK ) ;
0001-01-01 02:30:17 +02:30
DEBUG ( 5 , ( " reg_open_entry: %d \n " , __LINE__ ) ) ;
return r_u - > status ;
}
/*******************************************************************
reg_reply_info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_info ( pipes_struct * p , REG_Q_INFO * q_u , REG_R_INFO * r_u )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
NTSTATUS status = NT_STATUS_OK ;
0001-01-01 02:30:17 +02:30
char * key = NULL ;
0001-01-01 02:30:17 +02:30
uint32 type = 0x1 ; /* key type: REG_SZ */
0001-01-01 02:30:17 +02:30
UNISTR2 * uni_key = NULL ;
BUFFER2 * buf = NULL ;
0001-01-01 02:30:17 +02:30
fstring name ;
DEBUG ( 5 , ( " _reg_info: %d \n " , __LINE__ ) ) ;
0001-01-01 02:30:17 +02:30
if ( ! find_policy_by_hnd ( p , & q_u - > pol , NULL ) )
0001-01-01 02:30:17 +02:30
return NT_STATUS_INVALID_HANDLE ;
0001-01-01 02:30:17 +02:30
rpcstr_pull ( name , q_u - > uni_type . buffer , sizeof ( name ) , q_u - > uni_type . uni_str_len * 2 , 0 ) ;
0001-01-01 02:30:17 +02:30
DEBUG ( 5 , ( " reg_info: checking key: %s \n " , name ) ) ;
0001-01-01 02:30:17 +02:30
uni_key = ( UNISTR2 * ) talloc_zero ( p - > mem_ctx , sizeof ( UNISTR2 ) ) ;
buf = ( BUFFER2 * ) talloc_zero ( p - > mem_ctx , sizeof ( BUFFER2 ) ) ;
if ( ! uni_key | | ! buf )
return NT_STATUS_NO_MEMORY ;
0001-01-01 02:30:17 +02:30
if ( strequal ( name , " RefusePasswordChange " ) ) {
type = 0xF770 ;
0001-01-01 02:30:17 +02:30
status = NT_STATUS_NO_SUCH_FILE ;
0001-01-01 02:30:17 +02:30
init_unistr2 ( uni_key , " " , 0 ) ;
init_buffer2 ( buf , ( uint8 * ) uni_key - > buffer , uni_key - > uni_str_len * 2 ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
buf - > buf_max_len = 4 ;
0001-01-01 02:30:17 +02:30
goto out ;
}
switch ( lp_server_role ( ) ) {
case ROLE_DOMAIN_PDC :
case ROLE_DOMAIN_BDC :
key = " LanmanNT " ;
break ;
case ROLE_STANDALONE :
key = " ServerNT " ;
break ;
case ROLE_DOMAIN_MEMBER :
key = " WinNT " ;
break ;
}
/* This makes the server look like a member server to clients */
/* which tells clients that we have our own local user and */
/* group databases and helps with ACL support. */
0001-01-01 02:30:17 +02:30
init_unistr2 ( uni_key , key , strlen ( key ) + 1 ) ;
init_buffer2 ( buf , ( uint8 * ) uni_key - > buffer , uni_key - > uni_str_len * 2 ) ;
0001-01-01 02:30:17 +02:30
out :
0001-01-01 02:30:17 +02:30
init_reg_r_info ( q_u - > ptr_buf , r_u , buf , type , status ) ;
0001-01-01 02:30:17 +02:30
DEBUG ( 5 , ( " reg_open_entry: %d \n " , __LINE__ ) ) ;
return status ;
}
0001-01-01 02:30:17 +02:30
/*******************************************************************
reg_shutdwon
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# define SHUTDOWN_R_STRING "-r"
# define SHUTDOWN_F_STRING "-f"
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_shutdown ( pipes_struct * p , REG_Q_SHUTDOWN * q_u , REG_R_SHUTDOWN * r_u )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
NTSTATUS status = NT_STATUS_OK ;
0001-01-01 02:30:17 +02:30
pstring shutdown_script ;
UNISTR2 unimsg = q_u - > uni_msg ;
pstring message ;
0001-01-01 02:30:17 +02:30
pstring chkmsg ;
0001-01-01 02:30:17 +02:30
fstring timeout ;
fstring r ;
fstring f ;
0001-01-01 02:30:17 +02:30
/* message */
0001-01-01 02:30:17 +02:30
rpcstr_pull ( message , unimsg . buffer , sizeof ( message ) , unimsg . uni_str_len * 2 , 0 ) ;
0001-01-01 02:30:17 +02:30
/* security check */
0001-01-01 02:30:17 +02:30
alpha_strcpy ( chkmsg , message , NULL , sizeof ( message ) ) ;
0001-01-01 02:30:17 +02:30
/* timeout */
0001-01-01 02:30:17 +02:30
snprintf ( timeout , sizeof ( timeout ) , " %d " , q_u - > timeout ) ;
0001-01-01 02:30:17 +02:30
/* reboot */
0001-01-01 02:30:17 +02:30
snprintf ( r , sizeof ( r ) , ( q_u - > flags & REG_REBOOT_ON_SHUTDOWN ) ? SHUTDOWN_R_STRING : " " ) ;
0001-01-01 02:30:17 +02:30
/* force */
0001-01-01 02:30:17 +02:30
snprintf ( f , sizeof ( f ) , ( q_u - > flags & REG_FORCE_SHUTDOWN ) ? SHUTDOWN_F_STRING : " " ) ;
0001-01-01 02:30:17 +02:30
pstrcpy ( shutdown_script , lp_shutdown_script ( ) ) ;
if ( * shutdown_script ) {
int shutdown_ret ;
0001-01-01 02:30:17 +02:30
all_string_sub ( shutdown_script , " %m " , chkmsg , sizeof ( shutdown_script ) ) ;
0001-01-01 02:30:17 +02:30
all_string_sub ( shutdown_script , " %t " , timeout , sizeof ( shutdown_script ) ) ;
all_string_sub ( shutdown_script , " %r " , r , sizeof ( shutdown_script ) ) ;
all_string_sub ( shutdown_script , " %f " , f , sizeof ( shutdown_script ) ) ;
shutdown_ret = smbrun ( shutdown_script , NULL ) ;
DEBUG ( 3 , ( " _reg_shutdown: Running the command `%s' gave %d \n " , shutdown_script , shutdown_ret ) ) ;
}
return status ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
NTSTATUS _reg_abort_shutdown ( pipes_struct * p , REG_Q_ABORT_SHUTDOWN * q_u , REG_R_ABORT_SHUTDOWN * r_u )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
NTSTATUS status = NT_STATUS_OK ;
0001-01-01 02:30:17 +02:30
pstring abort_shutdown_script ;
pstrcpy ( abort_shutdown_script , lp_abort_shutdown_script ( ) ) ;
if ( * abort_shutdown_script ) {
int abort_shutdown_ret ;
abort_shutdown_ret = smbrun ( abort_shutdown_script , NULL ) ;
DEBUG ( 3 , ( " _reg_abort_shutdown: Running the command `%s' gave %d \n " , abort_shutdown_script , abort_shutdown_ret ) ) ;
}
return status ;
}