wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
[LIBRARY::LIBSAMBA-CONFIG]
|
||||
DESCRIPTION = Reading Samba configuration files
|
||||
VERSION = 0.0.1
|
||||
SO_VERSION = 0
|
||||
OBJ_FILES = loadparm.o \
|
||||
params.o \
|
||||
generic.o \
|
||||
util.o \
|
||||
../lib/version.o
|
||||
PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL
|
||||
PRIVATE_DEPENDENCIES = DYNCONFIG
|
||||
PUBLIC_PROTO_HEADER = proto.h
|
||||
PUBLIC_HEADERS = param.h
|
||||
|
||||
#################################
|
||||
# Start SUBSYSTEM share
|
||||
[LIBRARY::share]
|
||||
VERSION = 0.0.1
|
||||
SO_VERSION = 0
|
||||
DESCRIPTION = Services Configuration Library
|
||||
PUBLIC_HEADERS = share.h
|
||||
PUBLIC_PROTO_HEADER = share_proto.h
|
||||
OBJ_FILES = share.o
|
||||
PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL
|
||||
# End SUBSYSTEM share
|
||||
#################################
|
||||
|
||||
################################################
|
||||
# Start MODULE share_classic
|
||||
[MODULE::share_classic]
|
||||
SUBSYSTEM = share
|
||||
INIT_FUNCTION = share_classic_init
|
||||
OBJ_FILES = share_classic.o
|
||||
PUBLIC_DEPENDENCIES = LIBSAMBA-UTIL
|
||||
# End MODULE share_classic
|
||||
################################################
|
||||
|
||||
################################################
|
||||
# Start MODULE share_ldb
|
||||
[MODULE::share_ldb]
|
||||
SUBSYSTEM = share
|
||||
INIT_FUNCTION = share_ldb_init
|
||||
OBJ_FILES = share_ldb.o
|
||||
PUBLIC_DEPENDENCIES = ldb
|
||||
# End MODULE share_ldb
|
||||
################################################
|
||||
|
||||
[SUBSYSTEM::SECRETS]
|
||||
PRIVATE_PROTO_HEADER = secrets_proto.h
|
||||
OBJ_FILES = secrets.o
|
||||
PRIVATE_DEPENDENCIES = DB_WRAP UTIL_TDB
|
||||
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* 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 "lib/util/dlinklist.h"
|
||||
#include "param/param.h"
|
||||
#include "system/filesys.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_m(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);
|
||||
if (section == NULL)
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int 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);
|
||||
|
||||
if (p == NULL)
|
||||
return -1;
|
||||
|
||||
p->value = talloc_strdup(p, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 (separator == NULL)
|
||||
separator = LIST_SEP;
|
||||
|
||||
if (p->list_value == NULL) {
|
||||
p->list_value = str_list_make(ctx, p->value, separator);
|
||||
}
|
||||
|
||||
return p->list_value;
|
||||
}
|
||||
|
||||
int 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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
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);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
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);
|
||||
if (section == NULL)
|
||||
return False;
|
||||
|
||||
section->name = talloc_strdup(section, name);
|
||||
|
||||
DLIST_ADD(ctx->sections, section);
|
||||
}
|
||||
|
||||
/* Make sure this section is on top of the list for param_pfunc */
|
||||
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);
|
||||
if (p == NULL)
|
||||
return False;
|
||||
|
||||
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_init(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
return talloc_zero(mem_ctx, struct param_context);
|
||||
}
|
||||
|
||||
|
||||
int param_read(struct param_context *ctx, const char *fn)
|
||||
{
|
||||
ctx->sections = talloc_zero(ctx, struct param_section);
|
||||
if (ctx->sections == NULL)
|
||||
return -1;
|
||||
|
||||
ctx->sections->name = talloc_strdup(ctx->sections, "global");
|
||||
if (!pm_process( fn, param_sfunc, param_pfunc, ctx)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int param_write(struct param_context *ctx, const char *fn)
|
||||
{
|
||||
int file;
|
||||
struct param_section *section;
|
||||
|
||||
if (fn == NULL || ctx == NULL)
|
||||
return -1;
|
||||
|
||||
file = open(fn, O_WRONLY|O_CREAT, 0755);
|
||||
|
||||
if (file == -1)
|
||||
return -1;
|
||||
|
||||
for (section = ctx->sections; section; section = section->next) {
|
||||
struct param *param;
|
||||
|
||||
fdprintf(file, "[%s]\n", section->name);
|
||||
for (param = section->parameters; param; param = param->next) {
|
||||
fdprintf(file, "\t%s = %s\n", param->name, param->value);
|
||||
}
|
||||
fdprintf(file, "\n");
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
type definitions for loadparm
|
||||
|
||||
Copyright (C) Karl Auer 1993-1998
|
||||
|
||||
Largely re-written by Andrew Tridgell, September 1994
|
||||
|
||||
Copyright (C) Simo Sorce 2001
|
||||
Copyright (C) Alexander Bokovoy 2002
|
||||
Copyright (C) Stefan (metze) Metzmacher 2002
|
||||
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
|
||||
Copyright (C) James Myers 2003 <myersjj@samba.org>
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* the following are used by loadparm for option lists */
|
||||
typedef enum {
|
||||
P_BOOL,P_INTEGER,P_BYTES,P_LIST,P_STRING,P_USTRING,P_ENUM,P_SEP
|
||||
} parm_type;
|
||||
|
||||
typedef enum {
|
||||
P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
|
||||
} parm_class;
|
||||
|
||||
struct enum_list {
|
||||
int value;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct parm_struct {
|
||||
const char *label;
|
||||
parm_type type;
|
||||
parm_class class;
|
||||
void *ptr;
|
||||
BOOL (*special)(const char *, char **);
|
||||
const struct enum_list *enum_list;
|
||||
unsigned int flags;
|
||||
union {
|
||||
int bvalue;
|
||||
int ivalue;
|
||||
char *svalue;
|
||||
char cvalue;
|
||||
const char **lvalue;
|
||||
} def;
|
||||
};
|
||||
|
||||
#define FLAG_BASIC 0x0001 /* fundamental options */
|
||||
#define FLAG_SHARE 0x0002 /* file sharing options */
|
||||
#define FLAG_PRINT 0x0004 /* printing options */
|
||||
#define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
|
||||
#define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
|
||||
#define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
|
||||
#define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
|
||||
#define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
|
||||
#define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
|
||||
#define FLAG_DEFAULT 0x4000 /* this option was a default */
|
||||
#define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
|
||||
|
||||
#ifndef PRINTERS_NAME
|
||||
#define PRINTERS_NAME "printers"
|
||||
#endif
|
||||
|
||||
#ifndef HOMES_NAME
|
||||
#define HOMES_NAME "homes"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
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_H /* _PARAM_H */
|
||||
#define _PARAM_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;
|
||||
};
|
||||
|
||||
struct param_context;
|
||||
struct smbsrv_connection;
|
||||
|
||||
#define Auto (2)
|
||||
|
||||
#include "param/proto.h"
|
||||
|
||||
#endif /* _PARAM_H */
|
||||
@@ -0,0 +1,588 @@
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Microsoft Network Services for Unix, AKA., Andrew Tridgell's SAMBA.
|
||||
*
|
||||
* This module Copyright (C) 1990-1998 Karl Auer
|
||||
*
|
||||
* Rewritten almost completely by Christopher R. Hertel
|
||||
* at the University of Minnesota, September, 1997.
|
||||
* This module Copyright (C) 1997-1998 by the University of Minnesota
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* Module name: params
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*
|
||||
* This module performs lexical analysis and initial parsing of a
|
||||
* Windows-like parameter file. It recognizes and handles four token
|
||||
* types: section-name, parameter-name, parameter-value, and
|
||||
* end-of-file. Comments and line continuation are handled
|
||||
* internally.
|
||||
*
|
||||
* The entry point to the module is function pm_process(). This
|
||||
* function opens the source file, calls the Parse() function to parse
|
||||
* the input, and then closes the file when either the EOF is reached
|
||||
* or a fatal error is encountered.
|
||||
*
|
||||
* A sample parameter file might look like this:
|
||||
*
|
||||
* [section one]
|
||||
* parameter one = value string
|
||||
* parameter two = another value
|
||||
* [section two]
|
||||
* new parameter = some value or t'other
|
||||
*
|
||||
* The parameter file is divided into sections by section headers:
|
||||
* section names enclosed in square brackets (eg. [section one]).
|
||||
* Each section contains parameter lines, each of which consist of a
|
||||
* parameter name and value delimited by an equal sign. Roughly, the
|
||||
* syntax is:
|
||||
*
|
||||
* <file> :== { <section> } EOF
|
||||
*
|
||||
* <section> :== <section header> { <parameter line> }
|
||||
*
|
||||
* <section header> :== '[' NAME ']'
|
||||
*
|
||||
* <parameter line> :== NAME '=' VALUE '\n'
|
||||
*
|
||||
* Blank lines and comment lines are ignored. Comment lines are lines
|
||||
* beginning with either a semicolon (';') or a pound sign ('#').
|
||||
*
|
||||
* All whitespace in section names and parameter names is compressed
|
||||
* to single spaces. Leading and trailing whitespace is stipped from
|
||||
* both names and values.
|
||||
*
|
||||
* Only the first equals sign in a parameter line is significant.
|
||||
* Parameter values may contain equals signs, square brackets and
|
||||
* semicolons. Internal whitespace is retained in parameter values,
|
||||
* with the exception of the '\r' character, which is stripped for
|
||||
* historic reasons. Parameter names may not start with a left square
|
||||
* bracket, an equal sign, a pound sign, or a semicolon, because these
|
||||
* are used to identify other tokens.
|
||||
*
|
||||
* -------------------------------------------------------------------------- **
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/locale.h"
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Constants...
|
||||
*/
|
||||
|
||||
#define BUFR_INC 1024
|
||||
|
||||
|
||||
/* we can't use FILE* due to the 256 fd limit - use this cheap hack
|
||||
instead */
|
||||
typedef struct {
|
||||
char *buf;
|
||||
char *p;
|
||||
size_t size;
|
||||
char *bufr;
|
||||
int bSize;
|
||||
} myFILE;
|
||||
|
||||
static int mygetc(myFILE *f)
|
||||
{
|
||||
if (f->p >= f->buf+f->size) return EOF;
|
||||
/* be sure to return chars >127 as positive values */
|
||||
return (int)( *(f->p++) & 0x00FF );
|
||||
}
|
||||
|
||||
static void myfile_close(myFILE *f)
|
||||
{
|
||||
talloc_free(f);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- **
|
||||
* Functions...
|
||||
*/
|
||||
|
||||
static int EatWhitespace( myFILE *InFile )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Scan past whitespace (see ctype(3C)) and return the first non-whitespace
|
||||
* character, or newline, or EOF.
|
||||
*
|
||||
* Input: InFile - Input source.
|
||||
*
|
||||
* Output: The next non-whitespace character in the input stream.
|
||||
*
|
||||
* Notes: Because the config files use a line-oriented grammar, we
|
||||
* explicitly exclude the newline character from the list of
|
||||
* whitespace characters.
|
||||
* - Note that both EOF (-1) and the nul character ('\0') are
|
||||
* considered end-of-file markers.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int c;
|
||||
|
||||
for( c = mygetc( InFile ); isspace( c ) && ('\n' != c); c = mygetc( InFile ) )
|
||||
;
|
||||
return( c );
|
||||
} /* EatWhitespace */
|
||||
|
||||
static int EatComment( myFILE *InFile )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Scan to the end of a comment.
|
||||
*
|
||||
* Input: InFile - Input source.
|
||||
*
|
||||
* Output: The character that marks the end of the comment. Normally,
|
||||
* this will be a newline, but it *might* be an EOF.
|
||||
*
|
||||
* Notes: Because the config files use a line-oriented grammar, we
|
||||
* explicitly exclude the newline character from the list of
|
||||
* whitespace characters.
|
||||
* - Note that both EOF (-1) and the nul character ('\0') are
|
||||
* considered end-of-file markers.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int c;
|
||||
|
||||
for( c = mygetc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = mygetc( InFile ) )
|
||||
;
|
||||
return( c );
|
||||
} /* EatComment */
|
||||
|
||||
/*****************************************************************************
|
||||
* Scan backards within a string to discover if the last non-whitespace
|
||||
* character is a line-continuation character ('\\').
|
||||
*
|
||||
* Input: line - A pointer to a buffer containing the string to be
|
||||
* scanned.
|
||||
* pos - This is taken to be the offset of the end of the
|
||||
* string. This position is *not* scanned.
|
||||
*
|
||||
* Output: The offset of the '\\' character if it was found, or -1 to
|
||||
* indicate that it was not.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static int Continuation(char *line, int pos )
|
||||
{
|
||||
pos--;
|
||||
while( (pos >= 0) && isspace((int)line[pos]))
|
||||
pos--;
|
||||
|
||||
return (((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
|
||||
}
|
||||
|
||||
|
||||
static BOOL Section( myFILE *InFile, BOOL (*sfunc)(const char *, void *), void *userdata )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Scan a section name, and pass the name to function sfunc().
|
||||
*
|
||||
* Input: InFile - Input source.
|
||||
* sfunc - Pointer to the function to be called if the section
|
||||
* name is successfully read.
|
||||
*
|
||||
* Output: True if the section name was read and True was returned from
|
||||
* <sfunc>. False if <sfunc> failed or if a lexical error was
|
||||
* encountered.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int c;
|
||||
int i;
|
||||
int end;
|
||||
const char *func = "params.c:Section() -";
|
||||
|
||||
i = 0; /* <i> is the offset of the next free byte in bufr[] and */
|
||||
end = 0; /* <end> is the current "end of string" offset. In most */
|
||||
/* cases these will be the same, but if the last */
|
||||
/* character written to bufr[] is a space, then <end> */
|
||||
/* will be one less than <i>. */
|
||||
|
||||
c = EatWhitespace( InFile ); /* We've already got the '['. Scan */
|
||||
/* past initial white space. */
|
||||
|
||||
while( (EOF != c) && (c > 0) )
|
||||
{
|
||||
|
||||
/* Check that the buffer is big enough for the next character. */
|
||||
if( i > (InFile->bSize - 2) )
|
||||
{
|
||||
char *tb;
|
||||
|
||||
tb = talloc_realloc(InFile, InFile->bufr, char, InFile->bSize + BUFR_INC);
|
||||
if( NULL == tb )
|
||||
{
|
||||
DEBUG(0, ("%s Memory re-allocation failure.", func) );
|
||||
return( False );
|
||||
}
|
||||
InFile->bufr = tb;
|
||||
InFile->bSize += BUFR_INC;
|
||||
}
|
||||
|
||||
/* Handle a single character. */
|
||||
switch( c )
|
||||
{
|
||||
case ']': /* Found the closing bracket. */
|
||||
InFile->bufr[end] = '\0';
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
DEBUG(0, ("%s Empty section name in configuration file.\n", func ));
|
||||
return( False );
|
||||
}
|
||||
if( !sfunc(InFile->bufr,userdata) ) /* Got a valid name. Deal with it. */
|
||||
return( False );
|
||||
(void)EatComment( InFile ); /* Finish off the line. */
|
||||
return( True );
|
||||
|
||||
case '\n': /* Got newline before closing ']'. */
|
||||
i = Continuation( InFile->bufr, i ); /* Check for line continuation. */
|
||||
if( i < 0 )
|
||||
{
|
||||
InFile->bufr[end] = '\0';
|
||||
DEBUG(0, ("%s Badly formed line in configuration file: %s\n",
|
||||
func, InFile->bufr ));
|
||||
return( False );
|
||||
}
|
||||
end = ( (i > 0) && (' ' == InFile->bufr[i - 1]) ) ? (i - 1) : (i);
|
||||
c = mygetc( InFile ); /* Continue with next line. */
|
||||
break;
|
||||
|
||||
default: /* All else are a valid name chars. */
|
||||
if( isspace( c ) ) /* One space per whitespace region. */
|
||||
{
|
||||
InFile->bufr[end] = ' ';
|
||||
i = end + 1;
|
||||
c = EatWhitespace( InFile );
|
||||
}
|
||||
else /* All others copy verbatim. */
|
||||
{
|
||||
InFile->bufr[i++] = c;
|
||||
end = i;
|
||||
c = mygetc( InFile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* We arrive here if we've met the EOF before the closing bracket. */
|
||||
DEBUG(0, ("%s Unexpected EOF in the configuration file\n", func));
|
||||
return( False );
|
||||
} /* Section */
|
||||
|
||||
static BOOL Parameter( myFILE *InFile, BOOL (*pfunc)(const char *, const char *, void *), int c, void *userdata )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Scan a parameter name and value, and pass these two fields to pfunc().
|
||||
*
|
||||
* Input: InFile - The input source.
|
||||
* pfunc - A pointer to the function that will be called to
|
||||
* process the parameter, once it has been scanned.
|
||||
* c - The first character of the parameter name, which
|
||||
* would have been read by Parse(). Unlike a comment
|
||||
* line or a section header, there is no lead-in
|
||||
* character that can be discarded.
|
||||
*
|
||||
* Output: True if the parameter name and value were scanned and processed
|
||||
* successfully, else False.
|
||||
*
|
||||
* Notes: This function is in two parts. The first loop scans the
|
||||
* parameter name. Internal whitespace is compressed, and an
|
||||
* equal sign (=) terminates the token. Leading and trailing
|
||||
* whitespace is discarded. The second loop scans the parameter
|
||||
* value. When both have been successfully identified, they are
|
||||
* passed to pfunc() for processing.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int i = 0; /* Position within bufr. */
|
||||
int end = 0; /* bufr[end] is current end-of-string. */
|
||||
int vstart = 0; /* Starting position of the parameter value. */
|
||||
const char *func = "params.c:Parameter() -";
|
||||
|
||||
/* Read the parameter name. */
|
||||
while( 0 == vstart ) /* Loop until we've found the start of the value. */
|
||||
{
|
||||
|
||||
if( i > (InFile->bSize - 2) ) /* Ensure there's space for next char. */
|
||||
{
|
||||
char *tb;
|
||||
|
||||
tb = talloc_realloc(InFile, InFile->bufr, char, InFile->bSize + BUFR_INC );
|
||||
if( NULL == tb )
|
||||
{
|
||||
DEBUG(0, ("%s Memory re-allocation failure.", func) );
|
||||
return( False );
|
||||
}
|
||||
InFile->bufr = tb;
|
||||
InFile->bSize += BUFR_INC;
|
||||
}
|
||||
|
||||
switch( c )
|
||||
{
|
||||
case '=': /* Equal sign marks end of param name. */
|
||||
if( 0 == end ) /* Don't allow an empty name. */
|
||||
{
|
||||
DEBUG(0, ("%s Invalid parameter name in config. file.\n", func ));
|
||||
return( False );
|
||||
}
|
||||
InFile->bufr[end++] = '\0'; /* Mark end of string & advance. */
|
||||
i = end; /* New string starts here. */
|
||||
vstart = end; /* New string is parameter value. */
|
||||
InFile->bufr[i] = '\0'; /* New string is nul, for now. */
|
||||
break;
|
||||
|
||||
case '\n': /* Find continuation char, else error. */
|
||||
i = Continuation( InFile->bufr, i );
|
||||
if( i < 0 )
|
||||
{
|
||||
InFile->bufr[end] = '\0';
|
||||
DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n",
|
||||
func, InFile->bufr ));
|
||||
return( True );
|
||||
}
|
||||
end = ( (i > 0) && (' ' == InFile->bufr[i - 1]) ) ? (i - 1) : (i);
|
||||
c = mygetc( InFile ); /* Read past eoln. */
|
||||
break;
|
||||
|
||||
case '\0': /* Shouldn't have EOF within param name. */
|
||||
case EOF:
|
||||
InFile->bufr[i] = '\0';
|
||||
DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, InFile->bufr ));
|
||||
return( True );
|
||||
|
||||
default:
|
||||
if( isspace( c ) ) /* One ' ' per whitespace region. */
|
||||
{
|
||||
InFile->bufr[end] = ' ';
|
||||
i = end + 1;
|
||||
c = EatWhitespace( InFile );
|
||||
}
|
||||
else /* All others verbatim. */
|
||||
{
|
||||
InFile->bufr[i++] = c;
|
||||
end = i;
|
||||
c = mygetc( InFile );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now parse the value. */
|
||||
c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */
|
||||
while( (EOF !=c) && (c > 0) )
|
||||
{
|
||||
|
||||
if( i > (InFile->bSize - 2) ) /* Make sure there's enough room. */
|
||||
{
|
||||
char *tb;
|
||||
|
||||
tb = talloc_realloc(InFile, InFile->bufr, char, InFile->bSize + BUFR_INC );
|
||||
if( NULL == tb )
|
||||
{
|
||||
DEBUG(0, ("%s Memory re-allocation failure.", func) );
|
||||
return( False );
|
||||
}
|
||||
InFile->bufr = tb;
|
||||
InFile->bSize += BUFR_INC;
|
||||
}
|
||||
|
||||
switch( c )
|
||||
{
|
||||
case '\r': /* Explicitly remove '\r' because the older */
|
||||
c = mygetc( InFile ); /* version called fgets_slash() which also */
|
||||
break; /* removes them. */
|
||||
|
||||
case '\n': /* Marks end of value unless there's a '\'. */
|
||||
i = Continuation( InFile->bufr, i );
|
||||
if( i < 0 )
|
||||
c = 0;
|
||||
else
|
||||
{
|
||||
for( end = i; (end >= 0) && isspace((int)InFile->bufr[end]); end-- )
|
||||
;
|
||||
c = mygetc( InFile );
|
||||
}
|
||||
break;
|
||||
|
||||
default: /* All others verbatim. Note that spaces do */
|
||||
InFile->bufr[i++] = c; /* not advance <end>. This allows trimming */
|
||||
if( !isspace( c ) ) /* of whitespace at the end of the line. */
|
||||
end = i;
|
||||
c = mygetc( InFile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
InFile->bufr[end] = '\0'; /* End of value. */
|
||||
|
||||
return( pfunc( InFile->bufr, &InFile->bufr[vstart], userdata ) ); /* Pass name & value to pfunc(). */
|
||||
} /* Parameter */
|
||||
|
||||
static BOOL Parse( myFILE *InFile,
|
||||
BOOL (*sfunc)(const char *, void *),
|
||||
BOOL (*pfunc)(const char *, const char *, void *),
|
||||
void *userdata )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Scan & parse the input.
|
||||
*
|
||||
* Input: InFile - Input source.
|
||||
* sfunc - Function to be called when a section name is scanned.
|
||||
* See Section().
|
||||
* pfunc - Function to be called when a parameter is scanned.
|
||||
* See Parameter().
|
||||
*
|
||||
* Output: True if the file was successfully scanned, else False.
|
||||
*
|
||||
* Notes: The input can be viewed in terms of 'lines'. There are four
|
||||
* types of lines:
|
||||
* Blank - May contain whitespace, otherwise empty.
|
||||
* Comment - First non-whitespace character is a ';' or '#'.
|
||||
* The remainder of the line is ignored.
|
||||
* Section - First non-whitespace character is a '['.
|
||||
* Parameter - The default case.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int c;
|
||||
|
||||
c = EatWhitespace( InFile );
|
||||
while( (EOF != c) && (c > 0) )
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case '\n': /* Blank line. */
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case ';': /* Comment line. */
|
||||
case '#':
|
||||
c = EatComment( InFile );
|
||||
break;
|
||||
|
||||
case '[': /* Section Header. */
|
||||
if( !Section( InFile, sfunc, userdata ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
case '\\': /* Bogus backslash. */
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
|
||||
default: /* Parameter line. */
|
||||
if( !Parameter( InFile, pfunc, c, userdata ) )
|
||||
return( False );
|
||||
c = EatWhitespace( InFile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return( True );
|
||||
} /* Parse */
|
||||
|
||||
static myFILE *OpenConfFile( const char *FileName )
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Open a configuration file.
|
||||
*
|
||||
* Input: FileName - The pathname of the config file to be opened.
|
||||
*
|
||||
* Output: A pointer of type (char **) to the lines of the file
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
const char *func = "params.c:OpenConfFile() -";
|
||||
myFILE *ret;
|
||||
|
||||
ret = talloc(talloc_autofree_context(), myFILE);
|
||||
if (!ret) return NULL;
|
||||
|
||||
ret->buf = file_load(FileName, &ret->size, ret);
|
||||
if( NULL == ret->buf )
|
||||
{
|
||||
DEBUG( 1,
|
||||
("%s Unable to open configuration file \"%s\":\n\t%s\n",
|
||||
func, FileName, strerror(errno)) );
|
||||
talloc_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->p = ret->buf;
|
||||
ret->bufr = NULL;
|
||||
ret->bSize = 0;
|
||||
return( ret );
|
||||
} /* OpenConfFile */
|
||||
|
||||
BOOL pm_process( const char *FileName,
|
||||
BOOL (*sfunc)(const char *, void *),
|
||||
BOOL (*pfunc)(const char *, const char *, void *),
|
||||
void *userdata)
|
||||
/* ------------------------------------------------------------------------ **
|
||||
* Process the named parameter file.
|
||||
*
|
||||
* Input: FileName - The pathname of the parameter file to be opened.
|
||||
* sfunc - A pointer to a function that will be called when
|
||||
* a section name is discovered.
|
||||
* pfunc - A pointer to a function that will be called when
|
||||
* a parameter name and value are discovered.
|
||||
*
|
||||
* Output: TRUE if the file was successfully parsed, else FALSE.
|
||||
*
|
||||
* ------------------------------------------------------------------------ **
|
||||
*/
|
||||
{
|
||||
int result;
|
||||
myFILE *InFile;
|
||||
const char *func = "params.c:pm_process() -";
|
||||
|
||||
InFile = OpenConfFile( FileName ); /* Open the config file. */
|
||||
if( NULL == InFile )
|
||||
return( False );
|
||||
|
||||
DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) );
|
||||
|
||||
if( NULL != InFile->bufr ) /* If we already have a buffer */
|
||||
result = Parse( InFile, sfunc, pfunc, userdata ); /* (recursive call), then just */
|
||||
/* use it. */
|
||||
|
||||
else /* If we don't have a buffer */
|
||||
{ /* allocate one, then parse, */
|
||||
InFile->bSize = BUFR_INC; /* then free. */
|
||||
InFile->bufr = talloc_array(InFile, char, InFile->bSize );
|
||||
if( NULL == InFile->bufr )
|
||||
{
|
||||
DEBUG(0,("%s memory allocation failure.\n", func));
|
||||
myfile_close(InFile);
|
||||
return( False );
|
||||
}
|
||||
result = Parse( InFile, sfunc, pfunc, userdata );
|
||||
InFile->bufr = NULL;
|
||||
InFile->bSize = 0;
|
||||
}
|
||||
|
||||
myfile_close(InFile);
|
||||
|
||||
if( !result ) /* Generic failure. */
|
||||
{
|
||||
DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func));
|
||||
return( False );
|
||||
}
|
||||
|
||||
return( True ); /* Generic success. */
|
||||
} /* pm_process */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Copyright (C) Andrew Tridgell 1992-2001
|
||||
Copyright (C) Andrew Bartlett 2002
|
||||
Copyright (C) Rafal Szczesniak 2002
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/* the Samba secrets database stores any generated, private information
|
||||
such as the local SID and machine trust password */
|
||||
|
||||
#include "includes.h"
|
||||
#include "secrets.h"
|
||||
#include "param/param.h"
|
||||
#include "system/filesys.h"
|
||||
#include "db_wrap.h"
|
||||
#include "lib/ldb/include/ldb.h"
|
||||
#include "lib/tdb/include/tdb.h"
|
||||
#include "lib/util/util_tdb.h"
|
||||
#include "dsdb/samdb/samdb.h"
|
||||
|
||||
static struct tdb_wrap *tdb;
|
||||
|
||||
/**
|
||||
* Use a TDB to store an incrementing random seed.
|
||||
*
|
||||
* Initialised to the current pid, the very first time Samba starts,
|
||||
* and incremented by one each time it is needed.
|
||||
*
|
||||
* @note Not called by systems with a working /dev/urandom.
|
||||
*/
|
||||
static void get_rand_seed(int *new_seed)
|
||||
{
|
||||
*new_seed = getpid();
|
||||
if (tdb) {
|
||||
tdb_change_int32_atomic(tdb->tdb, "INFO/random_seed", new_seed, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* close the secrets database */
|
||||
void secrets_shutdown(void)
|
||||
{
|
||||
talloc_free(tdb);
|
||||
}
|
||||
|
||||
/* open up the secrets database */
|
||||
BOOL secrets_init(void)
|
||||
{
|
||||
char *fname;
|
||||
uint8_t dummy;
|
||||
|
||||
if (tdb)
|
||||
return True;
|
||||
|
||||
asprintf(&fname, "%s/secrets.tdb", lp_private_dir());
|
||||
|
||||
tdb = tdb_wrap_open(talloc_autofree_context(), fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
|
||||
|
||||
if (!tdb) {
|
||||
DEBUG(0,("Failed to open %s\n", fname));
|
||||
SAFE_FREE(fname);
|
||||
return False;
|
||||
}
|
||||
SAFE_FREE(fname);
|
||||
|
||||
/**
|
||||
* Set a reseed function for the crypto random generator
|
||||
*
|
||||
* This avoids a problem where systems without /dev/urandom
|
||||
* could send the same challenge to multiple clients
|
||||
*/
|
||||
set_rand_reseed_callback(get_rand_seed);
|
||||
|
||||
/* Ensure that the reseed is done now, while we are root, etc */
|
||||
generate_random_buffer(&dummy, sizeof(dummy));
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*
|
||||
connect to the schannel ldb
|
||||
*/
|
||||
struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
char *path;
|
||||
struct ldb_context *ldb;
|
||||
BOOL existed;
|
||||
const char *init_ldif =
|
||||
"dn: @ATTRIBUTES\n" \
|
||||
"computerName: CASE_INSENSITIVE\n" \
|
||||
"flatname: CASE_INSENSITIVE\n";
|
||||
|
||||
path = private_path(mem_ctx, "secrets.ldb");
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
existed = file_exist(path);
|
||||
|
||||
/* Secrets.ldb *must* always be local. If we call for a
|
||||
* system_session() we will recurse */
|
||||
ldb = ldb_wrap_connect(mem_ctx, path, NULL, NULL, 0, NULL);
|
||||
talloc_free(path);
|
||||
if (!ldb) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!existed) {
|
||||
gendb_add_ldif(ldb, init_ldif);
|
||||
}
|
||||
|
||||
return ldb;
|
||||
}
|
||||
|
||||
struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx,
|
||||
const char *domain)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message **msgs;
|
||||
int ldb_ret;
|
||||
const char *attrs[] = { "objectSid", NULL };
|
||||
struct dom_sid *result = NULL;
|
||||
|
||||
ldb = secrets_db_connect(mem_ctx);
|
||||
if (ldb == NULL) {
|
||||
DEBUG(5, ("secrets_db_connect failed\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldb_ret = gendb_search(ldb, ldb,
|
||||
ldb_dn_new(mem_ctx, ldb, SECRETS_PRIMARY_DOMAIN_DN),
|
||||
&msgs, attrs,
|
||||
SECRETS_PRIMARY_DOMAIN_FILTER, domain);
|
||||
|
||||
if (ldb_ret == -1) {
|
||||
DEBUG(5, ("Error searching for domain SID for %s: %s",
|
||||
domain, ldb_errstring(ldb)));
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ldb_ret == 0) {
|
||||
DEBUG(5, ("Did not find domain record for %s\n", domain));
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ldb_ret > 1) {
|
||||
DEBUG(5, ("Found more than one (%d) domain records for %s\n",
|
||||
ldb_ret, domain));
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = samdb_result_dom_sid(mem_ctx, msgs[0], "objectSid");
|
||||
if (result == NULL) {
|
||||
DEBUG(0, ("Domain object for %s does not contain a SID!\n",
|
||||
domain));
|
||||
talloc_free(ldb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* secrets.tdb file format info
|
||||
* Copyright (C) Andrew Tridgell 2000
|
||||
*
|
||||
* 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 _SECRETS_H
|
||||
#define _SECRETS_H
|
||||
|
||||
/* structure for storing machine account password
|
||||
(ie. when samba server is member of a domain */
|
||||
struct machine_acct_pass {
|
||||
uint8_t hash[16];
|
||||
time_t mod_time;
|
||||
};
|
||||
|
||||
#define SECRETS_PRIMARY_DOMAIN_DN "cn=Primary Domains"
|
||||
#define SECRETS_PRINCIPALS_DN "cn=Principals"
|
||||
#define SECRETS_PRIMARY_DOMAIN_FILTER "(&(flatname=%s)(objectclass=primaryDomain))"
|
||||
#define SECRETS_PRIMARY_REALM_FILTER "(&(realm=%s)(objectclass=primaryDomain))"
|
||||
#define SECRETS_KRBTGT_SEARCH "(&((|(realm=%s)(flatname=%s))(samAccountName=krbtgt)))"
|
||||
#define SECRETS_PRINCIPAL_SEARCH "(&(|(realm=%s)(flatname=%s))(servicePrincipalName=%s))"
|
||||
|
||||
#include "param/secrets_proto.h"
|
||||
|
||||
#endif /* _SECRETS_H */
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Modular services configuration system
|
||||
|
||||
Copyright (C) Simo Sorce 2006
|
||||
|
||||
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 "param/share.h"
|
||||
#include "build.h"
|
||||
|
||||
const char *share_string_option(struct share_config *scfg, const char *opt_name, const char *defval)
|
||||
{
|
||||
return scfg->ctx->ops->string_option(scfg, opt_name, defval);
|
||||
}
|
||||
|
||||
int share_int_option(struct share_config *scfg, const char *opt_name, int defval)
|
||||
{
|
||||
return scfg->ctx->ops->int_option(scfg, opt_name, defval);
|
||||
}
|
||||
|
||||
BOOL share_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval)
|
||||
{
|
||||
return scfg->ctx->ops->bool_option(scfg, opt_name, defval);
|
||||
}
|
||||
|
||||
const char **share_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
|
||||
{
|
||||
return scfg->ctx->ops->string_list_option(mem_ctx, scfg, opt_name);
|
||||
}
|
||||
|
||||
NTSTATUS share_list_all(TALLOC_CTX *mem_ctx, struct share_context *sctx, int *count, const char ***names)
|
||||
{
|
||||
return sctx->ops->list_all(mem_ctx, sctx, count, names);
|
||||
}
|
||||
|
||||
NTSTATUS share_get_config(TALLOC_CTX *mem_ctx, struct share_context *sctx, const char *name, struct share_config **scfg)
|
||||
{
|
||||
return sctx->ops->get_config(mem_ctx, sctx, name, scfg);
|
||||
}
|
||||
|
||||
NTSTATUS share_create(struct share_context *sctx, const char *name, struct share_info *info, int count)
|
||||
{
|
||||
if (sctx->ops->create) {
|
||||
return sctx->ops->create(sctx, name, info, count);
|
||||
}
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS share_set(struct share_context *sctx, const char *name, struct share_info *info, int count)
|
||||
{
|
||||
if (sctx->ops->set) {
|
||||
return sctx->ops->set(sctx, name, info, count);
|
||||
}
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS share_remove(struct share_context *sctx, const char *name)
|
||||
{
|
||||
if (sctx->ops->remove) {
|
||||
return sctx->ops->remove(sctx, name);
|
||||
}
|
||||
return NT_STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* List of currently available share backends */
|
||||
static struct share_ops **backends = NULL;
|
||||
|
||||
static const struct share_ops *share_backend_by_name(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; backends && backends[i]; i++) {
|
||||
if (strcmp(backends[i]->name, name) == 0) {
|
||||
return backends[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Register the share backend
|
||||
*/
|
||||
NTSTATUS share_register(const struct share_ops *ops)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (share_backend_by_name(ops->name) != NULL) {
|
||||
DEBUG(0,("SHARE backend [%s] already registered\n", ops->name));
|
||||
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (backends && backends[i]) {
|
||||
i++;
|
||||
}
|
||||
|
||||
backends = realloc_p(backends, struct share_ops *, i + 2);
|
||||
if (!backends) {
|
||||
smb_panic("out of memory in share_register");
|
||||
}
|
||||
|
||||
backends[i] = malloc(sizeof(struct share_ops));
|
||||
if (!backends[i]) {
|
||||
smb_panic("out of memory in share_register");
|
||||
}
|
||||
|
||||
backends[i] = smb_xmemdup(ops, sizeof(*ops));
|
||||
backends[i]->name = smb_xstrdup(ops->name);
|
||||
|
||||
backends[i + 1] = NULL;
|
||||
|
||||
DEBUG(3, ("SHARE backend [%s] registered.\n", ops->name));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS share_get_context(TALLOC_CTX *mem_ctx, struct share_context **ctx)
|
||||
{
|
||||
const struct share_ops *ops;
|
||||
|
||||
ops = share_backend_by_name(lp_share_backend());
|
||||
if (!ops) {
|
||||
DEBUG(0, ("share_init_connection: share backend [%s] not found!\n", lp_share_backend()));
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return ops->init(mem_ctx, ops, ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
initialise the SHARE subsystem
|
||||
*/
|
||||
NTSTATUS share_init(void)
|
||||
{
|
||||
init_module_fn static_init[] = STATIC_share_MODULES;
|
||||
init_module_fn *shared_init = load_samba_modules(NULL, "share");
|
||||
|
||||
run_init_functions(static_init);
|
||||
run_init_functions(shared_init);
|
||||
|
||||
talloc_free(shared_init);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Modular services configuration
|
||||
|
||||
Copyright (C) Simo Sorce 2006
|
||||
|
||||
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 _SHARE_H
|
||||
#define _SHARE_H
|
||||
|
||||
struct share_ops;
|
||||
|
||||
struct share_context {
|
||||
const struct share_ops *ops;
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
struct share_config {
|
||||
const char *name;
|
||||
struct share_context *ctx;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
enum share_info_type {
|
||||
SHARE_INFO_STRING,
|
||||
SHARE_INFO_INT,
|
||||
SHARE_INFO_BLOB
|
||||
};
|
||||
|
||||
struct share_info {
|
||||
enum share_info_type type;
|
||||
const char *name;
|
||||
void *value;
|
||||
};
|
||||
|
||||
struct share_ops {
|
||||
const char *name;
|
||||
NTSTATUS (*init)(TALLOC_CTX *, const struct share_ops*, struct share_context **);
|
||||
const char *(*string_option)(struct share_config *, const char *, const char *);
|
||||
int (*int_option)(struct share_config *, const char *, int);
|
||||
BOOL (*bool_option)(struct share_config *, const char *, BOOL);
|
||||
const char **(*string_list_option)(TALLOC_CTX *, struct share_config *, const char *);
|
||||
NTSTATUS (*list_all)(TALLOC_CTX *, struct share_context *, int *, const char ***);
|
||||
NTSTATUS (*get_config)(TALLOC_CTX *, struct share_context *, const char *, struct share_config **);
|
||||
NTSTATUS (*create)(struct share_context *, const char *, struct share_info *, int);
|
||||
NTSTATUS (*set)(struct share_context *, const char *, struct share_info *, int);
|
||||
NTSTATUS (*remove)(struct share_context *, const char *);
|
||||
};
|
||||
|
||||
#include "param/share_proto.h"
|
||||
|
||||
/* list of shares options */
|
||||
|
||||
#define SHARE_NAME "name"
|
||||
#define SHARE_PATH "path"
|
||||
#define SHARE_COMMENT "comment"
|
||||
#define SHARE_PASSWORD "password"
|
||||
#define SHARE_HOSTS_ALLOW "hosts-allow"
|
||||
#define SHARE_HOSTS_DENY "hosts-deny"
|
||||
#define SHARE_NTVFS_HANDLER "ntvfs-handler"
|
||||
#define SHARE_TYPE "type"
|
||||
#define SHARE_VOLUME "volume"
|
||||
#define SHARE_CSC_POLICY "csc-policy"
|
||||
#define SHARE_AVAILABLE "available"
|
||||
#define SHARE_BROWSEABLE "browseable"
|
||||
#define SHARE_MAX_CONNECTIONS "max-connections"
|
||||
|
||||
/* I'd like to see the following options go away
|
||||
* and always use EAs and SECDESCs */
|
||||
#define SHARE_READONLY "readonly"
|
||||
#define SHARE_MAP_SYSTEM "map-system"
|
||||
#define SHARE_MAP_HIDDEN "map-hidden"
|
||||
#define SHARE_MAP_ARCHIVE "map-archive"
|
||||
|
||||
#define SHARE_STRICT_LOCKING "strict-locking"
|
||||
#define SHARE_STRICT_SYNC "strict-sync"
|
||||
#define SHARE_MSDFS_ROOT "msdfs-root"
|
||||
#define SHARE_CI_FILESYSTEM "ci-filesystem"
|
||||
|
||||
/* defaults */
|
||||
|
||||
#define SHARE_HOST_ALLOW_DEFAULT NULL
|
||||
#define SHARE_HOST_DENY_DEFAULT NULL
|
||||
#define SHARE_VOLUME_DEFAULT NULL
|
||||
#define SHARE_TYPE_DEFAULT "DISK"
|
||||
#define SHARE_CSC_POLICY_DEFAULT 0
|
||||
#define SHARE_AVAILABLE_DEFAULT True
|
||||
#define SHARE_BROWSEABLE_DEFAULT True
|
||||
#define SHARE_MAX_CONNECTIONS_DEFAULT 0
|
||||
|
||||
/* I'd like to see the following options go away
|
||||
* and always use EAs and SECDESCs */
|
||||
#define SHARE_READONLY_DEFAULT True
|
||||
#define SHARE_MAP_SYSTEM_DEFAULT False
|
||||
#define SHARE_MAP_HIDDEN_DEFAULT False
|
||||
#define SHARE_MAP_ARCHIVE_DEFAULT True
|
||||
|
||||
#define SHARE_STRICT_LOCKING_DEFAULT True
|
||||
#define SHARE_STRICT_SYNC_DEFAULT False
|
||||
#define SHARE_MSDFS_ROOT_DEFAULT False
|
||||
#define SHARE_CI_FILESYSTEM_DEFAULT False
|
||||
|
||||
#endif /* _SHARE_H */
|
||||
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Classic file based services configuration
|
||||
|
||||
Copyright (C) Simo Sorce 2006
|
||||
|
||||
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 "param/share.h"
|
||||
|
||||
struct sclassic_snum {
|
||||
int snum;
|
||||
};
|
||||
|
||||
static NTSTATUS sclassic_init(TALLOC_CTX *mem_ctx, const struct share_ops *ops, struct share_context **ctx)
|
||||
{
|
||||
*ctx = talloc(mem_ctx, struct share_context);
|
||||
if (!*ctx) {
|
||||
DEBUG(0, ("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
(*ctx)->ops = ops;
|
||||
(*ctx)->priv_data = NULL;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static const char *sclassic_string_option(struct share_config *scfg, const char *opt_name, const char *defval)
|
||||
{
|
||||
struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
|
||||
char *parm, *val;
|
||||
const char *ret;
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
parm = talloc_strdup(scfg, opt_name);
|
||||
if (!parm) {
|
||||
return NULL;
|
||||
}
|
||||
val = strchr(parm, ':');
|
||||
*val = '\0';
|
||||
val++;
|
||||
|
||||
ret = lp_parm_string(s->snum, parm, val);
|
||||
if (!ret) {
|
||||
ret = defval;
|
||||
}
|
||||
talloc_free(parm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_NAME) == 0) {
|
||||
return scfg->name;
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_PATH) == 0) {
|
||||
return lp_pathname(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_COMMENT) == 0) {
|
||||
return lp_comment(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_VOLUME) == 0) {
|
||||
return volume_label(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_TYPE) == 0) {
|
||||
if (lp_print_ok(s->snum)) {
|
||||
return "PRINTER";
|
||||
}
|
||||
if (strcmp("NTFS", lp_fstype(s->snum)) == 0) {
|
||||
return "DISK";
|
||||
}
|
||||
return lp_fstype(s->snum);
|
||||
}
|
||||
|
||||
return defval;
|
||||
}
|
||||
|
||||
int sclassic_int_option(struct share_config *scfg, const char *opt_name, int defval)
|
||||
{
|
||||
struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
|
||||
char *parm, *val;
|
||||
int ret;
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
parm = talloc_strdup(scfg, opt_name);
|
||||
if (!parm) {
|
||||
return -1;
|
||||
}
|
||||
val = strchr(parm, ':');
|
||||
*val = '\0';
|
||||
val++;
|
||||
|
||||
ret = lp_parm_int(s->snum, parm, val, defval);
|
||||
if (!ret) {
|
||||
ret = defval;
|
||||
}
|
||||
talloc_free(parm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_CSC_POLICY) == 0) {
|
||||
ret = lp_csc_policy(s->snum);
|
||||
if (ret == -1) {
|
||||
return defval;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_MAX_CONNECTIONS) == 0) {
|
||||
ret = lp_max_connections(s->snum);
|
||||
if (ret == -1) {
|
||||
return defval;
|
||||
}
|
||||
}
|
||||
|
||||
return defval;
|
||||
}
|
||||
|
||||
BOOL sclassic_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval)
|
||||
{
|
||||
struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
|
||||
char *parm, *val;
|
||||
BOOL ret;
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
parm = talloc_strdup(scfg, opt_name);
|
||||
if(!parm) {
|
||||
return False;
|
||||
}
|
||||
val = strchr(parm, ':');
|
||||
*val = '\0';
|
||||
val++;
|
||||
|
||||
ret = lp_parm_bool(s->snum, parm, val, defval);
|
||||
talloc_free(parm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_AVAILABLE) == 0) {
|
||||
return lp_snum_ok(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_BROWSEABLE) == 0) {
|
||||
return lp_browseable(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_READONLY) == 0) {
|
||||
return lp_readonly(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_MAP_SYSTEM) == 0) {
|
||||
return lp_map_system(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_MAP_HIDDEN) == 0) {
|
||||
return lp_map_hidden(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_MAP_ARCHIVE) == 0) {
|
||||
return lp_map_archive(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_STRICT_LOCKING) == 0) {
|
||||
return lp_strict_locking(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_STRICT_SYNC) == 0) {
|
||||
return lp_strict_sync(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_MSDFS_ROOT) == 0) {
|
||||
return lp_msdfs_root(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_CI_FILESYSTEM) == 0) {
|
||||
return lp_ci_filesystem(s->snum);
|
||||
}
|
||||
|
||||
return defval;
|
||||
}
|
||||
|
||||
const char **sclassic_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
|
||||
{
|
||||
struct sclassic_snum *s = talloc_get_type(scfg->opaque, struct sclassic_snum);
|
||||
char *parm, *val;
|
||||
const char **ret;
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
parm = talloc_strdup(scfg, opt_name);
|
||||
if (!parm) {
|
||||
return NULL;
|
||||
}
|
||||
val = strchr(parm, ':');
|
||||
*val = '\0';
|
||||
val++;
|
||||
|
||||
ret = lp_parm_string_list(s->snum, parm, val, ",;");
|
||||
talloc_free(parm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_HOSTS_ALLOW) == 0) {
|
||||
return lp_hostsallow(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_HOSTS_DENY) == 0) {
|
||||
return lp_hostsdeny(s->snum);
|
||||
}
|
||||
|
||||
if (strcmp(opt_name, SHARE_NTVFS_HANDLER) == 0) {
|
||||
return lp_ntvfs_handler(s->snum);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS sclassic_list_all(TALLOC_CTX *mem_ctx,
|
||||
struct share_context *ctx,
|
||||
int *count,
|
||||
const char ***names)
|
||||
{
|
||||
int i;
|
||||
int num_services;
|
||||
const char **n;
|
||||
|
||||
num_services = lp_numservices();
|
||||
|
||||
n = talloc_array(mem_ctx, const char *, num_services);
|
||||
if (!n) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_services; i++) {
|
||||
n[i] = talloc_strdup(n, lp_servicename(i));
|
||||
if (!n[i]) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
talloc_free(n);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
*names = n;
|
||||
*count = num_services;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS sclassic_get_config(TALLOC_CTX *mem_ctx,
|
||||
struct share_context *ctx,
|
||||
const char *name,
|
||||
struct share_config **scfg)
|
||||
{
|
||||
int i, snum;
|
||||
struct share_config *s;
|
||||
struct sclassic_snum *scnum;
|
||||
|
||||
snum = -1;
|
||||
for (i = 0; i < lp_numservices(); i++) {
|
||||
if (strcasecmp_m(name, lp_servicename(i)) == 0) {
|
||||
snum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (snum < 0) {
|
||||
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
|
||||
s = talloc(mem_ctx, struct share_config);
|
||||
if (!s) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
s->name = talloc_strdup(s, lp_servicename(snum));
|
||||
if (!s->name) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
talloc_free(s);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
scnum = talloc(s, struct sclassic_snum);
|
||||
if (!scnum) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
talloc_free(s);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
scnum->snum = snum;
|
||||
|
||||
s->opaque = (void *)scnum;
|
||||
s->ctx = ctx;
|
||||
|
||||
*scfg = s;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS share_classic_init(void)
|
||||
{
|
||||
static struct share_ops ops = {
|
||||
.name = "classic",
|
||||
.init = sclassic_init,
|
||||
.string_option = sclassic_string_option,
|
||||
.int_option = sclassic_int_option,
|
||||
.bool_option = sclassic_bool_option,
|
||||
.string_list_option = sclassic_string_list_option,
|
||||
.list_all = sclassic_list_all,
|
||||
.get_config = sclassic_get_config
|
||||
};
|
||||
|
||||
return share_register(&ops);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
LDB based services configuration
|
||||
|
||||
Copyright (C) Simo Sorce 2006
|
||||
|
||||
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 "ldb/include/ldb.h"
|
||||
#include "ldb/include/ldb_errors.h"
|
||||
#include "auth/auth.h"
|
||||
#include "db_wrap.h"
|
||||
#include "param/share.h"
|
||||
|
||||
static NTSTATUS sldb_init(TALLOC_CTX *mem_ctx, const struct share_ops *ops, struct share_context **ctx)
|
||||
{
|
||||
struct ldb_context *sdb;
|
||||
|
||||
*ctx = talloc(mem_ctx, struct share_context);
|
||||
if (!*ctx) {
|
||||
DEBUG(0, ("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
sdb = ldb_wrap_connect( *ctx,
|
||||
private_path(*ctx, "share.ldb"),
|
||||
system_session(*ctx),
|
||||
NULL, 0, NULL);
|
||||
|
||||
if (!sdb) {
|
||||
talloc_free(*ctx);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
(*ctx)->ops = ops;
|
||||
(*ctx)->priv_data = (void *)sdb;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static const char *sldb_string_option(struct share_config *scfg, const char *opt_name, const char *defval)
|
||||
{
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message_element *el;
|
||||
|
||||
if (scfg == NULL) return defval;
|
||||
|
||||
msg = talloc_get_type(scfg->opaque, struct ldb_message);
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
char *name, *p;
|
||||
|
||||
name = talloc_strdup(scfg, opt_name);
|
||||
if (!name) {
|
||||
return NULL;
|
||||
}
|
||||
p = strchr(name, ':');
|
||||
*p = '-';
|
||||
|
||||
el = ldb_msg_find_element(msg, name);
|
||||
} else {
|
||||
el = ldb_msg_find_element(msg, opt_name);
|
||||
}
|
||||
|
||||
if (el == NULL) {
|
||||
return defval;
|
||||
}
|
||||
|
||||
return (const char *)(el->values[0].data);
|
||||
}
|
||||
|
||||
static int sldb_int_option(struct share_config *scfg, const char *opt_name, int defval)
|
||||
{
|
||||
const char *val;
|
||||
int ret;
|
||||
|
||||
val = sldb_string_option(scfg, opt_name, NULL);
|
||||
if (val == NULL) return defval;
|
||||
|
||||
errno = 0;
|
||||
ret = (int)strtol(val, NULL, 10);
|
||||
if (errno) return -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL sldb_bool_option(struct share_config *scfg, const char *opt_name, BOOL defval)
|
||||
{
|
||||
const char *val;
|
||||
|
||||
val = sldb_string_option(scfg, opt_name, NULL);
|
||||
if (val == NULL) return defval;
|
||||
|
||||
if (strcasecmp(val, "true") == 0) return True;
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
static const char **sldb_string_list_option(TALLOC_CTX *mem_ctx, struct share_config *scfg, const char *opt_name)
|
||||
{
|
||||
struct ldb_message *msg;
|
||||
struct ldb_message_element *el;
|
||||
const char **list;
|
||||
int i;
|
||||
|
||||
if (scfg == NULL) return NULL;
|
||||
|
||||
msg = talloc_get_type(scfg->opaque, struct ldb_message);
|
||||
|
||||
if (strchr(opt_name, ':')) {
|
||||
char *name, *p;
|
||||
|
||||
name = talloc_strdup(scfg, opt_name);
|
||||
if (!name) {
|
||||
return NULL;
|
||||
}
|
||||
p = strchr(name, ':');
|
||||
*p = '-';
|
||||
|
||||
el = ldb_msg_find_element(msg, name);
|
||||
} else {
|
||||
el = ldb_msg_find_element(msg, opt_name);
|
||||
}
|
||||
|
||||
if (el == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list = talloc_array(mem_ctx, const char *, el->num_values + 1);
|
||||
if (!list) return NULL;
|
||||
|
||||
for (i = 0; i < el->num_values; i++) {
|
||||
list[i] = (const char *)(el->values[i].data);
|
||||
}
|
||||
list[i] = NULL;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static NTSTATUS sldb_list_all(TALLOC_CTX *mem_ctx,
|
||||
struct share_context *ctx,
|
||||
int *count,
|
||||
const char ***names)
|
||||
{
|
||||
int ret, i, j;
|
||||
const char **n;
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_result *res;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
ret = ldb_search(ldb, ldb_dn_new(tmp_ctx, ldb, "CN=SHARES"), LDB_SCOPE_SUBTREE, "(name=*)", NULL, &res);
|
||||
talloc_steal(tmp_ctx, res);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
n = talloc_array(mem_ctx, const char *, res->count);
|
||||
if (!n) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < res->count; i++) {
|
||||
n[j] = talloc_strdup(n, ldb_msg_find_attr_as_string(res->msgs[i], "name", NULL));
|
||||
if (!n[j]) {
|
||||
DEBUG(0,("WARNING: Malformed share object in share database\n!"));
|
||||
continue;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
*names = n;
|
||||
*count = j;
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS sldb_get_config(TALLOC_CTX *mem_ctx,
|
||||
struct share_context *ctx,
|
||||
const char *name,
|
||||
struct share_config **scfg)
|
||||
{
|
||||
int ret;
|
||||
struct share_config *s;
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_result *res;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
|
||||
tmp_ctx = talloc_new(mem_ctx);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
ret = ldb_search_exp_fmt(ldb, tmp_ctx, &res,
|
||||
ldb_dn_new(tmp_ctx, ldb, "CN=SHARES"), LDB_SCOPE_SUBTREE, NULL,
|
||||
"(name=%s)", name);
|
||||
if (ret != LDB_SUCCESS || res->count != 1) {
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_BAD_NETWORK_NAME;
|
||||
}
|
||||
|
||||
s = talloc(tmp_ctx, struct share_config);
|
||||
if (!s) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
s->name = talloc_strdup(s, ldb_msg_find_attr_as_string(res->msgs[0], "name", NULL));
|
||||
if (!s->name) {
|
||||
DEBUG(0,("ERROR: Invalid share object!\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
s->opaque = talloc_steal(s, res->msgs[0]);
|
||||
if (!s->opaque) {
|
||||
DEBUG(0,("ERROR: Invalid share object!\n"));
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
s->ctx = ctx;
|
||||
|
||||
*scfg = talloc_steal(mem_ctx, s);
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
#define SHARE_ADD_STRING(name, value) do { \
|
||||
err = ldb_msg_add_string(msg, name, value); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add string share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
#define SHARE_ADD_INT(name, value) do { \
|
||||
err = ldb_msg_add_fmt(msg, name, "%d", value); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add integer share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
#define SHARE_ADD_BLOB(name, value) do { \
|
||||
err = ldb_msg_add_value(msg, name, value, NULL); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add blob share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
NTSTATUS sldb_create(struct share_context *ctx, const char *name, struct share_info *info, int count)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message *msg;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS ret;
|
||||
int err, i, j;
|
||||
|
||||
for (i = 0, j = 0; i < count || j != 0x03; i++) {
|
||||
if (strcasecmp(info[i].name, SHARE_TYPE) == 0) j |= 0x02;
|
||||
if (strcasecmp(info[i].name, SHARE_PATH) == 0) j |= 0x01;
|
||||
if (strcasecmp(info[i].name, SHARE_NAME) == 0) {
|
||||
if (strcasecmp(name, (char *)info[i].value) != 0) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!name || j != 0x03) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
msg = ldb_msg_new(tmp_ctx);
|
||||
if (!msg) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: escape info->name */
|
||||
msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
|
||||
if (!msg->dn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
SHARE_ADD_STRING("objectClass", "top");
|
||||
SHARE_ADD_STRING("objectClass", "share");
|
||||
SHARE_ADD_STRING("cn", name);
|
||||
SHARE_ADD_STRING(SHARE_NAME, name);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (strcasecmp(info[i].name, SHARE_NAME) == 0) continue;
|
||||
|
||||
switch (info[i].type) {
|
||||
case SHARE_INFO_STRING:
|
||||
SHARE_ADD_STRING(info[i].name, (char *)info[i].value);
|
||||
break;
|
||||
case SHARE_INFO_INT:
|
||||
SHARE_ADD_INT(info[i].name, *((int *)info[i].value));
|
||||
break;
|
||||
case SHARE_INFO_BLOB:
|
||||
SHARE_ADD_BLOB(info[i].name, (DATA_BLOB *)info[i].value);
|
||||
break;
|
||||
default:
|
||||
DEBUG(2,("ERROR: Invalid share info type for %s\n", info[i].name));
|
||||
ret = NT_STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Security Descriptor */
|
||||
|
||||
SHARE_ADD_STRING(SHARE_AVAILABLE, "True");
|
||||
SHARE_ADD_STRING(SHARE_BROWSEABLE, "True");
|
||||
SHARE_ADD_STRING(SHARE_READONLY, "False");
|
||||
SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "unixuid");
|
||||
SHARE_ADD_STRING(SHARE_NTVFS_HANDLER, "posix");
|
||||
|
||||
err = ldb_add(ldb, msg);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to add share %s to share.ldb\n"
|
||||
" err=%d [%s]\n", name, err, ldb_errstring(ldb)));
|
||||
if (err == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
ret = NT_STATUS_BAD_NETWORK_NAME;
|
||||
} else {
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK;
|
||||
done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define SHARE_MOD_STRING(name, value) do { \
|
||||
err = ldb_msg_add_empty(msg, name, LDB_FLAG_MOD_REPLACE, NULL); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add string share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} \
|
||||
err = ldb_msg_add_string(msg, name, value); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add string share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
#define SHARE_MOD_INT(name, value) do { \
|
||||
err = ldb_msg_add_empty(msg, name, LDB_FLAG_MOD_REPLACE, NULL); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add string share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} \
|
||||
err = ldb_msg_add_fmt(msg, name, "%d", value); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add integer share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
#define SHARE_MOD_BLOB(name, value) do { \
|
||||
err = ldb_msg_add_empty(msg, name, LDB_FLAG_MOD_REPLACE, NULL); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add string share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} \
|
||||
err = ldb_msg_add_value(msg, name, value, NULL); \
|
||||
if (err != LDB_SUCCESS) { \
|
||||
DEBUG(2,("ERROR: unable to add blob share option %s to ldb msg\n", name)); \
|
||||
ret = NT_STATUS_UNSUCCESSFUL; \
|
||||
goto done; \
|
||||
} } while(0)
|
||||
|
||||
NTSTATUS sldb_set(struct share_context *ctx, const char *name, struct share_info *info, int count)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message *msg;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS ret;
|
||||
bool do_rename = False;
|
||||
char *newname;
|
||||
int err, i;
|
||||
|
||||
if (!name) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
msg = ldb_msg_new(tmp_ctx);
|
||||
if (!msg) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* TODO: escape name */
|
||||
msg->dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
|
||||
if (!msg->dn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (strcasecmp(info[i].name, SHARE_NAME) == 0) {
|
||||
if (strcasecmp(name, (char *)info[i].value) != 0) {
|
||||
do_rename = True;
|
||||
newname = (char *)info[i].value;
|
||||
SHARE_MOD_STRING("cn", (char *)info[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
switch (info[i].type) {
|
||||
case SHARE_INFO_STRING:
|
||||
SHARE_MOD_STRING(info[i].name, (char *)info[i].value);
|
||||
break;
|
||||
case SHARE_INFO_INT:
|
||||
SHARE_MOD_INT(info[i].name, *((int *)info[i].value));
|
||||
break;
|
||||
case SHARE_INFO_BLOB:
|
||||
SHARE_MOD_BLOB(info[i].name, (DATA_BLOB *)info[i].value);
|
||||
break;
|
||||
default:
|
||||
DEBUG(2,("ERROR: Invalid share info type for %s\n", info[i].name));
|
||||
ret = NT_STATUS_INVALID_PARAMETER;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (do_rename) {
|
||||
struct ldb_dn *olddn, *newdn;
|
||||
|
||||
olddn = msg->dn;
|
||||
|
||||
/* TODO: escape newname */
|
||||
newdn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", newname);
|
||||
if (!newdn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = ldb_rename(ldb, olddn, newdn);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to rename share %s (to %s)\n"
|
||||
" err=%d [%s]\n", name, newname, err, ldb_errstring(ldb)));
|
||||
if (err == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
ret = NT_STATUS_BAD_NETWORK_NAME;
|
||||
} else {
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
msg->dn = newdn;
|
||||
}
|
||||
|
||||
err = ldb_modify(ldb, msg);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to add share %s to share.ldb\n"
|
||||
" err=%d [%s]\n", name, err, ldb_errstring(ldb)));
|
||||
if (err == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
ret = NT_STATUS_BAD_NETWORK_NAME;
|
||||
} else {
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK;
|
||||
done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS sldb_remove(struct share_context *ctx, const char *name)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_dn *dn;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
NTSTATUS ret;
|
||||
int err;
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (!tmp_ctx) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
ldb = talloc_get_type(ctx->priv_data, struct ldb_context);
|
||||
|
||||
dn = ldb_dn_new_fmt(tmp_ctx, ldb, "CN=%s,CN=SHARES", name);
|
||||
if (!dn) {
|
||||
DEBUG(0,("ERROR: Out of memory!\n"));
|
||||
ret = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
err = ldb_delete(ldb, dn);
|
||||
if (err != LDB_SUCCESS) {
|
||||
DEBUG(2,("ERROR: unable to remove share %s from share.ldb\n"
|
||||
" err=%d [%s]\n", name, err, ldb_errstring(ldb)));
|
||||
ret = NT_STATUS_UNSUCCESSFUL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = NT_STATUS_OK;
|
||||
done:
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS share_ldb_init(void)
|
||||
{
|
||||
static struct share_ops ops = {
|
||||
.name = "ldb",
|
||||
.init = sldb_init,
|
||||
.string_option = sldb_string_option,
|
||||
.int_option = sldb_int_option,
|
||||
.bool_option = sldb_bool_option,
|
||||
.string_list_option = sldb_string_list_option,
|
||||
.list_all = sldb_list_all,
|
||||
.get_config = sldb_get_config,
|
||||
.create = sldb_create,
|
||||
.set = sldb_set,
|
||||
.remove = sldb_remove
|
||||
};
|
||||
|
||||
return share_register(&ops);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Samba utility functions
|
||||
Copyright (C) Andrew Tridgell 1992-1998
|
||||
Copyright (C) Jeremy Allison 2001-2002
|
||||
Copyright (C) Simo Sorce 2001
|
||||
Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
|
||||
Copyright (C) James J Myers 2003
|
||||
|
||||
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 "dynconfig.h"
|
||||
#include "system/network.h"
|
||||
#include "system/filesys.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Misc utility functions
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
see if a string matches either our primary or one of our secondary
|
||||
netbios aliases. do a case insensitive match
|
||||
*/
|
||||
_PUBLIC_ BOOL is_myname(const char *name)
|
||||
{
|
||||
const char **aliases;
|
||||
int i;
|
||||
|
||||
if (strcasecmp(name, lp_netbios_name()) == 0) {
|
||||
return True;
|
||||
}
|
||||
|
||||
aliases = lp_netbios_aliases();
|
||||
for (i=0; aliases && aliases[i]; i++) {
|
||||
if (strcasecmp(name, aliases[i]) == 0) {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
A useful function for returning a path in the Samba lock directory.
|
||||
**/
|
||||
_PUBLIC_ char *lock_path(TALLOC_CTX* mem_ctx, const char *name)
|
||||
{
|
||||
char *fname, *dname;
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
|
||||
return talloc_strdup(mem_ctx, name);
|
||||
}
|
||||
|
||||
dname = talloc_strdup(mem_ctx, lp_lockdir());
|
||||
trim_string(dname,"","/");
|
||||
|
||||
if (!directory_exist(dname)) {
|
||||
mkdir(dname,0755);
|
||||
}
|
||||
|
||||
fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
|
||||
|
||||
talloc_free(dname);
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
A useful function for returning a path in the Samba piddir directory.
|
||||
**/
|
||||
static char *pid_path(TALLOC_CTX* mem_ctx, const char *name)
|
||||
{
|
||||
char *fname, *dname;
|
||||
|
||||
dname = talloc_strdup(mem_ctx, lp_piddir());
|
||||
trim_string(dname,"","/");
|
||||
|
||||
if (!directory_exist(dname)) {
|
||||
mkdir(dname,0755);
|
||||
}
|
||||
|
||||
fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
|
||||
|
||||
talloc_free(dname);
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns an absolute path to a file in the Samba lib directory.
|
||||
*
|
||||
* @param name File to find, relative to DATADIR.
|
||||
*
|
||||
* @retval Pointer to a talloc'ed string containing the full path.
|
||||
**/
|
||||
|
||||
_PUBLIC_ char *data_path(TALLOC_CTX* mem_ctx, const char *name)
|
||||
{
|
||||
char *fname;
|
||||
fname = talloc_asprintf(mem_ctx, "%s/%s", dyn_DATADIR, name);
|
||||
return fname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns an absolute path to a file in the Samba private directory.
|
||||
*
|
||||
* @param name File to find, relative to PRIVATEDIR.
|
||||
* if name is not relative, then use it as-is
|
||||
*
|
||||
* @retval Pointer to a talloc'ed string containing the full path.
|
||||
**/
|
||||
_PUBLIC_ char *private_path(TALLOC_CTX* mem_ctx, const char *name)
|
||||
{
|
||||
char *fname;
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (name[0] == 0 || name[0] == '/' || strstr(name, ":/")) {
|
||||
return talloc_strdup(mem_ctx, name);
|
||||
}
|
||||
fname = talloc_asprintf(mem_ctx, "%s/%s", lp_private_dir(), name);
|
||||
return fname;
|
||||
}
|
||||
|
||||
/**
|
||||
return a path in the smbd.tmp directory, where all temporary file
|
||||
for smbd go. If NULL is passed for name then return the directory
|
||||
path itself
|
||||
*/
|
||||
_PUBLIC_ char *smbd_tmp_path(TALLOC_CTX *mem_ctx, const char *name)
|
||||
{
|
||||
char *fname, *dname;
|
||||
|
||||
dname = pid_path(mem_ctx, "smbd.tmp");
|
||||
if (!directory_exist(dname)) {
|
||||
mkdir(dname,0755);
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
return dname;
|
||||
}
|
||||
|
||||
fname = talloc_asprintf(mem_ctx, "%s/%s", dname, name);
|
||||
talloc_free(dname);
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
static char *modules_path(TALLOC_CTX* mem_ctx, const char *name)
|
||||
{
|
||||
const char *env_moduledir = getenv("LD_SAMBA_MODULE_PATH");
|
||||
return talloc_asprintf(mem_ctx, "%s/%s",
|
||||
env_moduledir?env_moduledir:lp_modulesdir(),
|
||||
name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the initialization functions from DSO files for a specific subsystem.
|
||||
*
|
||||
* Will return an array of function pointers to initialization functions
|
||||
*/
|
||||
|
||||
_PUBLIC_ init_module_fn *load_samba_modules(TALLOC_CTX *mem_ctx, const char *subsystem)
|
||||
{
|
||||
char *path = modules_path(mem_ctx, subsystem);
|
||||
init_module_fn *ret;
|
||||
|
||||
ret = load_modules(mem_ctx, path);
|
||||
|
||||
talloc_free(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user