From 1a0aed36c0fc3815c832be1086a3a66256426414 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Thu, 19 Feb 2009 17:06:27 -0800 Subject: Added torture tests to RAW-NOTIFY * This adds a test to check the change notify behavior of the SMB server when more events have been generated than can be returned in a single change notify response. * Second test makes sure the server doesn't return notification events for changes to the watched directory itself --- source4/torture/raw/notify.c | 152 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 82f7d18323..3ffc58dbe6 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -561,7 +561,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t tv = timeval_current_ofs(1000, 0); t = timeval_to_nttime(&tv); - + /* get a handle on the directory */ @@ -1283,6 +1283,152 @@ done: return ret; } +/* + Test response when cached server events exceed single NT NOTFIY response + packet size. +*/ +static bool test_notify_overflow(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_notify notify; + union smb_open io; + int fnum, fnum2; + int count = 100; + struct smbcli_request *req1; + int i; + + printf("TESTING CHANGE NOTIFY EVENT OVERFLOW\n"); + + /* get a handle on the directory */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FILE_ALL; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* ask for a change notify, on name changes. */ + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + + notify.nttrans.in.recursive = true; + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + + /* cancel initial requests so the buffer is setup */ + smb_raw_ntcancel(req1); + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_CANCELLED); + + /* open a lot of files, filling up the server side notify buffer */ + printf("testing overflowed buffer notify on create of %d files\n", + count); + for (i=0;itree, fname, O_CREAT|O_RDWR, + DENY_NONE); + if (fnum2 == -1) { + printf("Failed to create %s - %s\n", + fname, smbcli_errstr(cli->tree)); + ret = false; + goto done; + } + talloc_free(fname); + smbcli_close(cli->tree, fnum2); + } + + /* expect that 0 events will be returned with NT_STATUS_OK */ + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 0); + +done: + smb_raw_exit(cli->session); + return ret; +} + +/* + Test if notifications are returned for changes to the base directory. + They shouldn't be. +*/ +static bool test_notify_basedir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_notify notify; + union smb_open io; + int fnum, fnum2; + int count = 100; + struct smbcli_request *req1; + int i; + + printf("TESTING CHANGE NOTIFY BASEDIR EVENTS\n"); + + /* get a handle on the directory */ + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = SEC_FILE_ALL; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = BASEDIR; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* create a test file that will also be modified */ + smbcli_close(cli->tree, smbcli_open(cli->tree, BASEDIR "\\tname1", + O_CREAT, 0)); + + /* ask for a change notify, on attribute changes. */ + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_ATTRIBUTES; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = true; + + req1 = smb_raw_changenotify_send(cli->tree, ¬ify); + + /* set attribute on the base dir */ + smbcli_setatr(cli->tree, BASEDIR, FILE_ATTRIBUTE_HIDDEN, 0); + + /* set attribute on a file to assure we receive a notification */ + smbcli_setatr(cli->tree, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN, 0); + msleep(200); + + /* check how many responses were given, expect only 1 for the file */ + status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_MODIFIED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "tname1", STR_UNICODE); + +done: + smb_raw_exit(cli->session); + return ret; +} + /* basic testing of change notify */ @@ -1291,7 +1437,7 @@ bool torture_raw_notify(struct torture_context *torture, struct smbcli_state *cli2) { bool ret = true; - + if (!torture_setup_dir(cli, BASEDIR)) { return false; } @@ -1307,6 +1453,8 @@ bool torture_raw_notify(struct torture_context *torture, ret &= test_notify_tcp_dis(torture); ret &= test_notify_double(cli, torture); ret &= test_notify_tree(cli, torture); + ret &= test_notify_overflow(cli, torture); + ret &= test_notify_basedir(cli, torture); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); -- cgit From 116ce19b10a1fd60776764974ad50776ff7c4714 Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 20 Feb 2009 15:10:21 -0800 Subject: Moved become_daemon() and close_low_fds() to shared util lib --- source4/smbd/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/smbd/server.c b/source4/smbd/server.c index 247a10f60f..d576782ab1 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -277,7 +277,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ if (opt_daemon) { DEBUG(3,("Becoming a daemon.\n")); - become_daemon(true); + become_daemon(true, false); } cleanup_tmp_files(cmdline_lp_ctx); -- cgit From 2539d678f54d09577d5c86fae1d6d43175bfca96 Mon Sep 17 00:00:00 2001 From: Zack Kirsch Date: Fri, 20 Feb 2009 15:29:29 -0800 Subject: s4 torture: Add comment to clarify test --- source4/torture/raw/samba3misc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4') diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 8cdccb3906..c4c790cb0a 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -672,6 +672,9 @@ bool torture_samba3_caseinsensitive(struct torture_context *torture) /* * Check that Samba3 correctly deals with conflicting posix byte range locks * on an underlying file + * + * Note: This test depends on "posix locking = yes". + * Note: To run this test, use "--option=torture:localdir=" */ bool torture_samba3_posixtimedlock(struct torture_context *tctx) -- cgit From fb1c564b78032b61bba182e748cdbadf94d26e15 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 18:21:20 +0100 Subject: Add --enable-external-* flags for libraries shipped with Samba, to allow explicitly enabling or disabling the use of the version provided by the system. --- source4/build/m4/public.m4 | 22 ++++++++++++++++++++++ source4/configure.ac | 9 ++++----- 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'source4') diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 1823f1ba97..a707a113cd 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -6,6 +6,8 @@ dnl Published under the GPL dnl dnl SMB_EXT_LIB_FROM_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) dnl +dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +dnl dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) dnl dnl SMB_ENABLE(name,default_build) @@ -125,6 +127,26 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG], fi ]) +dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) +AC_DEFUN([SMB_INCLUDED_LIB_PKGCONFIG], +[ + AC_ARG_ENABLE([external-]translit($1,`A-Z',`a-z'), + AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=auto)]), [], [enableval=auto]) + + if test $enableval = yes -o $enableval = auto; then + SMB_EXT_LIB_FROM_PKGCONFIG([$1], [$2], [$3], [ + if test $enableval = yes; then + AC_MSG_ERROR([Unable to find external $1]) + fi + ]) + else + ifelse([$4], [], [ + SMB_EXT_LIB($1) + SMB_ENABLE($1, NO) + ], [$4]) + fi +]) + dnl SMB_INCLUDE_MK(file) AC_DEFUN([SMB_INCLUDE_MK], [ diff --git a/source4/configure.ac b/source4/configure.ac index 85ea44f570..bc3c01173f 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -42,15 +42,14 @@ AC_CONFIG_FILES(param/samba-hostconfig.pc) AC_CONFIG_FILES(librpc/dcerpc_samr.pc) AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, - [], +SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= 1.2.0, [], [ m4_include(../lib/talloc/libtalloc.m4) SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= 1.1.3, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -60,13 +59,13 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= 1.1.3, SMB_INCLUDE_MK(../lib/tdb/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = 0.9.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = 0.9.3, [],[m4_include(../lib/tevent/samba.m4)] ) SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = 0.9.3, +SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = 0.9.3, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) -- cgit From 80e9e63cf611ed45cb2bfb4896f962270e92ee8e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 21 Feb 2009 18:59:12 +0100 Subject: Let --enable-external-libldb default to no (since linking against external LDB doesn't work yet). Fix flags when using internal libs. --- source4/build/m4/public.m4 | 6 ++++-- source4/configure.ac | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4') diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index a707a113cd..1927e9977f 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -131,15 +131,17 @@ dnl SMB_INCLUDED_LIB_PKGCONFIG(name,pkg-config name,[ACTION-IF-FOUND],[ACTION-IF AC_DEFUN([SMB_INCLUDED_LIB_PKGCONFIG], [ AC_ARG_ENABLE([external-]translit($1,`A-Z',`a-z'), - AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=auto)]), [], [enableval=auto]) + AS_HELP_STRING([--enable-external-]translit($1,`A-Z',`a-z'), [Use external $1 instead of built-in (default=ifelse([$5],[],auto,$5))]), [], [enableval=ifelse([$5],[],auto,$5)]) if test $enableval = yes -o $enableval = auto; then SMB_EXT_LIB_FROM_PKGCONFIG([$1], [$2], [$3], [ if test $enableval = yes; then AC_MSG_ERROR([Unable to find external $1]) fi + enableval=no ]) - else + fi + if test $enableval = no; then ifelse([$4], [], [ SMB_EXT_LIB($1) SMB_ENABLE($1, NO) diff --git a/source4/configure.ac b/source4/configure.ac index bc3c01173f..54ca9108b1 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -95,8 +95,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = 0.9.3, m4_include(lib/ldb/libldb.m4) SMB_INCLUDE_MK(lib/ldb/config.mk) AC_CONFIG_FILES(lib/ldb/ldb.pc) - ] -) + ], [no]) SMB_INCLUDE_MK(lib/ldb/python.mk) m4_include(lib/tls/config.m4) -- cgit From 24373c16a5b3e96ea3adc18e7aac837be59fb2c2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Feb 2009 14:22:39 +0100 Subject: s4-smbtorture: fix eventlog getinformation test. Guenther --- source4/torture/rpc/eventlog.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4') diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c index 2fd9d923f1..10c4886259 100644 --- a/source4/torture/rpc/eventlog.c +++ b/source4/torture/rpc/eventlog.c @@ -306,7 +306,7 @@ static bool test_GetLogInformation(struct torture_context *tctx, struct dcerpc_pipe *p) { NTSTATUS status; - struct eventlog_GetLogIntormation r; + struct eventlog_GetLogInformation r; struct eventlog_CloseEventLog cr; struct policy_handle handle; uint32_t bytes_needed = 0; @@ -320,14 +320,14 @@ static bool test_GetLogInformation(struct torture_context *tctx, r.out.buffer = NULL; r.out.bytes_needed = &bytes_needed; - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_INVALID_LEVEL, "GetLogInformation failed"); r.in.level = 0; - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_BUFFER_TOO_SMALL, "GetLogInformation failed"); @@ -335,7 +335,7 @@ static bool test_GetLogInformation(struct torture_context *tctx, r.in.buf_size = bytes_needed; r.out.buffer = talloc_array(tctx, uint8_t, bytes_needed); - status = dcerpc_eventlog_GetLogIntormation(p, tctx, &r); + status = dcerpc_eventlog_GetLogInformation(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetLogInformation failed"); -- cgit From 689b8f5bb36a003756ee41787487237eef48cfab Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 22 Feb 2009 01:50:49 -0500 Subject: Make all transactions nested in ldb. The current samba4 code expects this behavior anyway, and given we can only have one transaction active per ldb context this is the only sane model we can support. Fix ldb_tdb transactions, we could return back with an error with neither committing nor canceling the actual tdb transaction in some error paths within the ltdb commit and cancel transaction paths. Added also some debugging to trace what was going on. --- source4/lib/ldb/common/ldb.c | 132 +++++++++++++++++++++----------------- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 2 + 2 files changed, 75 insertions(+), 59 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 2fb5a8f9be..f1b28b6819 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -34,6 +34,19 @@ #include "ldb_private.h" +static int ldb_context_destructor(void *ptr) +{ + struct ldb_context *ldb = talloc_get_type(ptr, struct ldb_context); + + if (ldb->transaction_active) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "A transaction is still active in ldb context [%p]", + ldb); + } + + return 0; +} + /* initialise a ldb context The mem_ctx is required @@ -65,6 +78,8 @@ struct ldb_context *ldb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx) /* TODO: get timeout from options if available there */ ldb->default_timeout = 300; /* set default to 5 minutes */ + talloc_set_destructor((TALLOC_CTX *)ldb, ldb_context_destructor); + return ldb; } @@ -242,10 +257,24 @@ void ldb_reset_err_string(struct ldb_context *ldb) /* start a transaction */ -static int ldb_transaction_start_internal(struct ldb_context *ldb) +int ldb_transaction_start(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "start ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* explicit transaction active, count nested requests */ + if (ldb->transaction_active) { + ldb->transaction_active++; + return LDB_SUCCESS; + } + + /* start a new transaction */ + ldb->transaction_active++; + FIRST_OP(ldb, start_transaction); ldb_reset_err_string(ldb); @@ -266,10 +295,29 @@ static int ldb_transaction_start_internal(struct ldb_context *ldb) /* commit a transaction */ -static int ldb_transaction_commit_internal(struct ldb_context *ldb) +int ldb_transaction_commit(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "commit ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* commit only when all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, end_transaction); ldb_reset_err_string(ldb); @@ -290,10 +338,29 @@ static int ldb_transaction_commit_internal(struct ldb_context *ldb) /* cancel a transaction */ -static int ldb_transaction_cancel_internal(struct ldb_context *ldb) +int ldb_transaction_cancel(struct ldb_context *ldb) { struct ldb_module *module; int status; + + ldb->transaction_active--; + + ldb_debug(ldb, LDB_DEBUG_TRACE, + "cancel ldb transaction (nesting: %d)", + ldb->transaction_active); + + /* really cancel only if all nested transactions are complete */ + if (ldb->transaction_active > 0) { + return LDB_SUCCESS; + } + + if (ldb->transaction_active < 0) { + ldb_debug(ldb, LDB_DEBUG_FATAL, + "commit called but no ldb transactions are active!"); + ldb->transaction_active = 0; + return LDB_ERR_OPERATIONS_ERROR; + } + FIRST_OP(ldb, del_transaction); status = module->ops->del_transaction(module); @@ -309,66 +376,13 @@ static int ldb_transaction_cancel_internal(struct ldb_context *ldb) return status; } -int ldb_transaction_start(struct ldb_context *ldb) -{ - /* disable autotransactions */ - ldb->transaction_active++; - - return ldb_transaction_start_internal(ldb); -} - -int ldb_transaction_commit(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_commit_internal(ldb); -} - -int ldb_transaction_cancel(struct ldb_context *ldb) -{ - /* renable autotransactions (when we reach 0) */ - if (ldb->transaction_active > 0) - ldb->transaction_active--; - - return ldb_transaction_cancel_internal(ldb); -} - -static int ldb_autotransaction_start(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_start_internal(ldb); -} - -static int ldb_autotransaction_commit(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_commit_internal(ldb); -} - -static int ldb_autotransaction_cancel(struct ldb_context *ldb) -{ - /* explicit transaction active, ignore autotransaction request */ - if (ldb->transaction_active) - return LDB_SUCCESS; - - return ldb_transaction_cancel_internal(ldb); -} - /* autostarts a transacion if none active */ static int ldb_autotransaction_request(struct ldb_context *ldb, struct ldb_request *req) { int ret; - ret = ldb_autotransaction_start(ldb); + ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { return ret; } @@ -379,9 +393,9 @@ static int ldb_autotransaction_request(struct ldb_context *ldb, } if (ret == LDB_SUCCESS) { - return ldb_autotransaction_commit(ldb); + return ldb_transaction_commit(ldb); } - ldb_autotransaction_cancel(ldb); + ldb_transaction_cancel(ldb); if (ldb->err_string == NULL) { /* no error string was setup by the backend */ diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index d6276c4b86..24ec06ea32 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -865,6 +865,7 @@ static int ltdb_end_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_commit(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } @@ -883,6 +884,7 @@ static int ltdb_del_trans(struct ldb_module *module) ltdb->in_transaction--; if (ltdb_index_transaction_cancel(module) != 0) { + tdb_transaction_cancel(ltdb->tdb); return ltdb_err_map(tdb_error(ltdb->tdb)); } -- cgit From 1cd7fe71940b7420dd478321b8368a31ae713917 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 23 Feb 2009 17:35:49 -0500 Subject: Fix headers, ldb_includes.h is a private header, do not reference it from ldb.h --- source4/dsdb/samdb/ldb_modules/config.mk | 4 ++-- source4/dsdb/samdb/ldb_modules/linked_attributes.c | 1 + source4/dsdb/samdb/ldb_modules/objectclass.c | 1 + source4/dsdb/samdb/ldb_modules/ranged_results.c | 1 + source4/dsdb/samdb/ldb_modules/samba3sam.c | 2 +- source4/dsdb/samdb/ldb_modules/update_keytab.c | 1 + source4/dsdb/schema/schema_set.c | 1 + source4/lib/ldb/Makefile.in | 2 +- source4/lib/ldb/common/ldb_modules.c | 5 +---- source4/lib/ldb/include/ldb.h | 14 +++++++++++++- source4/lib/ldb/include/ldb_includes.h | 9 --------- source4/lib/ldb/include/ldb_private.h | 5 +---- source4/lib/ldb/ldb_ildap/ldb_ildap.c | 3 +-- source4/lib/ldb/ldb_ldap/ldb_ldap.c | 1 + source4/lib/ldb/ldb_map/ldb_map.c | 2 -- source4/lib/ldb/ldb_map/ldb_map.h | 2 ++ source4/lib/ldb/ldb_map/ldb_map_inbound.c | 2 -- source4/lib/ldb/ldb_map/ldb_map_outbound.c | 2 -- source4/lib/ldb/ldb_map/ldb_map_private.h | 1 + source4/lib/ldb/ldb_tdb/ldb_index.c | 1 + source4/lib/ldb/ldb_tdb/ldb_tdb.h | 8 +------- source4/lib/ldb/modules/operational.c | 5 +++++ source4/lib/ldb/modules/paged_results.c | 1 + source4/lib/ldb/modules/rdn_name.c | 1 + source4/lib/ldb/tools/cmdline.c | 1 + source4/lib/ldb/tools/ldbedit.c | 2 +- source4/lib/ldb/tools/ldbsearch.c | 1 + source4/lib/ldb/tools/ldbtest.c | 1 + 28 files changed, 42 insertions(+), 38 deletions(-) (limited to 'source4') diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index 01f5188b6f..583d1dcf04 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -89,7 +89,7 @@ ldb_samldb_OBJ_FILES = \ [MODULE::ldb_samba3sam] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(samba3sam) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SMBPASSWD \ +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB SMBPASSWD \ NSS_WRAPPER LIBSECURITY NDR_SECURITY # End MODULE ldb_samldb ################################################ @@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \ [MODULE::ldb_simple_ldap_map] SUBSYSTEM = LIBLDB INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid) -PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR +PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBLDB LIBNDR ENABLE = YES ALIASES = entryuuid nsuniqueid # End MODULE ldb_entryuuid diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 2365a58f78..4e28c8a149 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -30,6 +30,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" struct la_op_store { diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index 0261bb32e9..898d913965 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -35,6 +35,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/dsdb/samdb/ldb_modules/ranged_results.c b/source4/dsdb/samdb/ldb_modules/ranged_results.c index 8f36baa7d6..5ce69a26a2 100644 --- a/source4/dsdb/samdb/ldb_modules/ranged_results.c +++ b/source4/dsdb/samdb/ldb_modules/ranged_results.c @@ -29,6 +29,7 @@ * Author: Andrew Bartlett */ +#include "includes.h" #include "ldb_module.h" struct rr_context { diff --git a/source4/dsdb/samdb/ldb_modules/samba3sam.c b/source4/dsdb/samdb/ldb_modules/samba3sam.c index 3f10748085..59cb9de717 100644 --- a/source4/dsdb/samdb/ldb_modules/samba3sam.c +++ b/source4/dsdb/samdb/ldb_modules/samba3sam.c @@ -6,7 +6,7 @@ */ #include "includes.h" -#include "ldb/include/ldb_module.h" +#include "ldb_module.h" #include "ldb/ldb_map/ldb_map.h" #include "system/passwd.h" diff --git a/source4/dsdb/samdb/ldb_modules/update_keytab.c b/source4/dsdb/samdb/ldb_modules/update_keytab.c index 8920afee71..f1b6863cdb 100644 --- a/source4/dsdb/samdb/ldb_modules/update_keytab.c +++ b/source4/dsdb/samdb/ldb_modules/update_keytab.c @@ -29,6 +29,7 @@ #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_krb5.h" #include "system/kerberos.h" diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c index d6b3e40e1a..6abd8a8f88 100644 --- a/source4/dsdb/schema/schema_set.c +++ b/source4/dsdb/schema/schema_set.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "dlinklist.h" #include "dsdb/samdb/samdb.h" #include "lib/ldb/include/ldb_module.h" #include "param/param.h" diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in index 7f00e8ebee..663dea9f80 100644 --- a/source4/lib/ldb/Makefile.in +++ b/source4/lib/ldb/Makefile.in @@ -67,7 +67,7 @@ MDLD_FLAGS = @MDLD_FLAGS@ OBJS = $(MODULES_OBJ) $(COMMON_OBJ) $(LDB_TDB_OBJ) $(TDB_OBJ) $(TEVENT_OBJ) $(TALLOC_OBJ) $(POPT_OBJ) $(LDB_MAP_OBJ) @LIBREPLACEOBJ@ $(EXTRA_OBJ) -headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_includes.h $(srcdir)/include/ldb_module.h +headers = $(srcdir)/include/ldb.h $(srcdir)/include/ldb_errors.h $(srcdir)/include/ldb_handlers.h $(srcdir)/include/ldb_module.h BINS = bin/ldbadd bin/ldbsearch bin/ldbdel bin/ldbmodify bin/ldbedit bin/ldbrename bin/ldbtest diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 99a47767e1..ae97ef4cce 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -32,10 +32,7 @@ */ #include "ldb_private.h" - -#if (_SAMBA_BUILD_ >= 4) -#include "includes.h" -#endif +#include "dlinklist.h" #define LDB_MODULE_PREFIX "modules:" #define LDB_MODULE_PREFIX_LEN 8 diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 6990397a74..eb8e0ed11e 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -46,7 +46,19 @@ #define _LDB_H_ 1 /*! \endcond */ -#include "ldb_includes.h" +#ifndef bool +typedef int bool; +#endif +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif + +#include "talloc.h" +#include "tevent.h" +#include "ldb_errors.h" /* major restrictions as compared to normal LDAP: diff --git a/source4/lib/ldb/include/ldb_includes.h b/source4/lib/ldb/include/ldb_includes.h index a2927139c8..602bbec32c 100644 --- a/source4/lib/ldb/include/ldb_includes.h +++ b/source4/lib/ldb/include/ldb_includes.h @@ -4,11 +4,6 @@ a temporary includes file until I work on the ldb build system */ -#if (_SAMBA_BUILD_ >= 4) -/* tell ldb we have the internal ldap code */ -#define HAVE_ILDAP 1 -#endif - #if (_SAMBA_BUILD_ <= 3) /* allow forbidden string functions - should be replaced with _m functions */ #undef strcasecmp @@ -19,9 +14,5 @@ #include "replace.h" #include "system/filesys.h" #include "system/time.h" -#include -#include -#include "ldb_errors.h" -#include "dlinklist.h" #endif /*_LDB_PRIVATE_INCLUDES_H_*/ diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index 1ce9e9ecfd..2e8da9941c 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -37,6 +37,7 @@ #ifndef _LDB_PRIVATE_H_ #define _LDB_PRIVATE_H_ 1 +#include "ldb_includes.h" #include "ldb.h" #include "ldb_module.h" @@ -109,10 +110,6 @@ struct ldb_context { struct tevent_context *ev_ctx; }; -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) -#endif - /* The following definitions come from lib/ldb/common/ldb.c */ int ldb_connect_backend(struct ldb_context *ldb, const char *url, const char *options[], diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index b134405048..4447d0e09a 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -40,11 +40,10 @@ * author: Simo Sorce */ - #include "includes.h" #include "ldb_module.h" +#include "dlinklist.h" -#include "tevent.h" #include "libcli/ldap/ldap.h" #include "libcli/ldap/ldap_client.h" #include "auth/auth.h" diff --git a/source4/lib/ldb/ldb_ldap/ldb_ldap.c b/source4/lib/ldb/ldb_ldap/ldb_ldap.c index e1fcdb1353..43a01f75a7 100644 --- a/source4/lib/ldb/ldb_ldap/ldb_ldap.c +++ b/source4/lib/ldb/ldb_ldap/ldb_ldap.c @@ -38,6 +38,7 @@ * author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" #define LDAP_DEPRECATED 1 diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index ea2bfd1dc1..959540374c 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -35,8 +35,6 @@ * Author: Jelmer Vernooij, Martin Kuehl */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map.h b/source4/lib/ldb/ldb_map/ldb_map.h index 872208174e..3c1fe80895 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.h +++ b/source4/lib/ldb/ldb_map/ldb_map.h @@ -26,6 +26,8 @@ #ifndef __LDB_MAP_H__ #define __LDB_MAP_H__ +#include "ldb_module.h" + /* ldb_map is a skeleton LDB module that can be used for any other modules * that need to map attributes. * diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index e915a5f46a..822dea654e 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -24,8 +24,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index 327fa92f8d..eb7b4590ba 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -25,8 +25,6 @@ */ -#include "ldb_module.h" - #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_private.h b/source4/lib/ldb/ldb_map/ldb_map_private.h index 0c46443253..612d215ae9 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_private.h +++ b/source4/lib/ldb/ldb_map/ldb_map_private.h @@ -1,3 +1,4 @@ +#include "ldb_includes.h" /* A handy macro to report Out of Memory conditions */ #define map_oom(module) ldb_set_errstring(ldb_module_get_ctx(module), talloc_asprintf(module, "Out of Memory")); diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index cdbef3944b..ad27c9a9a9 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -32,6 +32,7 @@ */ #include "ldb_tdb.h" +#include "dlinklist.h" /* the idxptr code is a bit unusual. The way it works is to replace diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 7ebf199f6f..0a06cdb1b0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -1,11 +1,5 @@ -#if (_SAMBA_BUILD_ == 3) -#include "tdb/include/tdb.h" -#else -#include "replace.h" -#include "system/wait.h" +#include "ldb_includes.h" #include "tdb.h" -#endif - #include "ldb_module.h" /* this private structure is used by the ltdb backend in the diff --git a/source4/lib/ldb/modules/operational.c b/source4/lib/ldb/modules/operational.c index d862638389..43b223b52e 100644 --- a/source4/lib/ldb/modules/operational.c +++ b/source4/lib/ldb/modules/operational.c @@ -73,8 +73,13 @@ modifiersName: not supported by w2k3? */ +#include "ldb_includes.h" #include "ldb_module.h" +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) +#endif + /* construct a canonical name from a message */ diff --git a/source4/lib/ldb/modules/paged_results.c b/source4/lib/ldb/modules/paged_results.c index 7d7cdf66a0..2a06c5e6c5 100644 --- a/source4/lib/ldb/modules/paged_results.c +++ b/source4/lib/ldb/modules/paged_results.c @@ -32,6 +32,7 @@ * Author: Simo Sorce */ +#include "ldb_includes.h" #include "ldb_module.h" struct message_store { diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index a5ffcc034a..880678d89d 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -36,6 +36,7 @@ * Simo Sorce Mar 2006 */ +#include "ldb_includes.h" #include "ldb_module.h" struct rename_context { diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index 3dce9b187b..2701de5a48 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -21,6 +21,7 @@ License along with this library; if not, see . */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbedit.c b/source4/lib/ldb/tools/ldbedit.c index 3a915f8bea..9d3bd27983 100644 --- a/source4/lib/ldb/tools/ldbedit.c +++ b/source4/lib/ldb/tools/ldbedit.c @@ -30,7 +30,7 @@ * * Author: Andrew Tridgell */ - +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbsearch.c b/source4/lib/ldb/tools/ldbsearch.c index 35d4ac7002..ba0a2a8927 100644 --- a/source4/lib/ldb/tools/ldbsearch.c +++ b/source4/lib/ldb/tools/ldbsearch.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" diff --git a/source4/lib/ldb/tools/ldbtest.c b/source4/lib/ldb/tools/ldbtest.c index edaa9fb85c..6af0ee9336 100644 --- a/source4/lib/ldb/tools/ldbtest.c +++ b/source4/lib/ldb/tools/ldbtest.c @@ -31,6 +31,7 @@ * Author: Andrew Tridgell */ +#include "ldb_includes.h" #include "ldb.h" #include "tools/cmdline.h" -- cgit From 0016b9cee8d9e640e0b4604a81a900708a944c0d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 10:48:11 +1100 Subject: added a missing linefeed --- source4/utils/net/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index ba5296fd97..d934403ade 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -107,7 +107,7 @@ static const struct net_functable net_functable[] = { {"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage}, {"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage}, {"user", "manage user accounts\n", net_user, net_user_usage}, - {"machinepw", "Get a machine password out of our SAM", net_machinepw, + {"machinepw", "Get a machine password out of our SAM\n", net_machinepw, net_machinepw_usage}, {NULL, NULL, NULL, NULL} }; -- cgit From 10c047c6f4c0f6b9fdebbdf133a3bd72aa8776de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 00:58:29 +0100 Subject: Fix finding of setup data. --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a5b3e8322f..aca852c762 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -50,7 +50,7 @@ def find_setup_dir(): """Find the setup directory used by provision.""" dirname = os.path.dirname(__file__) if "/site-packages/" in dirname: - prefix = dirname[:dirname.index("/site-packages/")] + prefix = "/".join(dirname[:dirname.index("/site-packages/")].split("/")[:-2]) for suffix in ["share/setup", "share/samba/setup", "setup"]: ret = os.path.join(prefix, suffix) if os.path.isdir(ret): -- cgit From dcb2e7d57718ebd3db75999819ec8ef507f9dd7b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 01:00:09 +0100 Subject: expand tabs in python file, consistent with the rest of the file. --- source4/scripting/python/samba/provision.py | 78 ++++++++++++++--------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index aca852c762..5bcb23a5d4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -93,9 +93,9 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - self.olmmron = None - self.olmmrserveridsconf = None - self.olmmrsyncreplconf = None + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None class ProvisionNames(object): @@ -1178,7 +1178,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None): + ol_mmr_urls=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1300,50 +1300,50 @@ def provision_backend(setup_dir=None, message=None, { "LINK_ATTRS" : refint_attributes}) # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts - mmr_on_config = "" - mmr_replicator_acl = "" - mmr_serverids_config = "" + mmr_on_config = "" + mmr_replicator_acl = "" + mmr_serverids_config = "" mmr_syncrepl_schema_config = "" - mmr_syncrepl_config_config = "" - mmr_syncrepl_user_config = "" - - if ol_mmr_urls is not None: + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + + if ol_mmr_urls is not None: # For now, make these equal mmr_pass = adminpass - url_list=filter(None,ol_mmr_urls.split(' ')) + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) - mmr_on_config = "MirrorMode On" - mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" - serverid=0 - for url in url_list: - serverid=serverid+1 - mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(serverid), - "LDAPSERVER" : url }) + mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" + serverid=0 + for url in url_list: + serverid=serverid+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) rid=serverid*10 - rid=rid+1 - mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.schemadn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.schemadn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.configdn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.configdn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.domaindn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.domaindn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass }) @@ -1361,7 +1361,7 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) @@ -1380,9 +1380,9 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - - if ol_mmr_urls is not None: - setup_file(setup_path("cn=replicator.ldif"), + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), -- cgit From b9cf189404d5ef6b0a2440dc5f9670f0f6d0c131 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 24 Feb 2009 01:02:26 +0100 Subject: expand tabs in python file, consistent with the rest of the file. --- source4/scripting/python/samba/__init__.py | 2 +- source4/scripting/python/samba/samdb.py | 10 +++++----- source4/scripting/python/samba/tests/__init__.py | 4 ++-- source4/scripting/python/samba/tests/provision.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4') diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index e9fc26af20..a49e6e1ead 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -223,7 +223,7 @@ def check_all_substituted(text): :param text: The text to search for substitution variables """ if not "${" in text: - return + return var_start = text.find("${") var_end = text.find("}", var_start) diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 9cc55e5629..614970d3ec 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -201,11 +201,11 @@ userAccountControl: %u glue.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. - """ - glue.dsdb_set_ntds_invocation_id(self, invocation_id) + """Set the invocation id for this SamDB handle. + + :param invocation_id: GUID of the invocation id. + """ + glue.dsdb_set_ntds_invocation_id(self, invocation_id) def setexpiry(self, user, expiry_seconds, noexpiry): """Set the password expiry for a user diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index d827bfa004..b342b93c49 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -70,8 +70,8 @@ class SubstituteVarTestCase(unittest.TestCase): 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}") + samba.check_all_substituted("nothing to see here") + self.assertRaises(Exception, samba.check_all_substituted, "Not subsituted: ${FOOBAR}") class LdbExtensionTests(TestCaseInTempDir): diff --git a/source4/scripting/python/samba/tests/provision.py b/source4/scripting/python/samba/tests/provision.py index 352357f694..fdac9d4ea2 100644 --- a/source4/scripting/python/samba/tests/provision.py +++ b/source4/scripting/python/samba/tests/provision.py @@ -56,7 +56,7 @@ class ProvisionTestCase(samba.tests.TestCaseInTempDir): machinepass="machinepass", dnsdomain="example.com") self.assertEquals(1, len(secrets_ldb.search("samAccountName=krbtgt,flatname=EXAMPLE,CN=Principals"))) - self.assertEquals("keytab.path", + self.assertEquals("keytab.path", secrets_ldb.searchone(basedn="flatname=EXAMPLE,CN=primary domains", expression="(privateKeytab=*)", attribute="privateKeytab")) -- cgit From b9860043dc092df25d4a39074e106d7367ebbe8f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Feb 2009 11:39:44 +1100 Subject: fixed the event context for net vampire --- source4/utils/net/net_join.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/utils/net/net_join.c b/source4/utils/net/net_join.c index ad63340089..b0a25bb7c0 100644 --- a/source4/utils/net/net_join.c +++ b/source4/utils/net/net_join.c @@ -126,7 +126,7 @@ int net_vampire(struct net_context *ctx, int argc, const char **argv) domain_name = tmp; - libnetctx = libnet_context_init(NULL, ctx->lp_ctx); + libnetctx = libnet_context_init(ctx->event_ctx, ctx->lp_ctx); if (!libnetctx) { return -1; } -- cgit From 31f2cddcf5886b0a78290fdfa609a2ee63bda5ad Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Tue, 24 Feb 2009 11:37:58 +1100 Subject: Added mmr and olc to the OpenLDAP backend provisioning-scripts These extensions add mmr (multi-master-replication) and olc (openldap-online-configuration) capabilities to the provisioning-scripts (provision-backend and provision.py), for use with the openldap-backend (only versions >=2.4.15!). Changes / additions made to the provision-backend -script: added new command-line-options: --ol-mmr-urls= for use with mmr (can be combined with --ol-olc=yes), --ol-olc=[yes/no] (activate automatic conversion from static slapd.conf to olc), --ol-slaptest= (needed in conjunction with --ol-olc=yes) Changes / additions made to the provision.py -script: added extensions, that will automatically generate the chosen mmr and/or olc setup for the openldap backend, according to the to chosen parameters set in the provision-backend script Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 187 ++++++++++++++++++++++------ source4/setup/DB_CONFIG | 11 -- source4/setup/mmr_serverids.conf | 1 - source4/setup/olcOverlay={0}syncprov.ldif | 11 ++ source4/setup/olc_acl.conf | 4 + source4/setup/olc_mmr.conf | 3 + source4/setup/olc_pass.conf | 3 + source4/setup/olc_seed.ldif | 16 +++ source4/setup/olc_serverid.conf | 1 + source4/setup/olc_syncrepl.conf | 13 ++ source4/setup/olc_syncrepl_seed.conf | 5 + source4/setup/provision-backend | 12 +- source4/setup/slapd.conf | 20 +-- 13 files changed, 224 insertions(+), 63 deletions(-) create mode 100644 source4/setup/olcOverlay={0}syncprov.ldif create mode 100644 source4/setup/olc_acl.conf create mode 100644 source4/setup/olc_mmr.conf create mode 100644 source4/setup/olc_pass.conf create mode 100644 source4/setup/olc_seed.ldif create mode 100644 source4/setup/olc_serverid.conf create mode 100644 source4/setup/olc_syncrepl.conf create mode 100644 source4/setup/olc_syncrepl_seed.conf (limited to 'source4') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a5b3e8322f..8442c24d71 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -26,6 +26,7 @@ from base64 import b64encode import os +import sys import pwd import grp import time @@ -93,9 +94,14 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - self.olmmron = None - self.olmmrserveridsconf = None - self.olmmrsyncreplconf = None + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None + self.olcdir = None + self.olslaptest = None + self.olcseedldif = None + self.olcsyncprovdir = None + self.olcsyncprovfile = None class ProvisionNames(object): @@ -268,6 +274,14 @@ def provision_paths_from_lp(lp, dnsdomain): "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, "mmr_syncrepl.conf") + paths.olcdir = os.path.join(paths.ldapdir, + "slapd.d") + paths.olcseedldif = os.path.join(paths.ldapdir, + "olc_seed.ldif") + paths.olcsyncprovdir = os.path.join(paths.olcdir, + "cn=config/olcDatabase={0}config") + paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, + "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1178,7 +1192,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None): + ol_mmr_urls=None,ol_olc=None,ol_slaptest=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1205,6 +1219,19 @@ def provision_backend(setup_dir=None, message=None, make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + # openldap-online-configuration: validation of olc and slaptest + if ol_olc == "yes" and ol_slaptest is None: + sys.exit("Warning: OpenLDAP-Online-Configuration cant be setup without path to slaptest-Binary!") + + if ol_olc == "yes" and ol_slaptest is not None: + ol_slaptest = ol_slaptest + "/slaptest" + if not os.path.exists(ol_slaptest): + message (ol_slaptest) + sys.exit("Warning: Given Path to slaptest-Binary does not exist!") + ### + + + lp = param.LoadParm() lp.load(smbconf) @@ -1300,52 +1327,95 @@ def provision_backend(setup_dir=None, message=None, { "LINK_ATTRS" : refint_attributes}) # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts - mmr_on_config = "" - mmr_replicator_acl = "" - mmr_serverids_config = "" + mmr_on_config = "" + mmr_replicator_acl = "" + mmr_serverids_config = "" mmr_syncrepl_schema_config = "" - mmr_syncrepl_config_config = "" - mmr_syncrepl_user_config = "" - - if ol_mmr_urls is not None: + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + + + if ol_mmr_urls is not None: # For now, make these equal mmr_pass = adminpass - url_list=filter(None,ol_mmr_urls.split(' ')) + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) - mmr_on_config = "MirrorMode On" - mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" - serverid=0 - for url in url_list: - serverid=serverid+1 - mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(serverid), - "LDAPSERVER" : url }) + mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" + serverid=0 + for url in url_list: + serverid=serverid+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) rid=serverid*10 - rid=rid+1 - mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.schemadn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.schemadn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.configdn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.configdn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass}) - rid=rid+1 - mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(rid), - "MMRDN": names.domaindn, - "LDAPSERVER" : url, + rid=rid+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(rid), + "MMRDN": names.domaindn, + "LDAPSERVER" : url, "MMR_PASSWORD": mmr_pass }) + # olc = yes? + olc_config_pass = "" + olc_config_acl = "" + olc_syncrepl_config = "" + olc_mmr_config = "" + if ol_olc == "yes": + olc_config_pass += read_and_sub_file(setup_path("olc_pass.conf"), + { "OLC_PW": adminpass }) + olc_config_acl += read_and_sub_file(setup_path("olc_acl.conf"),{}) + + # if olc = yes + mmr = yes, generate cn=config-replication directives + # and olc_seed.lif for the other mmr-servers + if ol_olc == "yes" and ol_mmr_urls is not None: + serverid=0 + olc_serverids_config = "" + olc_syncrepl_config = "" + olc_syncrepl_seed_config = "" + olc_mmr_config = "" + olc_mmr_config += read_and_sub_file(setup_path("olc_mmr.conf"),{}) + rid=1000 + for url in url_list: + serverid=serverid+1 + olc_serverids_config += read_and_sub_file(setup_path("olc_serverid.conf"), + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) + + rid=rid+1 + olc_syncrepl_config += read_and_sub_file(setup_path("olc_syncrepl.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url, + "MMR_PASSWORD": adminpass}) + + olc_syncrepl_seed_config += read_and_sub_file(setup_path("olc_syncrepl_seed.conf"), + { "RID" : str(rid), + "LDAPSERVER" : url}) + + setup_file(setup_path("olc_seed.ldif"), paths.olcseedldif, + {"OLC_SERVER_ID_CONF": olc_serverids_config, + "OLC_PW": adminpass, + "OLC_SYNCREPL_CONF": olc_syncrepl_seed_config}) + + # end olc setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1360,8 +1430,12 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, + "OLC_CONFIG_PASS": olc_config_pass, + "OLC_SYNCREPL_CONFIG": olc_syncrepl_config, + "OLC_CONFIG_ACL": olc_config_acl, + "OLC_MMR_CONFIG": olc_mmr_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) @@ -1380,16 +1454,15 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - - if ol_mmr_urls is not None: - setup_file(setup_path("cn=replicator.ldif"), + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) - mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" @@ -1399,7 +1472,18 @@ def provision_backend(setup_dir=None, message=None, else: server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + if ol_olc != "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + if ol_olc == "yes" and ol_mmr_urls is None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc != "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + + if ol_olc == "yes" and ol_mmr_urls is not None: + slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" + ldapuser = "--username=samba-admin" @@ -1437,6 +1521,27 @@ def provision_backend(setup_dir=None, message=None, message("Run provision with: " + " ".join(args)) + # if --ol-olc=yes, generate online-configuration in ../private/ldap/slapd.d + if ol_olc == "yes": + if not os.path.isdir(paths.olcdir): + os.makedirs(paths.olcdir, 0770) + paths.olslaptest = str(ol_slaptest) + olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" + os.system(olc_command) + #os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest + #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" + + # workaround, if overlay syncprov is was not created properly during conversion to cn=config. + # otherwise, cn=config won't be replicated + if ol_olc == "yes" and ol_mmr_urls is not None: + if not os.path.exists(paths.olcsyncprovdir): + os.makedirs(paths.olcsyncprovdir, 0770) + setup_file(setup_path("olcOverlay={0}syncprov.ldif"), + os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) + + + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/DB_CONFIG b/source4/setup/DB_CONFIG index b4d2bfa868..74bb09d800 100644 --- a/source4/setup/DB_CONFIG +++ b/source4/setup/DB_CONFIG @@ -1,17 +1,6 @@ -# -# Set the database in memory cache size. -# set_cachesize 0 524288 0 - -# -# Set log values. -# set_lg_regionmax 104857 set_lg_max 1048576 set_lg_bsize 209715 set_lg_dir ${LDAPDBDIR}/bdb-logs - -# -# Set temporary file creation directory. -# set_tmp_dir ${LDAPDBDIR}/tmp diff --git a/source4/setup/mmr_serverids.conf b/source4/setup/mmr_serverids.conf index c6d14010b4..e4daf2028a 100644 --- a/source4/setup/mmr_serverids.conf +++ b/source4/setup/mmr_serverids.conf @@ -1,2 +1 @@ -# Generated from template mmr_serverids.conf ServerID ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif new file mode 100644 index 0000000000..4f5b513c67 --- /dev/null +++ b/source4/setup/olcOverlay={0}syncprov.ldif @@ -0,0 +1,11 @@ +dn: olcOverlay={0}syncprov +objectClass: olcOverlayConfig +objectClass: olcSyncProvConfig +olcOverlay: {0}syncprov +structuralObjectClass: olcSyncProvConfig +entryUUID: 41df5aca-785a-102d-9077-999999999999 +creatorsName: cn=config +createTimestamp: 20090116201111Z +entryCSN: 20090116201111.111111Z#000000#000#000000 +modifiersName: cn=config +modifyTimestamp: 20090116201111Z diff --git a/source4/setup/olc_acl.conf b/source4/setup/olc_acl.conf new file mode 100644 index 0000000000..c248b30fb5 --- /dev/null +++ b/source4/setup/olc_acl.conf @@ -0,0 +1,4 @@ +access to dn.sub="cn=config" + by dn="cn=samba-admin,cn=samba" write + by dn="cn=replicator,cn=samba" read + diff --git a/source4/setup/olc_mmr.conf b/source4/setup/olc_mmr.conf new file mode 100644 index 0000000000..2f60df1421 --- /dev/null +++ b/source4/setup/olc_mmr.conf @@ -0,0 +1,3 @@ +overlay syncprov +MirrorMode on + diff --git a/source4/setup/olc_pass.conf b/source4/setup/olc_pass.conf new file mode 100644 index 0000000000..4c66c1c43f --- /dev/null +++ b/source4/setup/olc_pass.conf @@ -0,0 +1,3 @@ +database config +rootdn cn=config + diff --git a/source4/setup/olc_seed.ldif b/source4/setup/olc_seed.ldif new file mode 100644 index 0000000000..afc3abe5a0 --- /dev/null +++ b/source4/setup/olc_seed.ldif @@ -0,0 +1,16 @@ +dn: cn=config +objectClass: olcGlobal +cn: config +${OLC_SERVER_ID_CONF} + +dn: olcDatabase={0}config,cn=config +objectClass: olcDatabaseConfig +olcDatabase: {0}config +olcRootDN: cn=config +olcRootPW: ${OLC_PW} +${OLC_SYNCREPL_CONF}olcMirrorMode: TRUE + +dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config +objectClass: olcSyncProvConfig +olcOverlay: syncprov + diff --git a/source4/setup/olc_serverid.conf b/source4/setup/olc_serverid.conf new file mode 100644 index 0000000000..3d28acbfb4 --- /dev/null +++ b/source4/setup/olc_serverid.conf @@ -0,0 +1 @@ +olcServerID: ${SERVERID} "${LDAPSERVER}" diff --git a/source4/setup/olc_syncrepl.conf b/source4/setup/olc_syncrepl.conf new file mode 100644 index 0000000000..fd7a58d03b --- /dev/null +++ b/source4/setup/olc_syncrepl.conf @@ -0,0 +1,13 @@ +# Generated from template olc_syncrepl.conf + +syncrepl rid=${RID} + provider="${LDAPSERVER}" + searchbase="cn=config" + filter="(!(olcDatabase={0}config))" + type=refreshAndPersist + retry="10 +" + bindmethod=sasl + saslmech=DIGEST-MD5 + authcid="replicator" + credentials="${MMR_PASSWORD}" + diff --git a/source4/setup/olc_syncrepl_seed.conf b/source4/setup/olc_syncrepl_seed.conf new file mode 100644 index 0000000000..1833fb9228 --- /dev/null +++ b/source4/setup/olc_syncrepl_seed.conf @@ -0,0 +1,5 @@ +olcSyncRepl: rid=${RID} provider="${LDAPSERVER}" + binddn="cn=config" bindmethod=sasl saslmech=DIGEST-MD5 + authcid="replicator" credentials="linux" + searchbase="cn=config" filter="(!(olcDatabase={0}config))" + type=refreshAndPersist retry="10 +" diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index eca209cb18..20e4420414 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -65,8 +65,12 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR") - + help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") +parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + choices=["yes", "no"]) +parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", + help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") opts = parser.parse_args()[0] @@ -103,5 +107,7 @@ provision_backend(setup_dir=setup_dir, message=message, smbconf=smbconf, targetd root=opts.root, serverrole=server_role, ldap_backend_type=opts.ldap_backend_type, ldap_backend_port=opts.ldap_backend_port, - ol_mmr_urls=opts.ol_mmr_urls) + ol_mmr_urls=opts.ol_mmr_urls, + ol_olc=opts.ol_olc, + ol_slaptest=opts.ol_slaptest) diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf index 506dc504b4..09dffbbfa3 100644 --- a/source4/setup/slapd.conf +++ b/source4/setup/slapd.conf @@ -7,7 +7,6 @@ sizelimit unlimited ${MMR_SERVERIDS_CONFIG} - include ${LDAPDIR}/backend-schema.schema pidfile ${LDAPDIR}/slapd.pid @@ -62,6 +61,13 @@ suffix cn=Samba directory ${LDAPDIR}/db/samba rootdn cn=Manager,cn=Samba +######################################## +## olc - configuration ### +${OLC_CONFIG_PASS} +${OLC_SYNCREPL_CONFIG} +${OLC_MMR_CONFIG} +${OLC_CONFIG_ACL} + ######################################## ### cn=schema ### database hdb @@ -78,10 +84,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=schema Subcontext ### @@ -107,10 +113,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=config Subcontext ### ${MMR_SYNCREPL_CONFIG_CONFIG} @@ -139,10 +145,10 @@ index cn eq index entryUUID,entryCSN eq #syncprov is stable in OpenLDAP 2.3, and available in 2.2. -#We only need this for the contextCSN attribute anyway.... +#We need this for the contextCSN attribute and mmr. overlay syncprov syncprov-sessionlog 100 -# syncprov-checkpoint 100 10 +syncprov-checkpoint 100 10 ### Multimaster-Replication of cn=user/base-dn context ### ${MMR_SYNCREPL_USER_CONFIG} -- cgit From 12184d413205d2ad7cbb9e1aaf2db97c7bcb4fc2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 11:40:18 +0100 Subject: s4:libcli: split out LIBCLI_LDAP_MESSAGE subsystem metze --- source4/headermap.txt | 1 + source4/libcli/ldap/config.mk | 21 +- source4/libcli/ldap/ldap.c | 1411 ---------------------------------- source4/libcli/ldap/ldap.h | 191 +---- source4/libcli/ldap/ldap_message.c | 1468 ++++++++++++++++++++++++++++++++++++ source4/libcli/ldap/ldap_message.h | 225 ++++++ source4/libcli/ldap/ldap_msg.c | 87 --- 7 files changed, 1709 insertions(+), 1695 deletions(-) delete mode 100644 source4/libcli/ldap/ldap.c create mode 100644 source4/libcli/ldap/ldap_message.c create mode 100644 source4/libcli/ldap/ldap_message.h delete mode 100644 source4/libcli/ldap/ldap_msg.c (limited to 'source4') diff --git a/source4/headermap.txt b/source4/headermap.txt index 8f3749a3b5..8a968315bf 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,6 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h +libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index 2708c66b68..a0e178ac40 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,14 +1,20 @@ +[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] +PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB +PRIVATE_DEPENDENCIES = ASN1_UTIL + +LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ + ldap_message.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h + [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET -PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS ASN1_UTIL \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec +PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ + LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap.o ldap_client.o ldap_bind.o \ - ldap_msg.o ldap_ildap.o ldap_controls.o) - - -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(libclisrcdir)/ldap/ldap_ndr.h + ldap_client.o ldap_bind.o \ + ldap_ildap.o ldap_controls.o) +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) @@ -16,3 +22,4 @@ $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_L PRIVATE_DEPENDENCIES = LIBLDB LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o +PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c deleted file mode 100644 index 7a65cc5c27..0000000000 --- a/source4/libcli/ldap/ldap.c +++ /dev/null @@ -1,1411 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - 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 . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index 3d99d6f47d..a642e671e6 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,200 +21,11 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" +#include "libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - struct tevent_context; struct cli_credentials; struct dom_sid; -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); #endif diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c new file mode 100644 index 0000000000..07362fa685 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.c @@ -0,0 +1,1468 @@ +/* + Unix SMB/CIFS mplementation. + LDAP protocol helper functions for SAMBA + + Copyright (C) Andrew Tridgell 2004 + Copyright (C) Volker Lendecke 2004 + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Simo Sorce 2004 + + 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 . + +*/ + +#include "includes.h" +#include "../lib/util/asn1.h" +#include "libcli/ldap/ldap.h" +#include "libcli/ldap/ldap_proto.h" + +_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct ldap_message); +} + + +static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, + struct ldb_message_element *attrib) +{ + attrib->values = talloc_realloc(mem_ctx, + attrib->values, + DATA_BLOB, + attrib->num_values+1); + if (attrib->values == NULL) + return false; + + attrib->values[attrib->num_values].data = talloc_steal(attrib->values, + value->data); + attrib->values[attrib->num_values].length = value->length; + attrib->num_values += 1; + return true; +} + +static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, + const struct ldb_message_element *attrib, + struct ldb_message_element **attribs, + int *num_attribs) +{ + *attribs = talloc_realloc(mem_ctx, + *attribs, + struct ldb_message_element, + *num_attribs+1); + + if (*attribs == NULL) + return false; + + (*attribs)[*num_attribs] = *attrib; + talloc_steal(*attribs, attrib->values); + talloc_steal(*attribs, attrib->name); + *num_attribs += 1; + return true; +} + +static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, + struct ldap_mod *mod, + struct ldap_mod **mods, + int *num_mods) +{ + *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); + + if (*mods == NULL) + return false; + + (*mods)[*num_mods] = *mod; + *num_mods += 1; + return true; +} + +static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) +{ + int i; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); + for (i=0; iu.list.num_elements; i++) { + if (!ldap_push_filter(data, tree->u.list.elements[i])) { + return false; + } + } + asn1_pop_tag(data); + break; + + case LDB_OP_NOT: + asn1_push_tag(data, ASN1_CONTEXT(2)); + if (!ldap_push_filter(data, tree->u.isnot.child)) { + return false; + } + asn1_pop_tag(data); + break; + + case LDB_OP_EQUALITY: + /* equality test */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, tree->u.equality.attr, + strlen(tree->u.equality.attr)); + asn1_write_OctetString(data, tree->u.equality.value.data, + tree->u.equality.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_SUBSTRING: + /* + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + */ + asn1_push_tag(data, ASN1_CONTEXT(4)); + asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + i = 0; + if ( ! tree->u.substring.start_with_wildcard) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + while (tree->u.substring.chunks[i]) { + int ctx; + + if (( ! tree->u.substring.chunks[i + 1]) && + (tree->u.substring.end_with_wildcard == 0)) { + ctx = 2; + } else { + ctx = 1; + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); + asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); + asn1_pop_tag(data); + i++; + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + case LDB_OP_GREATER: + /* greaterOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(5)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_LESS: + /* lessOrEqual test */ + asn1_push_tag(data, ASN1_CONTEXT(6)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_PRESENT: + /* present test */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); + asn1_write_LDAPString(data, tree->u.present.attr); + asn1_pop_tag(data); + return !data->has_error; + + case LDB_OP_APPROX: + /* approx test */ + asn1_push_tag(data, ASN1_CONTEXT(8)); + asn1_write_OctetString(data, tree->u.comparison.attr, + strlen(tree->u.comparison.attr)); + asn1_write_OctetString(data, tree->u.comparison.value.data, + tree->u.comparison.value.length); + asn1_pop_tag(data); + break; + + case LDB_OP_EXTENDED: + /* + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE + } + */ + asn1_push_tag(data, ASN1_CONTEXT(9)); + if (tree->u.extended.rule_id) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write_LDAPString(data, tree->u.extended.rule_id); + asn1_pop_tag(data); + } + if (tree->u.extended.attr) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_write_LDAPString(data, tree->u.extended.attr); + asn1_pop_tag(data); + } + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); + asn1_pop_tag(data); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_write_uint8(data, tree->u.extended.dnAttributes); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + + default: + return false; + } + return !data->has_error; +} + +static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) +{ + asn1_write_enumerated(data, result->resultcode); + asn1_write_OctetString(data, result->dn, + (result->dn) ? strlen(result->dn) : 0); + asn1_write_OctetString(data, result->errormessage, + (result->errormessage) ? + strlen(result->errormessage) : 0); + if (result->referral) { + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, result->referral, + strlen(result->referral)); + asn1_pop_tag(data); + } +} + +_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) +{ + struct asn1_data *data = asn1_init(mem_ctx); + int i, j; + + if (!data) return false; + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_Integer(data, msg->messageid); + + switch (msg->type) { + case LDAP_TAG_BindRequest: { + struct ldap_BindRequest *r = &msg->r.BindRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_Integer(data, r->version); + asn1_write_OctetString(data, r->dn, + (r->dn != NULL) ? strlen(r->dn) : 0); + + switch (r->mechanism) { + case LDAP_AUTH_MECH_SIMPLE: + /* context, primitive */ + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->creds.password, + strlen(r->creds.password)); + asn1_pop_tag(data); + break; + case LDAP_AUTH_MECH_SASL: + /* context, constructed */ + asn1_push_tag(data, ASN1_CONTEXT(3)); + asn1_write_OctetString(data, r->creds.SASL.mechanism, + strlen(r->creds.SASL.mechanism)); + if (r->creds.SASL.secblob) { + asn1_write_OctetString(data, r->creds.SASL.secblob->data, + r->creds.SASL.secblob->length); + } + asn1_pop_tag(data); + break; + default: + return false; + } + + asn1_pop_tag(data); + break; + } + case LDAP_TAG_BindResponse: { + struct ldap_BindResponse *r = &msg->r.BindResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->SASL.secblob) { + asn1_write_ContextSimple(data, 7, r->SASL.secblob); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_UnbindRequest: { +/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ + break; + } + case LDAP_TAG_SearchRequest: { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); + asn1_write_enumerated(data, r->scope); + asn1_write_enumerated(data, r->deref); + asn1_write_Integer(data, r->sizelimit); + asn1_write_Integer(data, r->timelimit); + asn1_write_BOOLEAN(data, r->attributesonly); + + if (!ldap_push_filter(data, r->tree)) { + return false; + } + + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + asn1_write_OctetString(data, r->attributes[i], + strlen(r->attributes[i])); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultEntry: { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attr = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attr->name, + strlen(attr->name)); + asn1_push_tag(data, ASN1_SEQUENCE(1)); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attr->values[j].data, + attr->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultDone: { + struct ldap_Result *r = &msg->r.SearchResultDone; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyRequest: { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_mods; i++) { + struct ldb_message_element *attrib = &r->mods[i].attrib; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_enumerated(data, r->mods[i].type); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jnum_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + + } + asn1_pop_tag(data); + asn1_pop_tag(data); + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyResponse: { + struct ldap_Result *r = &msg->r.ModifyResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddRequest: { + struct ldap_AddRequest *r = &msg->r.AddRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + + for (i=0; inum_attributes; i++) { + struct ldb_message_element *attrib = &r->attributes[i]; + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, attrib->name, + strlen(attrib->name)); + asn1_push_tag(data, ASN1_SET); + for (j=0; jattributes[i].num_values; j++) { + asn1_write_OctetString(data, + attrib->values[j].data, + attrib->values[j].length); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AddResponse: { + struct ldap_Result *r = &msg->r.AddResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelRequest: { + struct ldap_DelRequest *r = &msg->r.DelRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write(data, r->dn, strlen(r->dn)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_DelResponse: { + struct ldap_Result *r = &msg->r.DelResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNRequest: { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); + asn1_write_BOOLEAN(data, r->deleteolddn); + if (r->newsuperior) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->newsuperior, + strlen(r->newsuperior)); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ModifyDNResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareRequest: { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->dn, strlen(r->dn)); + asn1_push_tag(data, ASN1_SEQUENCE(0)); + asn1_write_OctetString(data, r->attribute, + strlen(r->attribute)); + asn1_write_OctetString(data, r->value.data, + r->value.length); + asn1_pop_tag(data); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_CompareResponse: { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, r); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_AbandonRequest: { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); + asn1_write_implicit_Integer(data, r->messageid); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_SearchResultReference: { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_write_OctetString(data, r->referral, strlen(r->referral)); + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedRequest: { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + case LDAP_TAG_ExtendedResponse: { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + asn1_push_tag(data, ASN1_APPLICATION(msg->type)); + ldap_encode_response(data, &r->response); + if (r->oid) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); + asn1_write(data, r->oid, strlen(r->oid)); + asn1_pop_tag(data); + } + if (r->value) { + asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); + asn1_write(data, r->value->data, r->value->length); + asn1_pop_tag(data); + } + asn1_pop_tag(data); + break; + } + default: + return false; + } + + if (msg->controls != NULL) { + asn1_push_tag(data, ASN1_CONTEXT(0)); + + for (i = 0; msg->controls[i] != NULL; i++) { + if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { + return false; + } + } + + asn1_pop_tag(data); + } + + asn1_pop_tag(data); + + if (data->has_error) { + asn1_free(data); + return false; + } + + *result = data_blob_talloc(mem_ctx, data->data, data->length); + asn1_free(data); + return true; +} + +static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, + DATA_BLOB blob) +{ + char *result = talloc_array(mem_ctx, char, blob.length+1); + memcpy(result, blob.data, blob.length); + result[blob.length] = '\0'; + return result; +} + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result) +{ + DATA_BLOB string; + if (!asn1_read_OctetString(data, mem_ctx, &string)) + return false; + *result = blob2string_talloc(mem_ctx, string); + data_blob_free(&string); + return true; +} + +static void ldap_decode_response(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + struct ldap_Result *result) +{ + asn1_read_enumerated(data, &result->resultcode); + asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); + asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); + if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + asn1_start_tag(data, ASN1_CONTEXT(3)); + asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); + asn1_end_tag(data); + } else { + result->referral = NULL; + } +} + +static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) +{ + + chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); + if (chunks == NULL) { + return NULL; + } + + chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); + if (chunks[chunk_num] == NULL) { + return NULL; + } + + chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); + if (chunks[chunk_num]->data == NULL) { + return NULL; + } + chunks[chunk_num]->length = strlen(value); + + chunks[chunk_num + 1] = '\0'; + + return chunks; +} + + +/* + parse the ASN.1 formatted search string into a ldb_parse_tree +*/ +static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, + struct asn1_data *data) +{ + uint8_t filter_tag; + struct ldb_parse_tree *ret; + + if (!asn1_peek_uint8(data, &filter_tag)) { + return NULL; + } + + filter_tag &= 0x1f; /* strip off the asn1 stuff */ + + ret = talloc(mem_ctx, struct ldb_parse_tree); + if (ret == NULL) return NULL; + + switch(filter_tag) { + case 0: + case 1: + /* AND or OR of one or more filters */ + ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; + ret->u.list.num_elements = 0; + ret->u.list.elements = NULL; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + while (asn1_tag_remaining(data) > 0) { + struct ldb_parse_tree *subtree; + subtree = ldap_decode_filter_tree(ret, data); + if (subtree == NULL) { + goto failed; + } + ret->u.list.elements = + talloc_realloc(ret, ret->u.list.elements, + struct ldb_parse_tree *, + ret->u.list.num_elements+1); + if (ret->u.list.elements == NULL) { + goto failed; + } + talloc_steal(ret->u.list.elements, subtree); + ret->u.list.elements[ret->u.list.num_elements] = subtree; + ret->u.list.num_elements++; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 2: + /* 'not' operation */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + ret->operation = LDB_OP_NOT; + ret->u.isnot.child = ldap_decode_filter_tree(ret, data); + if (ret->u.isnot.child == NULL) { + goto failed; + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + + case 3: { + /* equalityMatch */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attrib); + ret->u.equality.value.data = talloc_steal(ret, value.data); + ret->u.equality.value.length = value.length; + break; + } + case 4: { + /* substrings */ + DATA_BLOB attr; + uint8_t subs_tag; + char *value; + int chunk_num = 0; + + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + if (!asn1_read_OctetString(data, mem_ctx, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_SUBSTRING; + ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); + ret->u.substring.chunks = NULL; + ret->u.substring.start_with_wildcard = 1; + ret->u.substring.end_with_wildcard = 1; + + if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { + goto failed; + } + + while (asn1_tag_remaining(data)) { + asn1_peek_uint8(data, &subs_tag); + subs_tag &= 0x1f; /* strip off the asn1 stuff */ + if (subs_tag > 2) goto failed; + + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); + asn1_read_LDAPString(data, mem_ctx, &value); + asn1_end_tag(data); + + switch (subs_tag) { + case 0: + if (ret->u.substring.chunks != NULL) { + /* initial value found in the middle */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.start_with_wildcard = 0; + chunk_num = 1; + break; + + case 1: + if (ret->u.substring.end_with_wildcard == 0) { + /* "any" value found after a "final" value */ + goto failed; + } + + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + chunk_num++; + break; + + case 2: + ret->u.substring.chunks = ldap_decode_substring(ret, + ret->u.substring.chunks, + chunk_num, + value); + if (ret->u.substring.chunks == NULL) { + goto failed; + } + + ret->u.substring.end_with_wildcard = 0; + break; + + default: + goto failed; + } + + } + + if (!asn1_end_tag(data)) { /* SEQUENCE */ + goto failed; + } + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 5: { + /* greaterOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_GREATER; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 6: { + /* lessOrEqual */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_LESS; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 7: { + /* Normal presence, "attribute=*" */ + char *attr; + + if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { + goto failed; + } + if (!asn1_read_LDAPString(data, ret, &attr)) { + goto failed; + } + + ret->operation = LDB_OP_PRESENT; + ret->u.present.attr = talloc_steal(ret, attr); + + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + case 8: { + /* approx */ + const char *attrib; + DATA_BLOB value; + + asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib); + asn1_read_OctetString(data, mem_ctx, &value); + asn1_end_tag(data); + if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { + goto failed; + } + + ret->operation = LDB_OP_APPROX; + ret->u.comparison.attr = talloc_steal(ret, attrib); + ret->u.comparison.value.data = talloc_steal(ret, value.data); + ret->u.comparison.value.length = value.length; + break; + } + case 9: { + char *oid = NULL, *attr = NULL, *value; + uint8_t dnAttributes; + /* an extended search */ + if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { + goto failed; + } + + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, ret, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); + asn1_read_LDAPString(data, ret, &attr); + asn1_end_tag(data); + } + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); + asn1_read_LDAPString(data, ret, &value); + asn1_end_tag(data); + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == NULL) || (value == NULL)) { + goto failed; + } + + if (oid) { + ret->operation = LDB_OP_EXTENDED; + + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + ret->u.extended.rule_id = talloc_steal(ret, oid); + ret->u.extended.value.data = talloc_steal(ret, value); + ret->u.extended.value.length = strlen(value); + ret->u.extended.dnAttributes = dnAttributes; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } + if (!asn1_end_tag(data)) { + goto failed; + } + break; + } + + default: + DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); + goto failed; + } + + return ret; + +failed: + talloc_free(ret); + return NULL; +} + +/* Decode a single LDAP attribute, possibly containing multiple values */ +static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element *attrib) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); + asn1_start_tag(data, ASN1_SET); + while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { + DATA_BLOB blob; + asn1_read_OctetString(data, mem_ctx, &blob); + add_value_to_attrib(mem_ctx, &blob, attrib); + } + asn1_end_tag(data); + asn1_end_tag(data); + +} + +/* Decode a set of LDAP attributes, as found in the dereference control */ +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + struct ldb_message_element attrib; + ZERO_STRUCT(attrib); + ldap_decode_attrib(mem_ctx, data, &attrib); + add_attrib_to_array_talloc(mem_ctx, &attrib, + attributes, num_attributes); + } +} + +/* Decode a set of LDAP attributes, as found in a search entry */ +static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes) +{ + asn1_start_tag(data, ASN1_SEQUENCE(0)); + ldap_decode_attribs_bare(mem_ctx, data, + attributes, num_attributes); + asn1_end_tag(data); +} + +/* This routine returns LDAP status codes */ + +_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) +{ + uint8_t tag; + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_Integer(data, &msg->messageid); + + if (!asn1_peek_uint8(data, &tag)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + + switch(tag) { + + case ASN1_APPLICATION(LDAP_TAG_BindRequest): { + struct ldap_BindRequest *r = &msg->r.BindRequest; + msg->type = LDAP_TAG_BindRequest; + asn1_start_tag(data, tag); + asn1_read_Integer(data, &r->version); + asn1_read_OctetString_talloc(msg, data, &r->dn); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { + int pwlen; + r->creds.password = ""; + r->mechanism = LDAP_AUTH_MECH_SIMPLE; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + pwlen = asn1_tag_remaining(data); + if (pwlen == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + if (pwlen != 0) { + char *pw = talloc_array(msg, char, pwlen+1); + if (!pw) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, pw, pwlen); + pw[pwlen] = '\0'; + r->creds.password = pw; + } + asn1_end_tag(data); + } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ + asn1_start_tag(data, ASN1_CONTEXT(3)); + r->mechanism = LDAP_AUTH_MECH_SASL; + asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); + if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_OctetString(data, msg, &tmp_blob); + r->creds.SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->creds.SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->creds.SASL.secblob = NULL; + } + asn1_end_tag(data); + } else { + /* Neither Simple nor SASL bind */ + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_BindResponse): { + struct ldap_BindResponse *r = &msg->r.BindResponse; + msg->type = LDAP_TAG_BindResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + asn1_read_ContextSimple(data, 7, &tmp_blob); + r->SASL.secblob = talloc(msg, DATA_BLOB); + if (!r->SASL.secblob) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, + tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->SASL.secblob = NULL; + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { + msg->type = LDAP_TAG_UnbindRequest; + asn1_start_tag(data, tag); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { + struct ldap_SearchRequest *r = &msg->r.SearchRequest; + msg->type = LDAP_TAG_SearchRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->basedn); + asn1_read_enumerated(data, (int *)&(r->scope)); + asn1_read_enumerated(data, (int *)&(r->deref)); + asn1_read_Integer(data, &r->sizelimit); + asn1_read_Integer(data, &r->timelimit); + asn1_read_BOOLEAN(data, &r->attributesonly); + + r->tree = ldap_decode_filter_tree(msg, data); + if (r->tree == NULL) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_attributes = 0; + r->attributes = NULL; + + while (asn1_tag_remaining(data) > 0) { + + const char *attr; + if (!asn1_read_OctetString_talloc(msg, data, + &attr)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + if (!add_string_to_array(msg, attr, + &r->attributes, + &r->num_attributes)) + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { + struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; + msg->type = LDAP_TAG_SearchResultEntry; + r->attributes = NULL; + r->num_attributes = 0; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { + struct ldap_Result *r = &msg->r.SearchResultDone; + msg->type = LDAP_TAG_SearchResultDone; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { + struct ldap_SearchResRef *r = &msg->r.SearchResultReference; + msg->type = LDAP_TAG_SearchResultReference; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->referral); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { + struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; + msg->type = LDAP_TAG_ModifyRequest; + asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + + r->num_mods = 0; + r->mods = NULL; + + while (asn1_tag_remaining(data) > 0) { + struct ldap_mod mod; + int v; + ZERO_STRUCT(mod); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_enumerated(data, &v); + mod.type = v; + ldap_decode_attrib(msg, data, &mod.attrib); + asn1_end_tag(data); + if (!add_mod_to_array_talloc(msg, &mod, + &r->mods, &r->num_mods)) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } + + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { + struct ldap_Result *r = &msg->r.ModifyResponse; + msg->type = LDAP_TAG_ModifyResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddRequest): { + struct ldap_AddRequest *r = &msg->r.AddRequest; + msg->type = LDAP_TAG_AddRequest; + asn1_start_tag(data, tag); + asn1_read_OctetString_talloc(msg, data, &r->dn); + + r->attributes = NULL; + r->num_attributes = 0; + ldap_decode_attribs(msg, data, &r->attributes, + &r->num_attributes); + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_AddResponse): { + struct ldap_Result *r = &msg->r.AddResponse; + msg->type = LDAP_TAG_AddResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { + struct ldap_DelRequest *r = &msg->r.DelRequest; + int len; + char *dn; + msg->type = LDAP_TAG_DelRequest; + asn1_start_tag(data, + ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + dn = talloc_array(msg, char, len+1); + if (dn == NULL) + break; + asn1_read(data, dn, len); + dn[len] = '\0'; + r->dn = dn; + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_DelResponse): { + struct ldap_Result *r = &msg->r.DelResponse; + msg->type = LDAP_TAG_DelResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { + struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; + msg->type = LDAP_TAG_ModifyDNRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_read_OctetString_talloc(msg, data, &r->newrdn); + asn1_read_BOOLEAN(data, &r->deleteolddn); + r->newsuperior = NULL; + if (asn1_tag_remaining(data) > 0) { + int len; + char *newsup; + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); + len = asn1_tag_remaining(data); + if (len == -1) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + newsup = talloc_array(msg, char, len+1); + if (newsup == NULL) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + asn1_read(data, newsup, len); + newsup[len] = '\0'; + r->newsuperior = newsup; + asn1_end_tag(data); + } + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { + struct ldap_Result *r = &msg->r.ModifyDNResponse; + msg->type = LDAP_TAG_ModifyDNResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { + struct ldap_CompareRequest *r = &msg->r.CompareRequest; + msg->type = LDAP_TAG_CompareRequest; + asn1_start_tag(data, + ASN1_APPLICATION(LDAP_TAG_CompareRequest)); + asn1_read_OctetString_talloc(msg, data, &r->dn); + asn1_start_tag(data, ASN1_SEQUENCE(0)); + asn1_read_OctetString_talloc(msg, data, &r->attribute); + asn1_read_OctetString(data, msg, &r->value); + if (r->value.data) { + talloc_steal(msg, r->value.data); + } + asn1_end_tag(data); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { + struct ldap_Result *r = &msg->r.CompareResponse; + msg->type = LDAP_TAG_CompareResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, r); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { + struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; + msg->type = LDAP_TAG_AbandonRequest; + asn1_start_tag(data, tag); + asn1_read_implicit_Integer(data, &r->messageid); + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { + struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedRequest; + asn1_start_tag(data,tag); + if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + + case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { + struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; + DATA_BLOB tmp_blob = data_blob(NULL, 0); + + msg->type = LDAP_TAG_ExtendedResponse; + asn1_start_tag(data, tag); + ldap_decode_response(msg, data, &r->response); + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->oid = blob2string_talloc(msg, tmp_blob); + data_blob_free(&tmp_blob); + if (!r->oid) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + } else { + r->oid = NULL; + } + + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { + asn1_read_ContextSimple(data, 1, &tmp_blob); + r->value = talloc(msg, DATA_BLOB); + if (!r->value) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); + data_blob_free(&tmp_blob); + } else { + r->value = NULL; + } + + asn1_end_tag(data); + break; + } + default: + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + msg->controls = NULL; + msg->controls_decoded = NULL; + + if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { + int i = 0; + struct ldb_control **ctrl = NULL; + bool *decoded = NULL; + + asn1_start_tag(data, ASN1_CONTEXT(0)); + + while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { + DATA_BLOB value; + /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ + + ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); + if (!ctrl) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + decoded = talloc_realloc(msg, decoded, bool, i+1); + if (!decoded) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + ctrl[i] = talloc(ctrl, struct ldb_control); + if (!ctrl[i]) { + return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); + } + + if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + + if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { + if (ctrl[i]->critical) { + ctrl[i]->data = NULL; + decoded[i] = false; + i++; + } else { + talloc_free(ctrl[i]); + ctrl[i] = NULL; + } + } else { + decoded[i] = true; + i++; + } + } + + if (ctrl != NULL) { + ctrl[i] = NULL; + } + + msg->controls = ctrl; + msg->controls_decoded = decoded; + + asn1_end_tag(data); + } + + asn1_end_tag(data); + if ((data->has_error) || (data->nesting != NULL)) { + return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); + } + return NT_STATUS_OK; +} + + +/* + return NT_STATUS_OK if a blob has enough bytes in it to be a full + ldap packet. Set packet_size if true. +*/ +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) +{ + return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); +} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h new file mode 100644 index 0000000000..47ee724e97 --- /dev/null +++ b/source4/libcli/ldap/ldap_message.h @@ -0,0 +1,225 @@ +/* + Unix SMB/CIFS Implementation. + LDAP protocol helper functions for SAMBA + Copyright (C) Volker Lendecke 2004 + + 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 . + +*/ + +#ifndef _LIBCLI_LDAP_MESSAGE_H_ +#define _LIBCLI_LDAP_MESSAGE_H_ + +#include "libcli/ldap/ldap_errors.h" +#include "lib/ldb/include/ldb.h" + +enum ldap_request_tag { + LDAP_TAG_BindRequest = 0, + LDAP_TAG_BindResponse = 1, + LDAP_TAG_UnbindRequest = 2, + LDAP_TAG_SearchRequest = 3, + LDAP_TAG_SearchResultEntry = 4, + LDAP_TAG_SearchResultDone = 5, + LDAP_TAG_ModifyRequest = 6, + LDAP_TAG_ModifyResponse = 7, + LDAP_TAG_AddRequest = 8, + LDAP_TAG_AddResponse = 9, + LDAP_TAG_DelRequest = 10, + LDAP_TAG_DelResponse = 11, + LDAP_TAG_ModifyDNRequest = 12, + LDAP_TAG_ModifyDNResponse = 13, + LDAP_TAG_CompareRequest = 14, + LDAP_TAG_CompareResponse = 15, + LDAP_TAG_AbandonRequest = 16, + LDAP_TAG_SearchResultReference = 19, + LDAP_TAG_ExtendedRequest = 23, + LDAP_TAG_ExtendedResponse = 24 +}; + +enum ldap_auth_mechanism { + LDAP_AUTH_MECH_SIMPLE = 0, + LDAP_AUTH_MECH_SASL = 3 +}; + +struct ldap_Result { + int resultcode; + const char *dn; + const char *errormessage; + const char *referral; +}; + +struct ldap_BindRequest { + int version; + const char *dn; + enum ldap_auth_mechanism mechanism; + union { + const char *password; + struct { + const char *mechanism; + DATA_BLOB *secblob;/* optional */ + } SASL; + } creds; +}; + +struct ldap_BindResponse { + struct ldap_Result response; + union { + DATA_BLOB *secblob;/* optional */ + } SASL; +}; + +struct ldap_UnbindRequest { + uint8_t __dummy; +}; + +enum ldap_scope { + LDAP_SEARCH_SCOPE_BASE = 0, + LDAP_SEARCH_SCOPE_SINGLE = 1, + LDAP_SEARCH_SCOPE_SUB = 2 +}; + +enum ldap_deref { + LDAP_DEREFERENCE_NEVER = 0, + LDAP_DEREFERENCE_IN_SEARCHING = 1, + LDAP_DEREFERENCE_FINDING_BASE = 2, + LDAP_DEREFERENCE_ALWAYS +}; + +struct ldap_SearchRequest { + const char *basedn; + enum ldap_scope scope; + enum ldap_deref deref; + uint32_t timelimit; + uint32_t sizelimit; + bool attributesonly; + struct ldb_parse_tree *tree; + int num_attributes; + const char * const *attributes; +}; + +struct ldap_SearchResEntry { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_SearchResRef { + const char *referral; +}; + +enum ldap_modify_type { + LDAP_MODIFY_NONE = -1, + LDAP_MODIFY_ADD = 0, + LDAP_MODIFY_DELETE = 1, + LDAP_MODIFY_REPLACE = 2 +}; + +struct ldap_mod { + enum ldap_modify_type type; + struct ldb_message_element attrib; +}; + +struct ldap_ModifyRequest { + const char *dn; + int num_mods; + struct ldap_mod *mods; +}; + +struct ldap_AddRequest { + const char *dn; + int num_attributes; + struct ldb_message_element *attributes; +}; + +struct ldap_DelRequest { + const char *dn; +}; + +struct ldap_ModifyDNRequest { + const char *dn; + const char *newrdn; + bool deleteolddn; + const char *newsuperior;/* optional */ +}; + +struct ldap_CompareRequest { + const char *dn; + const char *attribute; + DATA_BLOB value; +}; + +struct ldap_AbandonRequest { + uint32_t messageid; +}; + +struct ldap_ExtendedRequest { + const char *oid; + DATA_BLOB *value;/* optional */ +}; + +struct ldap_ExtendedResponse { + struct ldap_Result response; + const char *oid;/* optional */ + DATA_BLOB *value;/* optional */ +}; + +union ldap_Request { + struct ldap_Result GeneralResult; + struct ldap_BindRequest BindRequest; + struct ldap_BindResponse BindResponse; + struct ldap_UnbindRequest UnbindRequest; + struct ldap_SearchRequest SearchRequest; + struct ldap_SearchResEntry SearchResultEntry; + struct ldap_Result SearchResultDone; + struct ldap_SearchResRef SearchResultReference; + struct ldap_ModifyRequest ModifyRequest; + struct ldap_Result ModifyResponse; + struct ldap_AddRequest AddRequest; + struct ldap_Result AddResponse; + struct ldap_DelRequest DelRequest; + struct ldap_Result DelResponse; + struct ldap_ModifyDNRequest ModifyDNRequest; + struct ldap_Result ModifyDNResponse; + struct ldap_CompareRequest CompareRequest; + struct ldap_Result CompareResponse; + struct ldap_AbandonRequest AbandonRequest; + struct ldap_ExtendedRequest ExtendedRequest; + struct ldap_ExtendedResponse ExtendedResponse; +}; + + +struct ldap_message { + int messageid; + enum ldap_request_tag type; + union ldap_Request r; + struct ldb_control **controls; + bool *controls_decoded; +}; + +struct asn1_data; + +struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); +NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); +bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); +NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); + +bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, + struct asn1_data *data, + const char **result); + +void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, + struct ldb_message_element **attributes, + int *num_attributes); + +#endif diff --git a/source4/libcli/ldap/ldap_msg.c b/source4/libcli/ldap/ldap_msg.c deleted file mode 100644 index e45213c004..0000000000 --- a/source4/libcli/ldap/ldap_msg.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2005 - Copyright (C) Volker Lendecke 2004 - - 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 . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_client.h" -#include "libcli/ldap/ldap_proto.h" - - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -- cgit From 1ab9c1a40290fbecf8b7090492363eab0443c7c6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:09:11 +0100 Subject: s4:libcli/ldap: remove reference to DEBUG() This prepares using ldap_message.c in source3/ later metze --- source4/libcli/ldap/ldap_message.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4') diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c index 07362fa685..d8bbf42634 100644 --- a/source4/libcli/ldap/ldap_message.c +++ b/source4/libcli/ldap/ldap_message.c @@ -940,7 +940,6 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, } default: - DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag)); goto failed; } -- cgit From 536318549fba35a4d9eb60fbb2d0e91b88c44a7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:13:41 +0100 Subject: libcli/ldap: move ldap_message.[ch] from source4/ to the toplevel metze --- source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 8 - source4/libcli/ldap/ldap.h | 2 +- source4/libcli/ldap/ldap_message.c | 1467 ------------------------------------ source4/libcli/ldap/ldap_message.h | 225 ------ source4/main.mk | 2 + 6 files changed, 4 insertions(+), 1702 deletions(-) delete mode 100644 source4/libcli/ldap/ldap_message.c delete mode 100644 source4/libcli/ldap/ldap_message.h (limited to 'source4') diff --git a/source4/headermap.txt b/source4/headermap.txt index 8a968315bf..9d8e698f5c 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -49,7 +49,7 @@ param/share.h: share.h ../lib/util/util_tdb.h: util_tdb.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h -libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_message.h: ldap_message.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a0e178ac40..a1f34a6513 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,11 +1,3 @@ -[SUBSYSTEM::LIBCLI_LDAP_MESSAGE] -PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBLDB -PRIVATE_DEPENDENCIES = ASN1_UTIL - -LIBCLI_LDAP_MESSAGE_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ - ldap_message.o) -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_message.h - [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ diff --git a/source4/libcli/ldap/ldap.h b/source4/libcli/ldap/ldap.h index a642e671e6..79cfef2128 100644 --- a/source4/libcli/ldap/ldap.h +++ b/source4/libcli/ldap/ldap.h @@ -21,7 +21,7 @@ #ifndef _SMB_LDAP_H_ #define _SMB_LDAP_H_ -#include "libcli/ldap/ldap_message.h" +#include "../libcli/ldap/ldap_message.h" #include "librpc/gen_ndr/misc.h" struct tevent_context; diff --git a/source4/libcli/ldap/ldap_message.c b/source4/libcli/ldap/ldap_message.c deleted file mode 100644 index d8bbf42634..0000000000 --- a/source4/libcli/ldap/ldap_message.c +++ /dev/null @@ -1,1467 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - LDAP protocol helper functions for SAMBA - - Copyright (C) Andrew Tridgell 2004 - Copyright (C) Volker Lendecke 2004 - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2004 - - 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 . - -*/ - -#include "includes.h" -#include "../lib/util/asn1.h" -#include "libcli/ldap/ldap.h" -#include "libcli/ldap/ldap_proto.h" - -_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx) -{ - return talloc_zero(mem_ctx, struct ldap_message); -} - - -static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value, - struct ldb_message_element *attrib) -{ - attrib->values = talloc_realloc(mem_ctx, - attrib->values, - DATA_BLOB, - attrib->num_values+1); - if (attrib->values == NULL) - return false; - - attrib->values[attrib->num_values].data = talloc_steal(attrib->values, - value->data); - attrib->values[attrib->num_values].length = value->length; - attrib->num_values += 1; - return true; -} - -static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx, - const struct ldb_message_element *attrib, - struct ldb_message_element **attribs, - int *num_attribs) -{ - *attribs = talloc_realloc(mem_ctx, - *attribs, - struct ldb_message_element, - *num_attribs+1); - - if (*attribs == NULL) - return false; - - (*attribs)[*num_attribs] = *attrib; - talloc_steal(*attribs, attrib->values); - talloc_steal(*attribs, attrib->name); - *num_attribs += 1; - return true; -} - -static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx, - struct ldap_mod *mod, - struct ldap_mod **mods, - int *num_mods) -{ - *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1); - - if (*mods == NULL) - return false; - - (*mods)[*num_mods] = *mod; - *num_mods += 1; - return true; -} - -static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree) -{ - int i; - - switch (tree->operation) { - case LDB_OP_AND: - case LDB_OP_OR: - asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1)); - for (i=0; iu.list.num_elements; i++) { - if (!ldap_push_filter(data, tree->u.list.elements[i])) { - return false; - } - } - asn1_pop_tag(data); - break; - - case LDB_OP_NOT: - asn1_push_tag(data, ASN1_CONTEXT(2)); - if (!ldap_push_filter(data, tree->u.isnot.child)) { - return false; - } - asn1_pop_tag(data); - break; - - case LDB_OP_EQUALITY: - /* equality test */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, tree->u.equality.attr, - strlen(tree->u.equality.attr)); - asn1_write_OctetString(data, tree->u.equality.value.data, - tree->u.equality.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_SUBSTRING: - /* - SubstringFilter ::= SEQUENCE { - type AttributeDescription, - -- at least one must be present - substrings SEQUENCE OF CHOICE { - initial [0] LDAPString, - any [1] LDAPString, - final [2] LDAPString } } - */ - asn1_push_tag(data, ASN1_CONTEXT(4)); - asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - i = 0; - if ( ! tree->u.substring.start_with_wildcard) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - while (tree->u.substring.chunks[i]) { - int ctx; - - if (( ! tree->u.substring.chunks[i + 1]) && - (tree->u.substring.end_with_wildcard == 0)) { - ctx = 2; - } else { - ctx = 1; - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx)); - asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i]); - asn1_pop_tag(data); - i++; - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - case LDB_OP_GREATER: - /* greaterOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(5)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_LESS: - /* lessOrEqual test */ - asn1_push_tag(data, ASN1_CONTEXT(6)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_PRESENT: - /* present test */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7)); - asn1_write_LDAPString(data, tree->u.present.attr); - asn1_pop_tag(data); - return !data->has_error; - - case LDB_OP_APPROX: - /* approx test */ - asn1_push_tag(data, ASN1_CONTEXT(8)); - asn1_write_OctetString(data, tree->u.comparison.attr, - strlen(tree->u.comparison.attr)); - asn1_write_OctetString(data, tree->u.comparison.value.data, - tree->u.comparison.value.length); - asn1_pop_tag(data); - break; - - case LDB_OP_EXTENDED: - /* - MatchingRuleAssertion ::= SEQUENCE { - matchingRule [1] MatchingRuleID OPTIONAL, - type [2] AttributeDescription OPTIONAL, - matchValue [3] AssertionValue, - dnAttributes [4] BOOLEAN DEFAULT FALSE - } - */ - asn1_push_tag(data, ASN1_CONTEXT(9)); - if (tree->u.extended.rule_id) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write_LDAPString(data, tree->u.extended.rule_id); - asn1_pop_tag(data); - } - if (tree->u.extended.attr) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_write_LDAPString(data, tree->u.extended.attr); - asn1_pop_tag(data); - } - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value); - asn1_pop_tag(data); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_write_uint8(data, tree->u.extended.dnAttributes); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - - default: - return false; - } - return !data->has_error; -} - -static void ldap_encode_response(struct asn1_data *data, struct ldap_Result *result) -{ - asn1_write_enumerated(data, result->resultcode); - asn1_write_OctetString(data, result->dn, - (result->dn) ? strlen(result->dn) : 0); - asn1_write_OctetString(data, result->errormessage, - (result->errormessage) ? - strlen(result->errormessage) : 0); - if (result->referral) { - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, result->referral, - strlen(result->referral)); - asn1_pop_tag(data); - } -} - -_PUBLIC_ bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx) -{ - struct asn1_data *data = asn1_init(mem_ctx); - int i, j; - - if (!data) return false; - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_Integer(data, msg->messageid); - - switch (msg->type) { - case LDAP_TAG_BindRequest: { - struct ldap_BindRequest *r = &msg->r.BindRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_Integer(data, r->version); - asn1_write_OctetString(data, r->dn, - (r->dn != NULL) ? strlen(r->dn) : 0); - - switch (r->mechanism) { - case LDAP_AUTH_MECH_SIMPLE: - /* context, primitive */ - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->creds.password, - strlen(r->creds.password)); - asn1_pop_tag(data); - break; - case LDAP_AUTH_MECH_SASL: - /* context, constructed */ - asn1_push_tag(data, ASN1_CONTEXT(3)); - asn1_write_OctetString(data, r->creds.SASL.mechanism, - strlen(r->creds.SASL.mechanism)); - if (r->creds.SASL.secblob) { - asn1_write_OctetString(data, r->creds.SASL.secblob->data, - r->creds.SASL.secblob->length); - } - asn1_pop_tag(data); - break; - default: - return false; - } - - asn1_pop_tag(data); - break; - } - case LDAP_TAG_BindResponse: { - struct ldap_BindResponse *r = &msg->r.BindResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->SASL.secblob) { - asn1_write_ContextSimple(data, 7, r->SASL.secblob); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_UnbindRequest: { -/* struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */ - break; - } - case LDAP_TAG_SearchRequest: { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->basedn, strlen(r->basedn)); - asn1_write_enumerated(data, r->scope); - asn1_write_enumerated(data, r->deref); - asn1_write_Integer(data, r->sizelimit); - asn1_write_Integer(data, r->timelimit); - asn1_write_BOOLEAN(data, r->attributesonly); - - if (!ldap_push_filter(data, r->tree)) { - return false; - } - - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - asn1_write_OctetString(data, r->attributes[i], - strlen(r->attributes[i])); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultEntry: { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attr = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attr->name, - strlen(attr->name)); - asn1_push_tag(data, ASN1_SEQUENCE(1)); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attr->values[j].data, - attr->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultDone: { - struct ldap_Result *r = &msg->r.SearchResultDone; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyRequest: { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_mods; i++) { - struct ldb_message_element *attrib = &r->mods[i].attrib; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_enumerated(data, r->mods[i].type); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jnum_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - - } - asn1_pop_tag(data); - asn1_pop_tag(data); - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyResponse: { - struct ldap_Result *r = &msg->r.ModifyResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddRequest: { - struct ldap_AddRequest *r = &msg->r.AddRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - - for (i=0; inum_attributes; i++) { - struct ldb_message_element *attrib = &r->attributes[i]; - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, attrib->name, - strlen(attrib->name)); - asn1_push_tag(data, ASN1_SET); - for (j=0; jattributes[i].num_values; j++) { - asn1_write_OctetString(data, - attrib->values[j].data, - attrib->values[j].length); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AddResponse: { - struct ldap_Result *r = &msg->r.AddResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelRequest: { - struct ldap_DelRequest *r = &msg->r.DelRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write(data, r->dn, strlen(r->dn)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_DelResponse: { - struct ldap_Result *r = &msg->r.DelResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNRequest: { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn)); - asn1_write_BOOLEAN(data, r->deleteolddn); - if (r->newsuperior) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->newsuperior, - strlen(r->newsuperior)); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ModifyDNResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareRequest: { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->dn, strlen(r->dn)); - asn1_push_tag(data, ASN1_SEQUENCE(0)); - asn1_write_OctetString(data, r->attribute, - strlen(r->attribute)); - asn1_write_OctetString(data, r->value.data, - r->value.length); - asn1_pop_tag(data); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_CompareResponse: { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, r); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_AbandonRequest: { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type)); - asn1_write_implicit_Integer(data, r->messageid); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_SearchResultReference: { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_write_OctetString(data, r->referral, strlen(r->referral)); - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedRequest: { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - case LDAP_TAG_ExtendedResponse: { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - asn1_push_tag(data, ASN1_APPLICATION(msg->type)); - ldap_encode_response(data, &r->response); - if (r->oid) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10)); - asn1_write(data, r->oid, strlen(r->oid)); - asn1_pop_tag(data); - } - if (r->value) { - asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11)); - asn1_write(data, r->value->data, r->value->length); - asn1_pop_tag(data); - } - asn1_pop_tag(data); - break; - } - default: - return false; - } - - if (msg->controls != NULL) { - asn1_push_tag(data, ASN1_CONTEXT(0)); - - for (i = 0; msg->controls[i] != NULL; i++) { - if (!ldap_encode_control(mem_ctx, data, msg->controls[i])) { - return false; - } - } - - asn1_pop_tag(data); - } - - asn1_pop_tag(data); - - if (data->has_error) { - asn1_free(data); - return false; - } - - *result = data_blob_talloc(mem_ctx, data->data, data->length); - asn1_free(data); - return true; -} - -static const char *blob2string_talloc(TALLOC_CTX *mem_ctx, - DATA_BLOB blob) -{ - char *result = talloc_array(mem_ctx, char, blob.length+1); - memcpy(result, blob.data, blob.length); - result[blob.length] = '\0'; - return result; -} - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result) -{ - DATA_BLOB string; - if (!asn1_read_OctetString(data, mem_ctx, &string)) - return false; - *result = blob2string_talloc(mem_ctx, string); - data_blob_free(&string); - return true; -} - -static void ldap_decode_response(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - struct ldap_Result *result) -{ - asn1_read_enumerated(data, &result->resultcode); - asn1_read_OctetString_talloc(mem_ctx, data, &result->dn); - asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage); - if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { - asn1_start_tag(data, ASN1_CONTEXT(3)); - asn1_read_OctetString_talloc(mem_ctx, data, &result->referral); - asn1_end_tag(data); - } else { - result->referral = NULL; - } -} - -static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value) -{ - - chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2); - if (chunks == NULL) { - return NULL; - } - - chunks[chunk_num] = talloc(mem_ctx, struct ldb_val); - if (chunks[chunk_num] == NULL) { - return NULL; - } - - chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value); - if (chunks[chunk_num]->data == NULL) { - return NULL; - } - chunks[chunk_num]->length = strlen(value); - - chunks[chunk_num + 1] = '\0'; - - return chunks; -} - - -/* - parse the ASN.1 formatted search string into a ldb_parse_tree -*/ -static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, - struct asn1_data *data) -{ - uint8_t filter_tag; - struct ldb_parse_tree *ret; - - if (!asn1_peek_uint8(data, &filter_tag)) { - return NULL; - } - - filter_tag &= 0x1f; /* strip off the asn1 stuff */ - - ret = talloc(mem_ctx, struct ldb_parse_tree); - if (ret == NULL) return NULL; - - switch(filter_tag) { - case 0: - case 1: - /* AND or OR of one or more filters */ - ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR; - ret->u.list.num_elements = 0; - ret->u.list.elements = NULL; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - while (asn1_tag_remaining(data) > 0) { - struct ldb_parse_tree *subtree; - subtree = ldap_decode_filter_tree(ret, data); - if (subtree == NULL) { - goto failed; - } - ret->u.list.elements = - talloc_realloc(ret, ret->u.list.elements, - struct ldb_parse_tree *, - ret->u.list.num_elements+1); - if (ret->u.list.elements == NULL) { - goto failed; - } - talloc_steal(ret->u.list.elements, subtree); - ret->u.list.elements[ret->u.list.num_elements] = subtree; - ret->u.list.num_elements++; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 2: - /* 'not' operation */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - ret->operation = LDB_OP_NOT; - ret->u.isnot.child = ldap_decode_filter_tree(ret, data); - if (ret->u.isnot.child == NULL) { - goto failed; - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - - case 3: { - /* equalityMatch */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attrib); - ret->u.equality.value.data = talloc_steal(ret, value.data); - ret->u.equality.value.length = value.length; - break; - } - case 4: { - /* substrings */ - DATA_BLOB attr; - uint8_t subs_tag; - char *value; - int chunk_num = 0; - - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - if (!asn1_read_OctetString(data, mem_ctx, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_SUBSTRING; - ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length); - ret->u.substring.chunks = NULL; - ret->u.substring.start_with_wildcard = 1; - ret->u.substring.end_with_wildcard = 1; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - goto failed; - } - - while (asn1_tag_remaining(data)) { - asn1_peek_uint8(data, &subs_tag); - subs_tag &= 0x1f; /* strip off the asn1 stuff */ - if (subs_tag > 2) goto failed; - - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag)); - asn1_read_LDAPString(data, mem_ctx, &value); - asn1_end_tag(data); - - switch (subs_tag) { - case 0: - if (ret->u.substring.chunks != NULL) { - /* initial value found in the middle */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.start_with_wildcard = 0; - chunk_num = 1; - break; - - case 1: - if (ret->u.substring.end_with_wildcard == 0) { - /* "any" value found after a "final" value */ - goto failed; - } - - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - chunk_num++; - break; - - case 2: - ret->u.substring.chunks = ldap_decode_substring(ret, - ret->u.substring.chunks, - chunk_num, - value); - if (ret->u.substring.chunks == NULL) { - goto failed; - } - - ret->u.substring.end_with_wildcard = 0; - break; - - default: - goto failed; - } - - } - - if (!asn1_end_tag(data)) { /* SEQUENCE */ - goto failed; - } - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 5: { - /* greaterOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_GREATER; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 6: { - /* lessOrEqual */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_LESS; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 7: { - /* Normal presence, "attribute=*" */ - char *attr; - - if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) { - goto failed; - } - if (!asn1_read_LDAPString(data, ret, &attr)) { - goto failed; - } - - ret->operation = LDB_OP_PRESENT; - ret->u.present.attr = talloc_steal(ret, attr); - - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - case 8: { - /* approx */ - const char *attrib; - DATA_BLOB value; - - asn1_start_tag(data, ASN1_CONTEXT(filter_tag)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib); - asn1_read_OctetString(data, mem_ctx, &value); - asn1_end_tag(data); - if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) { - goto failed; - } - - ret->operation = LDB_OP_APPROX; - ret->u.comparison.attr = talloc_steal(ret, attrib); - ret->u.comparison.value.data = talloc_steal(ret, value.data); - ret->u.comparison.value.length = value.length; - break; - } - case 9: { - char *oid = NULL, *attr = NULL, *value; - uint8_t dnAttributes; - /* an extended search */ - if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { - goto failed; - } - - /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's - we need to check we properly implement --SSS */ - /* either oid or type must be defined */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); - asn1_read_LDAPString(data, ret, &oid); - asn1_end_tag(data); - } - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2)); - asn1_read_LDAPString(data, ret, &attr); - asn1_end_tag(data); - } - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3)); - asn1_read_LDAPString(data, ret, &value); - asn1_end_tag(data); - /* dnAttributes is marked as BOOLEAN DEFAULT FALSE - it is not marked as OPTIONAL but openldap tools - do not set this unless it is to be set as TRUE - NOTE: openldap tools do not work with AD as it - seems that AD always requires the dnAttributes - boolean value to be set */ - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); - asn1_read_uint8(data, &dnAttributes); - asn1_end_tag(data); - } else { - dnAttributes = 0; - } - if ((oid == NULL && attr == NULL) || (value == NULL)) { - goto failed; - } - - if (oid) { - ret->operation = LDB_OP_EXTENDED; - - /* From the RFC2251: If the type field is - absent and matchingRule is present, the matchValue is compared - against all attributes in an entry which support that matchingRule - */ - if (attr) { - ret->u.extended.attr = talloc_steal(ret, attr); - } else { - ret->u.extended.attr = talloc_strdup(ret, "*"); - } - ret->u.extended.rule_id = talloc_steal(ret, oid); - ret->u.extended.value.data = talloc_steal(ret, value); - ret->u.extended.value.length = strlen(value); - ret->u.extended.dnAttributes = dnAttributes; - } else { - ret->operation = LDB_OP_EQUALITY; - ret->u.equality.attr = talloc_steal(ret, attr); - ret->u.equality.value.data = talloc_steal(ret, value); - ret->u.equality.value.length = strlen(value); - } - if (!asn1_end_tag(data)) { - goto failed; - } - break; - } - - default: - goto failed; - } - - return ret; - -failed: - talloc_free(ret); - return NULL; -} - -/* Decode a single LDAP attribute, possibly containing multiple values */ -static void ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element *attrib) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name); - asn1_start_tag(data, ASN1_SET); - while (asn1_peek_tag(data, ASN1_OCTET_STRING)) { - DATA_BLOB blob; - asn1_read_OctetString(data, mem_ctx, &blob); - add_value_to_attrib(mem_ctx, &blob, attrib); - } - asn1_end_tag(data); - asn1_end_tag(data); - -} - -/* Decode a set of LDAP attributes, as found in the dereference control */ -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - struct ldb_message_element attrib; - ZERO_STRUCT(attrib); - ldap_decode_attrib(mem_ctx, data, &attrib); - add_attrib_to_array_talloc(mem_ctx, &attrib, - attributes, num_attributes); - } -} - -/* Decode a set of LDAP attributes, as found in a search entry */ -static void ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes) -{ - asn1_start_tag(data, ASN1_SEQUENCE(0)); - ldap_decode_attribs_bare(mem_ctx, data, - attributes, num_attributes); - asn1_end_tag(data); -} - -/* This routine returns LDAP status codes */ - -_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg) -{ - uint8_t tag; - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_Integer(data, &msg->messageid); - - if (!asn1_peek_uint8(data, &tag)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - - switch(tag) { - - case ASN1_APPLICATION(LDAP_TAG_BindRequest): { - struct ldap_BindRequest *r = &msg->r.BindRequest; - msg->type = LDAP_TAG_BindRequest; - asn1_start_tag(data, tag); - asn1_read_Integer(data, &r->version); - asn1_read_OctetString_talloc(msg, data, &r->dn); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) { - int pwlen; - r->creds.password = ""; - r->mechanism = LDAP_AUTH_MECH_SIMPLE; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - pwlen = asn1_tag_remaining(data); - if (pwlen == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - if (pwlen != 0) { - char *pw = talloc_array(msg, char, pwlen+1); - if (!pw) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, pw, pwlen); - pw[pwlen] = '\0'; - r->creds.password = pw; - } - asn1_end_tag(data); - } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){ - asn1_start_tag(data, ASN1_CONTEXT(3)); - r->mechanism = LDAP_AUTH_MECH_SASL; - asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism); - if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */ - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_OctetString(data, msg, &tmp_blob); - r->creds.SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->creds.SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->creds.SASL.secblob = NULL; - } - asn1_end_tag(data); - } else { - /* Neither Simple nor SASL bind */ - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_BindResponse): { - struct ldap_BindResponse *r = &msg->r.BindResponse; - msg->type = LDAP_TAG_BindResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); - asn1_read_ContextSimple(data, 7, &tmp_blob); - r->SASL.secblob = talloc(msg, DATA_BLOB); - if (!r->SASL.secblob) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->SASL.secblob = data_blob_talloc(r->SASL.secblob, - tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->SASL.secblob = NULL; - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): { - msg->type = LDAP_TAG_UnbindRequest; - asn1_start_tag(data, tag); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchRequest): { - struct ldap_SearchRequest *r = &msg->r.SearchRequest; - msg->type = LDAP_TAG_SearchRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->basedn); - asn1_read_enumerated(data, (int *)&(r->scope)); - asn1_read_enumerated(data, (int *)&(r->deref)); - asn1_read_Integer(data, &r->sizelimit); - asn1_read_Integer(data, &r->timelimit); - asn1_read_BOOLEAN(data, &r->attributesonly); - - r->tree = ldap_decode_filter_tree(msg, data); - if (r->tree == NULL) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_attributes = 0; - r->attributes = NULL; - - while (asn1_tag_remaining(data) > 0) { - - const char *attr; - if (!asn1_read_OctetString_talloc(msg, data, - &attr)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - if (!add_string_to_array(msg, attr, - &r->attributes, - &r->num_attributes)) - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): { - struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry; - msg->type = LDAP_TAG_SearchResultEntry; - r->attributes = NULL; - r->num_attributes = 0; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): { - struct ldap_Result *r = &msg->r.SearchResultDone; - msg->type = LDAP_TAG_SearchResultDone; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): { - struct ldap_SearchResRef *r = &msg->r.SearchResultReference; - msg->type = LDAP_TAG_SearchResultReference; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->referral); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): { - struct ldap_ModifyRequest *r = &msg->r.ModifyRequest; - msg->type = LDAP_TAG_ModifyRequest; - asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - r->num_mods = 0; - r->mods = NULL; - - while (asn1_tag_remaining(data) > 0) { - struct ldap_mod mod; - int v; - ZERO_STRUCT(mod); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_enumerated(data, &v); - mod.type = v; - ldap_decode_attrib(msg, data, &mod.attrib); - asn1_end_tag(data); - if (!add_mod_to_array_talloc(msg, &mod, - &r->mods, &r->num_mods)) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } - - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): { - struct ldap_Result *r = &msg->r.ModifyResponse; - msg->type = LDAP_TAG_ModifyResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddRequest): { - struct ldap_AddRequest *r = &msg->r.AddRequest; - msg->type = LDAP_TAG_AddRequest; - asn1_start_tag(data, tag); - asn1_read_OctetString_talloc(msg, data, &r->dn); - - r->attributes = NULL; - r->num_attributes = 0; - ldap_decode_attribs(msg, data, &r->attributes, - &r->num_attributes); - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_AddResponse): { - struct ldap_Result *r = &msg->r.AddResponse; - msg->type = LDAP_TAG_AddResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): { - struct ldap_DelRequest *r = &msg->r.DelRequest; - int len; - char *dn; - msg->type = LDAP_TAG_DelRequest; - asn1_start_tag(data, - ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - dn = talloc_array(msg, char, len+1); - if (dn == NULL) - break; - asn1_read(data, dn, len); - dn[len] = '\0'; - r->dn = dn; - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_DelResponse): { - struct ldap_Result *r = &msg->r.DelResponse; - msg->type = LDAP_TAG_DelResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): { - struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest; - msg->type = LDAP_TAG_ModifyDNRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_read_OctetString_talloc(msg, data, &r->newrdn); - asn1_read_BOOLEAN(data, &r->deleteolddn); - r->newsuperior = NULL; - if (asn1_tag_remaining(data) > 0) { - int len; - char *newsup; - asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0)); - len = asn1_tag_remaining(data); - if (len == -1) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - newsup = talloc_array(msg, char, len+1); - if (newsup == NULL) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - asn1_read(data, newsup, len); - newsup[len] = '\0'; - r->newsuperior = newsup; - asn1_end_tag(data); - } - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): { - struct ldap_Result *r = &msg->r.ModifyDNResponse; - msg->type = LDAP_TAG_ModifyDNResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareRequest): { - struct ldap_CompareRequest *r = &msg->r.CompareRequest; - msg->type = LDAP_TAG_CompareRequest; - asn1_start_tag(data, - ASN1_APPLICATION(LDAP_TAG_CompareRequest)); - asn1_read_OctetString_talloc(msg, data, &r->dn); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_read_OctetString_talloc(msg, data, &r->attribute); - asn1_read_OctetString(data, msg, &r->value); - if (r->value.data) { - talloc_steal(msg, r->value.data); - } - asn1_end_tag(data); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_CompareResponse): { - struct ldap_Result *r = &msg->r.CompareResponse; - msg->type = LDAP_TAG_CompareResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, r); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): { - struct ldap_AbandonRequest *r = &msg->r.AbandonRequest; - msg->type = LDAP_TAG_AbandonRequest; - asn1_start_tag(data, tag); - asn1_read_implicit_Integer(data, &r->messageid); - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): { - struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedRequest; - asn1_start_tag(data,tag); - if (!asn1_read_ContextSimple(data, 0, &tmp_blob)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - - case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): { - struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse; - DATA_BLOB tmp_blob = data_blob(NULL, 0); - - msg->type = LDAP_TAG_ExtendedResponse; - asn1_start_tag(data, tag); - ldap_decode_response(msg, data, &r->response); - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->oid = blob2string_talloc(msg, tmp_blob); - data_blob_free(&tmp_blob); - if (!r->oid) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - } else { - r->oid = NULL; - } - - if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) { - asn1_read_ContextSimple(data, 1, &tmp_blob); - r->value = talloc(msg, DATA_BLOB); - if (!r->value) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length); - data_blob_free(&tmp_blob); - } else { - r->value = NULL; - } - - asn1_end_tag(data); - break; - } - default: - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - msg->controls = NULL; - msg->controls_decoded = NULL; - - if (asn1_peek_tag(data, ASN1_CONTEXT(0))) { - int i = 0; - struct ldb_control **ctrl = NULL; - bool *decoded = NULL; - - asn1_start_tag(data, ASN1_CONTEXT(0)); - - while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) { - DATA_BLOB value; - /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */ - - ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2); - if (!ctrl) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - decoded = talloc_realloc(msg, decoded, bool, i+1); - if (!decoded) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - ctrl[i] = talloc(ctrl, struct ldb_control); - if (!ctrl[i]) { - return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR); - } - - if (!ldap_decode_control_wrapper(ctrl, data, ctrl[i], &value)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - - if (!ldap_decode_control_value(ctrl, value, ctrl[i])) { - if (ctrl[i]->critical) { - ctrl[i]->data = NULL; - decoded[i] = false; - i++; - } else { - talloc_free(ctrl[i]); - ctrl[i] = NULL; - } - } else { - decoded[i] = true; - i++; - } - } - - if (ctrl != NULL) { - ctrl[i] = NULL; - } - - msg->controls = ctrl; - msg->controls_decoded = decoded; - - asn1_end_tag(data); - } - - asn1_end_tag(data); - if ((data->has_error) || (data->nesting != NULL)) { - return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); - } - return NT_STATUS_OK; -} - - -/* - return NT_STATUS_OK if a blob has enough bytes in it to be a full - ldap packet. Set packet_size if true. -*/ -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size) -{ - return asn1_full_tag(blob, ASN1_SEQUENCE(0), packet_size); -} diff --git a/source4/libcli/ldap/ldap_message.h b/source4/libcli/ldap/ldap_message.h deleted file mode 100644 index 47ee724e97..0000000000 --- a/source4/libcli/ldap/ldap_message.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 2004 - - 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 . - -*/ - -#ifndef _LIBCLI_LDAP_MESSAGE_H_ -#define _LIBCLI_LDAP_MESSAGE_H_ - -#include "libcli/ldap/ldap_errors.h" -#include "lib/ldb/include/ldb.h" - -enum ldap_request_tag { - LDAP_TAG_BindRequest = 0, - LDAP_TAG_BindResponse = 1, - LDAP_TAG_UnbindRequest = 2, - LDAP_TAG_SearchRequest = 3, - LDAP_TAG_SearchResultEntry = 4, - LDAP_TAG_SearchResultDone = 5, - LDAP_TAG_ModifyRequest = 6, - LDAP_TAG_ModifyResponse = 7, - LDAP_TAG_AddRequest = 8, - LDAP_TAG_AddResponse = 9, - LDAP_TAG_DelRequest = 10, - LDAP_TAG_DelResponse = 11, - LDAP_TAG_ModifyDNRequest = 12, - LDAP_TAG_ModifyDNResponse = 13, - LDAP_TAG_CompareRequest = 14, - LDAP_TAG_CompareResponse = 15, - LDAP_TAG_AbandonRequest = 16, - LDAP_TAG_SearchResultReference = 19, - LDAP_TAG_ExtendedRequest = 23, - LDAP_TAG_ExtendedResponse = 24 -}; - -enum ldap_auth_mechanism { - LDAP_AUTH_MECH_SIMPLE = 0, - LDAP_AUTH_MECH_SASL = 3 -}; - -struct ldap_Result { - int resultcode; - const char *dn; - const char *errormessage; - const char *referral; -}; - -struct ldap_BindRequest { - int version; - const char *dn; - enum ldap_auth_mechanism mechanism; - union { - const char *password; - struct { - const char *mechanism; - DATA_BLOB *secblob;/* optional */ - } SASL; - } creds; -}; - -struct ldap_BindResponse { - struct ldap_Result response; - union { - DATA_BLOB *secblob;/* optional */ - } SASL; -}; - -struct ldap_UnbindRequest { - uint8_t __dummy; -}; - -enum ldap_scope { - LDAP_SEARCH_SCOPE_BASE = 0, - LDAP_SEARCH_SCOPE_SINGLE = 1, - LDAP_SEARCH_SCOPE_SUB = 2 -}; - -enum ldap_deref { - LDAP_DEREFERENCE_NEVER = 0, - LDAP_DEREFERENCE_IN_SEARCHING = 1, - LDAP_DEREFERENCE_FINDING_BASE = 2, - LDAP_DEREFERENCE_ALWAYS -}; - -struct ldap_SearchRequest { - const char *basedn; - enum ldap_scope scope; - enum ldap_deref deref; - uint32_t timelimit; - uint32_t sizelimit; - bool attributesonly; - struct ldb_parse_tree *tree; - int num_attributes; - const char * const *attributes; -}; - -struct ldap_SearchResEntry { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_SearchResRef { - const char *referral; -}; - -enum ldap_modify_type { - LDAP_MODIFY_NONE = -1, - LDAP_MODIFY_ADD = 0, - LDAP_MODIFY_DELETE = 1, - LDAP_MODIFY_REPLACE = 2 -}; - -struct ldap_mod { - enum ldap_modify_type type; - struct ldb_message_element attrib; -}; - -struct ldap_ModifyRequest { - const char *dn; - int num_mods; - struct ldap_mod *mods; -}; - -struct ldap_AddRequest { - const char *dn; - int num_attributes; - struct ldb_message_element *attributes; -}; - -struct ldap_DelRequest { - const char *dn; -}; - -struct ldap_ModifyDNRequest { - const char *dn; - const char *newrdn; - bool deleteolddn; - const char *newsuperior;/* optional */ -}; - -struct ldap_CompareRequest { - const char *dn; - const char *attribute; - DATA_BLOB value; -}; - -struct ldap_AbandonRequest { - uint32_t messageid; -}; - -struct ldap_ExtendedRequest { - const char *oid; - DATA_BLOB *value;/* optional */ -}; - -struct ldap_ExtendedResponse { - struct ldap_Result response; - const char *oid;/* optional */ - DATA_BLOB *value;/* optional */ -}; - -union ldap_Request { - struct ldap_Result GeneralResult; - struct ldap_BindRequest BindRequest; - struct ldap_BindResponse BindResponse; - struct ldap_UnbindRequest UnbindRequest; - struct ldap_SearchRequest SearchRequest; - struct ldap_SearchResEntry SearchResultEntry; - struct ldap_Result SearchResultDone; - struct ldap_SearchResRef SearchResultReference; - struct ldap_ModifyRequest ModifyRequest; - struct ldap_Result ModifyResponse; - struct ldap_AddRequest AddRequest; - struct ldap_Result AddResponse; - struct ldap_DelRequest DelRequest; - struct ldap_Result DelResponse; - struct ldap_ModifyDNRequest ModifyDNRequest; - struct ldap_Result ModifyDNResponse; - struct ldap_CompareRequest CompareRequest; - struct ldap_Result CompareResponse; - struct ldap_AbandonRequest AbandonRequest; - struct ldap_ExtendedRequest ExtendedRequest; - struct ldap_ExtendedResponse ExtendedResponse; -}; - - -struct ldap_message { - int messageid; - enum ldap_request_tag type; - union ldap_Request r; - struct ldb_control **controls; - bool *controls_decoded; -}; - -struct asn1_data; - -struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx); -NTSTATUS ldap_decode(struct asn1_data *data, struct ldap_message *msg); -bool ldap_encode(struct ldap_message *msg, DATA_BLOB *result, TALLOC_CTX *mem_ctx); -NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size); - -bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx, - struct asn1_data *data, - const char **result); - -void ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data, - struct ldb_message_element **attributes, - int *num_attributes); - -#endif diff --git a/source4/main.mk b/source4/main.mk index 04f7a36a5f..ee2018fb69 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -50,3 +50,5 @@ mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk mkinclude ../lib/async_req/config.mk mkinclude ../libcli/security/config.mk +mkinclude ../libcli/ldap/config.mk + -- cgit From ef0fa403f1c5d670b7991770e7fbb8394879de4b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:52:37 +0100 Subject: libcli/ldap: move ldap_errors.h to the toplevel and install it metze --- source4/headermap.txt | 1 + source4/libcli/ldap/ldap_errors.h | 66 --------------------------------------- source4/libcli/util/nterr.c | 2 +- 3 files changed, 2 insertions(+), 67 deletions(-) delete mode 100644 source4/libcli/ldap/ldap_errors.h (limited to 'source4') diff --git a/source4/headermap.txt b/source4/headermap.txt index 9d8e698f5c..6417603d1d 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -50,6 +50,7 @@ param/share.h: share.h ../lib/util/util_ldb.h: util_ldb.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h +../libcli/ldap/ldap_errors.h: ldap_errors.h libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h diff --git a/source4/libcli/ldap/ldap_errors.h b/source4/libcli/ldap/ldap_errors.h deleted file mode 100644 index 17ac43814c..0000000000 --- a/source4/libcli/ldap/ldap_errors.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - Unix SMB/CIFS Implementation. - LDAP protocol helper functions for SAMBA - Copyright (C) Volker Lendecke 2004 - - 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 . - -*/ - -#ifndef _SMB_LDAP_ERRORS_H_ -#define _SMB_LDAP_ERRORS_H_ - -enum ldap_result_code { - LDAP_SUCCESS = 0, - LDAP_OPERATIONS_ERROR = 1, - LDAP_PROTOCOL_ERROR = 2, - LDAP_TIME_LIMIT_EXCEEDED = 3, - LDAP_SIZE_LIMIT_EXCEEDED = 4, - LDAP_COMPARE_FALSE = 5, - LDAP_COMPARE_TRUE = 6, - LDAP_AUTH_METHOD_NOT_SUPPORTED = 7, - LDAP_STRONG_AUTH_REQUIRED = 8, - LDAP_REFERRAL = 10, - LDAP_ADMIN_LIMIT_EXCEEDED = 11, - LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12, - LDAP_CONFIDENTIALITY_REQUIRED = 13, - LDAP_SASL_BIND_IN_PROGRESS = 14, - LDAP_NO_SUCH_ATTRIBUTE = 16, - LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17, - LDAP_INAPPROPRIATE_MATCHING = 18, - LDAP_CONSTRAINT_VIOLATION = 19, - LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20, - LDAP_INVALID_ATTRIBUTE_SYNTAX = 21, - LDAP_NO_SUCH_OBJECT = 32, - LDAP_ALIAS_PROBLEM = 33, - LDAP_INVALID_DN_SYNTAX = 34, - LDAP_ALIAS_DEREFERENCING_PROBLEM = 36, - LDAP_INAPPROPRIATE_AUTHENTICATION = 48, - LDAP_INVALID_CREDENTIALS = 49, - LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50, - LDAP_BUSY = 51, - LDAP_UNAVAILABLE = 52, - LDAP_UNWILLING_TO_PERFORM = 53, - LDAP_LOOP_DETECT = 54, - LDAP_NAMING_VIOLATION = 64, - LDAP_OBJECT_CLASS_VIOLATION = 65, - LDAP_NOT_ALLOWED_ON_NON_LEAF = 66, - LDAP_NOT_ALLOWED_ON_RDN = 67, - LDAP_ENTRY_ALREADY_EXISTS = 68, - LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69, - LDAP_AFFECTS_MULTIPLE_DSAS = 71, - LDAP_OTHER = 80 -}; - -#endif /* _SMB_LDAP_ERRORS_H_ */ diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index 8371837dcb..4e7cdf5c3a 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -20,7 +20,7 @@ /* NT error codes. please read nterr.h */ #include "includes.h" -#include "libcli/ldap/ldap_errors.h" +#include "../libcli/ldap/ldap_errors.h" #undef strcasecmp typedef struct -- cgit From 18b30e5646d7a484c1714eac9b9ce1f8c1a8241a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 12:50:43 +0100 Subject: libcli/ldap: move ldap_ndr from source4/ to toplevel metze --- source4/headermap.txt | 2 +- source4/libcli/ldap/config.mk | 7 +-- source4/libcli/ldap/ldap_ndr.c | 96 ------------------------------------------ source4/libcli/ldap/ldap_ndr.h | 12 ------ 4 files changed, 2 insertions(+), 115 deletions(-) delete mode 100644 source4/libcli/ldap/ldap_ndr.c delete mode 100644 source4/libcli/ldap/ldap_ndr.h (limited to 'source4') diff --git a/source4/headermap.txt b/source4/headermap.txt index 6417603d1d..8287044622 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -51,7 +51,7 @@ param/share.h: share.h ../lib/util/wrap_xattr.h: wrap_xattr.h ../libcli/ldap/ldap_message.h: ldap_message.h ../libcli/ldap/ldap_errors.h: ldap_errors.h -libcli/ldap/ldap_ndr.h: ldap_ndr.h +../libcli/ldap/ldap_ndr.h: ldap_ndr.h ../lib/tevent/tevent.h: tevent.h ../lib/tevent/tevent_internal.h: tevent_internal.h auth/session.h: samba/session.h diff --git a/source4/libcli/ldap/config.mk b/source4/libcli/ldap/config.mk index a1f34a6513..f0c0f5295d 100644 --- a/source4/libcli/ldap/config.mk +++ b/source4/libcli/ldap/config.mk @@ -1,7 +1,7 @@ [SUBSYSTEM::LIBCLI_LDAP] PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTEVENT LIBPACKET PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE samba_socket NDR_SAMR LIBTLS \ - LDAP_ENCODE LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE + LIBCLI_LDAP_NDR LIBNDR LP_RESOLVE gensec LIBCLI_LDAP_MESSAGE LIBCLI_LDAP_OBJ_FILES = $(addprefix $(libclisrcdir)/ldap/, \ ldap_client.o ldap_bind.o \ @@ -10,8 +10,3 @@ PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap.h $(eval $(call proto_header_template,$(libclisrcdir)/ldap/ldap_proto.h,$(LIBCLI_LDAP_OBJ_FILES:.o=.c))) -[SUBSYSTEM::LDAP_ENCODE] -PRIVATE_DEPENDENCIES = LIBLDB - -LDAP_ENCODE_OBJ_FILES = $(libclisrcdir)/ldap/ldap_ndr.o -PUBLIC_HEADERS += $(libclisrcdir)/ldap/ldap_ndr.h diff --git a/source4/libcli/ldap/ldap_ndr.c b/source4/libcli/ldap/ldap_ndr.c deleted file mode 100644 index f0a11ba41f..0000000000 --- a/source4/libcli/ldap/ldap_ndr.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - Unix SMB/CIFS mplementation. - - wrap/unwrap NDR encoded elements for ldap calls - - Copyright (C) Andrew Tridgell 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 . - -*/ - -#include "includes.h" -#include "libcli/ldap/ldap.h" -#include "librpc/gen_ndr/ndr_security.h" -#include "librpc/gen_ndr/ndr_misc.h" -#include "libcli/ldap/ldap_ndr.h" - -/* - encode a NDR uint32 as a ldap filter element -*/ -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value) -{ - uint8_t buf[4]; - struct ldb_val val; - SIVAL(buf, 0, value); - val.data = buf; - val.length = 4; - return ldb_binary_encode(mem_ctx, val); -} - -/* - encode a NDR dom_sid as a ldap filter element -*/ -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, sid, - (ndr_push_flags_fn_t)ndr_push_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - - -/* - encode a NDR GUID as a ldap filter element -*/ -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - char *ret; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_push_flags_fn_t)ndr_push_GUID); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return NULL; - } - ret = ldb_binary_encode(mem_ctx, blob); - data_blob_free(&blob); - return ret; -} - -/* - decode a NDR GUID from a ldap filter element -*/ -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid) -{ - DATA_BLOB blob; - enum ndr_err_code ndr_err; - - blob.data = val.data; - blob.length = val.length; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, guid, - (ndr_pull_flags_fn_t)ndr_pull_GUID); - talloc_free(val.data); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - return NT_STATUS_OK; -} diff --git a/source4/libcli/ldap/ldap_ndr.h b/source4/libcli/ldap/ldap_ndr.h deleted file mode 100644 index ee1f702c78..0000000000 --- a/source4/libcli/ldap/ldap_ndr.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LIBCLI_LDAP_LDAP_NDR_H__ -#define __LIBCLI_LDAP_LDAP_NDR_H__ - -#include "librpc/gen_ndr/ndr_misc.h" - -char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); -char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); -NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); - -#endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ - -- cgit From 7b1c5c94f6a08108d90a73ba78a91df661d68064 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 14:45:01 +0100 Subject: s4:libcli/ldap: don't use 'void **out' as arguments as the behavior is not defined in C. metze --- source4/libcli/ldap/ldap_controls.c | 49 ++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 17 deletions(-) (limited to 'source4') diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 109837c2bf..487ea61222 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -28,12 +28,13 @@ struct control_handler { const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void **out); + bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); }; -static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sort_resp_control *lsrc; @@ -77,8 +78,9 @@ static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB attr; DATA_BLOB rule; struct asn1_data *data = asn1_init(mem_ctx); @@ -156,8 +158,9 @@ static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data; struct ldb_extended_dn_control *ledc; @@ -196,8 +199,9 @@ static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_sd_flags_control *lsdfc; @@ -229,8 +233,9 @@ static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_search_options_control *lsoc; @@ -262,8 +267,9 @@ static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void **ou return true; } -static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_paged_control *lprc; @@ -310,8 +316,9 @@ static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void **out return true; } -static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB cookie; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_dirsync_control *ldc; @@ -365,8 +372,9 @@ static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void **out) /* seem that this controls has 2 forms one in case it is used with * a Search Request and another when used ina Search Response */ -static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB source_attribute; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_asq_control *lac; @@ -425,8 +433,9 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -434,8 +443,9 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -443,8 +453,9 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -452,8 +463,9 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -461,8 +473,9 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * return true; } -static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; if (in.length != 0) { return false; } @@ -470,8 +483,9 @@ static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB assertion_value, context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_req_control *lvrc; @@ -582,8 +596,9 @@ static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void **out) return true; } -static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; DATA_BLOB context_id; struct asn1_data *data = asn1_init(mem_ctx); struct ldb_vlv_resp_control *lvrc; @@ -1132,7 +1147,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) return true; } -static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void **out) +static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; -- cgit From f6b0a99cefaedfa7642af31f8fcc4457bacb07a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 24 Feb 2009 16:49:26 +0100 Subject: libcli/ldap: move generic ldap control encoding code to ldap_message.c As they can we static there, we pass the specific handlers as parameter where we need to support controls. metze --- source4/ldap_server/ldap_server.c | 4 +- source4/libcli/cldap/cldap.c | 12 ++-- source4/libcli/ldap/ldap_client.c | 4 +- source4/libcli/ldap/ldap_controls.c | 131 ++---------------------------------- 4 files changed, 14 insertions(+), 137 deletions(-) (limited to 'source4') diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index da44c02aa8..a924024160 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -104,7 +104,7 @@ static void ldapsrv_process_message(struct ldapsrv_connection *conn, bool ret; msg = call->replies->msg; - if (!ldap_encode(msg, &b, call)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &b, call)) { DEBUG(0,("Failed to encode ldap reply of type %d\n", msg->type)); talloc_free(call); return; @@ -150,7 +150,7 @@ static NTSTATUS ldapsrv_decode(void *private_data, DATA_BLOB blob) return NT_STATUS_NO_MEMORY; } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index 8d2e2e374c..b18ba12b1f 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -108,7 +108,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } /* this initial decode is used to find the message id */ - status = ldap_decode(asn1, ldap_msg); + status = ldap_decode(asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode ldap message: %s\n", nt_errstr(status))); talloc_free(tmp_ctx); @@ -343,7 +343,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, goto failed; } - if (!ldap_encode(msg, &req->encoded, req)) { + if (!ldap_encode(msg, NULL, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); goto failed; @@ -396,7 +396,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultEntry; msg->r.SearchResultEntry = *io->response; - if (!ldap_encode(msg, &blob1, req)) { + if (!ldap_encode(msg, NULL, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -409,7 +409,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) msg->type = LDAP_TAG_SearchResultDone; msg->r.SearchResultDone = *io->result; - if (!ldap_encode(msg, &blob2, req)) { + if (!ldap_encode(msg, NULL, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; @@ -463,7 +463,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, ldap_msg = talloc(mem_ctx, struct ldap_message); NT_STATUS_HAVE_NO_MEMORY(ldap_msg); - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search reply: %s\n", nt_errstr(status))); talloc_free(req); @@ -479,7 +479,7 @@ NTSTATUS cldap_search_recv(struct cldap_request *req, *io->out.response = ldap_msg->r.SearchResultEntry; /* decode the 2nd part */ - status = ldap_decode(req->asn1, ldap_msg); + status = ldap_decode(req->asn1, NULL, ldap_msg); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Failed to decode cldap search result entry: %s\n", nt_errstr(status))); talloc_free(req); diff --git a/source4/libcli/ldap/ldap_client.c b/source4/libcli/ldap/ldap_client.c index 3e54d7fff0..304a2e1253 100644 --- a/source4/libcli/ldap/ldap_client.c +++ b/source4/libcli/ldap/ldap_client.c @@ -200,7 +200,7 @@ static NTSTATUS ldap_recv_handler(void *private_data, DATA_BLOB blob) return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR); } - status = ldap_decode(asn1, msg); + status = ldap_decode(asn1, samba_ldap_control_handlers(), msg); if (!NT_STATUS_IS_OK(status)) { asn1_free(asn1); return status; @@ -608,7 +608,7 @@ _PUBLIC_ struct ldap_request *ldap_request_send(struct ldap_connection *conn, msg->messageid = req->messageid; - if (!ldap_encode(msg, &req->data, req)) { + if (!ldap_encode(msg, samba_ldap_control_handlers(), &req->data, req)) { status = NT_STATUS_INTERNAL_ERROR; goto failed; } diff --git a/source4/libcli/ldap/ldap_controls.c b/source4/libcli/ldap/ldap_controls.c index 487ea61222..7949758a80 100644 --- a/source4/libcli/ldap/ldap_controls.c +++ b/source4/libcli/ldap/ldap_controls.c @@ -26,12 +26,6 @@ #include "libcli/ldap/ldap_proto.h" #include "dsdb/samdb/samdb.h" -struct control_handler { - const char *oid; - bool (*decode)(void *mem_ctx, DATA_BLOB in, void *_out); - bool (*encode)(void *mem_ctx, void *in, DATA_BLOB *out); -}; - static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out) { void **out = (void **)_out; @@ -435,7 +429,6 @@ static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -445,7 +438,6 @@ static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -455,7 +447,6 @@ static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -465,7 +456,6 @@ static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out) static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -475,7 +465,6 @@ static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void * static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out) { - void **out = (void **)_out; if (in.length != 0) { return false; } @@ -1149,6 +1138,7 @@ static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out) static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) { + void **out = (void **)_out; struct asn1_data *data = asn1_init(mem_ctx); struct dsdb_openldap_dereference_result_control *control; struct dsdb_openldap_dereference_result **r = NULL; @@ -1216,7 +1206,7 @@ static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out) return true; } -struct control_handler ldap_known_controls[] = { +static const struct ldap_control_handler ldap_known_controls[] = { { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request }, { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request }, { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request }, @@ -1240,121 +1230,8 @@ struct control_handler ldap_known_controls[] = { { NULL, NULL, NULL } }; -bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value, struct ldb_control *ctrl) +const struct ldap_control_handler *samba_ldap_control_handlers(void) { - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].decode || !ldap_known_controls[i].decode(mem_ctx, value, &ctrl->data)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - return true; + return ldap_known_controls; } -bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl, DATA_BLOB *value) -{ - DATA_BLOB oid; - - if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_read_OctetString(data, mem_ctx, &oid)) { - return false; - } - ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length); - if (!ctrl->oid) { - return false; - } - - if (asn1_peek_tag(data, ASN1_BOOLEAN)) { - bool critical; - if (!asn1_read_BOOLEAN(data, &critical)) { - return false; - } - ctrl->critical = critical; - } else { - ctrl->critical = false; - } - - ctrl->data = NULL; - - if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) { - *value = data_blob(NULL, 0); - goto end_tag; - } - - if (!asn1_read_OctetString(data, mem_ctx, value)) { - return false; - } - -end_tag: - if (!asn1_end_tag(data)) { - return false; - } - - return true; -} - -bool ldap_encode_control(void *mem_ctx, struct asn1_data *data, struct ldb_control *ctrl) -{ - DATA_BLOB value; - int i; - - for (i = 0; ldap_known_controls[i].oid != NULL; i++) { - if (strcmp(ldap_known_controls[i].oid, ctrl->oid) == 0) { - if (!ldap_known_controls[i].encode) { - if (ctrl->critical) { - return false; - } else { - /* not encoding this control */ - return true; - } - } - if (!ldap_known_controls[i].encode(mem_ctx, ctrl->data, &value)) { - return false; - } - break; - } - } - if (ldap_known_controls[i].oid == NULL) { - return false; - } - - if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { - return false; - } - - if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) { - return false; - } - - if (ctrl->critical) { - if (!asn1_write_BOOLEAN(data, ctrl->critical)) { - return false; - } - } - - if (!ctrl->data) { - goto pop_tag; - } - - if (!asn1_write_OctetString(data, value.data, value.length)) { - return false; - } - -pop_tag: - if (!asn1_pop_tag(data)) { - return false; - } - - return true; -} -- cgit From 365925eea308673f15e03d81b69f04b8908468e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 11:37:57 -0800 Subject: Start fixing Solaris build failures. Jeremy. --- source4/heimdal/kuser/kuser_locl.h | 2 +- source4/heimdal/lib/krb5/krb5_locl.h | 2 +- source4/heimdal_build/internal.m4 | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4') diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h index 21e9776975..eed9e00af6 100644 --- a/source4/heimdal/kuser/kuser_locl.h +++ b/source4/heimdal/kuser/kuser_locl.h @@ -88,7 +88,7 @@ #include #endif -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) gettext(x) #define NP_(x,y) (x) diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 1a490392a9..ced722f2d9 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -118,7 +118,7 @@ struct sockaddr_dl; #define HEIMDAL_TEXTDOMAIN "heimdal_krb5" -#ifdef LIBINTL +#ifdef HAVE_LIBINTL_H #include #define N_(x,y) dgettext(HEIMDAL_TEXTDOMAIN, x) #else diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index b2f64a6825..50a3c8adda 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -69,7 +69,8 @@ AC_CHECK_HEADERS([ \ ttyname.h \ netinet/in.h \ netinet/in6.h \ - netinet6/in6.h + netinet6/in6.h \ + libintl.h ]) AC_CHECK_FUNCS([ \ -- cgit From e3746ac922c29f90d0dbb23a76f5387daf21c8c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Feb 2009 21:08:07 +0100 Subject: Fix some C++ warnings --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 33 ++++++++++++++++++--------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'source4') diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 0fa638e863..f1c063ed90 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -47,7 +47,8 @@ struct server_pipe_state { static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerReqChallenge *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; ZERO_STRUCTP(r->out.return_credentials); @@ -76,7 +77,8 @@ static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_cal static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerAuthenticate3 *r) { - struct server_pipe_state *pipe_state = dce_call->context->private_data; + struct server_pipe_state *pipe_state = + (struct server_pipe_state *)dce_call->context->private_data; struct creds_CredentialState *creds; void *sam_ctx; struct samr_Password *mach_pwd; @@ -148,7 +150,9 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, trust_dom_attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, + mem_ctx, NULL, &msgs, + trust_dom_attrs, "(&(trustPartner=%s)(objectclass=trustedDomain))", encoded_account); @@ -179,7 +183,8 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(struct dcesrv_call_state *dce_ca } /* pull the user attributes */ - num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, + num_records = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + NULL, &msgs, attrs, "(&(sAMAccountName=%s)(objectclass=user))", ldb_binary_encode_string(mem_ctx, account_name)); @@ -848,13 +853,14 @@ static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_C return WERR_DS_SERVICE_UNAVAILABLE; } - domain_dn = samdb_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_domain_to_dn((struct ldb_context *)sam_ctx, mem_ctx, r->in.domainname); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1218,13 +1224,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); } - domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx, + domain_dn = samdb_dns_domain_to_dn((struct ldb_context *)sam_ctx, + mem_ctx, r->in.domain_name); if (domain_dn == NULL) { return WERR_DS_SERVICE_UNAVAILABLE; } - ret = gendb_search_dn(sam_ctx, mem_ctx, domain_dn, &res, attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, + domain_dn, &res, attrs); if (ret != 1) { return WERR_NO_SUCH_DOMAIN; } @@ -1377,9 +1385,11 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - partitions_basedn = samdb_partitions_dn(sam_ctx, mem_ctx); + partitions_basedn = samdb_partitions_dn((struct ldb_context *)sam_ctx, + mem_ctx); - ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); + ret = gendb_search_dn((struct ldb_context *)sam_ctx, mem_ctx, NULL, + &dom_res, dom_attrs); if (ret == -1) { return WERR_GENERAL_FAILURE; } @@ -1387,7 +1397,8 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce return WERR_GENERAL_FAILURE; } - ret = gendb_search(sam_ctx, mem_ctx, partitions_basedn, &ref_res, ref_attrs, + ret = gendb_search((struct ldb_context *)sam_ctx, mem_ctx, + partitions_basedn, &ref_res, ref_attrs, "(&(objectClass=crossRef)(ncName=%s))", ldb_dn_get_linearized(dom_res[0]->dn)); if (ret == -1) { -- cgit From 3a88316e233079199117731756d35d0aea4670e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 12:19:06 -0800 Subject: Fix the build. Looks like no one ever compiled this on a system with a libintl.h before. Jeremy. --- source4/client/mount.cifs.c | 2 ++ source4/heimdal/kuser/kinit.c | 2 ++ source4/heimdal/lib/krb5/context.c | 12 ++++++++++++ 3 files changed, 16 insertions(+) (limited to 'source4') diff --git a/source4/client/mount.cifs.c b/source4/client/mount.cifs.c index 7167859d7b..899c90cefd 100644 --- a/source4/client/mount.cifs.c +++ b/source4/client/mount.cifs.c @@ -313,8 +313,10 @@ int main(int argc, char ** argv) FILE * pmntfile; /* setlocale(LC_ALL, ""); +#if defined(LOCALEDIR) bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); */ +#endif if(argc && argv) { thisprogram = argv[0]; diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index d1ef776716..fbb2d2287b 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -726,8 +726,10 @@ main (int argc, char **argv) setprogname (argv[0]); setlocale (LC_ALL, ""); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR); textdomain("heimdal_kuser"); +#endif ret = krb5_init_context (&context); if (ret == KRB5_CONFIG_BADFORMAT) diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index aa35a184c0..127dfa117d 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -295,7 +295,9 @@ krb5_init_context(krb5_context *context) *context = NULL; /* should have a run_once */ +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(HEIMDAL_TEXTDOMAIN, HEIMDAL_LOCALEDIR); +#endif p = calloc(1, sizeof(*p)); if(!p) @@ -836,20 +838,30 @@ krb5_init_ets(krb5_context context) { if(context->et_list == NULL){ krb5_add_et_list(context, initialize_krb5_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_krb5, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_asn1_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_asn1, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_heim_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_heim, HEIMDAL_LOCALEDIR); +#endif krb5_add_et_list(context, initialize_k524_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_k524, HEIMDAL_LOCALEDIR); +#endif #ifdef PKINIT krb5_add_et_list(context, initialize_hx_error_table_r); +#if defined(HEIMDAL_LOCALEDIR) bindtextdomain(COM_ERR_BINDDOMAIN_hx, HEIMDAL_LOCALEDIR); +#endif #endif } } -- cgit From a028e9640b54554f4ae036f46cc16ae73f00884e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 15:27:47 -0800 Subject: Make S4 build on OpenSolaris. Jeremy. --- source4/lib/tls/config.m4 | 2 ++ source4/lib/tls/config.mk | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/lib/tls/config.m4 b/source4/lib/tls/config.m4 index 0bafc5ddf1..c46a009e3d 100644 --- a/source4/lib/tls/config.m4 +++ b/source4/lib/tls/config.m4 @@ -40,4 +40,6 @@ if test x$use_gnutls = xyes; then AC_CHECK_TYPES([gnutls_datum_t],,,[#include "gnutls/gnutls.h"]) AC_DEFINE(ENABLE_GNUTLS,1,[Whether we have gnutls support (SSL)]) AC_CHECK_HEADERS(gcrypt.h) + AC_CHECK_LIB_EXT(gcrypt, GCRYPT_LIBS, gcry_control) + SMB_EXT_LIB(GCRYPT, $GCRYPT_LIBS) fi diff --git a/source4/lib/tls/config.mk b/source4/lib/tls/config.mk index ff1eedfd5d..0e1978cc1b 100644 --- a/source4/lib/tls/config.mk +++ b/source4/lib/tls/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::LIBTLS] PUBLIC_DEPENDENCIES = \ - LIBTALLOC GNUTLS LIBSAMBA-HOSTCONFIG samba_socket + LIBTALLOC GNUTLS GCRYPT LIBSAMBA-HOSTCONFIG samba_socket LIBTLS_OBJ_FILES = $(addprefix $(libtlssrcdir)/, tls.o tlscert.o) -- cgit From 503d15e8df9075ea9cf8b2d260487e68fc68f559 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Wed, 25 Feb 2009 10:27:19 +1100 Subject: Updates to the recent cn=config support for the OpenLDAP backend - removed workaround for olcSyncprovConfig - creation (works perfect now with 2.4.15, release was today) - added 1 message-helpline, which is displayed when running provision-backend with olc and/or mmr setup - corrected 1 wrong slapcommand-helpline - slapd.conf is removed now in case of olc-setup - added 1 copyright-line to provision.py and provision-backend Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision.py | 24 ++++++------------------ source4/setup/olcOverlay={0}syncprov.ldif | 11 ----------- source4/setup/provision-backend | 5 +++-- 3 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 source4/setup/olcOverlay={0}syncprov.ldif (limited to 'source4') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8442c24d71..c817bffbdd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -4,6 +4,7 @@ # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -100,8 +101,6 @@ class ProvisionPaths(object): self.olcdir = None self.olslaptest = None self.olcseedldif = None - self.olcsyncprovdir = None - self.olcsyncprovfile = None class ProvisionNames(object): @@ -278,10 +277,6 @@ def provision_paths_from_lp(lp, dnsdomain): "slapd.d") paths.olcseedldif = os.path.join(paths.ldapdir, "olc_seed.ldif") - paths.olcsyncprovdir = os.path.join(paths.olcdir, - "cn=config/olcDatabase={0}config") - paths.olcsyncprovfile = os.path.join(paths.olcsyncprovdir, - "olcOverlay={0}syncprov.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1479,7 +1474,7 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" if ol_olc != "yes" and ol_mmr_urls is not None: - slapdcommand="Start slapd with: slapd -F " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h \"" + ldapi_uri + " ldap://:\"" if ol_olc == "yes" and ol_mmr_urls is not None: slapdcommand="Start slapd with: slapd -F " + paths.olcdir + " -h \"" + ldapi_uri + " ldap://:\"" @@ -1505,6 +1500,8 @@ def provision_backend(setup_dir=None, message=None, message("LDAP admin password: %s" % adminpass) message(slapdcommand) + if ol_olc == "yes" or ol_mmr_urls is not None: + message("Attention to slapd-Port: must be different than 389!") assert isinstance(ldap_backend_type, str) assert isinstance(ldapuser, str) assert isinstance(adminpass, str) @@ -1528,19 +1525,10 @@ def provision_backend(setup_dir=None, message=None, paths.olslaptest = str(ol_slaptest) olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir + " >/dev/null 2>&1" os.system(olc_command) - #os.remove(paths.slapdconf) - # use line below for debugging during olc-conversion with slaptest + os.remove(paths.slapdconf) + # use line below for debugging during olc-conversion with slaptest, instead of olc_command above #olc_command = paths.olslaptest + " -f" + paths.slapdconf + " -F" + paths.olcdir" - # workaround, if overlay syncprov is was not created properly during conversion to cn=config. - # otherwise, cn=config won't be replicated - if ol_olc == "yes" and ol_mmr_urls is not None: - if not os.path.exists(paths.olcsyncprovdir): - os.makedirs(paths.olcsyncprovdir, 0770) - setup_file(setup_path("olcOverlay={0}syncprov.ldif"), - os.path.join(paths.olcsyncprovdir, "olcOverlay={0}syncprov.ldif"), {}) - - def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. diff --git a/source4/setup/olcOverlay={0}syncprov.ldif b/source4/setup/olcOverlay={0}syncprov.ldif deleted file mode 100644 index 4f5b513c67..0000000000 --- a/source4/setup/olcOverlay={0}syncprov.ldif +++ /dev/null @@ -1,11 +0,0 @@ -dn: olcOverlay={0}syncprov -objectClass: olcOverlayConfig -objectClass: olcSyncProvConfig -olcOverlay: {0}syncprov -structuralObjectClass: olcSyncProvConfig -entryUUID: 41df5aca-785a-102d-9077-999999999999 -creatorsName: cn=config -createTimestamp: 20090116201111Z -entryCSN: 20090116201111.111111Z#000000#000#000000 -modifiersName: cn=config -modifyTimestamp: 20090116201111Z diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend index 20e4420414..28e73ae302 100755 --- a/source4/setup/provision-backend +++ b/source4/setup/provision-backend @@ -4,6 +4,7 @@ # provision a Samba4 server # Copyright (C) Jelmer Vernooij 2007-2008 # Copyright (C) Andrew Bartlett 2008 +# Copyright (C) Oliver Liebel 2008-2009 # # Based on the original in EJS: # Copyright (C) Andrew Tridgell 2005 @@ -65,9 +66,9 @@ parser.add_option("--server-role", type="choice", metavar="ROLE", parser.add_option("--targetdir", type="string", metavar="DIR", help="Set target directory") parser.add_option("--ol-mmr-urls", type="string", metavar="LDAPSERVER", - help="List of LDAP-URLS [ ldap://:port/ (where port != 389) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") + help="List of LDAP-URLS [ ldap://:/ (where has to be different from 389!) ] separated with whitespaces for use with OpenLDAP-MMR (Multi-Master-Replication)") parser.add_option("--ol-olc", type="choice", metavar="OPENLDAP-OLC", - help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'", + help="To setup OpenLDAP-Backend with Online-Configuration [slapd.d] choose 'yes'. Note: Only OpenLDAP-Versions greater or equal 2.4.15 should be used!", choices=["yes", "no"]) parser.add_option("--ol-slaptest", type="string", metavar="SLAPTEST-PATH", help="Path to slaptest-binary [e.g.:'/usr/local/sbin']. Only for use with --ol-olc='yes'") -- cgit From cde5724780c0e52705e0f6e7cd41e0c884afbb40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Feb 2009 17:32:22 -0800 Subject: Added torture test from a usage case from the Apple OS/X client. Setting an attribute on a stream fnum must change the attribute on the base file. Jeremy. --- source4/torture/raw/streams.c | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) (limited to 'source4') diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index 0622e0809d..bf87bd224f 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1535,6 +1535,121 @@ static bool test_stream_large_streaminfo(struct torture_context *tctx, return ret; } +/* Test the effect of setting attributes on a stream. */ +static bool test_stream_attributes(struct torture_context *tctx, + struct smbcli_state *cli, + TALLOC_CTX *mem_ctx) +{ + bool ret = true; + NTSTATUS status; + union smb_open io; + const char *fname = BASEDIR "\\stream_attr.txt"; + const char *stream = "Stream One:$DATA"; + const char *fname_stream; + int fnum = -1; + union smb_fileinfo finfo; + union smb_setfileinfo sfinfo; + time_t basetime = (time(NULL) - 86400) & ~1; + + printf ("(%s) testing attribute setting on stream\n", __location__); + + fname_stream = talloc_asprintf(mem_ctx, "%s:%s", fname, stream); + + /* Create a file with a stream with attribute FILE_ATTRIBUTE_ARCHIVE. */ + ret = create_file_with_stream(tctx, cli, mem_ctx, fname, + fname_stream); + if (!ret) { + goto done; + } + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_BASIC_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + CHECK_STATUS(status, NT_STATUS_OK); + + if (finfo.basic_info.out.attrib != FILE_ATTRIBUTE_ARCHIVE) { + printf("(%s) Incorrect attrib %x - should be %x\n", \ + __location__, (unsigned int)finfo.basic_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_ARCHIVE); + ret = false; + goto done; + } + + /* Now open the stream name. */ + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.flags = 0; + io.ntcreatex.in.access_mask = (SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA| + SEC_FILE_APPEND_DATA|SEC_STD_READ_CONTROL|SEC_FILE_WRITE_ATTRIBUTE); + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.file_attr = 0; + io.ntcreatex.in.share_access = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname_stream; + + status = smb_raw_open(cli->tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + + /* Change the attributes + time on the stream fnum. */ + ZERO_STRUCT(sfinfo); + sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY; + unix_to_nt_time(&sfinfo.basic_info.in.write_time, basetime); + + sfinfo.generic.level = RAW_SFILEINFO_BASIC_INFORMATION; + sfinfo.generic.in.file.fnum = fnum; + status = smb_raw_setfileinfo(cli->tree, &sfinfo); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { + printf("(%s) %s - %s (should be %s)\n", __location__, "SETATTR", + nt_errstr(status), nt_errstr(NT_STATUS_OK)); + ret = false; + goto done; + } + + smbcli_close(cli->tree, fnum); + fnum = -1; + + ZERO_STRUCT(finfo); + finfo.generic.level = RAW_FILEINFO_ALL_INFO; + finfo.generic.in.file.path = fname; + status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); + if (!NT_STATUS_IS_OK(status)) { + printf("(%s) %s pathinfo - %s\n", __location__, "SETATTRE", nt_errstr(status)); + ret = false; + goto done; + } + + if (finfo.all_info.out.attrib != FILE_ATTRIBUTE_READONLY) { + printf("(%s) attrib incorrect. Was 0x%x, should be 0x%x\n", + __location__, + (unsigned int)finfo.all_info.out.attrib, + (unsigned int)FILE_ATTRIBUTE_READONLY); + ret = false; + goto done; + } + + if (nt_time_to_unix(finfo.all_info.out.write_time) != basetime) { + printf("(%s) time incorrect.\n", + __location__); + ret = false; + goto done; + } + + done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smbcli_unlink(cli->tree, fname); + return ret; +} + /* basic testing of streams calls */ @@ -1566,6 +1681,10 @@ bool torture_raw_streams(struct torture_context *torture, smb_raw_exit(cli->session); ret &= test_stream_create_disposition(torture, cli, torture); smb_raw_exit(cli->session); + + ret &= test_stream_attributes(torture, cli, torture); + smb_raw_exit(cli->session); + /* ret &= test_stream_large_streaminfo(torture, cli, torture); */ /* smb_raw_exit(cli->session); */ -- cgit From dc0e46afb7018a1da666729c6d61e8ea85dcf07d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 08:42:33 +0100 Subject: s4:build: add some comments to the SMB_EXT_LIB() definition metze --- source4/build/m4/public.m4 | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4') diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index 1927e9977f..ffdf92f784 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -157,6 +157,13 @@ mkinclude $1 " ]) +dnl +dnl SMB_EXT_LIB() just specifies the details of the library. +dnl Note: the library isn't enabled by default. +dnl You need to enable it with SMB_ENABLE(name) if configure +dnl find it should be used. E.g. it should not be enabled +dnl if the library is present, but the header file is missing. +dnl dnl SMB_EXT_LIB(name,libs,cflags,cppflags,ldflags) AC_DEFUN([SMB_EXT_LIB], [ -- cgit From eb5efd1978acd38cf6cc97e067b5105743ca5469 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 24 Feb 2009 23:38:42 -0800 Subject: s4 heimdal: Link libintl correctly --- source4/heimdal_build/internal.m4 | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4') diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 50a3c8adda..a48777fab1 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -170,6 +170,12 @@ SMB_ENABLE(OPENPTY,YES) SMB_EXT_LIB(OPENPTY,[${OPENPTY_LIBS}],[${OPENPTY_CFLAGS}],[${OPENPTY_CPPFLAGS}],[${OPENPTY_LDFLAGS}]) +AC_CHECK_LIB_EXT(intl, INTL_LIBS, gettext) + +SMB_ENABLE(INTL,YES) + +SMB_EXT_LIB(INTL, $INTL_LIBS) + smb_save_LIBS=$LIBS RESOLV_LIBS="" LIBS="" -- cgit From 2bd8cacf0e5ed6965f5791c4a86320d4978d9b15 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Feb 2009 15:05:24 +0100 Subject: s4:lib/events: map TEVENT_DEBUG_TRACE to debug level 10 metze --- source4/lib/events/tevent_s4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c index a05ac0796f..89ca7bbe5c 100644 --- a/source4/lib/events/tevent_s4.c +++ b/source4/lib/events/tevent_s4.c @@ -41,7 +41,7 @@ static void ev_wrap_debug(void *context, enum tevent_debug_level level, samba_level = 2; break; case TEVENT_DEBUG_TRACE: - samba_level = 5; + samba_level = 10; break; }; -- cgit From fd3f3e68f2e6be0196473f641f8edb41e40ca761 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 25 Feb 2009 10:02:41 -0500 Subject: Use stdbool.h instead of manually defining bool --- source4/lib/ldb/include/ldb.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'source4') diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index eb8e0ed11e..be41151409 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -46,16 +46,7 @@ #define _LDB_H_ 1 /*! \endcond */ -#ifndef bool -typedef int bool; -#endif -#ifndef true -#define true 1 -#endif -#ifndef false -#define false 0 -#endif - +#include #include "talloc.h" #include "tevent.h" #include "ldb_errors.h" -- cgit From f90250b54923588d756a02e76876fc66a6c68074 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Wed, 25 Feb 2009 11:27:37 -0800 Subject: s4: make libintl a build dependency of heimdal_krb5 so all dependent binaries are linked properly --- source4/heimdal_build/internal.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 9e32898a07..77dbf0fb98 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -255,7 +255,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \ CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/krb5 -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/com_err PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_PKINIT_ASN1 HEIMDAL_WIND \ HEIMDAL_KRB5_ASN1 HEIMDAL_HX509 HEIMDAL_HCRYPTO \ - LIBNETIF LIBSAMBA-HOSTCONFIG + LIBNETIF LIBSAMBA-HOSTCONFIG INTL PUBLIC_DEPENDENCIES = HEIMDAL_COM_ERR # End SUBSYSTEM HEIMDAL_KRB5 ####################### -- cgit From 666cc916ebea618fbf7bfed99dbfff38326189fa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 16:17:44 +0100 Subject: s4-smbtorture: add test_GetPrintProcessorDirectory to RPC-SPOOLSS. Guenther --- source4/torture/rpc/spoolss.c | 64 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'source4') diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index de600e8fb3..f8a66e7753 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -168,6 +168,69 @@ static bool test_EnumPorts(struct torture_context *tctx, return true; } +static bool test_GetPrintProcessorDirectory(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct test_spoolss_context *ctx) +{ + NTSTATUS status; + struct spoolss_GetPrintProcessorDirectory r; + struct { + uint16_t level; + const char *server; + } levels[] = {{ + .level = 1, + .server = NULL + },{ + .level = 1, + .server = "" + },{ + .level = 78, + .server = "" + },{ + .level = 1, + .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) + },{ + .level = 1024, + .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) + } + }; + int i; + uint32_t needed; + + for (i=0;iserver_handle, true); ret &= test_EnumPorts(torture, p, ctx); ret &= test_GetPrinterDriverDirectory(torture, p, ctx); + ret &= test_GetPrintProcessorDirectory(torture, p, ctx); ret &= test_EnumPrinterDrivers(torture, p, ctx); ret &= test_EnumMonitors(torture, p, ctx); ret &= test_EnumPrintProcessors(torture, p, ctx); -- cgit From 6cd30a351a13822a557f20de3abe04bd8b2e3112 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 21:10:44 +0100 Subject: s4-smbtorture: expand RPC-SPOOLSS enumform and getform tests for level 2 forms. Guenther --- source4/torture/rpc/spoolss.c | 74 ++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 32 deletions(-) (limited to 'source4') diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index f8a66e7753..04c9768ea8 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -742,7 +742,8 @@ static bool test_ClosePrinter(struct torture_context *tctx, static bool test_GetForm(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle, - const char *form_name) + const char *form_name, + uint32_t level) { NTSTATUS status; struct spoolss_GetForm r; @@ -750,12 +751,12 @@ static bool test_GetForm(struct torture_context *tctx, r.in.handle = handle; r.in.form_name = form_name; - r.in.level = 1; + r.in.level = level; r.in.buffer = NULL; r.in.offered = 0; r.out.needed = &needed; - torture_comment(tctx, "Testing GetForm\n"); + torture_comment(tctx, "Testing GetForm level %d\n", r.in.level); status = dcerpc_spoolss_GetForm(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetForm failed"); @@ -787,45 +788,54 @@ static bool test_EnumForms(struct torture_context *tctx, bool ret = true; uint32_t needed; uint32_t count; + uint32_t levels[] = { 1, 2 }; + int i; - r.in.handle = handle; - r.in.level = 1; - r.in.buffer = NULL; - r.in.offered = 0; - r.out.needed = &needed; - r.out.count = &count; + for (i=0; i Date: Wed, 25 Feb 2009 23:04:52 +0100 Subject: s4-spoolss: implement dcesrv_spoolss_GetPrintProcessorDirectory. Guenther --- source4/ntptr/ntptr.h | 3 ++ source4/ntptr/ntptr_interface.c | 9 ++++++ source4/ntptr/simple_ldb/ntptr_simple_ldb.c | 43 +++++++++++++++++++++++++++++ source4/rpc_server/spoolss/dcesrv_spoolss.c | 14 +++++++++- 4 files changed, 68 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/ntptr/ntptr.h b/source4/ntptr/ntptr.h index 24c467fe65..91817a202f 100644 --- a/source4/ntptr/ntptr.h +++ b/source4/ntptr/ntptr.h @@ -74,6 +74,7 @@ struct spoolss_EnumForms; struct spoolss_EnumPorts; struct spoolss_EnumPrintProcessors; struct spoolss_XcvData; +struct spoolss_GetPrintProcessorDirectory; /* the ntptr operations structure - contains function pointers to the backend implementations of each operation */ @@ -144,6 +145,8 @@ struct ntptr_ops { /* PrintProcessor functions */ WERROR (*EnumPrintProcessors)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, struct spoolss_EnumPrintProcessors *r); + WERROR (*GetPrintProcessorDirectory)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r); /* Printer functions */ WERROR (*EnumPrinters)(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, diff --git a/source4/ntptr/ntptr_interface.c b/source4/ntptr/ntptr_interface.c index 109a9f560b..b65a2e32cd 100644 --- a/source4/ntptr/ntptr_interface.c +++ b/source4/ntptr/ntptr_interface.c @@ -263,6 +263,15 @@ WERROR ntptr_EnumPrintProcessors(struct ntptr_context *ntptr, TALLOC_CTX *mem_ct return ntptr->ops->EnumPrintProcessors(ntptr, mem_ctx, r); } +WERROR ntptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r) +{ + if (!ntptr->ops->GetPrintProcessorDirectory) { + return WERR_NOT_SUPPORTED; + } + return ntptr->ops->GetPrintProcessorDirectory(ntptr, mem_ctx, r); +} + /* Printer functions */ WERROR ntptr_EnumPrinters(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index c570b03a35..459babce0e 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -750,6 +750,47 @@ static WERROR sptr_GetPrinterForm(struct ntptr_GenericHandle *printer, TALLOC_CT return WERR_OK; } +static WERROR sptr_GetPrintProcessorDirectory(struct ntptr_context *ntptr, TALLOC_CTX *mem_ctx, + struct spoolss_GetPrintProcessorDirectory *r) +{ + union spoolss_PrintProcessorDirectoryInfo *info; + const char *prefix; + const char *postfix; + + /* + * NOTE: normally r->in.level is 1, but both w2k3 and nt4 sp6a + * are ignoring the r->in.level completely, so we do :-) + */ + + /* + * TODO: check the server name is ours + * - if it's a invalid UNC then return WERR_INVALID_NAME + * - if it's the wrong host name return WERR_INVALID_PARAM + * - if it's "" then we need to return a local WINDOWS path + */ + if (!r->in.server || !r->in.server[0]) { + prefix = "C:\\PRTPROCS"; + } else { + prefix = talloc_asprintf(mem_ctx, "%s\\prnproc$", r->in.server); + W_ERROR_HAVE_NO_MEMORY(prefix); + } + + if (r->in.environment && strcmp(SPOOLSS_ARCHITECTURE_NT_X86, r->in.environment) == 0) { + postfix = "W32X86"; + } else { + return WERR_INVALID_ENVIRONMENT; + } + + info = talloc(mem_ctx, union spoolss_PrintProcessorDirectoryInfo); + W_ERROR_HAVE_NO_MEMORY(info); + + info->info1.directory_name = talloc_asprintf(mem_ctx, "%s\\%s", prefix, postfix); + W_ERROR_HAVE_NO_MEMORY(info->info1.directory_name); + + r->out.info = info; + return WERR_OK; +} + /* initialialise the simble ldb backend, registering ourselves with the ntptr subsystem @@ -793,6 +834,8 @@ static const struct ntptr_ops ntptr_simple_ldb_ops = { /* PrintProcessor functions */ /* .EnumPrintProcessors = sptr_EnumPrintProcessors, */ + .GetPrintProcessorDirectory = sptr_GetPrintProcessorDirectory, + /* Printer functions */ .EnumPrinters = sptr_EnumPrinters, .OpenPrinter = sptr_OpenPrinter, diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 33c657cc1b..89b93bbaa4 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -454,7 +454,19 @@ static WERROR dcesrv_spoolss_EnumPrintProcessors(struct dcesrv_call_state *dce_c static WERROR dcesrv_spoolss_GetPrintProcessorDirectory(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct spoolss_GetPrintProcessorDirectory *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct ntptr_context *ntptr = talloc_get_type(dce_call->context->private_data, struct ntptr_context); + WERROR status; + struct smb_iconv_convenience *ic = lp_iconv_convenience(ntptr->lp_ctx); + + status = dcesrv_spoolss_check_server_name(dce_call, mem_ctx, r->in.server); + W_ERROR_NOT_OK_RETURN(status); + + status = ntptr_GetPrintProcessorDirectory(ntptr, mem_ctx, r); + W_ERROR_NOT_OK_RETURN(status); + + *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, ic, r->out.info, r->in.level); + r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL); + return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER); } -- cgit From 8bf0c256d7f06fe7d0abf031921abd83e6956c8b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 9 Feb 2009 22:22:45 +0100 Subject: s4-smbtorture: add test_AddJob test to RPC-SPOOLSS test. Guenther --- source4/torture/rpc/spoolss.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source4') diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c index 04c9768ea8..9d8bc4b186 100644 --- a/source4/torture/rpc/spoolss.c +++ b/source4/torture/rpc/spoolss.c @@ -1045,6 +1045,33 @@ static bool test_SetJob(struct torture_context *tctx, return true; } +static bool test_AddJob(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct policy_handle *handle) +{ + NTSTATUS status; + struct spoolss_AddJob r; + uint32_t needed; + + r.in.level = 0; + r.in.handle = handle; + r.in.offered = 0; + r.out.needed = &needed; + + torture_comment(tctx, "Testing AddJob\n"); + + status = dcerpc_spoolss_AddJob(p, tctx, &r); + torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "AddJob failed"); + + r.in.level = 1; + + status = dcerpc_spoolss_AddJob(p, tctx, &r); + torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, "AddJob failed"); + + return true; +} + + static bool test_EnumJobs(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) @@ -1084,6 +1111,7 @@ static bool test_EnumJobs(struct torture_context *tctx, info = r.out.info; for (j = 0; j < count; j++) { + test_GetJob(tctx, p, handle, info[j].info1.job_id); test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE); test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME); @@ -1163,6 +1191,7 @@ static bool test_DoPrintTest(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed"); torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed"); + ret &= test_AddJob(tctx, p, handle); ret &= test_EnumJobs(tctx, p, handle); ret &= test_SetJob(tctx, p, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE); -- cgit From 7e01ec5560e8193c8e8853ba49c0ee625956c1fd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Feb 2009 23:42:03 +0100 Subject: s4-spoolss: implement dcesrv_spoolss_AddJob which always is a dummy. Guenther --- source4/rpc_server/spoolss/dcesrv_spoolss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 89b93bbaa4..f1ef2f0acb 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -546,7 +546,11 @@ static WERROR dcesrv_spoolss_EndDocPrinter(struct dcesrv_call_state *dce_call, T static WERROR dcesrv_spoolss_AddJob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct spoolss_AddJob *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + if (r->in.level != 1) { + return WERR_UNKNOWN_LEVEL; + } + + return WERR_INVALID_PARAM; } -- cgit From 76a0050e239b1fb9e2135f2e6cea80ed780a0ee0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 26 Feb 2009 13:12:07 +1100 Subject: A simple hack to avoid the segfault in #6138 Thanks to Andrew Kroeger for reporting this. This fix just for the release. A better fix will make it into the master branch soon. Andrew Bartlett --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index f1c063ed90..2efddc74fc 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1220,7 +1220,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA /* Win7-beta will send the domain name in the form the user typed, so we have to cope with both the short and long form here */ - if (strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) { + if (r->in.domain_name == NULL || strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) { r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); } -- cgit From c3632e4efc506a401a9d75c4d75b14a1a220caa2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 26 Feb 2009 13:21:08 +1100 Subject: Mark as the Samba 4.0 alpha7 release --- source4/VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/VERSION b/source4/VERSION index e7d05f6a09..20256436eb 100644 --- a/source4/VERSION +++ b/source4/VERSION @@ -89,7 +89,7 @@ SAMBA_VERSION_RC_RELEASE= # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # # -> "3.0.0-SVN-build-199" # ######################################################## -SAMBA_VERSION_IS_GIT_SNAPSHOT=yes +SAMBA_VERSION_IS_GIT_SNAPSHOT=no ######################################################## # This is for specifying a release nickname # -- cgit From b679f6b25673969800f31cf0bd0f57799bb0598c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 09:10:23 +0100 Subject: s4:VERSION: mark as 4.0.0-alpha8 gitsnapshot metze --- source4/VERSION | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4') diff --git a/source4/VERSION b/source4/VERSION index 20256436eb..58f8cc169d 100644 --- a/source4/VERSION +++ b/source4/VERSION @@ -57,7 +57,7 @@ SAMBA_VERSION_TP_RELEASE= # e.g. SAMBA_VERSION_ALPHA_RELEASE=1 # # -> "4.0.0alpha1" # ######################################################## -SAMBA_VERSION_ALPHA_RELEASE=7 +SAMBA_VERSION_ALPHA_RELEASE=8 ######################################################## # For 'pre' releases the version will be # @@ -89,7 +89,7 @@ SAMBA_VERSION_RC_RELEASE= # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # # -> "3.0.0-SVN-build-199" # ######################################################## -SAMBA_VERSION_IS_GIT_SNAPSHOT=no +SAMBA_VERSION_IS_GIT_SNAPSHOT=yes ######################################################## # This is for specifying a release nickname # -- cgit From 64662cb0c34425f7a0ccc66e43c21b7b69451ca9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 09:42:29 +0100 Subject: s4:ldb_map: include ldb_includes.h first to get replace.h as first header This should bring the build on AIX one step further. metze --- source4/lib/ldb/ldb_map/ldb_map.c | 1 + source4/lib/ldb/ldb_map/ldb_map_inbound.c | 1 + source4/lib/ldb/ldb_map/ldb_map_outbound.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4') diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index 959540374c..5b4ea7910a 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -35,6 +35,7 @@ * Author: Jelmer Vernooij, Martin Kuehl */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_inbound.c b/source4/lib/ldb/ldb_map/ldb_map_inbound.c index 822dea654e..455740ce59 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_inbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_inbound.c @@ -24,6 +24,7 @@ */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" diff --git a/source4/lib/ldb/ldb_map/ldb_map_outbound.c b/source4/lib/ldb/ldb_map/ldb_map_outbound.c index eb7b4590ba..ffcefad6be 100644 --- a/source4/lib/ldb/ldb_map/ldb_map_outbound.c +++ b/source4/lib/ldb/ldb_map/ldb_map_outbound.c @@ -25,6 +25,7 @@ */ +#include "ldb_includes.h" #include "ldb_map.h" #include "ldb_map_private.h" -- cgit From b6597424dbacdbfcaa37d8860fc4343be1a4514a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:05:58 +0100 Subject: s4:heimdal_build: don't always build setprogname.o This hopefully fixes the build on Mac OS 10, where setprogname() is available via libc. asn1_compile and compile_et use only .ho files again and don't use socket_wrapper anymore. metze --- source4/heimdal_build/internal.m4 | 1 + source4/heimdal_build/internal.mk | 50 ++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 17 deletions(-) (limited to 'source4') diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index a48777fab1..3039c8a796 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -77,6 +77,7 @@ AC_CHECK_FUNCS([ \ atexit \ cgetent \ getprogname \ + setprogname \ inet_aton \ gethostname \ getnameinfo \ diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 77dbf0fb98..ea8d4731db 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -568,27 +568,36 @@ $(heimdalsrcdir)/lib/wind/bidi_table.h $(heimdalsrcdir)/lib/wind/bidi_table.c: $ clean:: @rm -f $(heimdalsrcdir)/lib/wind/bidi_table.h $(heimdalsrcdir)/lib/wind/bidi_table.c -[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME] +[SUBSYSTEM::HEIMDAL_ROKEN_PROGNAME] -HEIMDAL_ROKEN_GETPROGNAME_OBJ_FILES = $(heimdalsrcdir)/lib/roken/getprogname.o -$(HEIMDAL_ROKEN_GETPROGNAME_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +HEIMDAL_ROKEN_PROGNAME_OBJ_FILES = \ + $(heimdalsrcdir)/lib/roken/getprogname.o \ + $(heimdalsrcdir)/lib/roken/setprogname.o +$(HEIMDAL_ROKEN_PROGNAME_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) [SUBSYSTEM::HEIMDAL_ROKEN_CLOSEFROM] HEIMDAL_ROKEN_CLOSEFROM_OBJ_FILES = $(heimdalsrcdir)/lib/roken/closefrom.o $(HEIMDAL_ROKEN_CLOSEFROM_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) -[SUBSYSTEM::HEIMDAL_ROKEN_GETPROGNAME_H] +[SUBSYSTEM::HEIMDAL_ROKEN_PROGNAME_H] -HEIMDAL_ROKEN_GETPROGNAME_H_OBJ_FILES = $(heimdalsrcdir)/lib/roken/getprogname.ho -$(HEIMDAL_ROKEN_GETPROGNAME_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +HEIMDAL_ROKEN_PROGNAME_H_OBJ_FILES = \ + $(heimdalsrcdir)/lib/roken/getprogname.ho \ + $(heimdalsrcdir)/lib/roken/setprogname.ho +$(HEIMDAL_ROKEN_PROGNAME_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 + +[SUBSYSTEM::HEIMDAL_ROKEN_CLOSEFROM_H] + +HEIMDAL_ROKEN_CLOSEFROM_H_OBJ_FILES = $(heimdalsrcdir)/lib/roken/closefrom.ho +$(HEIMDAL_ROKEN_CLOSEFROM_H_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 ####################### # Start SUBSYSTEM HEIMDAL_ROKEN [SUBSYSTEM::HEIMDAL_ROKEN] CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) PRIVATE_DEPENDENCIES = \ - HEIMDAL_ROKEN_GETPROGNAME \ + HEIMDAL_ROKEN_PROGNAME \ HEIMDAL_ROKEN_CLOSEFROM \ RESOLV \ LIBREPLACE_NETWORK @@ -615,7 +624,6 @@ HEIMDAL_ROKEN_OBJ_FILES = \ $(heimdalsrcdir)/lib/roken/roken_gethostby.o \ $(heimdalsrcdir)/lib/roken/signal.o \ $(heimdalsrcdir)/lib/roken/vis.o \ - $(heimdalsrcdir)/lib/roken/setprogname.o \ $(heimdalsrcdir)/lib/roken/strlwr.o \ $(heimdalsrcdir)/lib/roken/strsep_copy.o \ $(heimdalsrcdir)/lib/roken/strsep.o \ @@ -631,7 +639,17 @@ HEIMDAL_ROKEN_OBJ_FILES = \ $(heimdalbuildsrcdir)/replace.o $(HEIMDAL_ROKEN_OBJ_FILES) $(HEIMDAL_ROKEN_OBJ_FILES:.o=.d):: $(heimdalsrcdir)/lib/roken/roken.h -$(HEIMDAL_ROKEN_OBJ_FILES:.o=.ho) $(HEIMDAL_ROKEN_OBJ_FILES:.o=.hd):: $(heimdalsrcdir)/lib/roken/roken.h + +[SUBSYSTEM::HEIMDAL_ROKEN_H] +CFLAGS = -I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 +PRIVATE_DEPENDENCIES = \ + HEIMDAL_ROKEN_PROGNAME_H \ + HEIMDAL_ROKEN_CLOSEFROM_H \ + RESOLV \ + LIBREPLACE_NETWORK + +HEIMDAL_ROKEN_H_OBJ_FILES = $(HEIMDAL_ROKEN_OBJ_FILES:.o=.ho) +$(HEIMDAL_ROKEN_H_OBJ_FILES:.ho=.hd):: $(heimdalsrcdir)/lib/roken/roken.h $(heimdalsrcdir)/lib/roken/roken.h: @echo 'Creating $(heimdalsrcdir)/lib/roken/roken.h' @@ -656,7 +674,7 @@ HEIMDAL_COM_ERR_OBJ_FILES = \ # Start BINARY asn1_compile [BINARY::asn1_compile] USE_HOSTCC = YES -PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN +PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN_H ASN1C = $(builddir)/bin/asn1_compile @@ -680,10 +698,9 @@ dist:: $(heimdalsrcdir)/lib/asn1/lex.c asn1_compile_OBJ_FILES = \ $(asn1_compile_ASN1_OBJ_FILES) \ - $(heimdalsrcdir)/lib/vers/print_version.ho \ - $(socketwrappersrcdir)/socket_wrapper.ho \ + $(heimdalsrcdir)/lib/vers/print_version.ho -$(asn1_compile_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +$(asn1_compile_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/asn1 -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 $(eval $(call heimdal_proto_header_template, \ $(heimdalsrcdir)/lib/asn1/der-protos.h, \ @@ -699,7 +716,7 @@ $(eval $(call heimdal_proto_header_template, \ # Start BINARY compile_et [BINARY::compile_et] USE_HOSTCC = YES -PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN +PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN_H # End BINARY compile_et ####################### @@ -708,10 +725,9 @@ ET_COMPILER = $(builddir)/bin/compile_et compile_et_OBJ_FILES = $(heimdalsrcdir)/lib/vers/print_version.ho \ $(heimdalsrcdir)/lib/com_err/parse.ho \ $(heimdalsrcdir)/lib/com_err/lex.ho \ - $(heimdalsrcdir)/lib/com_err/compile_et.ho \ - $(socketwrappersrcdir)/socket_wrapper.ho \ + $(heimdalsrcdir)/lib/com_err/compile_et.ho -$(compile_et_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/com_err -I$(heimdalsrcdir)/lib/roken -I$(socketwrappersrcdir) +$(compile_et_OBJ_FILES): CFLAGS+=-I$(heimdalbuildsrcdir) -I$(heimdalsrcdir)/lib/com_err -I$(heimdalsrcdir)/lib/roken -DSOCKET_WRAPPER_DISABLE=1 $(heimdalsrcdir)/lib/com_err/lex.c:: $(heimdalsrcdir)/lib/com_err/parse.c dist:: $(heimdalsrcdir)/lib/com_err/lex.c -- cgit From 8e4816f0078fd94a1b83798f52a63dc679eed47e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 10:55:00 +0100 Subject: s4:Makefile: try to fix 'make installheaders' on *BSD systems metze --- source4/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/Makefile b/source4/Makefile index 508836f6da..15b1b8ba40 100644 --- a/source4/Makefile +++ b/source4/Makefile @@ -146,7 +146,7 @@ endif clean:: @find ../lib ../libcli ../librpc ../nsswitch -name '*.o' -o -name '*.ho' | xargs rm -f -PUBLIC_HEADERS += $(srcdir)/version.h +PUBLIC_HEADERS += ./version.h libraries:: $(STATIC_LIBS) $(SHARED_LIBS) modules:: $(PLUGINS) -- cgit From d3ac11c64a95c2041dc0002b8cc59d756736d3be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 26 Feb 2009 13:12:54 +0100 Subject: s4:heimdal_build: correrctly switch closefrom() and get/setprogname() replacements on and off metze --- source4/heimdal_build/internal.m4 | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4') diff --git a/source4/heimdal_build/internal.m4 b/source4/heimdal_build/internal.m4 index 3039c8a796..4cd7521c37 100644 --- a/source4/heimdal_build/internal.m4 +++ b/source4/heimdal_build/internal.m4 @@ -269,16 +269,18 @@ SMB_ENABLE(compile_et, YES) # only add closefrom if needed SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM, NO) +SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM_H, NO) if test t$ac_cv_func_closefrom != tyes; then SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM, YES) + SMB_ENABLE(HEIMDAL_ROKEN_CLOSEFROM_H, YES) fi # only add getprogname if needed -SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, NO) -SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, NO) +SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME, NO) +SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME_H, NO) if test t$ac_cv_func_getprogname != tyes; then - SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME, YES) - SMB_ENABLE(HEIMDAL_ROKEN_GETPROGNAME_H, YES) + SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME, YES) + SMB_ENABLE(HEIMDAL_ROKEN_PROGNAME_H, YES) fi VPATH="$VPATH:\$(HEIMDAL_VPATH)" -- cgit From bcadb77c18f9ed9be22762871617f1a12294e88c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 2009 10:13:57 -0800 Subject: Add another torture test inspired by George @ Apple. Inside a directory, keep a file open and then renaming the directory should fail with ACCESS_DENIED. This is connected to the test case where the close was failing due to a delayed write on a file not being able to succeed when Samba allowed the containing directory to be renamed. I will fix this in the server shortly (this should be done across connections also but with will be very hard in Samba - would need a full scan of the open file db on every directory rename) - so I will fix for the local case first (scanning local file opens inside an smbd is cheap). Jeremy. --- source4/torture/raw/rename.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source4') diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c index 9d629f0bbf..951d91a684 100644 --- a/source4/torture/raw/rename.c +++ b/source4/torture/raw/rename.c @@ -516,6 +516,91 @@ done: return ret; } +/* + test dir rename. +*/ +static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *cli) +{ + union smb_open io; + union smb_rename ren_io; + NTSTATUS status; + const char *dname1 = BASEDIR "\\dir_for_rename"; + const char *dname2 = BASEDIR "\\renamed_dir"; + const char *fname = BASEDIR "\\dir_for_rename\\file.txt"; + bool ret = true; + int fnum = -1; + + printf("Checking rename on a directory containing an open file.\n"); + + if (!torture_setup_dir(cli, BASEDIR)) { + return false; + } + + /* create a directory */ + smbcli_rmdir(cli->tree, dname1); + smbcli_rmdir(cli->tree, dname2); + smbcli_unlink(cli->tree, dname1); + smbcli_unlink(cli->tree, dname2); + + ZERO_STRUCT(io); + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io.ntcreatex.in.fname = dname1; + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + + fnum = io.ntcreatex.out.file.fnum; + smbcli_close(cli->tree, fnum); + + /* Now create and hold open a file. */ + ZERO_STRUCT(io); + + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.fname = fname; + + /* Create the file. */ + + status = smb_raw_open(cli->tree, tctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + fnum = io.ntcreatex.out.file.fnum; + + /* Now try and rename the directory. */ + + ZERO_STRUCT(ren_io); + ren_io.generic.level = RAW_RENAME_RENAME; + ren_io.rename.in.pattern1 = dname1; + ren_io.rename.in.pattern2 = dname2; + ren_io.rename.in.attrib = 0; + + status = smb_raw_rename(cli->tree, &ren_io); + CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); + +done: + + if (fnum != -1) { + smbcli_close(cli->tree, fnum); + } + smb_raw_exit(cli->session); + smbcli_deltree(cli->tree, BASEDIR); + return ret; +} + extern bool test_trans2rename(struct torture_context *tctx, struct smbcli_state *cli1, struct smbcli_state *cli2); extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state *cli1); @@ -533,6 +618,7 @@ struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx) torture_suite_add_1smb_test(suite, "nttransrename", test_nttransrename); torture_suite_add_1smb_test(suite, "ntrename", test_ntrename); torture_suite_add_1smb_test(suite, "osxrename", test_osxrename); + torture_suite_add_1smb_test(suite, "directory rename", test_dir_rename); return suite; } -- cgit From fe8cf69ec644f399d4b41c21b74703e0e500e092 Mon Sep 17 00:00:00 2001 From: Björn Jacke Date: Thu, 26 Feb 2009 16:32:57 +0100 Subject: don't hardcode python path Signed-off-by: Michael Adam --- source4/selftest/tests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/selftest/tests.sh b/source4/selftest/tests.sh index 36e3bbe364..99e530ec38 100755 --- a/source4/selftest/tests.sh +++ b/source4/selftest/tests.sh @@ -23,6 +23,11 @@ then PERL=perl fi +if [ ! -n "$PYTHON" ] +then + PYTHON=python +fi + plantest() { name=$1 env=$2 @@ -394,7 +399,6 @@ then plantest "nss.test using winbind" member $VALGRIND $nsstest4 $samba4bindir/shared/libnss_winbind.so fi -PYTHON=/usr/bin/python SUBUNITRUN="$VALGRIND $PYTHON $samba4srcdir/scripting/bin/subunitrun" plantest "ldb.python" none PYTHONPATH="$PYTHONPATH:$samba4srcdir/lib/ldb/tests/python/" $SUBUNITRUN api plantest "credentials.python" none PYTHONPATH="$PYTHONPATH:$samba4srcdir/auth/credentials/tests" $SUBUNITRUN bindings -- cgit From 9569d979de43970399f33645323e9091338084f6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Feb 2009 20:57:49 -0800 Subject: And the prize for the most pain caused in the build farm for a simple typo goes to..... Tim Prouty !!!! Sorry Tim, nice test but you made a typo in passing in the size of an array so we were reading uninitialized memory :-). That took far longer than it should have to track down... (%$&#ing build system....). The build farm should now slowly go back to normal. Jeremy. --- source4/torture/raw/streams.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4') diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c index bf87bd224f..d0d21ccc06 100644 --- a/source4/torture/raw/streams.c +++ b/source4/torture/raw/streams.c @@ -1454,7 +1454,7 @@ static bool test_stream_create_disposition(struct torture_context *tctx, status = smb_raw_open(cli->tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); - if (!check_stream_list(cli, fname, 2, &default_stream_name)) { + if (!check_stream_list(cli, fname, 1, &default_stream_name)) { goto done; } -- cgit