1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-18 17:57:55 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test

(This used to be commit 1e042908992cdf3149ffc24472c7f0b1c3f9edef)
This commit is contained in:
Andrew Tridgell 2008-01-25 23:16:34 +11:00
commit 98d2b00dbe
23 changed files with 974 additions and 327 deletions

View File

@ -14,5 +14,5 @@ PRIVATE_DEPENDENCIES = \
SECRETS
[PYTHON::swig_credentials]
PUBLIC_DEPENDENCIES = CREDENTIALS
PUBLIC_DEPENDENCIES = CREDENTIALS LIBCMDLINE_CREDENTIALS
SWIG_FILE = credentials.i

View File

@ -27,6 +27,7 @@
#include "includes.h"
#include "auth/credentials/credentials.h"
#include "param/param.h"
#include "lib/cmdline/credentials.h"
typedef struct cli_credentials cli_credentials;
%}
@ -93,6 +94,8 @@ typedef struct cli_credentials {
bool authentication_requested(void);
bool wrong_password(void);
bool set_cmdline_callbacks();
}
} cli_credentials;

View File

@ -82,6 +82,7 @@ Credentials.is_anonymous = new_instancemethod(_credentials.Credentials_is_anonym
Credentials.get_nt_hash = new_instancemethod(_credentials.Credentials_get_nt_hash,None,Credentials)
Credentials.authentication_requested = new_instancemethod(_credentials.Credentials_authentication_requested,None,Credentials)
Credentials.wrong_password = new_instancemethod(_credentials.Credentials_wrong_password,None,Credentials)
Credentials.set_cmdline_callbacks = new_instancemethod(_credentials.Credentials_set_cmdline_callbacks,None,Credentials)
Credentials_swigregister = _credentials.Credentials_swigregister
Credentials_swigregister(Credentials)

View File

@ -2521,6 +2521,7 @@ static swig_module_info swig_module = {swig_types, 16, 0, 0, 0, 0};
#include "includes.h"
#include "auth/credentials/credentials.h"
#include "param/param.h"
#include "lib/cmdline/credentials.h"
typedef struct cli_credentials cli_credentials;
@ -3486,6 +3487,34 @@ fail:
}
SWIGINTERN PyObject *_wrap_Credentials_set_cmdline_callbacks(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
cli_credentials *arg1 = (cli_credentials *) 0 ;
bool result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
char * kwnames[] = {
(char *) "self", NULL
};
arg1 = NULL;
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"|O:Credentials_set_cmdline_callbacks",kwnames,&obj0)) SWIG_fail;
if (obj0) {
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_cli_credentials, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Credentials_set_cmdline_callbacks" "', argument " "1"" of type '" "cli_credentials *""'");
}
arg1 = (cli_credentials *)(argp1);
}
result = (bool)cli_credentials_set_cmdline_callbacks(arg1);
resultobj = SWIG_From_bool((bool)(result));
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_delete_Credentials(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
cli_credentials *arg1 = (cli_credentials *) 0 ;
@ -3545,6 +3574,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"Credentials_get_nt_hash", (PyCFunction) _wrap_Credentials_get_nt_hash, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Credentials_authentication_requested", (PyCFunction) _wrap_Credentials_authentication_requested, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Credentials_wrong_password", (PyCFunction) _wrap_Credentials_wrong_password, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Credentials_set_cmdline_callbacks", (PyCFunction) _wrap_Credentials_set_cmdline_callbacks, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"delete_Credentials", (PyCFunction) _wrap_delete_Credentials, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Credentials_swigregister", Credentials_swigregister, METH_VARARGS, NULL},
{ (char *)"Credentials_swiginit", Credentials_swiginit, METH_VARARGS, NULL},

View File

@ -83,6 +83,9 @@ class CredentialsTests(unittest.TestCase):
# Just check the method is there and doesn't raise an exception
self.creds.guess()
def test_set_cmdline_callbacks(self):
self.creds.set_cmdline_callbacks()
def test_authentication_requested(self):
self.creds.set_username("")
self.assertFalse(self.creds.authentication_requested())

View File

@ -27,20 +27,20 @@ m4_include(lib/charset/config.m4)
m4_include(lib/socket/config.m4)
m4_include(nsswitch/nsstest.m4)
AC_OUTPUT(lib/registry/registry.pc)
AC_OUTPUT(librpc/dcerpc.pc)
AC_OUTPUT(librpc/ndr.pc)
AC_OUTPUT(torture/torture.pc)
AC_OUTPUT(auth/gensec/gensec.pc)
AC_OUTPUT(param/samba-config.pc)
AC_OUTPUT(librpc/dcerpc_samr.pc)
AC_CONFIG_FILES(lib/registry/registry.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(librpc/ndr.pc)
AC_CONFIG_FILES(torture/torture.pc)
AC_CONFIG_FILES(auth/gensec/gensec.pc)
AC_CONFIG_FILES(param/samba-config.pc)
AC_CONFIG_FILES(librpc/dcerpc_samr.pc)
SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.1.0,
[],
[
m4_include(lib/talloc/libtalloc.m4)
SMB_INCLUDE_MK(lib/talloc/config.mk)
AC_OUTPUT(lib/talloc/talloc.pc)
AC_CONFIG_FILES(lib/talloc/talloc.pc)
]
)
@ -49,7 +49,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.0,
[
m4_include(lib/tdb/libtdb.m4)
SMB_INCLUDE_MK(lib/tdb/config.mk)
AC_OUTPUT(lib/tdb/tdb.pc)
AC_CONFIG_FILES(lib/tdb/tdb.pc)
]
)
@ -60,7 +60,6 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1,
SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk)
SMB_INCLUDE_MK(lib/ldb/tools/config.mk)
SMB_SUBSYSTEM(ldb_map, [], [LIBLDB])
AC_OUTPUT(lib/ldb/ldb.pc)
define_ldb_modulesdir=no
],
[
@ -84,6 +83,7 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb >= 0.9.1,
m4_include(lib/ldb/sqlite3.m4)
m4_include(lib/ldb/libldb.m4)
SMB_INCLUDE_MK(lib/ldb/config.mk)
AC_CONFIG_FILES(lib/ldb/ldb.pc)
]
)
SMB_INCLUDE_MK(lib/ldb/python.mk)

View File

