2007-12-11 21:21:17 +01:00
/*
* Unix SMB / CIFS implementation .
2008-04-07 15:12:44 +02:00
* libsmbconf - Samba configuration library
2008-01-03 00:44:47 +01:00
* Copyright ( C ) Michael Adam 2007 - 2008
2007-12-11 21:21:17 +01:00
* 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"
2008-03-19 12:37:17 +01:00
# include "smbconf_private.h"
2007-12-11 21:21:17 +01:00
2007-12-23 03:47:16 +01:00
/**********************************************************************
*
2008-03-21 16:40:20 +01:00
* internal helper functions
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-04-08 15:48:01 +02:00
static sbcErr smbconf_global_check ( struct smbconf_ctx * ctx )
2008-03-21 16:40:20 +01:00
{
if ( ! smbconf_share_exists ( ctx , GLOBAL_NAME ) ) {
return smbconf_create_share ( ctx , GLOBAL_NAME ) ;
}
2011-04-08 15:48:01 +02:00
return SBC_ERR_OK ;
2008-03-21 16:40:20 +01:00
}
/**********************************************************************
*
* The actual libsmbconf API functions that are exported .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-04-07 15:27:52 +02:00
const char * sbcErrorString ( sbcErr error )
{
switch ( error ) {
case SBC_ERR_OK :
return " SBC_ERR_OK " ;
case SBC_ERR_NOT_IMPLEMENTED :
return " SBC_ERR_NOT_IMPLEMENTED " ;
case SBC_ERR_NOT_SUPPORTED :
return " SBC_ERR_NOT_SUPPORTED " ;
case SBC_ERR_UNKNOWN_FAILURE :
return " SBC_ERR_UNKNOWN_FAILURE " ;
case SBC_ERR_NOMEM :
return " SBC_ERR_NOMEM " ;
case SBC_ERR_INVALID_PARAM :
return " SBC_ERR_INVALID_PARAM " ;
case SBC_ERR_BADFILE :
return " SBC_ERR_BADFILE " ;
case SBC_ERR_NO_SUCH_SERVICE :
return " SBC_ERR_NO_SUCH_SERVICE " ;
case SBC_ERR_IO_FAILURE :
return " SBC_ERR_IO_FAILURE " ;
case SBC_ERR_CAN_NOT_COMPLETE :
return " SBC_ERR_CAN_NOT_COMPLETE " ;
case SBC_ERR_NO_MORE_ITEMS :
return " SBC_ERR_NO_MORE_ITEMS " ;
case SBC_ERR_FILE_EXISTS :
return " SBC_ERR_FILE_EXISTS " ;
case SBC_ERR_ACCESS_DENIED :
return " SBC_ERR_ACCESS_DENIED " ;
}
return " unknown sbcErr value " ;
}
2008-10-20 23:52:02 +02:00
/**
* Tell whether the backend requires messaging to be set up
* for the backend to work correctly .
*/
bool smbconf_backend_requires_messaging ( struct smbconf_ctx * ctx )
{
return ctx - > ops - > requires_messaging ( ctx ) ;
}
2008-10-23 11:16:50 +02:00
/**
* Tell whether the source is writeable .
*/
bool smbconf_is_writeable ( struct smbconf_ctx * ctx )
{
return ctx - > ops - > is_writeable ( ctx ) ;
}
2008-01-13 01:40:05 +01:00
/**
* Close the configuration .
*/
2008-03-21 01:04:57 +01:00
void smbconf_shutdown ( struct smbconf_ctx * ctx )
2008-01-13 01:40:05 +01:00
{
2009-01-21 17:10:20 +01:00
talloc_free ( ctx ) ;
2008-01-13 01:40:05 +01:00
}
2008-02-18 18:21:14 +01:00
/**
2008-03-18 23:29:11 +01:00
* Detect changes in the configuration .
* The given csn struct is filled with the current csn .
* smbconf_changed ( ) can also be used for initial retrieval
* of the csn .
2008-02-18 18:21:14 +01:00
*/
2008-03-18 23:29:11 +01:00
bool smbconf_changed ( struct smbconf_ctx * ctx , struct smbconf_csn * csn ,
const char * service , const char * param )
2008-02-18 18:21:14 +01:00
{
2008-03-18 23:29:11 +01:00
struct smbconf_csn old_csn ;
if ( csn = = NULL ) {
return false ;
}
old_csn = * csn ;
2008-03-20 12:28:41 +01:00
ctx - > ops - > get_csn ( ctx , csn , service , param ) ;
2008-03-18 23:29:11 +01:00
return ( csn - > csn ! = old_csn . csn ) ;
2008-02-18 18:21:14 +01:00
}
2007-12-25 03:08:00 +01:00
/**
* Drop the whole configuration ( restarting empty ) .
*/
2011-04-08 10:40:02 +02:00
sbcErr smbconf_drop ( struct smbconf_ctx * ctx )
2007-12-25 02:55:07 +01:00
{
2008-03-20 12:28:41 +01:00
return ctx - > ops - > drop ( ctx ) ;
2007-12-25 02:55:07 +01:00
}
2007-12-29 22:08:11 +01:00
/**
* Get the whole configuration as lists of strings with counts :
*
* num_shares : number of shares
* share_names : list of length num_shares of share names
* num_params : list of length num_shares of parameter counts for each share
* param_names : list of lists of parameter names for each share
* param_values : list of lists of parameter values for each share
*/
2011-04-11 17:43:10 +02:00
sbcErr smbconf_get_config ( struct smbconf_ctx * ctx ,
2008-03-19 10:47:23 +01:00
TALLOC_CTX * mem_ctx ,
uint32_t * num_shares ,
2008-04-22 16:31:16 +02:00
struct smbconf_service * * * services )
2007-12-29 22:08:11 +01:00
{
2011-04-08 14:19:15 +02:00
sbcErr err ;
2007-12-29 22:08:11 +01:00
TALLOC_CTX * tmp_ctx = NULL ;
uint32_t tmp_num_shares ;
char * * tmp_share_names ;
2008-04-22 16:31:16 +02:00
struct smbconf_service * * tmp_services ;
2007-12-29 22:08:11 +01:00
uint32_t count ;
2008-04-22 16:31:16 +02:00
if ( ( num_shares = = NULL ) | | ( services = = NULL ) ) {
2011-04-11 17:43:10 +02:00
err = SBC_ERR_INVALID_PARAM ;
2007-12-29 22:08:11 +01:00
goto done ;
}
2008-01-21 15:28:04 +01:00
tmp_ctx = talloc_stackframe ( ) ;
2007-12-29 22:08:11 +01:00
2011-04-08 14:19:15 +02:00
err = smbconf_get_share_names ( ctx , tmp_ctx , & tmp_num_shares ,
& tmp_share_names ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2007-12-29 22:08:11 +01:00
goto done ;
}
2009-01-21 18:50:16 +01:00
tmp_services = talloc_array ( tmp_ctx , struct smbconf_service * ,
2008-04-22 16:31:16 +02:00
tmp_num_shares ) ;
if ( tmp_services = = NULL ) {
2011-04-11 17:43:10 +02:00
err = SBC_ERR_NOMEM ;
2007-12-29 22:08:11 +01:00
goto done ;
}
for ( count = 0 ; count < tmp_num_shares ; count + + ) {
2011-04-08 17:20:35 +02:00
err = smbconf_get_share ( ctx , tmp_services ,
tmp_share_names [ count ] ,
& tmp_services [ count ] ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2007-12-29 22:08:11 +01:00
goto done ;
}
}
2011-04-11 17:43:10 +02:00
err = SBC_ERR_OK ;
2007-12-29 22:08:11 +01:00
* num_shares = tmp_num_shares ;
if ( tmp_num_shares > 0 ) {
2008-04-22 16:31:16 +02:00
* services = talloc_move ( mem_ctx , & tmp_services ) ;
2007-12-29 22:08:11 +01:00
} else {
2008-04-22 16:31:16 +02:00
* services = NULL ;
2007-12-29 22:08:11 +01:00
}
done :
2009-01-21 17:10:20 +01:00
talloc_free ( tmp_ctx ) ;
2011-04-11 17:43:10 +02:00
return err ;
2007-12-29 22:08:11 +01:00
}
2007-12-29 12:53:19 +01:00
/**
* get the list of share names defined in the configuration .
*/
2011-04-08 14:19:15 +02:00
sbcErr smbconf_get_share_names ( struct smbconf_ctx * ctx ,
2008-03-19 10:47:23 +01:00
TALLOC_CTX * mem_ctx ,
2008-03-17 18:01:33 +01:00
uint32_t * num_shares ,
char * * * share_names )
2007-12-29 12:52:09 +01:00
{
2008-03-20 12:28:41 +01:00
return ctx - > ops - > get_share_names ( ctx , mem_ctx , num_shares ,
share_names ) ;
2007-12-29 12:52:09 +01:00
}
2007-12-31 01:14:44 +01:00
/**
* check if a share / service of a given name exists
*/
2008-03-17 18:01:33 +01:00
bool smbconf_share_exists ( struct smbconf_ctx * ctx ,
const char * servicename )
2007-12-31 01:14:44 +01:00
{
2008-03-20 12:28:41 +01:00
return ctx - > ops - > share_exists ( ctx , servicename ) ;
2007-12-31 01:14:44 +01:00
}
2008-01-03 11:30:14 +01:00
/**
* Add a service if it does not already exist .
*/
2011-04-08 15:48:01 +02:00
sbcErr smbconf_create_share ( struct smbconf_ctx * ctx ,
2008-03-17 18:01:33 +01:00
const char * servicename )
2008-01-03 11:30:14 +01:00
{
2008-04-15 17:37:39 +02:00
if ( ( servicename ! = NULL ) & & smbconf_share_exists ( ctx , servicename ) ) {
2011-04-08 15:48:01 +02:00
return SBC_ERR_FILE_EXISTS ;
2008-01-03 11:30:14 +01:00
}
2008-03-20 12:28:41 +01:00
return ctx - > ops - > create_share ( ctx , servicename ) ;
2008-01-03 11:30:14 +01:00
}
2013-05-16 11:55:04 +02:00
/**
* create and set the definition for a new share ( service ) .
*/
sbcErr smbconf_create_set_share ( struct smbconf_ctx * ctx ,
struct smbconf_service * service )
{
sbcErr err , err2 ;
int i ;
uint32_t num_includes = 0 ;
char * * includes = NULL ;
TALLOC_CTX * tmp_ctx = NULL ;
if ( ( service - > name ! = NULL ) & & smbconf_share_exists ( ctx , service - > name ) )
{
return SBC_ERR_FILE_EXISTS ;
}
err = smbconf_transaction_start ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
return err ;
}
tmp_ctx = talloc_stackframe ( ) ;
err = smbconf_create_share ( ctx , service - > name ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
goto cancel ;
}
for ( i = 0 ; i < service - > num_params ; i + + ) {
if ( strequal ( service - > param_names [ i ] , " include " ) ) {
includes = talloc_realloc ( tmp_ctx , includes , char * ,
num_includes + 1 ) ;
if ( includes = = NULL ) {
err = SBC_ERR_NOMEM ;
goto cancel ;
}
includes [ num_includes ] = talloc_strdup ( includes ,
service - > param_values [ i ] ) ;
if ( includes [ num_includes ] = = NULL ) {
err = SBC_ERR_NOMEM ;
goto cancel ;
}
num_includes + + ;
} else {
err = smbconf_set_parameter ( ctx ,
service - > name ,
service - > param_names [ i ] ,
service - > param_values [ i ] ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
goto cancel ;
}
}
}
err = smbconf_set_includes ( ctx , service - > name , num_includes ,
2014-02-27 09:31:42 +01:00
discard_const_p ( const char * , includes ) ) ;
2013-05-16 11:55:04 +02:00
if ( ! SBC_ERROR_IS_OK ( err ) ) {
goto cancel ;
}
err = smbconf_transaction_commit ( ctx ) ;
goto done ;
cancel :
err2 = smbconf_transaction_cancel ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err2 ) ) {
DEBUG ( 5 , ( __location__ " : Error cancelling transaction: %s \n " ,
sbcErrorString ( err2 ) ) ) ;
}
done :
talloc_free ( tmp_ctx ) ;
return err ;
}
2007-12-29 03:38:13 +01:00
/**
* get a definition of a share ( service ) from configuration .
*/
2011-04-08 17:20:35 +02:00
sbcErr smbconf_get_share ( struct smbconf_ctx * ctx ,
2008-03-19 10:47:23 +01:00
TALLOC_CTX * mem_ctx ,
2008-04-22 16:31:16 +02:00
const char * servicename ,
struct smbconf_service * * service )
2007-12-29 03:38:13 +01:00
{
2008-04-22 16:31:16 +02:00
return ctx - > ops - > get_share ( ctx , mem_ctx , servicename , service ) ;
2007-12-29 03:38:13 +01:00
}
2007-12-25 02:24:39 +01:00
/**
* delete a service from configuration
2007-12-25 02:21:30 +01:00
*/
2011-04-11 11:39:03 +02:00
sbcErr smbconf_delete_share ( struct smbconf_ctx * ctx , const char * servicename )
2007-12-25 02:21:30 +01:00
{
2008-03-20 11:54:30 +01:00
if ( ! smbconf_share_exists ( ctx , servicename ) ) {
2011-04-11 11:39:03 +02:00
return SBC_ERR_NO_SUCH_SERVICE ;
2008-03-20 11:54:30 +01:00
}
2008-03-20 12:28:41 +01:00
return ctx - > ops - > delete_share ( ctx , servicename ) ;
2007-12-25 02:21:30 +01:00
}
2007-12-29 02:26:33 +01:00
/**
* set a configuration parameter to the value provided .
*/
2011-04-11 13:23:26 +02:00
sbcErr smbconf_set_parameter ( struct smbconf_ctx * ctx ,
2008-03-17 18:01:33 +01:00
const char * service ,
const char * param ,
const char * valstr )
2007-12-23 03:41:55 +01:00
{
2008-03-20 12:28:41 +01:00
return ctx - > ops - > set_parameter ( ctx , service , param , valstr ) ;
2007-12-23 03:41:55 +01:00
}
2008-01-13 23:00:16 +01:00
/**
* Set a global parameter
* ( i . e . a parameter in the [ global ] service ) .
*
* This also creates [ global ] when it does not exist .
*/
2011-04-11 13:23:26 +02:00
sbcErr smbconf_set_global_parameter ( struct smbconf_ctx * ctx ,
2008-03-17 18:01:33 +01:00
const char * param , const char * val )
2008-01-13 23:00:16 +01:00
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-01-13 23:00:16 +01:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2011-04-11 13:23:26 +02:00
return err ;
2008-01-13 23:00:16 +01:00
}
2011-04-11 13:23:26 +02:00
err = smbconf_set_parameter ( ctx , GLOBAL_NAME , param , val ) ;
2008-01-13 23:00:16 +01:00
2011-04-11 13:23:26 +02:00
return err ;
2008-01-13 23:00:16 +01:00
}
2007-12-29 02:26:33 +01:00
/**
* get the value of a configuration parameter as a string
*/
2011-04-11 13:50:53 +02:00
sbcErr smbconf_get_parameter ( struct smbconf_ctx * ctx ,
2008-03-19 10:47:23 +01:00
TALLOC_CTX * mem_ctx ,
2008-03-17 18:01:33 +01:00
const char * service ,
const char * param ,
char * * valstr )
2007-12-23 15:07:20 +01:00
{
2007-12-29 02:12:33 +01:00
if ( valstr = = NULL ) {
2011-04-11 13:50:53 +02:00
return SBC_ERR_INVALID_PARAM ;
2007-12-29 02:12:33 +01:00
}
2008-03-20 12:28:41 +01:00
return ctx - > ops - > get_parameter ( ctx , mem_ctx , service , param , valstr ) ;
2007-12-23 15:07:20 +01:00
}
2008-01-13 23:12:27 +01:00
/**
* Get the value of a global parameter .
*
* Create [ global ] if it does not exist .
*/
2011-04-11 13:50:53 +02:00
sbcErr smbconf_get_global_parameter ( struct smbconf_ctx * ctx ,
2008-03-19 10:47:23 +01:00
TALLOC_CTX * mem_ctx ,
2008-03-17 18:01:33 +01:00
const char * param ,
char * * valstr )
2008-01-13 23:12:27 +01:00
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-01-13 23:12:27 +01:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2011-04-11 13:50:53 +02:00
return err ;
2008-01-13 23:12:27 +01:00
}
2011-04-11 13:50:53 +02:00
err = smbconf_get_parameter ( ctx , mem_ctx , GLOBAL_NAME , param ,
valstr ) ;
2011-04-08 15:48:01 +02:00
2011-04-11 13:50:53 +02:00
return err ;
2008-01-13 23:12:27 +01:00
}
2007-12-29 02:26:33 +01:00
/**
* delete a parameter from configuration
*/
2011-04-11 14:20:32 +02:00
sbcErr smbconf_delete_parameter ( struct smbconf_ctx * ctx ,
2008-03-17 18:01:33 +01:00
const char * service , const char * param )
2007-12-23 02:55:25 +01:00
{
2008-03-20 12:28:41 +01:00
return ctx - > ops - > delete_parameter ( ctx , service , param ) ;
2007-12-23 02:55:25 +01:00
}
2007-12-23 03:52:00 +01:00
2008-01-13 23:16:01 +01:00
/**
* Delete a global parameter .
*
* Create [ global ] if it does not exist .
*/
2011-04-11 14:20:32 +02:00
sbcErr smbconf_delete_global_parameter ( struct smbconf_ctx * ctx ,
2008-03-17 18:01:33 +01:00
const char * param )
2008-01-13 23:16:01 +01:00
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-01-13 23:16:01 +01:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2011-04-11 14:20:32 +02:00
return err ;
2008-01-13 23:16:01 +01:00
}
2011-04-11 14:20:32 +02:00
err = smbconf_delete_parameter ( ctx , GLOBAL_NAME , param ) ;
2008-01-13 23:16:01 +01:00
2011-04-11 14:20:32 +02:00
return err ;
2008-01-13 23:16:01 +01:00
}
2008-04-08 01:56:32 +02:00
2011-04-11 14:52:52 +02:00
sbcErr smbconf_get_includes ( struct smbconf_ctx * ctx ,
2008-04-08 10:16:03 +02:00
TALLOC_CTX * mem_ctx ,
2008-04-08 01:56:32 +02:00
const char * service ,
uint32_t * num_includes , char * * * includes )
{
2008-04-08 10:16:03 +02:00
return ctx - > ops - > get_includes ( ctx , mem_ctx , service , num_includes ,
includes ) ;
2008-04-08 01:56:32 +02:00
}
2011-04-11 14:52:52 +02:00
sbcErr smbconf_get_global_includes ( struct smbconf_ctx * ctx ,
2008-04-08 14:24:42 +02:00
TALLOC_CTX * mem_ctx ,
uint32_t * num_includes , char * * * includes )
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-04-08 14:24:42 +02:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
2011-04-11 14:52:52 +02:00
if ( ! SBC_ERROR_IS_OK ( err ) ) {
return err ;
2008-04-08 14:24:42 +02:00
}
2011-04-11 14:52:52 +02:00
err = smbconf_get_includes ( ctx , mem_ctx , GLOBAL_NAME ,
2011-04-08 15:48:01 +02:00
num_includes , includes ) ;
2008-04-08 14:24:42 +02:00
2011-04-11 14:52:52 +02:00
return err ;
2008-04-08 14:24:42 +02:00
}
2011-04-11 15:14:52 +02:00
sbcErr smbconf_set_includes ( struct smbconf_ctx * ctx ,
2008-04-08 01:56:32 +02:00
const char * service ,
uint32_t num_includes , const char * * includes )
{
return ctx - > ops - > set_includes ( ctx , service , num_includes , includes ) ;
}
2008-04-08 14:24:42 +02:00
2011-04-11 15:14:52 +02:00
sbcErr smbconf_set_global_includes ( struct smbconf_ctx * ctx ,
2008-04-08 14:24:42 +02:00
uint32_t num_includes ,
const char * * includes )
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-04-08 14:24:42 +02:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2011-04-11 15:14:52 +02:00
return err ;
2008-04-08 14:24:42 +02:00
}
2011-04-11 15:14:52 +02:00
err = smbconf_set_includes ( ctx , GLOBAL_NAME ,
num_includes , includes ) ;
2008-04-08 14:24:42 +02:00
2011-04-11 15:14:52 +02:00
return err ;
2008-04-08 14:24:42 +02:00
}
2008-04-09 22:21:15 +02:00
2011-04-11 16:01:22 +02:00
sbcErr smbconf_delete_includes ( struct smbconf_ctx * ctx , const char * service )
2008-04-09 22:21:15 +02:00
{
return ctx - > ops - > delete_includes ( ctx , service ) ;
}
2011-04-11 16:01:22 +02:00
sbcErr smbconf_delete_global_includes ( struct smbconf_ctx * ctx )
2008-04-09 22:21:15 +02:00
{
2011-04-08 15:48:01 +02:00
sbcErr err ;
2008-04-09 22:21:15 +02:00
2011-04-08 15:48:01 +02:00
err = smbconf_global_check ( ctx ) ;
if ( ! SBC_ERROR_IS_OK ( err ) ) {
2011-04-11 16:01:22 +02:00
return err ;
2008-04-09 22:21:15 +02:00
}
2011-04-11 16:01:22 +02:00
err = smbconf_delete_includes ( ctx , GLOBAL_NAME ) ;
2008-04-09 22:21:15 +02:00
2011-04-11 16:01:22 +02:00
return err ;
2008-04-09 22:21:15 +02:00
}
2009-02-24 10:52:30 +01:00
2011-04-11 17:24:13 +02:00
sbcErr smbconf_transaction_start ( struct smbconf_ctx * ctx )
2009-02-24 10:52:30 +01:00
{
return ctx - > ops - > transaction_start ( ctx ) ;
}
2011-04-11 17:24:13 +02:00
sbcErr smbconf_transaction_commit ( struct smbconf_ctx * ctx )
2009-02-24 10:52:30 +01:00
{
return ctx - > ops - > transaction_commit ( ctx ) ;
}
2011-04-11 17:24:13 +02:00
sbcErr smbconf_transaction_cancel ( struct smbconf_ctx * ctx )
2009-02-24 10:52:30 +01:00
{
return ctx - > ops - > transaction_cancel ( ctx ) ;
}