summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/smb_macros.h5
-rw-r--r--source3/modules/vfs_recycle.c226
-rw-r--r--source3/param/loadparm.c450
-rw-r--r--source3/passdb/pdb_mysql.c123
-rw-r--r--source3/passdb/pdb_xml.c7
5 files changed, 542 insertions, 269 deletions
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 8efb966d0b..b39c7a0ebc 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -98,8 +98,11 @@
#define ERROR_WAS_LOCK_DENIED(status) (NT_STATUS_EQUAL((status), NT_STATUS_LOCK_NOT_GRANTED) || \
NT_STATUS_EQUAL((status), NT_STATUS_FILE_LOCK_CONFLICT) )
+/* the service number for the [globals] defaults */
+#define GLOBAL_SECTION_SNUM (-1)
/* translates a connection number into a service number */
-#define SNUM(conn) ((conn)?(conn)->service:-1)
+#define SNUM(conn) ((conn)?(conn)->service:GLOBAL_SECTION_SNUM)
+
/* access various service details */
#define SERVICE(snum) (lp_servicename(snum))
diff --git a/source3/modules/vfs_recycle.c b/source3/modules/vfs_recycle.c
index 5372a7e64c..85ce257c02 100644
--- a/source3/modules/vfs_recycle.c
+++ b/source3/modules/vfs_recycle.c
@@ -37,7 +37,7 @@ static const char *delimiter = "|"; /* delimiter for options */
typedef struct recycle_bin_struct
{
- TALLOC_CTX *ctx;
+ TALLOC_CTX *mem_ctx;
char *repository; /* name of the recycle bin directory */
BOOL keep_dir_tree; /* keep directory structure of deleted file in recycle bin */
BOOL versions; /* create versions of deleted files with identical name */
@@ -48,6 +48,19 @@ typedef struct recycle_bin_struct
SMB_OFF_T maxsize; /* maximum file size to be saved */
} recycle_bin_struct;
+typedef struct recycle_bin_connections {
+ int conn;
+ recycle_bin_struct *data;
+ struct recycle_bin_connections *next;
+} recycle_bin_connections;
+
+typedef struct recycle_bin_private_data {
+ TALLOC_CTX *mem_ctx;
+ recycle_bin_connections *conns;
+} recycle_bin_private_data;
+
+struct smb_vfs_handle_struct *recycle_bin_private_handle;
+
/* VFS operations */
static struct vfs_ops default_vfs_ops; /* For passthrough operation */
@@ -69,16 +82,6 @@ static vfs_op_tuple recycle_ops[] = {
{NULL, SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
};
-static BOOL check_bool_param(const char *value)
-{
- if (strwicmp(value, "yes") == 0 ||
- strwicmp(value, "true") == 0 ||
- strwicmp(value, "1") == 0)
- return True;
-
- return False;
-}
-
/**
* VFS initialisation function.
*
@@ -87,6 +90,8 @@ static BOOL check_bool_param(const char *value)
static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops,
struct smb_vfs_handle_struct *vfs_handle)
{
+ TALLOC_CTX *mem_ctx = NULL;
+
DEBUG(10, ("Initializing VFS module recycle\n"));
memcpy(&default_vfs_ops, def_vfs_ops, sizeof(struct vfs_ops));
vfs_recycle_debug_level = debug_add_class("vfs_recycle_bin");
@@ -97,6 +102,20 @@ static vfs_op_tuple *recycle_init(const struct vfs_ops *def_vfs_ops,
DEBUG(0, ("vfs_recycle: Debug class number of 'vfs_recycle': %d\n", vfs_recycle_debug_level));
}
+ recycle_bin_private_handle = vfs_handle;
+ if (!(mem_ctx = talloc_init("recycle bin data"))) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ return NULL;
+ }
+
+ recycle_bin_private_handle->data = talloc(mem_ctx, sizeof(recycle_bin_private_data));
+ if (recycle_bin_private_handle->data == NULL) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ return NULL;
+ }
+ ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->mem_ctx = mem_ctx;
+ ((recycle_bin_private_data *)(recycle_bin_private_handle->data))->conns = NULL;
+
return recycle_ops;
}
@@ -104,84 +123,91 @@ static int recycle_connect(struct connection_struct *conn, const char *service,
{
TALLOC_CTX *ctx = NULL;
recycle_bin_struct *recbin;
- char *servicename;
- char *tmp_str;
+ recycle_bin_connections *recconn;
+ recycle_bin_connections *recconnbase;
+ recycle_bin_private_data *recdata;
+ const char *tmp_str;
DEBUG(10, ("Called for service %s (%d) as user %s\n", service, SNUM(conn), user));
- if (!(ctx = talloc_init("recycle bin"))) {
- DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
- return 0;
+ if (recycle_bin_private_handle)
+ recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
+ else {
+ DEBUG(0, ("Recycle bin not initialized!\n"));
+ return -1;
}
- recbin = talloc(ctx,sizeof(recycle_bin_struct));
- if ( recbin == NULL) {
+ if (!(ctx = talloc_init("recycle bin connection"))) {
DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
return -1;
}
- recbin->ctx = ctx;
- /* Set defaults */
- recbin->repository = talloc_strdup(ctx, ".recycle");
- ALLOC_CHECK(recbin->repository, error);
- recbin->keep_dir_tree = False;
- recbin->versions = False;
- recbin->touch = False;
- recbin->exclude = "";
- recbin->exclude_dir = "";
- recbin->noversions = "";
- recbin->maxsize = 0;
+ recbin = talloc_zero(ctx, sizeof(recycle_bin_struct));
+ if (recbin == NULL) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ return -1;
+ }
+ recbin->mem_ctx = ctx;
/* parse configuration options */
- servicename = talloc_strdup(recbin->ctx, lp_servicename(SNUM(conn)));
- DEBUG(10, ("servicename = %s\n",servicename));
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "repository")) != NULL) {
- recbin->repository = talloc_sub_conn(ctx, conn, tmp_str);
+ if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "repository", ".recycle")) != NULL) {
+ recbin->repository = talloc_sub_conn(recbin->mem_ctx, conn, tmp_str);
ALLOC_CHECK(recbin->repository, error);
trim_string(recbin->repository, "/", "/");
DEBUG(5, ("recycle.bin: repository = %s\n", recbin->repository));
+ } else {
+ DEBUG(0,("recycle.bin: no repository found (fail) !\n"));
+ goto error;
+ }
+
+ recbin->keep_dir_tree = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "keeptree", False);
+ DEBUG(5, ("recycle.bin: keeptree = %d\n", recbin->keep_dir_tree));
+
+ recbin->versions = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "versions", False);
+ DEBUG(5, ("recycle.bin: versions = %d\n", recbin->versions));
+
+ recbin->touch = lp_parm_bool(SNUM(conn), "vfs_recycle_bin", "touch", False);
+ DEBUG(5, ("recycle.bin: touch = %d\n", recbin->touch));
+
+ recbin->maxsize = lp_parm_ulong(SNUM(conn), "vfs_recycle_bin", "maxsize" , 0);
+ if (recbin->maxsize == 0) {
+ recbin->maxsize = -1;
+ DEBUG(5, ("recycle.bin: maxsize = -infinite-\n"));
+ } else {
+ DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize));
}
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "keeptree")) != NULL) {
- if (check_bool_param(tmp_str) == True)
- recbin->keep_dir_tree = True;
- DEBUG(5, ("recycle.bin: keeptree = %s\n", tmp_str));
- }
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "versions")) != NULL) {
- if (check_bool_param(tmp_str) == True)
- recbin->versions = True;
- DEBUG(5, ("recycle.bin: versions = %s\n", tmp_str));
- }
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "touch")) != NULL) {
- if (check_bool_param(tmp_str) == True)
- recbin->touch = True;
- DEBUG(5, ("recycle.bin: touch = %s\n", tmp_str));
- }
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "maxsize")) != NULL) {
- recbin->maxsize = strtoul(tmp_str, NULL, 10);
- if (recbin->maxsize == 0) {
- recbin->maxsize = -1;
- DEBUG(5, ("recycle.bin: maxsize = -infinite-\n"));
- } else {
- DEBUG(5, ("recycle.bin: maxsize = %ld\n", (long int)recbin->maxsize));
- }
- }
- if ((tmp_str = lp_parm_string(servicename, "vfs_recycle_bin", "exclude")) != NULL) {
- recbin->exclude = talloc_strdup(ctx, tmp_str);
+
+ if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude", "")) != NULL) {
+ recbin->exclude = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->exclude, error);
DEBUG(5, ("recycle.bin: exclude = %s\n", recbin->exclude));
}
- if ((tmp_str = lp_parm_string(servicename,"vfs_recycle_bin", "exclude_dir")) != NULL) {
- recbin->exclude_dir = talloc_strdup(ctx, tmp_str);
+ if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "exclude_dir", "")) != NULL) {
+ recbin->exclude_dir = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->exclude_dir, error);
DEBUG(5, ("recycle.bin: exclude_dir = %s\n", recbin->exclude_dir));
}
- if ((tmp_str = lp_parm_string(servicename,"vfs_recycle_bin", "noversions")) != NULL) {
- recbin->noversions = talloc_strdup(ctx, tmp_str);
+ if ((tmp_str = lp_parm_const_string(SNUM(conn), "vfs_recycle_bin", "noversions", "")) != NULL) {
+ recbin->noversions = talloc_strdup(recbin->mem_ctx, tmp_str);
ALLOC_CHECK(recbin->noversions, error);
DEBUG(5, ("recycle.bin: noversions = %s\n", recbin->noversions));
}
- conn->vfs_private = (void *)recbin;
+ recconn = talloc(recdata->mem_ctx, sizeof(recycle_bin_connections));
+ if (recconn == NULL) {
+ DEBUG(0, ("Failed to allocate memory in VFS module recycle_bin\n"));
+ goto error;
+ }
+ recconn->conn = SNUM(conn);
+ recconn->data = recbin;
+ recconn->next = NULL;
+ if (recdata->conns) {
+ recconnbase = recdata->conns;
+ while (recconnbase->next != NULL) recconnbase = recconnbase->next;
+ recconnbase->next = recconn;
+ } else {
+ recdata->conns = recconn;
+ }
return default_vfs_ops.connect(conn, service, user);
error:
@@ -191,10 +217,35 @@ error:
static void recycle_disconnect(struct connection_struct *conn)
{
+ recycle_bin_private_data *recdata;
+ recycle_bin_connections *recconn;
+
DEBUG(10, ("Disconnecting VFS module recycle bin\n"));
- if (conn->vfs_private) {
- talloc_destroy(((recycle_bin_struct *)conn->vfs_private)->ctx);
- conn->vfs_private = NULL;
+
+ if (recycle_bin_private_handle)
+ recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
+ else {
+ DEBUG(0, ("Recycle bin not initialized!\n"));
+ return;
+ }
+
+ if (recdata) {
+ if (recdata->conns) {
+ if (recdata->conns->conn == SNUM(conn)) {
+ talloc_destroy(recdata->conns->data->mem_ctx);
+ recdata->conns = recdata->conns->next;
+ } else {
+ recconn = recdata->conns;
+ while (recconn->next) {
+ if (recconn->next->conn == SNUM(conn)) {
+ talloc_destroy(recconn->next->data->mem_ctx);
+ recconn->next = recconn->next->next;
+ break;
+ }
+ recconn = recconn->next;
+ }
+ }
+ }
}
default_vfs_ops.disconnect(conn);
}
@@ -379,26 +430,35 @@ static void recycle_touch(connection_struct *conn, const char *fname)
/**
* Check if file should be recycled
**/
-static int recycle_unlink(connection_struct *conn, const char *inname)
+static int recycle_unlink(connection_struct *conn, const char *file_name)
{
+ recycle_bin_private_data *recdata;
+ recycle_bin_connections *recconn;
recycle_bin_struct *recbin;
- char *file_name = NULL;
char *path_name = NULL;
char *temp_name = NULL;
char *final_name = NULL;
- char *base;
+ const char *base;
int i;
- SMB_BIG_UINT dfree, dsize, bsize;
- SMB_OFF_T file_size, space_avail;
+/* SMB_BIG_UINT dfree, dsize, bsize; */
+ SMB_OFF_T file_size; /* space_avail; */
BOOL exist;
int rc = -1;
- file_name = strdup(inname);
- ALLOC_CHECK(file_name, done);
-
- if (conn->vfs_private)
- recbin = (recycle_bin_struct *)conn->vfs_private;
- else {
+ recbin = NULL;
+ if (recycle_bin_private_handle) {
+ recdata = (recycle_bin_private_data *)(recycle_bin_private_handle->data);
+ if (recdata) {
+ if (recdata->conns) {
+ recconn = recdata->conns;
+ while (recconn && recconn->conn != SNUM(conn)) recconn = recconn->next;
+ if (recconn != NULL) {
+ recbin = recconn->data;
+ }
+ }
+ }
+ }
+ if (recbin == NULL) {
DEBUG(0, ("Recycle bin not initialized!\n"));
rc = default_vfs_ops.unlink(conn, file_name);
goto done;
@@ -504,10 +564,9 @@ static int recycle_unlink(connection_struct *conn, const char *inname)
}
}
- final_name = (char *)malloc(PATH_MAX);
+ asprintf(&final_name, "%s/%s", temp_name, base);
ALLOC_CHECK(final_name, done);
- snprintf(final_name, PATH_MAX, "%s/%s", temp_name, base);
- DEBUG(10, ("recycle.bin: recycled file name%s\n", temp_name)); /* new filename with path */
+ DEBUG(10, ("recycle.bin: recycled file name: %s\n", temp_name)); /* new filename with path */
/* check if we should delete file from recycle bin */
if (recycle_file_exist(conn, final_name)) {
@@ -538,7 +597,6 @@ static int recycle_unlink(connection_struct *conn, const char *inname)
recycle_touch(conn, final_name);
done:
- SAFE_FREE(file_name);
SAFE_FREE(path_name);
SAFE_FREE(temp_name);
SAFE_FREE(final_name);
@@ -546,6 +604,6 @@ done:
}
int vfs_recycle_init(void)
-{
- return smb_register_vfs("recycle", recycle_init, SMB_VFS_INTERFACE_VERSION);
+{
+ return smb_register_vfs("recycle", recycle_init, SMB_VFS_INTERFACE_VERSION);
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 90cf288430..c96e750a54 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -81,6 +81,14 @@ extern int extra_time_offset;
static BOOL defaults_saved = False;
+typedef struct _param_opt_struct param_opt_struct;
+struct _param_opt_struct {
+ param_opt_struct *prev, *next;
+ char *key;
+ char *value;
+ char **list;
+};
+
/*
* This structure describes global (ie., server-wide) parameters.
*/
@@ -278,6 +286,7 @@ typedef struct
int restrict_anonymous;
int name_cache_timeout;
BOOL client_signing;
+ param_opt_struct *param_opt;
}
global;
@@ -400,6 +409,7 @@ typedef struct
BOOL bNTAclSupport;
BOOL bUseSendfile;
BOOL bProfileAcls;
+ param_opt_struct *param_opt;
char dummy[3]; /* for alignment */
}
@@ -520,6 +530,8 @@ static service sDefault = {
True, /* bNTAclSupport */
False, /* bUseSendfile */
False, /* bProfileAcls */
+
+ NULL, /* Parametric options */
"" /* dummy */
};
@@ -1856,49 +1868,6 @@ FN_GLOBAL_BOOL(lp_algorithmic_rid_base, &Globals.bAlgorithmicRidBase)
FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
-typedef struct _param_opt_struct param_opt_struct;
-struct _param_opt_struct {
- char *key;
- char *value;
- param_opt_struct *prev, *next;
-};
-
-static param_opt_struct *param_opt = NULL;
-
-/* Return parametric option from given service. Type is a part of option before ':' */
-/* Parametric option has following syntax: 'Type: option = value' */
-/* Returned value is allocated in 'lp_talloc' context */
-
-char *lp_parm_string(const char *servicename, const char *type, const char *option)
-{
- param_opt_struct *data;
- pstring vfskey;
-
- if (param_opt != NULL) {
- ZERO_STRUCT(vfskey);
- pstr_sprintf(vfskey, "%s:%s:%s", (servicename==NULL) ? "global" : servicename,
- type, option);
- data = param_opt;
- while (data) {
- if (strcmp(data->key, vfskey) == 0) {
- return lp_string(data->value);
- }
- data = data->next;
- }
- /* Try to fetch the same option but from globals */
- pstr_sprintf(vfskey, "global:%s:%s", type, option);
- data = param_opt;
- while (data) {
- if (strcmp(data->key, vfskey) == 0) {
- return lp_string(data->value);
- }
- data = data->next;
- }
-
- }
- return NULL;
-}
-
/* local prototypes */
static int map_parameter(const char *pszParmName);
@@ -1912,6 +1881,238 @@ static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
static BOOL do_section(const char *pszSectionName);
static void init_copymap(service * pservice);
+/* This is a helper function for parametrical options support. */
+/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
+/* Actual parametrical functions are quite simple */
+static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
+{
+ BOOL global_section = False;
+ char* param_key;
+ param_opt_struct *data;
+
+ if (snum >= iNumServices) return NULL;
+
+ if (snum < 0) {
+ data = Globals.param_opt;
+ global_section = True;
+ } else {
+ data = ServicePtrs[snum]->param_opt;
+ }
+
+ asprintf(&param_key, "%s:%s", type, option);
+ if (!param_key) {
+ DEBUG(0,("asprintf failed!\n"));
+ return NULL;
+ }
+
+ while (data) {
+ if (strcmp(data->key, param_key) == 0) {
+ string_free(&param_key);
+ return data;
+ }
+ data = data->next;
+ }
+
+ if (!global_section) {
+ /* Try to fetch the same option but from globals */
+ /* but only if we are not already working with Globals */
+ data = Globals.param_opt;
+ while (data) {
+ if (strcmp(data->key, param_key) == 0) {
+ string_free(&param_key);
+ return data;
+ }
+ data = data->next;
+ }
+ }
+
+ string_free(&param_key);
+
+ return NULL;
+}
+
+
+/*******************************************************************
+convenience routine to return int parameters.
+********************************************************************/
+static int lp_int(const char *s)
+{
+
+ if (!s) {
+ DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
+ return (-1);
+ }
+
+ return atoi(s);
+}
+
+/*******************************************************************
+convenience routine to return unsigned long parameters.
+********************************************************************/
+static int lp_ulong(const char *s)
+{
+
+ if (!s) {
+ DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
+ return (-1);
+ }
+
+ return strtoul(s, NULL, 10);
+}
+
+/*******************************************************************
+convenience routine to return boolean parameters.
+********************************************************************/
+static BOOL lp_bool(const char *s)
+{
+ BOOL ret = False;
+
+ if (!s) {
+ DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
+ return False;
+ }
+
+ if (!set_boolean(&ret,s)) {
+ DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
+ return False;
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+convenience routine to return enum parameters.
+********************************************************************/
+static int lp_enum(const char *s,const struct enum_list *_enum)
+{
+ int i;
+
+ if (!s || !_enum) {
+ DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
+ return (-1);
+ }
+
+ for (i=0; _enum[i].name; i++) {
+ if (strcasecmp(_enum[i].name,s)==0)
+ return _enum[i].value;
+ }
+
+ DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
+ return (-1);
+}
+
+
+/* DO NOT USE lp_parm_string ANYMORE!!!!
+ * use lp_parm_const_string or lp_parm_talloc_string
+ *
+ * lp_parm_string is only used to let old modules find this symbol
+ */
+#undef lp_parm_string
+ char *lp_parm_string(const char *servicename, const char *type, const char *option)
+{
+ return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+/* the returned value is talloced in lp_talloc */
+char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data == NULL||data->value==NULL) {
+ if (def) {
+ return lp_string(def);
+ } else {
+ return NULL;
+ }
+ }
+
+ return lp_string(data->value);
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data == NULL||data->value==NULL)
+ return def;
+
+ return data->value;
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
+const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data == NULL||data->value==NULL)
+ return (const char **)def;
+
+ if (data->list==NULL) {
+ data->list = str_list_make(data->value, NULL);
+ }
+
+ return (const char **)data->list;
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
+int lp_parm_int(int snum, const char *type, const char *option, int def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data && data->value && *data->value)
+ return lp_int(data->value);
+
+ return def;
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
+unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data && data->value && *data->value)
+ return lp_ulong(data->value);
+
+ return def;
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
+BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data && data->value && *data->value)
+ return lp_bool(data->value);
+
+ return def;
+}
+
+/* Return parametric option from a given service. Type is a part of option before ':' */
+/* Parametric option has following syntax: 'Type: option = value' */
+
+int lp_parm_enum(int snum, const char *type, const char *option,
+ const struct enum_list *_enum, int def)
+{
+ param_opt_struct *data = get_parametrics(snum, type, option);
+
+ if (data && data->value && *data->value && _enum)
+ return lp_enum(data->value, _enum);
+
+ return def;
+}
+
/***************************************************************************
Initialise a service to the defaults.
@@ -1930,6 +2131,7 @@ static void init_service(service * pservice)
static void free_service(service *pservice)
{
int i;
+ param_opt_struct *data, *pdata;
if (!pservice)
return;
@@ -1953,7 +2155,19 @@ static void free_service(service *pservice)
(((char *)pservice) +
PTR_DIFF(parm_table[i].ptr, &sDefault)));
}
-
+
+ data = pservice->param_opt;
+ if (data)
+ DEBUG(5,("Freeing parametrics:\n"));
+ while (data) {
+ DEBUG(5,("[%s = %s]\n", data->key, data->value));
+ string_free(&data->key);
+ string_free(&data->value);
+ str_list_free(&data->list);
+ pdata = data->next;
+ SAFE_FREE(data);
+ data = pdata;
+ }
ZERO_STRUCTP(pservice);
}
@@ -1968,14 +2182,28 @@ static int add_a_service(const service *pservice, const char *name)
int i;
service tservice;
int num_to_alloc = iNumServices + 1;
+ param_opt_struct *data, *pdata;
tservice = *pservice;
/* it might already exist */
if (name) {
i = getservicebyname(name, NULL);
- if (i >= 0)
+ if (i >= 0) {
+ /* Clean all parametric options for service */
+ /* They will be added during parsing again */
+ data = ServicePtrs[i]->param_opt;
+ while (data) {
+ string_free(&data->key);
+ string_free(&data->value);
+ str_list_free(&data->list);
+ pdata = data->next;
+ SAFE_FREE(data);
+ data = pdata;
+ }
+ ServicePtrs[i]->param_opt = NULL;
return (i);
+ }
}
/* find an invalid one */
@@ -2035,7 +2263,7 @@ BOOL lp_add_home(const char *pszHomename, int iDefaultService,
return (False);
if (!(*(ServicePtrs[iDefaultService]->szPath))
- || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
+ || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
pstrcpy(newHomedir, pszHomedir);
} else {
pstrcpy(newHomedir, lp_pathname(iDefaultService));
@@ -2219,6 +2447,8 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
{
int i;
BOOL bcopyall = (pcopymapDest == NULL);
+ param_opt_struct *data, *pdata, *paramo;
+ BOOL not_added;
for (i = 0; parm_table[i].label; i++)
if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
@@ -2272,6 +2502,32 @@ static void copy_service(service * pserviceDest, service * pserviceSource, BOOL
(void *)pserviceSource->copymap,
sizeof(BOOL) * NUMPARAMETERS);
}
+
+ data = pserviceSource->param_opt;
+ while (data) {
+ not_added = True;
+ pdata = pserviceDest->param_opt;
+ /* Traverse destination */
+ while (pdata) {
+ /* If we already have same option, override it */
+ if (strcmp(pdata->key, data->key) == 0) {
+ string_free(&pdata->value);
+ str_list_free(&data->list);
+ pdata->value = strdup(data->value);
+ not_added = False;
+ break;
+ }
+ pdata = pdata->next;
+ }
+ if (not_added) {
+ paramo = smb_xmalloc(sizeof(param_opt_struct));
+ paramo->key = strdup(data->key);
+ paramo->value = strdup(data->value);
+ paramo->list = NULL;
+ DLIST_ADD(pserviceDest->param_opt, paramo);
+ }
+ data = data->next;
+ }
}
/***************************************************************************
@@ -2868,25 +3124,48 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
int parmnum, i, slen;
void *parm_ptr = NULL; /* where we are going to store the result */
void *def_ptr = NULL;
- pstring vfskey;
+ pstring param_key;
char *sep;
- param_opt_struct *paramo;
+ param_opt_struct *paramo, *data;
+ BOOL not_added;
parmnum = map_parameter(pszParmName);
if (parmnum < 0) {
if ((sep=strchr(pszParmName, ':')) != NULL) {
- *sep = 0;
- ZERO_STRUCT(vfskey);
- pstr_sprintf(vfskey, "%s:%s:",
- (snum >= 0) ? lp_servicename(snum) : "global", pszParmName);
- slen = strlen(vfskey);
- pstrcat(vfskey, sep+1);
- trim_string(vfskey+slen, " ", " ");
- paramo = smb_xmalloc(sizeof(param_opt_struct));
- paramo->key = strdup(vfskey);
- paramo->value = strdup(pszParmValue);
- DLIST_ADD(param_opt, paramo);
+ *sep = '\0';
+ ZERO_STRUCT(param_key);
+ pstr_sprintf(param_key, "%s:", pszParmName);
+ slen = strlen(param_key);
+ pstrcat(param_key, sep+1);
+ trim_string(param_key+slen, " ", " ");
+ not_added = True;
+ data = (snum < 0) ? Globals.param_opt :
+ ServicePtrs[snum]->param_opt;
+ /* Traverse destination */
+ while (data) {
+ /* If we already have same option, override it */
+ if (strcmp(data->key, param_key) == 0) {
+ string_free(&data->value);
+ str_list_free(&data->list);
+ data->value = strdup(pszParmValue);
+ not_added = False;
+ break;
+ }
+ data = data->next;
+ }
+ if (not_added) {
+ paramo = smb_xmalloc(sizeof(param_opt_struct));
+ paramo->key = strdup(param_key);
+ paramo->value = strdup(pszParmValue);
+ paramo->list = NULL;
+ if (snum < 0) {
+ DLIST_ADD(Globals.param_opt, paramo);
+ } else {
+ DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
+ }
+ }
+
*sep = ':';
return (True);
}
@@ -3236,7 +3515,6 @@ static void dump_globals(FILE *f)
{
int i;
param_opt_struct *data;
- char *s;
fprintf(f, "# Global parameters\n[global]\n");
@@ -3250,14 +3528,11 @@ static void dump_globals(FILE *f)
print_parameter(&parm_table[i], parm_table[i].ptr, f);
fprintf(f, "\n");
}
- if (param_opt != NULL) {
- data = param_opt;
+ if (Globals.param_opt != NULL) {
+ data = Globals.param_opt;
while(data) {
- if (((s=strstr(data->key, "global")) == data->key) &&
- (*(s+strlen("global")) == ':')) {
- fprintf(f, "\t%s = %s\n", s+strlen("global")+1, data->value);
- }
- data = data->next;
+ fprintf(f, "\t%s = %s\n", data->key, data->value);
+ data = data->next;
}
}
@@ -3284,8 +3559,6 @@ static void dump_a_service(service * pService, FILE * f)
{
int i;
param_opt_struct *data;
- const char *sn;
- char *s;
if (pService != &sDefault)
fprintf(f, "\n[%s]\n", pService->szService);
@@ -3314,28 +3587,24 @@ static void dump_a_service(service * pService, FILE * f)
((char *)pService) + pdiff, f);
fprintf(f, "\n");
}
- if (param_opt != NULL) {
- data = param_opt;
- sn = (pService == &sDefault) ? "global" : pService->szService;
+ if (pService->param_opt != NULL) {
+ data = pService->param_opt;
while(data) {
- if (((s=strstr(data->key, sn)) == data->key) &&
- (*(s+strlen(sn)) == ':')) {
- fprintf(f, "\t%s = %s\n", s+strlen(sn)+1, data->value);
- }
- data = data->next;
+ fprintf(f, "\t%s = %s\n", data->key, data->value);
+ data = data->next;
}
}
}
/***************************************************************************
- Return info about the next service in a service. snum==-1 gives the globals.
+ Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
Return NULL when out of parameters.
***************************************************************************/
struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
{
- if (snum == -1) {
+ if (snum < 0) {
/* do the globals */
for (; parm_table[*i].label; (*i)++) {
if (parm_table[*i].class == P_SEPARATOR)
@@ -3657,16 +3926,17 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
lp_save_defaults();
}
- if (param_opt != NULL) {
- data = param_opt;
+ if (Globals.param_opt != NULL) {
+ data = Globals.param_opt;
while (data) {
- SAFE_FREE(data->key);
- SAFE_FREE(data->value);
+ string_free(&data->key);
+ string_free(&data->value);
+ str_list_free(&data->list);
pdata = data->next;
SAFE_FREE(data);
data = pdata;
}
- param_opt = NULL;
+ Globals.param_opt = NULL;
}
/* We get sections first, so have to start 'behind' to make up */
@@ -3696,7 +3966,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
/* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
/* if bWINSsupport is true and we are in the client */
if (in_client && Globals.bWINSsupport) {
- lp_do_parameter(-1, "wins server", "127.0.0.1");
+ lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
}
init_iconv();
@@ -3765,8 +4035,10 @@ int lp_servicenumber(const char *pszServiceName)
{
int iService;
fstring serviceName;
-
-
+
+ if (!pszServiceName)
+ return GLOBAL_SECTION_SNUM;
+
for (iService = iNumServices - 1; iService >= 0; iService--) {
if (VALID(iService) && ServicePtrs[iService]->szService) {
/*
@@ -3780,8 +4052,10 @@ int lp_servicenumber(const char *pszServiceName)
}
}
- if (iService < 0)
+ if (iService < 0) {
DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
+ return GLOBAL_SECTION_SNUM;
+ }
return (iService);
}
diff --git a/source3/passdb/pdb_mysql.c b/source3/passdb/pdb_mysql.c
index f3cb998ee1..ec8c6f9ab8 100644
--- a/source3/passdb/pdb_mysql.c
+++ b/source3/passdb/pdb_mysql.c
@@ -25,12 +25,12 @@
#define CONFIG_LOGON_TIME_DEFAULT "logon_time"
#define CONFIG_LOGOFF_TIME_DEFAULT "logoff_time"
#define CONFIG_KICKOFF_TIME_DEFAULT "kickoff_time"
-#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
-#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
-#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
+#define CONFIG_PASS_LAST_SET_TIME_DEFAULT "pass_last_set_time"
+#define CONFIG_PASS_CAN_CHANGE_TIME_DEFAULT "pass_can_change_time"
+#define CONFIG_PASS_MUST_CHANGE_TIME_DEFAULT "pass_must_change_time"
#define CONFIG_USERNAME_DEFAULT "username"
#define CONFIG_DOMAIN_DEFAULT "domain"
-#define CONFIG_NT_USERNAME_DEFAULT "nt_username"
+#define CONFIG_NT_USERNAME_DEFAULT "nt_username"
#define CONFIG_FULLNAME_DEFAULT "nt_fullname"
#define CONFIG_HOME_DIR_DEFAULT "home_dir"
#define CONFIG_DIR_DRIVE_DEFAULT "dir_drive"
@@ -40,8 +40,8 @@
#define CONFIG_WORKSTATIONS_DEFAULT "workstations"
#define CONFIG_UNKNOWN_STR_DEFAULT "unknown_str"
#define CONFIG_MUNGED_DIAL_DEFAULT "munged_dial"
-#define CONFIG_UID_DEFAULT "uid"
-#define CONFIG_GID_DEFAULT "gid"
+#define CONFIG_UID_DEFAULT "uid"
+#define CONFIG_GID_DEFAULT "gid"
#define CONFIG_USER_SID_DEFAULT "user_sid"
#define CONFIG_GROUP_SID_DEFAULT "group_sid"
#define CONFIG_LM_PW_DEFAULT "lm_pw"
@@ -53,11 +53,11 @@
#define CONFIG_HOURS_LEN_DEFAULT "hours_len"
#define CONFIG_UNKNOWN_5_DEFAULT "unknown_5"
#define CONFIG_UNKNOWN_6_DEFAULT "unknown_6"
-#define CONFIG_HOST_DEFAULT "localhost"
-#define CONFIG_USER_DEFAULT "samba"
-#define CONFIG_PASS_DEFAULT ""
-#define CONFIG_PORT_DEFAULT "3306"
-#define CONFIG_DB_DEFAULT "samba"
+#define CONFIG_HOST_DEFAULT "localhost"
+#define CONFIG_USER_DEFAULT "samba"
+#define CONFIG_PASS_DEFAULT ""
+#define CONFIG_PORT_DEFAULT "3306"
+#define CONFIG_DB_DEFAULT "samba"
static int mysqlsam_debug_level = DBGC_ALL;
@@ -91,7 +91,7 @@ typedef struct pdb_mysql_query {
}
static void pdb_mysql_int_field(struct pdb_methods *m,
- struct pdb_mysql_query *q, char *name, int value)
+ struct pdb_mysql_query *q, const char *name, int value)
{
if (!name || strchr(name, '\''))
return; /* This field shouldn't be set by us */
@@ -110,7 +110,7 @@ static void pdb_mysql_int_field(struct pdb_methods *m,
static NTSTATUS pdb_mysql_string_field(struct pdb_methods *methods,
struct pdb_mysql_query *q,
- char *name, const char *value)
+ const char *name, const char *value)
{
char *esc_value;
struct pdb_mysql_data *data;
@@ -145,20 +145,17 @@ static NTSTATUS pdb_mysql_string_field(struct pdb_methods *methods,
return NT_STATUS_OK;
}
-static char * config_value(pdb_mysql_data * data, char *name, char *default_value)
-{
- if (lp_parm_string(NULL, data->location, name))
- return lp_parm_string(NULL, data->location, name);
+#define config_value(data,name,default_value) \
+ lp_parm_const_string(GLOBAL_SECTION_SNUM, (data)->location, name, default_value)
- return default_value;
-}
+static const char * config_value_write(pdb_mysql_data * data, const char *name, const char *default_value) {
+ char const *v = NULL;
+ char const *swrite = NULL;
-static char * config_value_write(pdb_mysql_data * data, char *name, char *default_value) {
- char *v = config_value(data, name, NULL);
- char *swrite;
+ v = lp_parm_const_string(GLOBAL_SECTION_SNUM, data->location, name, default_value);
if (!v)
- return default_value;
+ return NULL;
swrite = strchr(v, ':');
@@ -176,13 +173,15 @@ static char * config_value_write(pdb_mysql_data * data, char *name, char *defaul
return swrite;
}
-static const char * config_value_read(pdb_mysql_data * data, char *name, char *default_value)
+static const char * config_value_read(pdb_mysql_data * data, const char *name, const char *default_value)
{
- char *v = config_value(data, name, NULL);
+ char *v = NULL;
char *swrite;
+ v = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, data->location, name, default_value);
+
if (!v)
- return default_value;
+ return "NULL";
swrite = strchr(v, ':');
@@ -190,7 +189,7 @@ static const char * config_value_read(pdb_mysql_data * data, char *name, char *d
if (!swrite) {
if (strlen(v) == 0)
return "NULL";
- return v;
+ return (const char *)v;
}
/* Otherwise, we have to cut the ':write_part' */
@@ -198,11 +197,11 @@ static const char * config_value_read(pdb_mysql_data * data, char *name, char *d
if (strlen(v) == 0)
return "NULL";
- return v;
+ return (const char *)v;
}
/* Wrapper for atol that returns 0 if 'a' points to NULL */
-static long xatol(char *a)
+static long xatol(const char *a)
{
long ret = 0;
@@ -369,7 +368,7 @@ static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
}
DEBUG(5,
- ("mysqlsam_setsampwent succeeded(%lu results)!\n",
+ ("mysqlsam_setsampwent succeeded(%llu results)!\n",
mysql_num_rows(data->pwent)));
return NT_STATUS_OK;
@@ -893,59 +892,6 @@ static NTSTATUS mysqlsam_update_sam_account(struct pdb_methods *methods,
return mysqlsam_replace_sam_account(methods, newpwd, 1);
}
-static NTSTATUS mysqlsam_getgrsid(struct pdb_methods *methods, GROUP_MAP *map,
- DOM_SID sid, BOOL with_priv)
-{
- return get_group_map_from_sid(sid, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_getgrgid(struct pdb_methods *methods, GROUP_MAP *map,
- gid_t gid, BOOL with_priv)
-{
- return get_group_map_from_gid(gid, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_getgrnam(struct pdb_methods *methods, GROUP_MAP *map,
- char *name, BOOL with_priv)
-{
- return get_group_map_from_ntname(name, map, with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_add_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_INSERT) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_update_group_mapping_entry(struct pdb_methods *methods,
- GROUP_MAP *map)
-{
- return add_mapping_entry(map, TDB_REPLACE) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_delete_group_mapping_entry(struct pdb_methods *methods,
- DOM_SID sid)
-{
- return group_map_remove(sid) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-static NTSTATUS mysqlsam_enum_group_mapping(struct pdb_methods *methods,
- enum SID_NAME_USE sid_name_use,
- GROUP_MAP **rmap, int *num_entries,
- BOOL unix_only, BOOL with_priv)
-{
- return enum_group_mapping(sid_name_use, rmap, num_entries, unix_only,
- with_priv) ?
- NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
-}
-
-
static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_methods ** pdb_method,
const char *location)
{
@@ -979,13 +925,6 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho
(*pdb_method)->add_sam_account = mysqlsam_add_sam_account;
(*pdb_method)->update_sam_account = mysqlsam_update_sam_account;
(*pdb_method)->delete_sam_account = mysqlsam_delete_sam_account;
- (*pdb_method)->getgrsid = mysqlsam_getgrsid;
- (*pdb_method)->getgrgid = mysqlsam_getgrgid;
- (*pdb_method)->getgrnam = mysqlsam_getgrnam;
- (*pdb_method)->add_group_mapping_entry = mysqlsam_add_group_mapping_entry;
- (*pdb_method)->update_group_mapping_entry = mysqlsam_update_group_mapping_entry;
- (*pdb_method)->delete_group_mapping_entry = mysqlsam_delete_group_mapping_entry;
- (*pdb_method)->enum_group_mapping = mysqlsam_enum_group_mapping;
data = talloc(pdb_context->mem_ctx, sizeof(struct pdb_mysql_data));
(*pdb_method)->private_data = data;
@@ -993,7 +932,7 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho
data->pwent = NULL;
if (!location) {
- DEBUG(0, ("No identifier specified. See README for details\n"));
+ DEBUG(0, ("No identifier specified. Check the Samba HOWTO Collection for details\n"));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -1032,7 +971,7 @@ static NTSTATUS mysqlsam_init(struct pdb_context * pdb_context, struct pdb_metho
return NT_STATUS_OK;
}
-int pdb_mysql_init()
+int pdb_mysql_init(void)
{
return smb_register_passdb("mysql", mysqlsam_init, PASSDB_INTERFACE_VERSION);
}
diff --git a/source3/passdb/pdb_xml.c b/source3/passdb/pdb_xml.c
index ae3199e3a4..26e722dea1 100644
--- a/source3/passdb/pdb_xml.c
+++ b/source3/passdb/pdb_xml.c
@@ -512,7 +512,7 @@ static NTSTATUS xmlsam_add_sam_account(struct pdb_methods *methods, SAM_ACCOUNT
return NT_STATUS_OK;
}
-NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
+static NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
const char *location)
{
NTSTATUS nt_status;
@@ -553,8 +553,7 @@ NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
(*pdb_method)->enum_group_mapping = NULL;
data = talloc(pdb_context->mem_ctx, sizeof(pdb_xml));
- data->location =
- (location ? talloc_strdup(pdb_context->mem_ctx, location) : "passdb.xml");
+ data->location = talloc_strdup(pdb_context->mem_ctx, (location ? location : "passdb.xml"));
data->pwent = NULL;
data->written = 0;
(*pdb_method)->private_data = data;
@@ -564,7 +563,7 @@ NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method,
return NT_STATUS_OK;
}
-int pdb_xml_init()
+int pdb_xml_init(void)
{
return smb_register_passdb("xml", xmlsam_init, PASSDB_INTERFACE_VERSION);
}