diff --git a/source/include/structs.h b/source/include/structs.h index 59ab6a77da6..997e1445ef4 100644 --- a/source/include/structs.h +++ b/source/include/structs.h @@ -284,3 +284,7 @@ struct samba3; struct ldb_map_attribute; struct ldb_map_objectclass; + +struct param_context; +struct param_section; +struct param; diff --git a/source/lib/samba3/samba3.c b/source/lib/samba3/samba3.c index 56a77386935..d90d5edbfee 100644 --- a/source/lib/samba3/samba3.c +++ b/source/lib/samba3/samba3.c @@ -20,12 +20,6 @@ #include "includes.h" #include "lib/samba3/samba3.h" -struct smbconf_data { - TALLOC_CTX *ctx; - struct samba3 *db; - struct samba3_share_info *current_share; -}; - struct samba3_domainsecrets *samba3_find_domainsecrets(struct samba3 *db, const char *name) { int i; @@ -38,93 +32,6 @@ struct samba3_domainsecrets *samba3_find_domainsecrets(struct samba3 *db, const return NULL; } -struct samba3_share_info *samba3_find_share(struct samba3 *db, const char *name) -{ - int i; - for (i = 0; i < db->share_count; i++) { - if (!strcasecmp_m(db->shares[i].name, name)) - return &db->shares[i]; - } - - return NULL; -} - - -struct samba3_share_info *samba3_find_add_share(struct samba3 *db, TALLOC_CTX* ctx, const char *name) -{ - struct samba3_share_info *share = samba3_find_share(db, name); - - if (share) - return share; - - db->shares = talloc_realloc(ctx, db->shares, struct samba3_share_info, db->share_count+1); - ZERO_STRUCT(db->shares[db->share_count]); - db->shares[db->share_count].name = talloc_strdup(ctx, name); - db->share_count++; - - return &db->shares[db->share_count-1]; -} - -const char *samba3_get_param(struct samba3 *samba3, const char *section, const char *param) -{ - int i; - struct samba3_share_info *share = samba3_find_share(samba3, section); - - if (share == NULL) - return NULL; - - for (i = 0; i < share->parameter_count; i++) { - if (!strcasecmp_m(share->parameters[i].name, param)) - return share->parameters[i].value; - } - - return NULL; -} - - -static BOOL samba3_sfunc (const char *name, void *_db) -{ - struct smbconf_data *privdat = _db; - - privdat->current_share = samba3_find_add_share(privdat->db, privdat->ctx, name); - - return True; -} - -static BOOL samba3_pfunc (const char *name, const char *value, void *_db) -{ - struct smbconf_data *privdat = _db; - struct samba3_parameter *p; - - privdat->current_share->parameters = - talloc_realloc(privdat->ctx, privdat->current_share->parameters, - struct samba3_parameter, - privdat->current_share->parameter_count+1); - - p = &privdat->current_share->parameters[privdat->current_share->parameter_count]; - p->name = talloc_strdup(privdat->ctx, name); - p->value = talloc_strdup(privdat->ctx, value); - - privdat->current_share->parameter_count++; - - return True; -} - -NTSTATUS samba3_read_smbconf(const char *fn, TALLOC_CTX *ctx, struct samba3 *db) -{ - struct smbconf_data privdat; - - privdat.ctx = ctx; - privdat.db = db; - privdat.current_share = samba3_find_add_share(db, ctx, "global"); - - if (!pm_process( fn, samba3_sfunc, samba3_pfunc, &privdat )) { - return NT_STATUS_UNSUCCESSFUL; - } - - return NT_STATUS_OK; -} - NTSTATUS samba3_read(const char *smbconf, const char *libdir, TALLOC_CTX *ctx, struct samba3 **samba3) { struct samba3 *ret; @@ -133,7 +40,7 @@ NTSTATUS samba3_read(const char *smbconf, const char *libdir, TALLOC_CTX *ctx, s ret = talloc_zero(ctx, struct samba3); if (smbconf) - samba3_read_smbconf(smbconf, ctx, ret); + ret->configuration = param_read(ret, smbconf); dbfile = talloc_asprintf(ctx, "%s/account_policy.tdb", libdir); samba3_read_account_policy(dbfile, ctx, &ret->policy); diff --git a/source/lib/samba3/samba3.h b/source/lib/samba3/samba3.h index b8a9c68617d..f0f4c99513c 100644 --- a/source/lib/samba3/samba3.h +++ b/source/lib/samba3/samba3.h @@ -23,6 +23,7 @@ #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/samr.h" +#include "param/generic.h" struct samba3_samaccount { uint32_t logon_time, @@ -185,21 +186,15 @@ struct samba3_secrets } *afs_keyfiles; }; -struct samba3_parameter { - char *name; - char *value; -}; - struct samba3_share_info { char *name; struct security_descriptor secdesc; - - uint32_t parameter_count; - struct samba3_parameter *parameters; }; struct samba3 { + struct param_context *configuration; + uint32_t winsdb_count; struct samba3_winsdb_entry *winsdb_entries; diff --git a/source/lib/samba3/share_info.c b/source/lib/samba3/share_info.c index 3479a7063c5..e96adfc175e 100644 --- a/source/lib/samba3/share_info.c +++ b/source/lib/samba3/share_info.c @@ -66,7 +66,11 @@ NTSTATUS samba3_read_share_info(const char *fn, TALLOC_CTX *ctx, struct samba3 * name = talloc_strndup(ctx, kbuf.dptr+strlen("SECDESC/"), kbuf.dsize-strlen("SECDESC/")); - share = samba3_find_add_share(db, ctx, name); + db->shares = talloc_realloc(db, db->shares, struct samba3_share_info, db->share_count+1); + share = &db->shares[db->share_count]; + db->share_count++; + + share->name = talloc_strdup(db, name); vbuf = tdb_fetch(tdb, kbuf); blob.data = (uint8_t *)vbuf.dptr; diff --git a/source/lib/util_strlist.c b/source/lib/util_strlist.c index d5c4d915850..8efa1f92d20 100644 --- a/source/lib/util_strlist.c +++ b/source/lib/util_strlist.c @@ -22,7 +22,7 @@ /* build a null terminated list of strings from a input string and a - separator list. The sepatator list must contain characters less than + separator list. The separator list must contain characters less than or equal to 0x2f for this to work correctly on multi-byte strings */ const char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep) @@ -70,6 +70,25 @@ const char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char * return ret; } +/* join a list back to one string */ +char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char seperator) +{ + char *ret = NULL; + int i; + + if (list[0] == NULL) + return talloc_strdup(mem_ctx, ""); + + ret = talloc_strdup(mem_ctx, list[0]); + + for (i = 1; list[i]; i++) { + ret = talloc_asprintf_append(ret, "%c%s", seperator, list[i]); + } + + return ret; +} + + /* return the number of elements in a string list */ diff --git a/source/param/config.mk b/source/param/config.mk index 1f5b6367547..5126f7cd52a 100644 --- a/source/param/config.mk +++ b/source/param/config.mk @@ -2,4 +2,5 @@ INIT_OBJ_FILES = dynconfig.o ADD_OBJ_FILES = param/loadparm.o \ param/params.o \ - passdb/secrets.o + passdb/secrets.o \ + param/generic.o diff --git a/source/param/generic.c b/source/param/generic.c new file mode 100644 index 00000000000..0129f82eeb9 --- /dev/null +++ b/source/param/generic.c @@ -0,0 +1,231 @@ +/* + * Unix SMB/CIFS implementation. + * Copyright (C) Jelmer Vernooij 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 + * 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 02139, USA. + */ + +#include "includes.h" +#include "dlinklist.h" +#include "param/generic.h" + +struct param_section *param_get_section(struct param_context *ctx, const char *name) +{ + struct param_section *sect; + + if (name == NULL) + name = GLOBAL_NAME; + + for (sect = ctx->sections; sect; sect = sect->next) { + if (!strcasecmp_m(sect->name, name)) + return sect; + } + + return NULL; +} + +struct param *param_section_get (struct param_section *section, const char *name) +{ + struct param *p; + + for (p = section->parameters; p; p = p->next) { + if (strcasecmp(p->name, name) == 0) + return p; + } + + return NULL; +} + +struct param *param_get (struct param_context *ctx, const char *section_name, const char *name) +{ + struct param_section *section = param_get_section(ctx, section_name); + if (section == NULL) + return NULL; + + return param_section_get(section, name); +} + +/* Look up parameter. If it is not found, add it */ +static struct param *param_get_add(struct param_context *ctx, const char *section_name, const char *name) +{ + struct param_section *section; + struct param *p; + + section = param_get_section(ctx, section_name); + + if (section == NULL) { + section = talloc_zero(ctx, struct param_section); + section->name = talloc_strdup(section, section_name); + DLIST_ADD(ctx->sections, section); + } + + p = param_section_get(section, name); + if (p == NULL) { + p = talloc_zero(section, struct param); + p->name = talloc_strdup(p, name); + DLIST_ADD(section->parameters, p); + } + + return p; +} + +const char *param_get_string(struct param_context *ctx, const char *section, const char *param) +{ + struct param *p = param_get(ctx, section, param); + + if (p == NULL) + return NULL; + + return p->value; +} + +void param_set_string(struct param_context *ctx, const char *section, const char *param, const char *value) +{ + struct param *p = param_get_add(ctx, section, param); + + p->value = talloc_strdup(p, value); +} + +const char **param_get_string_list(struct param_context *ctx, const char *section, const char *param, + const char *separator) +{ + struct param *p = param_get(ctx, section, param); + + if (p == NULL) + return NULL; + + if (p->list_value == NULL) { + p->list_value = str_list_make(ctx, p->value, separator); + } + + return p->list_value; +} + +void param_set_string_list(struct param_context *ctx, const char *section, const char *param, const char **list) +{ + struct param *p = param_get_add(ctx, section, param); + + p->value = str_list_join(p, list, ' '); + p->list_value = str_list_copy(p, list); +} + +int param_get_int(struct param_context *ctx, const char *section, const char *param, int default_v) +{ + const char *value = param_get_string(ctx, section, param); + + if (value) + return strtol(value, NULL, 0); + + return default_v; +} + +void param_set_int(struct param_context *ctx, const char *section, const char *param, int value) +{ + struct param *p = param_get_add(ctx, section, param); + + p->value = talloc_asprintf(p, "%d", value); +} + +unsigned long param_get_ulong(struct param_context *ctx, const char *section, const char *param, unsigned long default_v) +{ + const char *value = param_get_string(ctx, section, param); + + if (value) + return strtoul(value, NULL, 0); + + return default_v; +} + +void param_set_ulong(struct param_context *ctx, const char *section, const char *name, unsigned long value) +{ + struct param *p = param_get_add(ctx, section, name); + + p->value = talloc_asprintf(p, "%lu", value); +} + +static BOOL param_sfunc (const char *name, void *_ctx) +{ + struct param_context *ctx = _ctx; + struct param_section *section = param_get_section(ctx, name); + + if (section == NULL) { + section = talloc_zero(ctx, struct param_section); + section->name = talloc_strdup(section, name); + + DLIST_ADD(ctx->sections, section); + } + + DLIST_PROMOTE(ctx->sections, section); + + return True; +} + + + +static BOOL param_pfunc (const char *name, const char *value, void *_ctx) +{ + struct param_context *ctx = _ctx; + struct param *p = param_section_get(ctx->sections, name); + + if (!p) { + p = talloc_zero(ctx->sections, struct param); + p->name = talloc_strdup(p, name); + p->value = talloc_strdup(p, value); + DLIST_ADD(ctx->sections->parameters, p); + } else { /* Replace current value */ + talloc_free(p->value); + p->value = talloc_strdup(p, value); + } + + return True; +} + +struct param_context *param_read(TALLOC_CTX *mem_ctx, const char *fn) +{ + struct param_context *ctx = talloc_zero(mem_ctx, struct param_context); + + ctx->sections = talloc_zero(ctx, struct param_section); + ctx->sections->name = talloc_strdup(ctx->sections, "global"); + + if (!pm_process( fn, param_sfunc, param_pfunc, ctx)) { + talloc_free(ctx); + return NULL; + } + + return ctx; +} + +int param_write(FILE *file, struct param_context *ctx) +{ + struct param_section *section; + + if (file == NULL) + return -1; + + if (ctx == NULL) + return -1; + + for (section = ctx->sections; section; section = section->next) { + struct param *param; + + fprintf(file, "[%s]\n", section->name); + for (param = section->parameters; param; param = param->next) { + fprintf(file, "\t%s = %s\n", param->name, param->value); + } + fprintf(file, "\n"); + } + + return 0; +} diff --git a/source/param/generic.h b/source/param/generic.h new file mode 100644 index 00000000000..1d3a5c7cb39 --- /dev/null +++ b/source/param/generic.h @@ -0,0 +1,41 @@ +/* + Unix SMB/CIFS implementation. + Generic parameter parsing interface + Copyright (C) Jelmer Vernooij 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 + 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 02139, USA. +*/ + +#ifndef _PARAM_GENERIC_H /* _PARAM_GENERIC_H */ +#define _PARAM_GENERIC_H + +struct param_context { + struct param_section *sections; +}; + +struct param { + const char *name; + char *value; + const char **list_value; + struct param *prev, *next; +}; + +struct param_section { + const char *name; + struct param_section *prev, *next; + struct param *parameters; +}; + +#endif /* _PARAM_GENERIC_H */ diff --git a/source/scripting/ejs/smbcalls_samba3.c b/source/scripting/ejs/smbcalls_samba3.c index 936426c2da2..e8e6b416e2d 100644 --- a/source/scripting/ejs/smbcalls_samba3.c +++ b/source/scripting/ejs/smbcalls_samba3.c @@ -288,8 +288,8 @@ static struct MprVar mprSecrets(struct samba3_secrets *sec) static struct MprVar mprShares(struct samba3 *samba3) { - struct MprVar mpv = mprObject("array"), s, ps, p; - int i, j; + struct MprVar mpv = mprObject("array"), s; + int i; for (i = 0; i < samba3->share_count; i++) { s = mprObject("share"); @@ -298,18 +298,7 @@ static struct MprVar mprShares(struct samba3 *samba3) /* FIXME: secdesc */ - ps = mprObject("array"); - - for (j = 0; j < samba3->shares[i].parameter_count; j++) { - p = mprObject("parameter"); - - mprSetVar(&p, "name", mprString(samba3->shares[i].parameters[j].name)); - mprSetVar(&p, "value", mprString(samba3->shares[i].parameters[j].value)); - - mprAddArray(&ps, j, p); - } - - mprSetVar(&s, "parameters", ps); + mprAddArray(&mpv, i, s); } return mpv; @@ -389,29 +378,6 @@ static struct MprVar mprWinsEntries(struct samba3 *samba3) return mpv; } -static int ejs_get_param(MprVarHandle eid, int argc, struct MprVar **argv) -{ - struct samba3 *samba3; - const char *tmp; - - if (argc < 2) { - ejsSetErrorMsg(eid, "get_param invalid arguments"); - return -1; - } - - samba3 = mprGetThisPtr(eid, "samba3"); - mprAssert(samba3); - tmp = samba3_get_param(samba3, mprToString(argv[0]), mprToString(argv[1])); - - if (tmp == NULL) { - mpr_Return(eid, mprCreateUndefinedVar()); - } else { - mpr_Return(eid, mprString(tmp)); - } - - return 0; -} - static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **argv) { struct samba3 *samba3 = NULL; @@ -435,8 +401,6 @@ static int ejs_find_domainsecrets(MprVarHandle eid, int argc, struct MprVar **ar return 0; } - - /* initialise samba3 ejs subsystem */ @@ -470,7 +434,6 @@ static int ejs_samba3_read(MprVarHandle eid, int argc, struct MprVar **argv) mprSetVar(&mpv, "idmapdb", mprIdmapDb(&samba3->idmap)); mprSetVar(&mpv, "policy", mprPolicy(&samba3->policy)); mprSetVar(&mpv, "registry", mprRegistry(&samba3->registry)); - mprSetCFunction(&mpv, "get_param", ejs_get_param); mprSetCFunction(&mpv, "find_domainsecrets", ejs_find_domainsecrets); mpr_Return(eid, mpv);