2007-12-11 21:21:17 +01:00
/*
* Unix SMB / CIFS implementation .
* libnet smbconf registry Support
* Copyright ( C ) Michael Adam 2007
* Copyright ( C ) Guenther Deschner 2007
*
* 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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2007-12-23 03:47:16 +01:00
/**********************************************************************
*
* Helper functions ( mostly registry related )
* TODO : These should be eventually static .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-11 21:21:17 +01:00
/*
* Open a subkey of KEY_SMBCONF ( i . e a service )
*/
2007-12-26 00:53:19 +01:00
WERROR libnet_smbconf_open_path ( TALLOC_CTX * ctx ,
const char * subkeyname ,
uint32 desired_access ,
struct registry_key * * key )
2007-12-11 21:21:17 +01:00
{
WERROR werr = WERR_OK ;
char * path = NULL ;
NT_USER_TOKEN * token ;
if ( ! ( token = registry_create_admin_token ( ctx ) ) ) {
DEBUG ( 1 , ( " Error creating admin token \n " ) ) ;
goto done ;
}
if ( subkeyname = = NULL ) {
path = talloc_strdup ( ctx , KEY_SMBCONF ) ;
} else {
path = talloc_asprintf ( ctx , " %s \\ %s " , KEY_SMBCONF , subkeyname ) ;
}
werr = reg_open_path ( ctx , path , desired_access ,
token , key ) ;
2007-12-26 00:53:19 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
DEBUG ( 1 , ( " Error opening registry path '%s': %s \n " ,
path , dos_errstr ( werr ) ) ) ;
}
2007-12-11 21:21:17 +01:00
done :
TALLOC_FREE ( path ) ;
return werr ;
}
/*
* check if a subkey of KEY_SMBCONF of a given name exists
*/
2007-12-24 00:53:22 +01:00
bool libnet_smbconf_key_exists ( const char * subkeyname )
2007-12-11 21:21:17 +01:00
{
2007-12-24 00:57:04 +01:00
bool ret = false ;
2007-12-11 21:21:17 +01:00
WERROR werr = WERR_OK ;
2007-12-24 00:53:22 +01:00
TALLOC_CTX * mem_ctx = talloc_stackframe ( ) ;
struct registry_key * key = NULL ;
2007-12-11 21:21:17 +01:00
2007-12-26 00:53:19 +01:00
werr = libnet_smbconf_open_path ( mem_ctx , subkeyname , REG_KEY_READ , & key ) ;
2007-12-11 21:21:17 +01:00
if ( W_ERROR_IS_OK ( werr ) ) {
2007-12-24 00:57:04 +01:00
ret = true ;
2007-12-11 21:21:17 +01:00
}
TALLOC_FREE ( mem_ctx ) ;
return ret ;
}
2007-12-24 00:56:24 +01:00
static bool libnet_smbconf_value_exists ( struct registry_key * key ,
2007-12-23 03:47:16 +01:00
const char * param )
{
2007-12-24 00:57:04 +01:00
bool ret = false ;
2007-12-23 03:47:16 +01:00
WERROR werr = WERR_OK ;
2007-12-24 00:56:24 +01:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
2007-12-23 03:47:16 +01:00
struct registry_value * value = NULL ;
werr = reg_queryvalue ( ctx , key , param , & value ) ;
if ( W_ERROR_IS_OK ( werr ) ) {
2007-12-24 00:57:04 +01:00
ret = true ;
2007-12-23 03:47:16 +01:00
}
2007-12-24 00:56:24 +01:00
TALLOC_FREE ( ctx ) ;
2007-12-23 03:47:16 +01:00
return ret ;
}
2007-12-11 21:21:17 +01:00
/*
* open the base key KEY_SMBCONF
*/
WERROR libnet_smbconf_open_basepath ( TALLOC_CTX * ctx , uint32 desired_access ,
struct registry_key * * key )
{
return libnet_smbconf_open_path ( ctx , NULL , desired_access , key ) ;
}
/*
* create a subkey of KEY_SMBCONF
*/
2007-12-23 04:10:15 +01:00
WERROR libnet_smbconf_reg_createkey_internal ( TALLOC_CTX * ctx ,
const char * subkeyname ,
struct registry_key * * newkey )
2007-12-11 21:21:17 +01:00
{
WERROR werr = WERR_OK ;
struct registry_key * create_parent = NULL ;
TALLOC_CTX * create_ctx ;
enum winreg_CreateAction action = REG_ACTION_NONE ;
/* create a new talloc ctx for creation. it will hold
* the intermediate parent key ( SMBCONF ) for creation
* and will be destroyed when leaving this function . . . */
if ( ! ( create_ctx = talloc_new ( ctx ) ) ) {
werr = WERR_NOMEM ;
goto done ;
}
werr = libnet_smbconf_open_basepath ( create_ctx , REG_KEY_WRITE , & create_parent ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = reg_createkey ( ctx , create_parent , subkeyname ,
REG_KEY_WRITE , newkey , & action ) ;
if ( W_ERROR_IS_OK ( werr ) & & ( action ! = REG_CREATED_NEW_KEY ) ) {
d_fprintf ( stderr , " Key '%s' already exists. \n " , subkeyname ) ;
werr = WERR_ALREADY_EXISTS ;
}
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr , " Error creating key %s: %s \n " ,
subkeyname , dos_errstr ( werr ) ) ;
}
done :
TALLOC_FREE ( create_ctx ) ;
return werr ;
}
2007-12-23 03:34:36 +01:00
/*
* add a value to a key .
*/
WERROR libnet_smbconf_reg_setvalue_internal ( struct registry_key * key ,
const char * valname ,
const char * valstr )
{
struct registry_value val ;
WERROR werr = WERR_OK ;
char * subkeyname ;
const char * canon_valname ;
const char * canon_valstr ;
if ( ! lp_canonicalize_parameter_with_value ( valname , valstr ,
& canon_valname ,
& canon_valstr ) )
{
if ( canon_valname = = NULL ) {
d_fprintf ( stderr , " invalid parameter '%s' given \n " ,
valname ) ;
} else {
d_fprintf ( stderr , " invalid value '%s' given for "
" parameter '%s' \n " , valstr , valname ) ;
}
werr = WERR_INVALID_PARAM ;
goto done ;
}
ZERO_STRUCT ( val ) ;
val . type = REG_SZ ;
val . v . sz . str = CONST_DISCARD ( char * , canon_valstr ) ;
val . v . sz . len = strlen ( canon_valstr ) + 1 ;
if ( registry_smbconf_valname_forbidden ( canon_valname ) ) {
d_fprintf ( stderr , " Parameter '%s' not allowed in registry. \n " ,
canon_valname ) ;
werr = WERR_INVALID_PARAM ;
goto done ;
}
subkeyname = strrchr_m ( key - > key - > name , ' \\ ' ) ;
if ( ( subkeyname = = NULL ) | | ( * ( subkeyname + 1 ) = = ' \0 ' ) ) {
d_fprintf ( stderr , " Invalid registry key '%s' given as "
" smbconf section. \n " , key - > key - > name ) ;
werr = WERR_INVALID_PARAM ;
goto done ;
}
subkeyname + + ;
if ( ! strequal ( subkeyname , GLOBAL_NAME ) & &
lp_parameter_is_global ( valname ) )
{
d_fprintf ( stderr , " Global paramter '%s' not allowed in "
" service definition ('%s'). \n " , canon_valname ,
subkeyname ) ;
werr = WERR_INVALID_PARAM ;
goto done ;
}
werr = reg_setvalue ( key , canon_valname , & val ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
d_fprintf ( stderr ,
" Error adding value '%s' to "
" key '%s': %s \n " ,
canon_valname , key - > key - > name , dos_errstr ( werr ) ) ;
}
done :
return werr ;
}
2007-12-23 03:47:16 +01:00
/**********************************************************************
*
* The actual net conf api functions , that are exported .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-25 03:08:00 +01:00
/**
* Drop the whole configuration ( restarting empty ) .
*/
2007-12-25 03:05:06 +01:00
WERROR libnet_smbconf_drop ( void )
2007-12-25 02:55:07 +01:00
{
char * path , * p ;
WERROR werr = WERR_OK ;
NT_USER_TOKEN * token ;
struct registry_key * parent_key = NULL ;
struct registry_key * new_key = NULL ;
2007-12-25 03:05:06 +01:00
TALLOC_CTX * mem_ctx = talloc_stackframe ( ) ;
2007-12-25 02:55:07 +01:00
enum winreg_CreateAction action ;
2007-12-25 03:05:06 +01:00
if ( ! ( token = registry_create_admin_token ( mem_ctx ) ) ) {
2007-12-25 02:55:07 +01:00
/* what is the appropriate error code here? */
werr = WERR_CAN_NOT_COMPLETE ;
goto done ;
}
2007-12-25 03:05:06 +01:00
path = talloc_strdup ( mem_ctx , KEY_SMBCONF ) ;
2007-12-25 02:55:07 +01:00
if ( path = = NULL ) {
werr = WERR_NOMEM ;
goto done ;
}
p = strrchr ( path , ' \\ ' ) ;
* p = ' \0 ' ;
2007-12-25 03:05:06 +01:00
werr = reg_open_path ( mem_ctx , path , REG_KEY_WRITE , token , & parent_key ) ;
2007-12-25 02:55:07 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-25 03:05:06 +01:00
werr = reg_deletekey_recursive ( mem_ctx , parent_key , p + 1 ) ;
2007-12-25 02:55:07 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-25 03:05:06 +01:00
werr = reg_createkey ( mem_ctx , parent_key , p + 1 , REG_KEY_WRITE ,
2007-12-25 02:55:07 +01:00
& new_key , & action ) ;
done :
2007-12-25 03:05:06 +01:00
TALLOC_FREE ( mem_ctx ) ;
2007-12-25 02:55:07 +01:00
return werr ;
}
2007-12-25 02:24:39 +01:00
/**
* delete a service from configuration
2007-12-25 02:21:30 +01:00
*/
2007-12-25 02:31:41 +01:00
WERROR libnet_smbconf_delshare ( const char * servicename )
2007-12-25 02:21:30 +01:00
{
WERROR werr = WERR_OK ;
struct registry_key * key = NULL ;
2007-12-25 02:31:41 +01:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
2007-12-25 02:21:30 +01:00
werr = libnet_smbconf_open_basepath ( ctx , REG_KEY_WRITE , & key ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-25 02:31:41 +01:00
werr = reg_deletekey_recursive ( key , key , servicename ) ;
2007-12-25 02:21:30 +01:00
done :
2007-12-25 02:31:41 +01:00
TALLOC_FREE ( ctx ) ;
2007-12-25 02:21:30 +01:00
return werr ;
}
2007-12-25 03:29:05 +01:00
WERROR libnet_smbconf_setparm ( const char * service ,
2007-12-23 03:41:55 +01:00
const char * param ,
const char * valstr )
{
WERROR werr ;
struct registry_key * key = NULL ;
2007-12-25 03:29:05 +01:00
TALLOC_CTX * mem_ctx = talloc_stackframe ( ) ;
2007-12-23 03:41:55 +01:00
2007-12-24 00:53:22 +01:00
if ( ! libnet_smbconf_key_exists ( service ) ) {
2007-12-23 04:10:15 +01:00
werr = libnet_smbconf_reg_createkey_internal ( mem_ctx , service ,
& key ) ;
2007-12-23 03:41:55 +01:00
} else {
werr = libnet_smbconf_open_path ( mem_ctx , service , REG_KEY_WRITE ,
& key ) ;
}
2007-12-24 01:00:46 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-23 03:41:55 +01:00
werr = libnet_smbconf_reg_setvalue_internal ( key , param , valstr ) ;
2007-12-24 01:00:46 +01:00
done :
2007-12-25 03:29:05 +01:00
TALLOC_FREE ( mem_ctx ) ;
2007-12-23 03:41:55 +01:00
return werr ;
}
2007-12-23 15:07:20 +01:00
WERROR libnet_smbconf_getparm ( TALLOC_CTX * mem_ctx ,
const char * service ,
const char * param ,
struct registry_value * * value )
{
WERROR werr ;
struct registry_key * key = NULL ;
2007-12-24 00:53:22 +01:00
if ( ! libnet_smbconf_key_exists ( service ) ) {
2007-12-24 00:47:43 +01:00
werr = WERR_NO_SUCH_SERVICE ;
goto done ;
2007-12-23 15:07:20 +01:00
}
werr = libnet_smbconf_open_path ( mem_ctx , service , REG_KEY_READ , & key ) ;
2007-12-24 00:47:43 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-23 15:07:20 +01:00
2007-12-24 00:56:24 +01:00
if ( ! libnet_smbconf_value_exists ( key , param ) ) {
2007-12-24 00:47:43 +01:00
werr = WERR_INVALID_PARAM ;
goto done ;
2007-12-23 15:07:20 +01:00
}
werr = reg_queryvalue ( mem_ctx , key , param , value ) ;
2007-12-24 00:47:43 +01:00
done :
TALLOC_FREE ( key ) ;
2007-12-23 15:07:20 +01:00
return werr ;
}
2007-12-25 03:34:04 +01:00
WERROR libnet_smbconf_delparm ( const char * service ,
2007-12-23 02:55:25 +01:00
const char * param )
{
struct registry_key * key = NULL ;
WERROR werr = WERR_OK ;
2007-12-25 03:34:04 +01:00
TALLOC_CTX * mem_ctx = talloc_stackframe ( ) ;
2007-12-23 02:55:25 +01:00
2007-12-24 00:53:22 +01:00
if ( ! libnet_smbconf_key_exists ( service ) ) {
2007-12-23 02:55:25 +01:00
return WERR_NO_SUCH_SERVICE ;
}
2007-12-23 23:58:58 +01:00
werr = libnet_smbconf_open_path ( mem_ctx , service , REG_KEY_ALL , & key ) ;
2007-12-24 01:03:14 +01:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2007-12-23 02:55:25 +01:00
2007-12-24 00:56:24 +01:00
if ( ! libnet_smbconf_value_exists ( key , param ) ) {
2007-12-24 01:03:14 +01:00
werr = WERR_INVALID_PARAM ;
goto done ;
2007-12-23 02:55:25 +01:00
}
werr = reg_deletevalue ( key , param ) ;
2007-12-24 01:03:14 +01:00
done :
2007-12-25 03:34:04 +01:00
TALLOC_FREE ( mem_ctx ) ;
2007-12-23 23:02:47 +01:00
return werr ;
2007-12-23 02:55:25 +01:00
}
2007-12-23 03:52:00 +01:00
/**********************************************************************
*
2007-12-25 03:16:25 +01:00
* Convenience functions that are also exported .
2007-12-23 03:52:00 +01:00
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-25 03:29:05 +01:00
WERROR libnet_smbconf_set_global_param ( const char * param ,
2007-12-23 03:52:00 +01:00
const char * val )
{
2007-12-25 03:29:05 +01:00
return libnet_smbconf_setparm ( GLOBAL_NAME , param , val ) ;
2007-12-23 03:52:00 +01:00
}