@ -509,6 +509,18 @@ static int replmd_modify_originating(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
/* TODO:
* - get the whole old object
* - if the old object doesn't exist report an error
* - give an error when a readonly attribute should
* be modified
* - merge the changed into the old object
* if the caller set values to the same value
* ignore the attribute, return success when no
* attribute was changed
* - calculate the new replPropertyMetaData attribute
*/
if (add_time_element(msg, "whenChanged", t) != 0) {
talloc_free(down_req);
return LDB_ERR_OPERATIONS_ERROR;
@ -523,6 +535,11 @@ static int replmd_modify_originating(struct ldb_module *module,
}
}
/* TODO:
* - sort the attributes by attid with replmd_ldb_message_sort()
* - replace the old object with the newly constructed one
*/
ldb_set_timeout_from_prev_req(module->ldb, req, down_req);
/* go on with the call chain */

View File

@ -5,7 +5,7 @@
Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
Copyright (C) 2006 Simo Sorce <idra@samba.org>
Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@ -102,8 +102,44 @@ typedef int ldb_error;
$1->data = PyString_AsString($input);
}
%inline %{
PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx,
struct ldb_message_element *el,
struct ldb_val *val)
{
const struct ldb_schema_attribute *a;
struct ldb_val new_val;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
PyObject *ret;
new_val = *val;
if (ldb_ctx != NULL) {
a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
if (a != NULL) {
if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
talloc_free(mem_ctx);
return NULL;
}
}
}
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
return ret;
}
%}
%typemap(out,noblock=1) struct ldb_val * {
$result = PyString_FromStringAndSize((const char *)$1->data, $1->length)
}
%typemap(out,noblock=1) struct ldb_val {
$result = PyString_FromStringAndSize((const char *)$1.data, $1.length);
$result = PyString_FromStringAndSize((const char *)$1.data, $1.length)
}
/*
@ -259,7 +295,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
return me;
}
PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
ldb_msg_element *me)
{
int i;
PyObject *result;
@ -269,8 +306,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
for (i = 0; i < me->num_values; i++) {
PyList_SetItem(result, i,
PyString_FromStringAndSize((const char *)me->values[i].data,
me->values[i].length));
ldb_val_to_py_object(ldb_ctx, me, &me->values[i]));
}
return result;
@ -287,12 +323,12 @@ typedef struct ldb_message_element {
#ifdef SWIGPYTHON
PyObject *__iter__(void)
{
return PyObject_GetIter(ldb_msg_element_to_set($self));
return PyObject_GetIter(ldb_msg_element_to_set(NULL, $self));
}
PyObject *__set__(void)
{
return ldb_msg_element_to_set($self);
return ldb_msg_element_to_set(NULL, $self);
}
ldb_msg_element(PyObject *set_obj, int flags=0, const char *name = NULL)
@ -311,9 +347,7 @@ typedef struct ldb_message_element {
if (i < 0 || i >= $self->num_values)
return Py_None;
return PyString_FromStringAndSize(
(const char *)$self->values[i].data,
$self->values[i].length);
return ldb_val_to_py_object(NULL, $self, &$self->values[i]);
}
~ldb_msg_element() { talloc_free($self); }
@ -622,6 +656,35 @@ typedef struct ldb_context {
ldb_dn *get_root_basedn();
ldb_dn *get_schema_basedn();
ldb_dn *get_default_basedn();
PyObject *schema_format_value(const char *element_name, PyObject *val)
{
const struct ldb_schema_attribute *a;
struct ldb_val old_val;
struct ldb_val new_val;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
PyObject *ret;
old_val.data = PyString_AsString(val);
old_val.length = PyString_Size(val);
a = ldb_schema_attribute_by_name($self, element_name);
if (a == NULL) {
return Py_None;
}
if (a->syntax->ldif_write_fn($self, mem_ctx, &old_val, &new_val) != 0) {
talloc_free(mem_ctx);
return Py_None;
}
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
return ret;
}
const char *errstring();
void set_create_perms(unsigned int perms);
void set_modules_dir(const char *path);
@ -633,7 +696,10 @@ typedef struct ldb_context {
ldb_error transaction_start();
ldb_error transaction_commit();
ldb_error transaction_cancel();
void schema_attribute_remove(const char *name);
ldb_error schema_attribute_add(const char *attribute, unsigned flags, const char *syntax);
ldb_error setup_wellknown_attributes(void);
#ifdef SWIGPYTHON
%typemap(in,numinputs=0,noblock=1) struct ldb_result **result_as_bool (struct ldb_result *tmp) { $1 = &tmp; }
%typemap(argout,noblock=1) struct ldb_result **result_as_bool { $result = ((*$1)->count > 0)?Py_True:Py_False; }

View File

@ -65,6 +65,7 @@ CHANGETYPE_NONE = _ldb.CHANGETYPE_NONE
CHANGETYPE_ADD = _ldb.CHANGETYPE_ADD
CHANGETYPE_DELETE = _ldb.CHANGETYPE_DELETE
CHANGETYPE_MODIFY = _ldb.CHANGETYPE_MODIFY
ldb_val_to_py_object = _ldb.ldb_val_to_py_object
class Dn(object):
thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
__repr__ = _swig_repr
@ -218,6 +219,7 @@ Ldb.get_config_basedn = new_instancemethod(_ldb.Ldb_get_config_basedn,None,Ldb)
Ldb.get_root_basedn = new_instancemethod(_ldb.Ldb_get_root_basedn,None,Ldb)
Ldb.get_schema_basedn = new_instancemethod(_ldb.Ldb_get_schema_basedn,None,Ldb)
Ldb.get_default_basedn = new_instancemethod(_ldb.Ldb_get_default_basedn,None,Ldb)
Ldb.schema_format_value = new_instancemethod(_ldb.Ldb_schema_format_value,None,Ldb)
Ldb.errstring = new_instancemethod(_ldb.Ldb_errstring,None,Ldb)
Ldb.set_create_perms = new_instancemethod(_ldb.Ldb_set_create_perms,None,Ldb)
Ldb.set_modules_dir = new_instancemethod(_ldb.Ldb_set_modules_dir,None,Ldb)
@ -227,6 +229,9 @@ Ldb.get_opaque = new_instancemethod(_ldb.Ldb_get_opaque,None,Ldb)
Ldb.transaction_start = new_instancemethod(_ldb.Ldb_transaction_start,None,Ldb)
Ldb.transaction_commit = new_instancemethod(_ldb.Ldb_transaction_commit,None,Ldb)
Ldb.transaction_cancel = new_instancemethod(_ldb.Ldb_transaction_cancel,None,Ldb)
Ldb.schema_attribute_remove = new_instancemethod(_ldb.Ldb_schema_attribute_remove,None,Ldb)
Ldb.schema_attribute_add = new_instancemethod(_ldb.Ldb_schema_attribute_add,None,Ldb)
Ldb.setup_wellknown_attributes = new_instancemethod(_ldb.Ldb_setup_wellknown_attributes,None,Ldb)
Ldb.__contains__ = new_instancemethod(_ldb.Ldb___contains__,None,Ldb)
Ldb.parse_ldif = new_instancemethod(_ldb.Ldb_parse_ldif,None,Ldb)
Ldb_swigregister = _ldb.Ldb_swigregister

View File

@ -2470,20 +2470,21 @@ SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags)
#define SWIGTYPE_p_ldb_message_element swig_types[8]
#define SWIGTYPE_p_ldb_module_ops swig_types[9]
#define SWIGTYPE_p_ldb_result swig_types[10]
#define SWIGTYPE_p_long_long swig_types[11]
#define SWIGTYPE_p_p_char swig_types[12]
#define SWIGTYPE_p_p_ldb_control swig_types[13]
#define SWIGTYPE_p_p_ldb_result swig_types[14]
#define SWIGTYPE_p_short swig_types[15]
#define SWIGTYPE_p_signed_char swig_types[16]
#define SWIGTYPE_p_unsigned_char swig_types[17]
#define SWIGTYPE_p_unsigned_int swig_types[18]
#define SWIGTYPE_p_unsigned_long swig_types[19]
#define SWIGTYPE_p_unsigned_long_long swig_types[20]
#define SWIGTYPE_p_unsigned_short swig_types[21]
#define SWIGTYPE_p_void swig_types[22]
static swig_type_info *swig_types[24];
static swig_module_info swig_module = {swig_types, 23, 0, 0, 0, 0};
#define SWIGTYPE_p_ldb_val swig_types[11]
#define SWIGTYPE_p_long_long swig_types[12]
#define SWIGTYPE_p_p_char swig_types[13]
#define SWIGTYPE_p_p_ldb_control swig_types[14]
#define SWIGTYPE_p_p_ldb_result swig_types[15]
#define SWIGTYPE_p_short swig_types[16]
#define SWIGTYPE_p_signed_char swig_types[17]
#define SWIGTYPE_p_unsigned_char swig_types[18]
#define SWIGTYPE_p_unsigned_int swig_types[19]
#define SWIGTYPE_p_unsigned_long swig_types[20]
#define SWIGTYPE_p_unsigned_long_long swig_types[21]
#define SWIGTYPE_p_unsigned_short swig_types[22]
#define SWIGTYPE_p_void swig_types[23]
static swig_type_info *swig_types[25];
static swig_module_info swig_module = {swig_types, 24, 0, 0, 0, 0};
#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
@ -2550,6 +2551,37 @@ SWIG_From_int (int value)
}
PyObject *ldb_val_to_py_object(struct ldb_context *ldb_ctx,
struct ldb_message_element *el,
struct ldb_val *val)
{
const struct ldb_schema_attribute *a;
struct ldb_val new_val;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
PyObject *ret;
new_val = *val;
if (ldb_ctx != NULL) {
a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
if (a != NULL) {
if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
talloc_free(mem_ctx);
return NULL;
}
}
}
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
return ret;
}
SWIGINTERN swig_type_info*
SWIG_pchar_descriptor(void)
{
@ -2719,7 +2751,8 @@ ldb_msg_element *ldb_msg_element_from_pyobject(TALLOC_CTX *mem_ctx,
return me;
}
PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
PyObject *ldb_msg_element_to_set(struct ldb_context *ldb_ctx,
ldb_msg_element *me)
{
int i;
PyObject *result;
@ -2729,8 +2762,7 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
for (i = 0; i < me->num_values; i++) {
PyList_SetItem(result, i,
PyString_FromStringAndSize((const char *)me->values[i].data,
me->values[i].length));
ldb_val_to_py_object(ldb_ctx, me, &me->values[i]));
}
return result;
@ -2738,10 +2770,10 @@ PyObject *ldb_msg_element_to_set(ldb_msg_element *me)
SWIGINTERN PyObject *ldb_msg_element___iter__(ldb_msg_element *self){
return PyObject_GetIter(ldb_msg_element_to_set(self));
return PyObject_GetIter(ldb_msg_element_to_set(NULL, self));
}
SWIGINTERN PyObject *ldb_msg_element___set__(ldb_msg_element *self){
return ldb_msg_element_to_set(self);
return ldb_msg_element_to_set(NULL, self);
}
#include <limits.h>
@ -2898,9 +2930,7 @@ SWIGINTERN PyObject *ldb_msg_element_get(ldb_msg_element *self,int i){
if (i < 0 || i >= self->num_values)
return Py_None;
return PyString_FromStringAndSize(
(const char *)self->values[i].data,
self->values[i].length);
return ldb_val_to_py_object(NULL, self, &self->values[i]);
}
SWIGINTERN void delete_ldb_msg_element(ldb_msg_element *self){ talloc_free(self); }
@ -3129,6 +3159,33 @@ SWIGINTERN ldb_error ldb_add__SWIG_1(ldb *self,PyObject *py_msg){
fail:
return 80;
}
SWIGINTERN PyObject *ldb_schema_format_value(ldb *self,char const *element_name,PyObject *val){
const struct ldb_schema_attribute *a;
struct ldb_val old_val;
struct ldb_val new_val;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
PyObject *ret;
old_val.data = PyString_AsString(val);
old_val.length = PyString_Size(val);
a = ldb_schema_attribute_by_name(self, element_name);
if (a == NULL) {
return Py_None;
}
if (a->syntax->ldif_write_fn(self, mem_ctx, &old_val, &new_val) != 0) {
talloc_free(mem_ctx);
return Py_None;
}
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
return ret;
}
SWIGINTERN ldb_error ldb___contains__(ldb *self,ldb_dn *dn,struct ldb_result **result_as_bool){
return ldb_search(self, dn, LDB_SCOPE_BASE, NULL, NULL,
result_as_bool);
@ -3153,6 +3210,52 @@ static char *timestring(time_t t)
#ifdef __cplusplus
extern "C" {
#endif
SWIGINTERN PyObject *_wrap_ldb_val_to_py_object(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
struct ldb_context *arg1 = (struct ldb_context *) 0 ;
struct ldb_message_element *arg2 = (struct ldb_message_element *) 0 ;
struct ldb_val *arg3 = (struct ldb_val *) 0 ;
PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
void *argp3 = 0 ;
int res3 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
char * kwnames[] = {
(char *) "ldb_ctx",(char *) "el",(char *) "val", NULL
};
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:ldb_val_to_py_object",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ldb_val_to_py_object" "', argument " "1"" of type '" "struct ldb_context *""'");
}
arg1 = (struct ldb_context *)(argp1);
res2 = SWIG_ConvertPtr(obj1, &argp2,SWIGTYPE_p_ldb_message_element, 0 | 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ldb_val_to_py_object" "', argument " "2"" of type '" "struct ldb_message_element *""'");
}
arg2 = (struct ldb_message_element *)(argp2);
res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_ldb_val, 0 | 0 );
if (!SWIG_IsOK(res3)) {
SWIG_exception_fail(SWIG_ArgError(res3), "in method '" "ldb_val_to_py_object" "', argument " "3"" of type '" "struct ldb_val *""'");
}
arg3 = (struct ldb_val *)(argp3);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = (PyObject *)ldb_val_to_py_object(arg1,arg2,arg3);
resultobj = result;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_new_Dn(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
@ -4875,6 +4978,49 @@ fail:
}
SWIGINTERN PyObject *_wrap_Ldb_schema_format_value(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
PyObject *arg3 = (PyObject *) 0 ;
PyObject *result = 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "element_name",(char *) "val", NULL
};
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO:Ldb_schema_format_value",kwnames,&obj0,&obj1,&obj2)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_schema_format_value" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_format_value" "', argument " "2"" of type '" "char const *""'");
}
arg2 = (char *)(buf2);
arg3 = obj2;
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = (PyObject *)ldb_schema_format_value(arg1,(char const *)arg2,arg3);
resultobj = result;
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return resultobj;
fail:
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb_errstring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
@ -5197,6 +5343,140 @@ fail:
}
SWIGINTERN PyObject *_wrap_Ldb_schema_attribute_remove(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "name", NULL
};
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_schema_attribute_remove",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_schema_attribute_remove" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_attribute_remove" "', argument " "2"" of type '" "char const *""'");
}
arg2 = (char *)(buf2);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
ldb_schema_attribute_remove(arg1,(char const *)arg2);
resultobj = SWIG_Py_Void();
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return resultobj;
fail:
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb_schema_attribute_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
char *arg2 = (char *) 0 ;
unsigned int arg3 ;
char *arg4 = (char *) 0 ;
ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
unsigned int val3 ;
int ecode3 = 0 ;
int res4 ;
char *buf4 = 0 ;
int alloc4 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
PyObject * obj2 = 0 ;
PyObject * obj3 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "attribute",(char *) "flags",(char *) "syntax", NULL
};
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOOO:Ldb_schema_attribute_add",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_schema_attribute_add" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_schema_attribute_add" "', argument " "2"" of type '" "char const *""'");
}
arg2 = (char *)(buf2);
ecode3 = SWIG_AsVal_unsigned_SS_int(obj2, &val3);
if (!SWIG_IsOK(ecode3)) {
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Ldb_schema_attribute_add" "', argument " "3"" of type '" "unsigned int""'");
}
arg3 = (unsigned int)(val3);
res4 = SWIG_AsCharPtrAndSize(obj3, &buf4, NULL, &alloc4);
if (!SWIG_IsOK(res4)) {
SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "Ldb_schema_attribute_add" "', argument " "4"" of type '" "char const *""'");
}
arg4 = (char *)(buf4);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = ldb_schema_attribute_add(arg1,(char const *)arg2,arg3,(char const *)arg4);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_strerror(result)));
SWIG_fail;
}
resultobj = Py_None;
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
return resultobj;
fail:
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
if (alloc4 == SWIG_NEWOBJ) free((char*)buf4);
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb_setup_wellknown_attributes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject *swig_obj[1] ;
if (!args) SWIG_fail;
swig_obj[0] = args;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_setup_wellknown_attributes" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = ldb_setup_wellknown_attributes(arg1);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_strerror(result)));
SWIG_fail;
}
resultobj = Py_None;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb___contains__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
@ -5400,6 +5680,7 @@ fail:
static PyMethodDef SwigMethods[] = {
{ (char *)"ldb_val_to_py_object", (PyCFunction) _wrap_ldb_val_to_py_object, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"new_Dn", (PyCFunction) _wrap_new_Dn, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"delete_Dn", (PyCFunction)_wrap_delete_Dn, METH_O, NULL},
{ (char *)"Dn_validate", (PyCFunction)_wrap_Dn_validate, METH_O, NULL},
@ -5454,6 +5735,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"Ldb_get_root_basedn", (PyCFunction)_wrap_Ldb_get_root_basedn, METH_O, NULL},
{ (char *)"Ldb_get_schema_basedn", (PyCFunction)_wrap_Ldb_get_schema_basedn, METH_O, NULL},
{ (char *)"Ldb_get_default_basedn", (PyCFunction)_wrap_Ldb_get_default_basedn, METH_O, NULL},
{ (char *)"Ldb_schema_format_value", (PyCFunction) _wrap_Ldb_schema_format_value, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_errstring", (PyCFunction)_wrap_Ldb_errstring, METH_O, NULL},
{ (char *)"Ldb_set_create_perms", (PyCFunction) _wrap_Ldb_set_create_perms, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_set_modules_dir", (PyCFunction) _wrap_Ldb_set_modules_dir, METH_VARARGS | METH_KEYWORDS, NULL},
@ -5463,6 +5745,9 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"Ldb_transaction_start", (PyCFunction)_wrap_Ldb_transaction_start, METH_O, NULL},
{ (char *)"Ldb_transaction_commit", (PyCFunction)_wrap_Ldb_transaction_commit, METH_O, NULL},
{ (char *)"Ldb_transaction_cancel", (PyCFunction)_wrap_Ldb_transaction_cancel, METH_O, NULL},
{ (char *)"Ldb_schema_attribute_remove", (PyCFunction) _wrap_Ldb_schema_attribute_remove, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_schema_attribute_add", (PyCFunction) _wrap_Ldb_schema_attribute_add, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_setup_wellknown_attributes", (PyCFunction)_wrap_Ldb_setup_wellknown_attributes, METH_O, NULL},
{ (char *)"Ldb___contains__", (PyCFunction) _wrap_Ldb___contains__, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_parse_ldif", (PyCFunction) _wrap_Ldb_parse_ldif, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_swigregister", Ldb_swigregister, METH_VARARGS, NULL},
@ -5488,6 +5773,7 @@ static swig_type_info _swigt__p_ldb_message = {"_p_ldb_message", "ldb_msg *|stru
static swig_type_info _swigt__p_ldb_message_element = {"_p_ldb_message_element", "struct ldb_message_element *|ldb_msg_element *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_module_ops = {"_p_ldb_module_ops", "struct ldb_module_ops *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_result = {"_p_ldb_result", "struct ldb_result *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_ldb_val = {"_p_ldb_val", "struct ldb_val *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_long_long = {"_p_long_long", "int_least64_t *|int_fast64_t *|int64_t *|long long *|intmax_t *", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
static swig_type_info _swigt__p_p_ldb_control = {"_p_p_ldb_control", "struct ldb_control **", 0, 0, (void*)0, 0};
@ -5513,6 +5799,7 @@ static swig_type_info *swig_type_initial[] = {
&_swigt__p_ldb_message_element,
&_swigt__p_ldb_module_ops,
&_swigt__p_ldb_result,
&_swigt__p_ldb_val,
&_swigt__p_long_long,
&_swigt__p_p_char,
&_swigt__p_p_ldb_control,
@ -5538,6 +5825,7 @@ static swig_cast_info _swigc__p_ldb_message[] = { {&_swigt__p_ldb_message, 0, 0
static swig_cast_info _swigc__p_ldb_message_element[] = { {&_swigt__p_ldb_message_element, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_module_ops[] = { {&_swigt__p_ldb_module_ops, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_result[] = { {&_swigt__p_ldb_result, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_ldb_val[] = { {&_swigt__p_ldb_val, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_long_long[] = { {&_swigt__p_long_long, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
static swig_cast_info _swigc__p_p_ldb_control[] = { {&_swigt__p_p_ldb_control, 0, 0, 0},{0, 0, 0, 0}};
@ -5563,6 +5851,7 @@ static swig_cast_info *swig_cast_initial[] = {
_swigc__p_ldb_message_element,
_swigc__p_ldb_module_ops,
_swigc__p_ldb_result,
_swigc__p_ldb_val,
_swigc__p_long_long,
_swigc__p_p_char,
_swigc__p_p_ldb_control,

View File

@ -86,6 +86,7 @@ sub HeaderStruct($$;$)
{
my($struct,$name,$tail) = @_;
pidl "struct $name";
pidl $tail if defined($tail) and not defined($struct->{ELEMENTS});
return if (not defined($struct->{ELEMENTS}));
pidl " {\n";
$tab_depth++;
@ -178,6 +179,7 @@ sub HeaderUnion($$;$)
my %done = ();
pidl "union $name";
pidl $tail if defined($tail) and not defined($union->{ELEMENTS});
return if (not defined($union->{ELEMENTS}));
pidl " {\n";
$tab_depth++;

View File

@ -66,3 +66,14 @@ WERROR dsdb_attach_schema_from_ldif_file(struct ldb_context *ldb, const char *pf
const char *samba_version_string(void);
int dsdb_set_global_schema(struct ldb_context *ldb);
int ldb_register_samba_handlers(struct ldb_context *ldb);
%inline %{
bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid)
{
struct GUID invocation_id_in;
if (NT_STATUS_IS_ERR(GUID_from_string(guid, &invocation_id_in))) {
return false;
}
return samdb_set_ntds_invocation_id(ldb, &invocation_id_in);
}
%}

View File

@ -70,5 +70,6 @@ dsdb_attach_schema_from_ldif_file = _misc.dsdb_attach_schema_from_ldif_file
version = _misc.version
dsdb_set_global_schema = _misc.dsdb_set_global_schema
ldb_register_samba_handlers = _misc.ldb_register_samba_handlers
dsdb_set_ntds_invocation_id = _misc.dsdb_set_ntds_invocation_id

View File

@ -2794,6 +2794,16 @@ SWIG_From_int (int value)
return SWIG_From_long (value);
}
bool dsdb_set_ntds_invocation_id(struct ldb_context *ldb, const char *guid)
{
struct GUID invocation_id_in;
if (NT_STATUS_IS_ERR(GUID_from_string(guid, &invocation_id_in))) {
return false;
}
return samdb_set_ntds_invocation_id(ldb, &invocation_id_in);
}
#ifdef __cplusplus
extern "C" {
#endif
@ -3102,6 +3112,46 @@ fail:
}
SWIGINTERN PyObject *_wrap_dsdb_set_ntds_invocation_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
struct ldb_context *arg1 = (struct ldb_context *) 0 ;
char *arg2 = (char *) 0 ;
bool result;
void *argp1 = 0 ;
int res1 = 0 ;
int res2 ;
char *buf2 = 0 ;
int alloc2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
(char *) "ldb",(char *) "guid", NULL
};
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:dsdb_set_ntds_invocation_id",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "dsdb_set_ntds_invocation_id" "', argument " "1"" of type '" "struct ldb_context *""'");
}
arg1 = (struct ldb_context *)(argp1);
res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "dsdb_set_ntds_invocation_id" "', argument " "2"" of type '" "char const *""'");
}
arg2 = (char *)(buf2);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = (bool)dsdb_set_ntds_invocation_id(arg1,(char const *)arg2);
resultobj = SWIG_From_bool((bool)(result));
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return resultobj;
fail:
if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
return NULL;
}
static PyMethodDef SwigMethods[] = {
{ (char *)"random_password", (PyCFunction) _wrap_random_password, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"ldb_set_credentials", (PyCFunction) _wrap_ldb_set_credentials, METH_VARARGS | METH_KEYWORDS, NULL},
@ -3112,6 +3162,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"version", (PyCFunction)_wrap_version, METH_NOARGS, NULL},
{ (char *)"dsdb_set_global_schema", (PyCFunction) _wrap_dsdb_set_global_schema, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"ldb_register_samba_handlers", (PyCFunction) _wrap_ldb_register_samba_handlers, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"dsdb_set_ntds_invocation_id", (PyCFunction) _wrap_dsdb_set_ntds_invocation_id, METH_VARARGS | METH_KEYWORDS, NULL},
{ NULL, NULL, 0, NULL }
};

View File

@ -62,7 +62,7 @@ void py_load_samba_modules(void)
void py_update_path(const char *bindir)
{
char *newpath;
asprintf(&newpath, "%s:%s/python:%s/../scripting/python", Py_GetPath(), bindir, bindir);
asprintf(&newpath, "%s/python:%s/../scripting/python:%s", bindir, bindir, Py_GetPath());
PySys_SetPath(newpath);
free(newpath);
}

View File

@ -1,8 +1,10 @@
#!/usr/bin/python
# Unix SMB/CIFS implementation.
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
#
# Based on the original in EJS:
# Copyright (C) Andrew Tridgell <tridge@samba.org> 2005
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -89,7 +91,7 @@ class Ldb(ldb.Ldb):
set_session_info = misc.ldb_set_session_info
set_loadparm = misc.ldb_set_loadparm
def searchone(self, basedn, attribute, expression=None,
def searchone(self, attribute, basedn=None, expression=None,
scope=ldb.SCOPE_BASE):
"""Search for one attribute as a string.
@ -104,7 +106,7 @@ class Ldb(ldb.Ldb):
return None
values = set(res[0][attribute])
assert len(values) == 1
return values.pop()
return self.schema_format_value(attribute, values.pop())
def erase(self):
"""Erase this ldb, removing all records."""
@ -192,6 +194,21 @@ def substitute_var(text, values):
return text
def check_all_substituted(text):
"""Make sure that all substitution variables in a string have been replaced.
If not, raise an exception.
:param text: The text to search for substitution variables
"""
if not "${" in text:
return
var_start = text.find("${")
var_end = text.find("}", var_start)
raise Exception("Not all variables substituted: %s" % text[var_start:var_end+1])
def valid_netbios_name(name):
"""Check whether a name is valid as a NetBIOS name. """
# FIXME: There are probably more constraints here.

View File

@ -50,6 +50,7 @@ class VersionOptions(optparse.OptionGroup):
class CredentialsOptions(optparse.OptionGroup):
def __init__(self, parser):
self.no_pass = False
optparse.OptionGroup.__init__(self, parser, "Credentials Options")
self.add_option("--simple-bind-dn", metavar="DN", action="callback",
callback=self._set_simple_bind_dn, type=str,
@ -62,6 +63,8 @@ class CredentialsOptions(optparse.OptionGroup):
self.add_option("-W", "--workgroup", metavar="WORKGROUP",
action="callback", type=str,
help="Workgroup", callback=self._parse_workgroup)
self.add_option("-N", "--no-pass", action="store_true",
help="Don't ask for a password")
self.creds = Credentials()
def _parse_username(self, option, opt_str, arg, parser):
@ -77,4 +80,7 @@ class CredentialsOptions(optparse.OptionGroup):
self.creds.set_bind_dn(arg)
def get_credentials(self):
self.creds.guess()
if not self.no_pass:
self.creds.set_cmdline_callbacks()
return self.creds

View File

@ -1,10 +1,25 @@
#
# backend code for provisioning a Samba4 server
# Released under the GNU GPL v3 or later
# Copyright Jelmer Vernooij 2007
# Unix SMB/CIFS implementation.
# backend code for provisioning a Samba4 server
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
#
# Based on the original in EJS:
# Copyright Andrew Tridgell 2005
# Copyright (C) Andrew Tridgell <tridge@samba.org> 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 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from base64 import b64encode
@ -17,9 +32,10 @@ from socket import gethostname, gethostbyname
import param
import registry
import samba
from samba import Ldb, substitute_var, valid_netbios_name
from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted
from samba.samdb import SamDB
import security
import urllib
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE
@ -53,7 +69,7 @@ class ProvisionPaths:
self.ldap_schema_basedn_ldif = None
def install_ok(lp, session_info, credentials):
def check_install(lp, session_info, credentials):
"""Check whether the current install seems ok.
:param lp: Loadparm context
@ -61,12 +77,11 @@ def install_ok(lp, session_info, credentials):
:param credentials: Credentials
"""
if lp.get("realm") == "":
return False
raise Error("Realm empty")
ldb = Ldb(lp.get("sam database"), session_info=session_info,
credentials=credentials, lp=lp)
if len(ldb.search("(cn=Administrator)")) != 1:
return False
return True
raise "No administrator account found"
def findnss(nssfn, *names):
@ -112,7 +127,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None):
if subst_vars is not None:
data = substitute_var(data, subst_vars)
assert "${" not in data
check_all_substituted(data)
ldb.add_ldif(data)
@ -128,7 +143,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None):
if substvars is not None:
data = substitute_var(data, substvars)
assert "${" not in data
check_all_substituted(data)
ldb.modify_ldif(data)
@ -159,25 +174,30 @@ def setup_file(template, fname, substvars):
data = open(template, 'r').read()
if substvars:
data = substitute_var(data, substvars)
assert not "${" in data
check_all_substituted(data)
open(f, 'w').write(data)
def provision_paths_from_lp(lp, dnsdomain):
def provision_paths_from_lp(lp, dnsdomain, private_dir=None):
"""Set the default paths for provisioning.
:param lp: Loadparm context.
:param dnsdomain: DNS Domain name
"""
paths = ProvisionPaths()
private_dir = lp.get("private dir")
if private_dir is None:
private_dir = lp.get("private dir")
paths.keytab = "secrets.keytab"
paths.dns_keytab = "dns.keytab"
else:
paths.keytab = os.path.join(private_dir, "secrets.keytab")
paths.dns_keytab = os.path.join(private_dir, "dns.keytab")
paths.shareconf = os.path.join(private_dir, "share.ldb")
paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb")
paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb")
paths.templates = os.path.join(private_dir, "templates.ldb")
paths.keytab = os.path.join(private_dir, "secrets.keytab")
paths.dns_keytab = os.path.join(private_dir, "dns.keytab")
paths.dns = os.path.join(private_dir, dnsdomain + ".zone")
paths.winsdb = os.path.join(private_dir, "wins.ldb")
paths.s4_ldapi_path = os.path.join(private_dir, "ldapi")
@ -235,103 +255,33 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users,
ldb.setup_name_mapping(domaindn, sid + "-520", wheel)
def provision_become_dc(setup_dir, message, paths, lp, session_info,
credentials):
def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
credentials, configdn, schemadn, domaindn,
hostname, netbiosname, dnsdomain, realm,
rootdn, serverrole, ldap_backend=None,
ldap_backend_type=None, erase=False):
"""Setup the partitions for the SAM database.
Alternatively, provision() may call this, and then populate the database.
:param erase: Remove the existing data present in the database.
:param
:note: This will wipe the Sam Database!
:note: This function always removes the local SAM LDB file. The erase
parameter controls whether to erase the existing data, which
may not be stored locally but in LDAP.
"""
assert session_info is not None
erase = False
def setup_path(file):
return os.path.join(setup_dir, file)
os.path.unlink(paths.samdb)
message("Setting up templates db")
setup_templatesdb(paths.templates, setup_path, session_info=session_info,
credentials=credentials, lp=lp)
if os.path.exists(samdb_path):
os.unlink(samdb_path)
# Also wipes the database
message("Setting up sam.ldb")
samdb = SamDB(paths.samdb, session_info=session_info,
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
message("Setting up sam.ldb partitions")
setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn)
samdb = SamDB(paths.samdb, session_info=session_info,
credentials=credentials, lp=lp)
ldb.transaction_start()
try:
message("Setting up sam.ldb attributes")
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn,
hostname, dnsdomain, realm, rootdn, configdn,
netbiosname)
if erase:
message("Erasing data from partitions")
samdb.erase_partitions()
message("Setting up sam.ldb indexes")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
except:
samdb.transaction_cancel()
raise
samdb.transaction_commit()
message("Setting up %s" % paths.secrets)
secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info,
credentials, lp)
setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"),
{ "MACHINEPASS_B64": b64encode(machinepass) })
def setup_secretsdb(path, setup_path, session_info, credentials, lp):
if os.path.exists(path):
os.unlink(path)
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp)
secrets_ldb.erase()
secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))
secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))
return secrets_ldb
def setup_templatesdb(path, setup_path, session_info, credentials, lp):
templates_ldb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
templates_ldb.erase()
templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif"))
def setup_registry(path, setup_path, session_info, credentials, lp):
reg = registry.Registry()
hive = registry.open_ldb(path, session_info=session_info,
credentials=credentials, lp_ctx=lp)
reg.mount_hive(hive, "HKEY_LOCAL_MACHINE")
provision_reg = setup_path("provision.reg")
assert os.path.exists(provision_reg)
reg.diff_apply(provision_reg)
def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
dnsdomain, realm, rootdn, configdn, netbiosname):
setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"DNSDOMAIN": dnsdomain,
"DEFAULTSITE": DEFAULTSITE,
"REALM": realm,
"DNSNAME": "%s.%s" % (hostname, dnsdomain),
"DOMAINDN": domaindn,
"ROOTDN": rootdn,
"CONFIGDN": configdn,
"VERSION": samba.version(),
})
def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn):
#Add modules to the list to activate them by default
#beware often order is important
#
@ -361,6 +311,25 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn):
modules_list2 = ["show_deleted",
"partition"]
domaindn_ldb = "users.ldb"
if ldap_backend is not None:
domaindn_ldb = ldap_backend
configdn_ldb = "configuration.ldb"
if ldap_backend is not None:
configdn_ldb = ldap_backend
schema_ldb = "schema.ldb"
if ldap_backend is not None:
schema_ldb = ldap_backend
if ldap_backend_type == "fedora-ds":
backend_modules = ["nsuniqueid","paged_searches"]
elif ldap_backend_type == "openldap":
backend_modules = ["normalise","entryuuid","paged_searches"]
elif serverrole == "domain controller":
backend_modules = ["repl_meta_data"]
else:
backend_modules = ["objectguid"]
setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), {
"SCHEMADN": schemadn,
"SCHEMADN_LDB": "schema.ldb",
@ -369,21 +338,145 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn):
"CONFIGDN_LDB": "configuration.ldb",
"DOMAINDN": domaindn,
"DOMAINDN_LDB": "users.ldb",
"SCHEMADN_MOD": "schema_fsmo",
"CONFIGDN_MOD": "naming_fsmo",
"CONFIGDN_MOD2": ",objectguid",
"DOMAINDN_MOD": "pdc_fsmo,password_hash",
"DOMAINDN_MOD2": ",objectguid",
"SCHEMADN_MOD": "schema_fsmo,instancetype",
"CONFIGDN_MOD": "naming_fsmo,instancetype",
"DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype",
"MODULES_LIST": ",".join(modules_list),
"TDB_MODULES_LIST": ","+",".join(tdb_modules_list),
"MODULES_LIST2": ",".join(modules_list2),
"BACKEND_MOD": ",".join(backend_modules),
})
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
samdb.transaction_start()
try:
message("Setting up sam.ldb attributes")
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
dnsdomain, realm, rootdn, configdn, netbiosname)
if erase:
message("Erasing data from partitions")
samdb.erase_partitions()
except:
samdb.transaction_cancel()
raise
samdb.transaction_commit()
return samdb
def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain,
netbiosname, domainsid, keytab_path, samdb_url,
dns_keytab_path, dnspass, machinepass):
"""Add DC-specific bits to a secrets database.
:param secretsdb: Ldb Handle to the secrets database
:param setup_path: Setup path function
:param machinepass: Machine password
"""
setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), {
"MACHINEPASS_B64": b64encode(machinepass),
"DOMAIN": domain,
"REALM": realm,
"DNSDOMAIN": dnsdomain,
"DOMAINSID": str(domainsid),
"SECRETS_KEYTAB": keytab_path,
"NETBIOSNAME": netbiosname,
"SAM_LDB": samdb_url,
"DNS_KEYTAB": dns_keytab_path,
"DNSPASS_B64": b64encode(dnspass),
})
def setup_secretsdb(path, setup_path, session_info, credentials, lp):
"""Setup the secrets database.
:param path: Path to the secrets database.
:param setup_path: Get the path to a setup file.
:param session_info: Session info.
:param credentials: Credentials
:param lp: Loadparm context
:return: LDB handle for the created secrets database
"""
if os.path.exists(path):
os.unlink(path)
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
lp=lp)
secrets_ldb.erase()
secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))
secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,
lp=lp)
secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))
return secrets_ldb
def setup_templatesdb(path, setup_path, session_info, credentials, lp):
"""Setup the templates database.
:param path: Path to the database.
:param setup_path: Function for obtaining the path to setup files.
:param session_info: Session info
:param credentials: Credentials
:param lp: Loadparm context
"""
templates_ldb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
templates_ldb.erase()
templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif"))
def setup_registry(path, setup_path, session_info, credentials, lp):
"""Setup the registry.
:param path: Path to the registry database
:param setup_path: Function that returns the path to a setup.
:param session_info: Session information
:param credentials: Credentials
:param lp: Loadparm context
"""
reg = registry.Registry()
hive = registry.open_ldb(path, session_info=session_info,
credentials=credentials, lp_ctx=lp)
reg.mount_hive(hive, "HKEY_LOCAL_MACHINE")
provision_reg = setup_path("provision.reg")
assert os.path.exists(provision_reg)
reg.diff_apply(provision_reg)
def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname,
dnsdomain, realm, rootdn, configdn, netbiosname):
"""Setup the SamDB rootdse.
:param samdb: Sam Database handle
:param setup_path: Obtain setup path
...
"""
setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"DNSDOMAIN": dnsdomain,
"DEFAULTSITE": DEFAULTSITE,
"REALM": realm,
"DNSNAME": "%s.%s" % (hostname, dnsdomain),
"DOMAINDN": domaindn,
"ROOTDN": rootdn,
"CONFIGDN": configdn,
"VERSION": samba.version(),
})
def setup_self_join(samdb, configdn, schemadn, domaindn,
netbiosname, hostname, dnsdomain, machinepass, dnspass,
realm, domainname, domainsid, invocationid, setup_path,
policyguid, hostguid=None):
"""Join a host to its own domain."""
if hostguid is not None:
hostguid_add = "objectGUID: %s" % hostguid
else:
@ -413,43 +506,39 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
def setup_samdb(path, setup_path, session_info, credentials, lp,
schemadn, configdn, domaindn, dnsdomain, realm,
netbiosname, message, hostname, rootdn, erase,
domainsid, aci, rdn_dc, domainguid, policyguid,
domainname, blank, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass):
domainsid, aci, domainguid, policyguid,
domainname, fill, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass,
serverrole, ldap_backend=None, ldap_backend_type=None):
"""Setup a complete SAM Database.
"""
# Also wipes the database
message("Setting up sam.ldb")
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
message("Setting up sam.ldb partitions")
setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn)
setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
domaindn=domaindn, message=message, lp=lp,
credentials=credentials, session_info=session_info,
hostname=hostname, netbiosname=netbiosname,
dnsdomain=dnsdomain, realm=realm, rootdn=rootdn,
ldap_backend=ldap_backend, serverrole=serverrole,
ldap_backend_type=ldap_backend_type, erase=erase)
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
samdb.transaction_start()
try:
message("Setting up sam.ldb attributes")
samdb.load_ldif_file_add(setup_path("provision_init.ldif"))
message("Setting up sam.ldb rootDSE")
setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn,
hostname, dnsdomain, realm, rootdn, configdn,
netbiosname)
if erase:
message("Erasing data from partitions")
samdb.erase_partitions()
except:
samdb.transaction_cancel()
raise
samdb.transaction_commit()
if fill == FILL_DRS:
# We want to finish here, but setup the index before we do so
message("Setting up sam.ldb index")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
return samdb
message("Pre-loading the Samba 4 and AD schema")
samdb = SamDB(path, session_info=session_info,
credentials=credentials, lp=lp)
samdb.set_domain_sid(domainsid)
if lp.get("server role") == "domain controller":
samdb.set_invocation_id(invocationid)
load_schema(setup_path, samdb, schemadn, netbiosname, configdn)
samdb.transaction_start()
@ -459,7 +548,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
"DOMAINDN": domaindn,
"ACI": aci,
"RDN_DC": rdn_dc,
})
message("Modifying DomainDN: " + domaindn + "")
@ -469,7 +557,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
domainguid_mod = ""
setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), {
"RDN_DC": rdn_dc,
"LDAPTIME": timestring(int(time.time())),
"DOMAINSID": str(domainsid),
"SCHEMADN": schemadn,
@ -500,7 +587,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb"
})
message("Modifying schema container")
setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), {
setup_modify_ldif(samdb,
setup_path("provision_schema_basedn_modify.ldif"), {
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"DEFAULTSITE": DEFAULTSITE,
@ -549,7 +637,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
"CONFIGDN": configdn,
})
if not blank:
if fill == FILL_FULL:
message("Setting up sam.ldb users and groups")
setup_add_ldif(samdb, setup_path("provision_users.ldif"), {
"DOMAINDN": domaindn,
@ -561,17 +649,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
if lp.get("server role") == "domain controller":
message("Setting up self join")
setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn,
invocationid=invocationid, dnspass=dnspass, netbiosname=netbiosname,
dnsdomain=dnsdomain, realm=realm, machinepass=machinepass,
domainname=domainname, domainsid=domainsid, policyguid=policyguid,
hostname=hostname, hostguid=hostguid, setup_path=setup_path)
setup_self_join(samdb, configdn=configdn, schemadn=schemadn,
domaindn=domaindn, invocationid=invocationid,
dnspass=dnspass, netbiosname=netbiosname,
dnsdomain=dnsdomain, realm=realm,
machinepass=machinepass, domainname=domainname,
domainsid=domainsid, policyguid=policyguid,
hostname=hostname, hostguid=hostguid,
setup_path=setup_path)
#We want to setup the index last, as adds are faster unindexed
message("Setting up sam.ldb index")
samdb.load_ldif_file_add(setup_path("provision_index.ldif"))
message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
except:
samdb.transaction_cancel()
raise
@ -579,14 +668,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
samdb.transaction_commit()
return samdb
FILL_FULL = "FULL"
FILL_NT4SYNC = "NT4SYNC"
FILL_DRS = "DRS"
def provision(lp, setup_dir, message, blank, paths, session_info,
credentials, ldapbackend, realm=None, domain=None, hostname=None,
hostip=None, domainsid=None, hostguid=None, adminpass=None,
krbtgtpass=None, domainguid=None, policyguid=None,
invocationid=None, machinepass=None, dnspass=None, root=None,
nobody=None, nogroup=None, users=None, wheel=None, backup=None,
aci=None, serverrole=None):
def provision(lp, setup_dir, message, paths, session_info,
credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None,
domain=None, hostname=None, hostip=None, domainsid=None,
hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,
policyguid=None, invocationid=None, machinepass=None,
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
wheel=None, backup=None, aci=None, serverrole=None, erase=False,
ldap_backend=None, ldap_backend_type=None):
"""Provision samba4
:note: caution, this wipes all existing data!
@ -595,14 +688,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
def setup_path(file):
return os.path.join(setup_dir, file)
erase = False
if domainsid is None:
domainsid = security.random_sid()
if policyguid is None:
policyguid = uuid.random()
if invocationid is None:
invocationid = uuid.random()
if adminpass is None:
adminpass = misc.random_password(12)
if krbtgtpass is None:
@ -612,45 +701,41 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
if dnspass is None:
dnspass = misc.random_password(12)
if root is None:
root = findnss(pwd.getpwnam, "root")[4]
root = findnss(pwd.getpwnam, "root")[0]
if nobody is None:
nobody = findnss(pwd.getpwnam, "nobody")[4]
nobody = findnss(pwd.getpwnam, "nobody")[0]
if nogroup is None:
nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2]
nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0]
if users is None:
users = findnss(grp.getgrnam, "users", "guest", "other", "unknown",
"usr")[2]
"usr")[0]
if wheel is None:
wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2]
wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0]
if backup is None:
backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2]
backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0]
if aci is None:
aci = "# no aci for local ldb"
if serverrole is None:
serverrole = lp.get("server role")
if invocationid is None and serverrole == "domain controller":
invocationid = uuid.random()
if realm is None:
realm = lp.get("realm")
else:
if lp.get("realm").upper() != realm.upper():
raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" %
if lp.get("realm").upper() != realm.upper():
raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" %
(lp.get("realm"), realm))
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
if ldap_backend == "ldapi":
# provision-backend will set this path suggested slapd command line / fedorads.inf
ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="")
assert realm is not None
realm = realm.upper()
if domain is None:
domain = lp.get("workgroup")
else:
if lp.get("workgroup").upper() != domain.upper():
raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n",
lp.get("workgroup"), domain)
assert domain is not None
domain = domain.upper()
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
if hostname is None:
hostname = gethostname().split(".")[0].lower()
@ -662,13 +747,30 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
raise InvalidNetbiosName(netbiosname)
dnsdomain = realm.lower()
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
rootdn = domaindn
if serverrole == "domain controller":
domaindn = "DC=" + dnsdomain.replace(".", ",DC=")
if domain is None:
domain = lp.get("workgroup")
if lp.get("workgroup").upper() != domain.upper():
raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'",
lp.get("workgroup"), domain)
assert domain is not None
domain = domain.upper()
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
else:
domaindn = "CN=" + netbiosname
domain = netbiosname
if rootdn is None:
rootdn = domaindn
configdn = "CN=Configuration," + rootdn
schemadn = "CN=Schema," + configdn
rdn_dc = domaindn.split(",")[0][len("DC="):]
message("set DOMAIN SID: %s" % str(domainsid))
message("Provisioning for %s in realm %s" % (domain, realm))
message("Using administrator password: %s" % adminpass)
@ -684,7 +786,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
smbconfsuffix = "member"
else:
assert "Invalid server role setting: %s" % serverrole
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, {
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
paths.smbconf, {
"HOSTNAME": hostname,
"DOMAIN_CONF": domain,
"REALM_CONF": realm,
@ -701,6 +804,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
credentials=credentials, lp=lp)
share_ldb.load_ldif_file_add(setup_path("share.ldif"))
message("Setting up secrets.ldb")
secrets_ldb = setup_secretsdb(paths.secrets, setup_path,
session_info=session_info,
@ -714,44 +818,47 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
setup_templatesdb(paths.templates, setup_path, session_info=session_info,
credentials=credentials, lp=lp)
samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials,
lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn,
dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message,
hostname=hostname, rootdn=rootdn, erase=erase, domainsid=domainsid, aci=aci,
rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid,
domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass,
hostguid=hostguid, invocationid=invocationid, machinepass=machinepass,
dnspass=dnspass)
samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info,
credentials=credentials, lp=lp, schemadn=schemadn,
configdn=configdn, domaindn=domaindn,
dnsdomain=dnsdomain, netbiosname=netbiosname,
realm=realm, message=message, hostname=hostname,
rootdn=rootdn, erase=erase, domainsid=domainsid,
aci=aci, domainguid=domainguid, policyguid=policyguid,
domainname=domain, fill=samdb_fill,
adminpass=adminpass, krbtgtpass=krbtgtpass,
hostguid=hostguid, invocationid=invocationid,
machinepass=machinepass, dnspass=dnspass,
serverrole=serverrole, ldap_backend=ldap_backend,
ldap_backend_type=ldap_backend_type)
if lp.get("server role") == "domain controller":
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755)
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755)
os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755)
if not os.path.isdir(paths.netlogon):
policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies",
"{" + policyguid + "}")
os.makedirs(policy_path, 0755)
os.makedirs(os.path.join(policy_path, "Machine"), 0755)
os.makedirs(os.path.join(policy_path, "User"), 0755)
if not os.path.isdir(paths.netlogon):
os.makedirs(paths.netlogon, 0755)
secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp)
setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), {
"MACHINEPASS_B64": b64encode(machinepass),
"DOMAIN": domain,
"REALM": realm,
"LDAPTIME": timestring(int(time.time())),
"DNSDOMAIN": dnsdomain,
"DOMAINSID": str(domainsid),
"SECRETS_KEYTAB": paths.keytab,
"NETBIOSNAME": netbiosname,
"SAM_LDB": paths.samdb,
"DNS_KEYTAB": paths.dns_keytab,
"DNSPASS_B64": b64encode(dnspass),
})
secrets_ldb = Ldb(paths.secrets, session_info=session_info,
credentials=credentials, lp=lp)
secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm,
netbiosname=netbiosname, domainsid=domainsid,
keytab_path=paths.keytab, samdb_url=paths.samdb,
dns_keytab_path=paths.dns_keytab, dnspass=dnspass,
machinepass=machinepass, dnsdomain=dnsdomain)
if not blank:
setup_name_mappings(samdb, str(domainsid),
domaindn, root=root, nobody=nobody,
nogroup=nogroup, wheel=wheel, users=users,
backup=backup)
if samdb_fill == FILL_FULL:
setup_name_mappings(samdb, str(domainsid), domaindn, root=root,
nobody=nobody, nogroup=nogroup, wheel=wheel,
users=users, backup=backup)
message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
message("Setting up phpLDAPadmin configuration")
create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path)
create_phpldapadmin_config(paths.phpldapadminconfig, setup_path,
ldapi_url)
message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
@ -759,9 +866,9 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
samdb = SamDB(paths.samdb, session_info=session_info,
credentials=credentials, lp=lp)
domainguid = samdb.searchone(domaindn, "objectGUID")
domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")
assert isinstance(domainguid, str)
hostguid = samdb.searchone(domaindn, "objectGUID",
hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID",
expression="(&(objectClass=computer)(cn=%s))" % hostname,
scope=SCOPE_SUBTREE)
assert isinstance(hostguid, str)
@ -775,15 +882,15 @@ def provision(lp, setup_dir, message, blank, paths, session_info,
return domaindn
def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path):
def create_phpldapadmin_config(path, setup_path, ldapi_uri):
"""Create a PHP LDAP admin configuration file.
:param path: Path to write the configuration to.
:param setup_path: Function to generate setup paths.
:param s4_ldapi_path: Path to Samba 4 LDAPI socket.
"""
setup_file(setup_path("phpldapadmin-config.php"),
path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")})
setup_file(setup_path("phpldapadmin-config.php"), path,
{"S4_LDAPI_URI": ldapi_uri})
def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
@ -802,6 +909,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn,
:param domainguid: GUID of the domain.
:param hostguid: GUID of the host.
"""
assert isinstance(domainguid, str)
setup_file(setup_path("provision.zone"), path, {
"DNSPASS_B64": b64encode(dnspass),
@ -833,6 +941,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn):
"SCHEMADN": schemadn,
"NETBIOSNAME": netbiosname,
"CONFIGDN": configdn,
"DEFAULTSITE": DEFAULTSITE})
"DEFAULTSITE": DEFAULTSITE
})
samdb.attach_schema_from_ldif(head_data, schema_data)

View File

@ -1,10 +1,10 @@
#!/usr/bin/python
# Unix SMB/CIFS implementation.
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
#
# Based on the original in EJS:
# Copyright (C) Andrew Tridgell 2005
# Copyright (C) Andrew Tridgell <tridge@samba.org> 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
@ -105,7 +105,7 @@ userAccountControl: %u
assert(len(res) == 1 and res[0].defaultNamingContext is not None)
domain_dn = res[0]["defaultNamingContext"][0]
assert(domain_dn is not None)
dom_users = self.searchone(domain_dn, "dn", "name=Domain Users")
dom_users = self.searchone(basedn=domain_dn, attribute="dn", expression="name=Domain Users")
assert(dom_users is not None)
user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn)
@ -145,3 +145,10 @@ member: %s
def attach_schema_from_ldif(self, pf, df):
misc.dsdb_attach_schema_from_ldif_file(self, pf, df)
def set_invocation_id(self, invocation_id):
"""Set the invocation id for this SamDB handle.
:param invocation_id: GUID of the invocation id.
"""
misc.dsdb_set_ntds_invocation_id(self, invocation_id)

View File

@ -1,7 +1,7 @@
#!/usr/bin/python
# Unix SMB/CIFS implementation.
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
#
# 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
@ -67,6 +67,10 @@ class SubstituteVarTestCase(unittest.TestCase):
def test_unknown_var(self):
self.assertEquals("foo ${bla} gsff",
samba.substitute_var("foo ${bla} gsff", {"bar": "bla"}))
def test_check_all_substituted(self):
samba.check_all_substituted("nothing to see here")
self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}")
class LdbExtensionTests(TestCaseInTempDir):
@ -75,7 +79,7 @@ class LdbExtensionTests(TestCaseInTempDir):
l = samba.Ldb(path)
try:
l.add({"dn": "foo=dc", "bar": "bla"})
self.assertEquals("bla", l.searchone(ldb.Dn(l, "foo=dc"), "bar"))
self.assertEquals("bla", l.searchone(basedn=ldb.Dn(l, "foo=dc"), attribute="bar"))
finally:
del l
os.unlink(path)

View File

@ -1,7 +1,7 @@
#!/usr/bin/python
# Unix SMB/CIFS implementation.
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
#
# 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
@ -18,7 +18,7 @@
#
import os
from samba.provision import setup_secretsdb
from samba.provision import setup_secretsdb, secretsdb_become_dc
import samba.tests
from ldb import Dn
@ -33,11 +33,34 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir):
ldb = setup_secretsdb(path, setup_path, None, None, None)
try:
self.assertEquals("LSA Secrets",
ldb.searchone(Dn(ldb, "CN=LSA Secrets"), "CN"))
ldb.searchone(basedn="CN=LSA Secrets", attribute="CN"))
finally:
del ldb
os.unlink(path)
def test_become_dc(self):
path = os.path.join(self.tempdir, "secrets.ldb")
secrets_ldb = setup_secretsdb(path, setup_path, None, None, None)
try:
secretsdb_become_dc(secrets_ldb, setup_path, domain="EXAMPLE",
realm="example", netbiosname="myhost",
domainsid="S-5-22", keytab_path="keytab.path",
samdb_url="ldap://url/",
dns_keytab_path="dns.keytab", dnspass="bla",
machinepass="machinepass", dnsdomain="example.com")
self.assertEquals(1,
len(secrets_ldb.search("samAccountName=krbtgt,flatname=EXAMPLE,CN=Principals")))
self.assertEquals("keytab.path",
secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains",
expression="(privateKeytab=*)",
attribute="privateKeytab"))
self.assertEquals("S-5-22",
secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains",
expression="objectSid=*", attribute="objectSid"))
finally:
del secrets_ldb
os.unlink(path)
class Disabled:
def test_setup_templatesdb(self):

View File

@ -7,7 +7,7 @@
"""Support code for upgrading from Samba 3 to Samba 4."""
from provision import findnss, provision
from provision import findnss, provision, FILL_DRS
import grp
import ldb
import pwd
@ -245,7 +245,8 @@ def upgrade_provision(samba3, setup_dir, message, credentials, session_info, lp,
else:
machinepass = None
domaindn = provision(lp=lp, setup_dir=setup_dir, message=message, blank=True, ldapbackend=None,
domaindn = provision(lp=lp, setup_dir=setup_dir, message=message,
samdb_fill=FILL_DRS, ldapbackend=None,
paths=paths, session_info=session_info, credentials=credentials, realm=realm,
domain=domainname, domainsid=domainsid, domainguid=domainguid,
machinepass=machinepass, serverrole=serverrole)

View File

@ -2,7 +2,8 @@
#
# Unix SMB/CIFS implementation.
# provision a Samba4 server
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
#
# Based on the original in EJS:
# Copyright (C) Andrew Tridgell 2005
@ -33,8 +34,10 @@ import samba
from auth import system_session
import samba.getopt as options
import param
from samba.provision import (provision,
provision_paths_from_lp)
from samba.provision import (provision,
provision_paths_from_lp,
FILL_FULL, FILL_NT4SYNC,
FILL_DRS)
parser = optparse.OptionParser("provision [options]")
sambaopts = options.SambaOptions(parser)
@ -84,8 +87,9 @@ parser.add_option("--blank", action="store_true",
help="do not add users or groups, just the structure")
parser.add_option("--ldap-backend", type="string", metavar="LDAPSERVER",
help="LDAP server to use for this provision")
parser.add_option("--ldap-module=", type="string", metavar="MODULE",
help="LDB mapping module to use for the LDAP backend")
parser.add_option("--ldap-backend-type", type="choice", metavar="LDAP-BACKEND-TYPE",
help="LDB mapping module to use for the LDAP backend",
choices=["fedora-ds", "openldap"])
parser.add_option("--aci", type="string", metavar="ACI",
help="An arbitary LDIF fragment, particularly useful to loading a backend ACI value into a target LDAP server. You must provide at least a realm and domain")
parser.add_option("--server-role", type="choice", metavar="ROLE",
@ -112,61 +116,58 @@ if opts.realm is None or opts.domain is None:
sys.exit(1)
# cope with an initially blank smb.conf
private_dir = None
lp = sambaopts.get_loadparm()
if opts.targetdir is not None:
if not os.path.exists(opts.targetdir):
os.mkdir(opts.targetdir)
lp.set("private dir", os.path.abspath(opts.targetdir))
private_dir = os.path.join(opts.targetdir, "private")
if not os.path.exists(private_dir):
os.mkdir(private_dir)
lp.set("private dir", os.path.abspath(private_dir))
lp.set("lock dir", os.path.abspath(opts.targetdir))
lp.set("realm", opts.realm)
lp.set("workgroup", opts.domain)
lp.set("server role", opts.server_role or "domain controller")
if opts.aci is not None:
print "set ACI: %s" % opts.aci
paths = provision_paths_from_lp(lp, opts.realm.lower())
paths = provision_paths_from_lp(lp, opts.realm.lower(), private_dir)
paths.smbconf = sambaopts.get_loadparm_path()
if opts.ldap_backend:
if opts.ldap_backend == "ldapi":
subobj.ldap_backend = subobj.ldapi_uri
if not opts.ldap_module:
subobj.ldapmodule = "entryuuid"
subobj.domaindn_ldb = subobj.ldap_backend
subobj.domaindn_mod2 = ",%s,paged_searches" % subobj.ldapmodule
subobj.configdn_ldb = subobj.ldap_backend
subobj.configdn_mod2 = ",%s,paged_searches" % subobj.ldapmodule
subobj.schemadn_ldb = subobj.ldap_backend
subobj.schemadn_mod2 = ",%s,paged_searches" % subobj.ldapmodule
message("LDAP module: %s on backend: %s" % (subobj.ldapmodule, subobj.ldap_backend))
creds = credopts.get_credentials()
setup_dir = opts.setupdir
if setup_dir is None:
setup_dir = "setup"
if opts.partitions_only:
provision_become_dc(setup_dir, message, False,
paths, lp, system_session(), creds)
else:
provision(lp, setup_dir, message, opts.blank, paths,
system_session(), creds, opts.ldap_backend, realm=opts.realm,
domainguid=opts.domain_guid, domainsid=opts.domain_sid,
policyguid=opts.policy_guid, hostname=opts.host_name,
hostip=opts.host_ip, hostguid=opts.host_guid,
invocationid=opts.invocationid, adminpass=opts.adminpass,
krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass,
dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody,
nogroup=opts.nogroup, wheel=opts.wheel, users=opts.users,
aci=opts.aci, serverrole=opts.server_role)
message("To reproduce this provision, run with:")
def shell_escape(arg):
if " " in arg:
return '"%s"' % arg
return arg
message(" ".join([shell_escape(arg) for arg in sys.argv]))
samdb_fill = FILL_FULL
if opts.blank:
samdb_fill = FILL_NT4SYNC
elif opts.partitions_only:
samdb_fill = FILL_DRS
provision(lp, setup_dir, message, paths,
system_session(), creds, opts.ldap_backend,
samdb_fill=samdb_fill, realm=opts.realm,
domainguid=opts.domain_guid, domainsid=opts.domain_sid,
policyguid=opts.policy_guid, hostname=opts.host_name,
hostip=opts.host_ip, hostguid=opts.host_guid,
invocationid=opts.invocationid, adminpass=opts.adminpass,
krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass,
dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody,
nogroup=opts.nogroup, wheel=opts.wheel, users=opts.users,
aci=opts.aci, serverrole=opts.server_role,
ldap_backend=opts.ldap_backend,
ldap_backend_type=opts.ldap_backend_type)
message("To reproduce this provision, run with:")
def shell_escape(arg):
if " " in arg:
return '"%s"' % arg
return arg
message(" ".join([shell_escape(arg) for arg in sys.argv]))
message("All OK")