wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+51
View File
@@ -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
+269
View File
@@ -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
+81
View File
@@ -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
+48
View File
@@ -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 */
+588
View File
@@ -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 */
/* -------------------------------------------------------------------------- */
+177
View File
@@ -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;
}
+40
View File
@@ -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 */
+161
View File
@@ -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;
}
+118
View File
@@ -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 */
+331
View File
@@ -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);
}
+585
View File
@@ -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);
}
+196
View File
@@ -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;
}