diff options
author | Jeremy Allison <jra@samba.org> | 2009-10-17 10:36:33 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2009-10-17 10:36:33 -0700 |
commit | 7c51fa6d699a653cafa90df8e44911b576118ebd (patch) | |
tree | 543bf9ca698e03eff81104898b33e77f1abed319 /source3/lib | |
parent | cc3a6770c77ec8fe1cd63bf4c682853c56201f0c (diff) | |
parent | 3e3214fd91471bca5b6c4d3782e922d252d588fb (diff) | |
download | samba-7c51fa6d699a653cafa90df8e44911b576118ebd.tar.gz samba-7c51fa6d699a653cafa90df8e44911b576118ebd.tar.bz2 samba-7c51fa6d699a653cafa90df8e44911b576118ebd.zip |
Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/ldb/ldb_tdb/ldb_tdb.h | 6 | ||||
-rw-r--r-- | source3/lib/netapi/examples/Makefile.in | 20 | ||||
-rw-r--r-- | source3/lib/netapi/examples/netlogon/netlogon_control.c | 143 | ||||
-rw-r--r-- | source3/lib/netapi/examples/netlogon/netlogon_control2.c | 147 | ||||
-rw-r--r-- | source3/lib/netapi/examples/netlogon/nltest.c | 251 | ||||
-rw-r--r-- | source3/lib/netapi/group.c | 8 | ||||
-rw-r--r-- | source3/lib/netapi/libnetapi.c | 94 | ||||
-rw-r--r-- | source3/lib/netapi/libnetapi.h | 17 | ||||
-rw-r--r-- | source3/lib/netapi/netapi.h | 92 | ||||
-rw-r--r-- | source3/lib/netapi/netlogon.c | 240 | ||||
-rw-r--r-- | source3/lib/smbldap.c | 20 | ||||
-rw-r--r-- | source3/lib/system.c | 2 | ||||
-rw-r--r-- | source3/lib/util_reg.c | 95 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 35 |
14 files changed, 1096 insertions, 74 deletions
diff --git a/source3/lib/ldb/ldb_tdb/ldb_tdb.h b/source3/lib/ldb/ldb_tdb/ldb_tdb.h index 486d948fa0..caf8ba8d0c 100644 --- a/source3/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source3/lib/ldb/ldb_tdb/ldb_tdb.h @@ -3,13 +3,7 @@ #include "system/filesys.h" #endif -#if (_SAMBA_BUILD_ >= 4) -#include "lib/tdb/include/tdb.h" -#elif defined(_SAMBA_BUILD_) -#include "../tdb/include/tdb.h" -#else #include "tdb.h" -#endif /* this private structure is used by the ltdb backend in the ldb_context */ diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index 2a99f5744a..4e921b6555 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -65,7 +65,10 @@ PROGS = bin/getdc@EXEEXT@ \ bin/file_getinfo@EXEEXT@ \ bin/file_enum@EXEEXT@ \ bin/shutdown_init@EXEEXT@ \ - bin/shutdown_abort@EXEEXT@ + bin/shutdown_abort@EXEEXT@ \ + bin/netlogon_control@EXEEXT@ \ + bin/netlogon_control2@EXEEXT@ \ + bin/nltest@EXEEXT@ all: $(PROGS) @@ -143,6 +146,9 @@ FILEGETINFO_OBJ = file/file_getinfo.o $(CMDLINE_OBJ) FILEENUM_OBJ = file/file_enum.o $(CMDLINE_OBJ) SHUTDOWNINIT_OBJ = shutdown/shutdown_init.o $(CMDLINE_OBJ) SHUTDOWNABORT_OBJ = shutdown/shutdown_abort.o $(CMDLINE_OBJ) +NETLOGONCONTROL_OBJ = netlogon/netlogon_control.o $(CMDLINE_OBJ) +NETLOGONCONTROL2_OBJ = netlogon/netlogon_control2.o $(CMDLINE_OBJ) +NLTEST_OBJ = netlogon/nltest.o $(CMDLINE_OBJ) bin/getdc@EXEEXT@: $(BINARY_PREREQS) $(GETDC_OBJ) @echo Linking $@ @@ -340,6 +346,18 @@ bin/shutdown_abort@EXEEXT@: $(BINARY_PREREQS) $(SHUTDOWNABORT_OBJ) @echo Linking $@ @$(CC) $(CCFLAGS) -o $@ $(SHUTDOWNABORT_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS) +bin/netlogon_control@EXEEXT@: $(BINARY_PREREQS) $(NETLOGONCONTROL_OBJ) + @echo Linking $@ + @$(CC) $(CCFLAGS) -o $@ $(NETLOGONCONTROL_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS) + +bin/netlogon_control2@EXEEXT@: $(BINARY_PREREQS) $(NETLOGONCONTROL2_OBJ) + @echo Linking $@ + @$(CC) $(CCFLAGS) -o $@ $(NETLOGONCONTROL2_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS) + +bin/nltest@EXEEXT@: $(BINARY_PREREQS) $(NLTEST_OBJ) + @echo Linking $@ + @$(CC) $(CCFLAGS) -o $@ $(NLTEST_OBJ) $(LDFLAGS) $(DYNEXP) $(CMDLINE_LIBS) + clean: -rm -f $(PROGS) -rm -f core */*~ *~ \ diff --git a/source3/lib/netapi/examples/netlogon/netlogon_control.c b/source3/lib/netapi/examples/netlogon/netlogon_control.c new file mode 100644 index 0000000000..34361cdec2 --- /dev/null +++ b/source3/lib/netapi/examples/netlogon/netlogon_control.c @@ -0,0 +1,143 @@ +/* + * Unix SMB/CIFS implementation. + * I_NetLogonControl query + * Copyright (C) Guenther Deschner 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <netapi.h> + +#include "common.h" + +int main(int argc, const char **argv) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx = NULL; + const char *hostname = NULL; + uint32_t function_code = NETLOGON_CONTROL_QUERY; + uint32_t level = 1; + uint8_t *buffer = NULL; + struct NETLOGON_INFO_1 *i1 = NULL; + struct NETLOGON_INFO_2 *i2 = NULL; + struct NETLOGON_INFO_3 *i3 = NULL; + struct NETLOGON_INFO_4 *i4 = NULL; + + poptContext pc; + int opt; + + struct poptOption long_options[] = { + POPT_AUTOHELP + POPT_COMMON_LIBNETAPI_EXAMPLES + POPT_TABLEEND + }; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + pc = poptGetContext("netlogon_control", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "hostname"); + while((opt = poptGetNextOpt(pc)) != -1) { + } + + if (!poptPeekArg(pc)) { + poptPrintHelp(pc, stderr, 0); + goto out; + } + hostname = poptGetArg(pc); + + if (poptPeekArg(pc)) { + function_code = atoi(poptGetArg(pc)); + } + + if (poptPeekArg(pc)) { + level = atoi(poptGetArg(pc)); + } + + /* I_NetLogonControl */ + + status = I_NetLogonControl(hostname, + function_code, + level, + &buffer); + if (status != 0) { + printf("I_NetLogonControl failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + goto out; + } + + if (!buffer) { + goto out; + } + + switch (level) { + case 1: + i1 = (struct NETLOGON_INFO_1 *)buffer; + + printf("Flags: %x\n", i1->netlog1_flags); + printf("Connection Status Status = %d 0x%x %s\n", + i1->netlog1_pdc_connection_status, + i1->netlog1_pdc_connection_status, + libnetapi_errstr(i1->netlog1_pdc_connection_status)); + + break; + case 2: + i2 = (struct NETLOGON_INFO_2 *)buffer; + + printf("Flags: %x\n", i2->netlog2_flags); + printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name); + printf("Trusted DC Connection Status Status = %d 0x%x %s\n", + i2->netlog2_tc_connection_status, + i2->netlog2_tc_connection_status, + libnetapi_errstr(i2->netlog2_tc_connection_status)); + printf("Trust Verification Status Status = %d 0x%x %s\n", + i2->netlog2_pdc_connection_status, + i2->netlog2_pdc_connection_status, + libnetapi_errstr(i2->netlog2_pdc_connection_status)); + + break; + case 3: + i3 = (struct NETLOGON_INFO_3 *)buffer; + + printf("Flags: %x\n", i3->netlog1_flags); + printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts); + + break; + case 4: + i4 = (struct NETLOGON_INFO_4 *)buffer; + + printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name); + printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name); + + break; + default: + break; + } + + out: + NetApiBufferFree(buffer); + libnetapi_free(ctx); + poptFreeContext(pc); + + return status; +} diff --git a/source3/lib/netapi/examples/netlogon/netlogon_control2.c b/source3/lib/netapi/examples/netlogon/netlogon_control2.c new file mode 100644 index 0000000000..ea8e8c254c --- /dev/null +++ b/source3/lib/netapi/examples/netlogon/netlogon_control2.c @@ -0,0 +1,147 @@ +/* + * Unix SMB/CIFS implementation. + * I_NetLogonControl2 query + * Copyright (C) Guenther Deschner 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <netapi.h> + +#include "common.h" + +int main(int argc, const char **argv) +{ + NET_API_STATUS status; + struct libnetapi_ctx *ctx = NULL; + const char *hostname = NULL; + uint32_t function_code = NETLOGON_CONTROL_QUERY; + uint32_t level = 1; + uint8_t *buffer = NULL; + struct NETLOGON_INFO_1 *i1 = NULL; + struct NETLOGON_INFO_2 *i2 = NULL; + struct NETLOGON_INFO_3 *i3 = NULL; + struct NETLOGON_INFO_4 *i4 = NULL; + const char *domain = NULL; + + poptContext pc; + int opt; + + struct poptOption long_options[] = { + POPT_AUTOHELP + POPT_COMMON_LIBNETAPI_EXAMPLES + POPT_TABLEEND + }; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + pc = poptGetContext("netlogon_control", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "hostname"); + while((opt = poptGetNextOpt(pc)) != -1) { + } + + if (!poptPeekArg(pc)) { + poptPrintHelp(pc, stderr, 0); + goto out; + } + hostname = poptGetArg(pc); + + if (poptPeekArg(pc)) { + function_code = atoi(poptGetArg(pc)); + } + + if (poptPeekArg(pc)) { + level = atoi(poptGetArg(pc)); + } + + domain = "TEST"; + + /* I_NetLogonControl2 */ + + status = I_NetLogonControl2(hostname, + function_code, + level, + (uint8_t *)domain, + &buffer); + if (status != 0) { + printf("I_NetLogonControl2 failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + goto out; + } + + if (!buffer) { + goto out; + } + + switch (level) { + case 1: + i1 = (struct NETLOGON_INFO_1 *)buffer; + + printf("Flags: %x\n", i1->netlog1_flags); + printf("Connection Status Status = %d 0x%x %s\n", + i1->netlog1_pdc_connection_status, + i1->netlog1_pdc_connection_status, + libnetapi_errstr(i1->netlog1_pdc_connection_status)); + + break; + case 2: + i2 = (struct NETLOGON_INFO_2 *)buffer; + + printf("Flags: %x\n", i2->netlog2_flags); + printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name); + printf("Trusted DC Connection Status Status = %d 0x%x %s\n", + i2->netlog2_tc_connection_status, + i2->netlog2_tc_connection_status, + libnetapi_errstr(i2->netlog2_tc_connection_status)); + printf("Trust Verification Status Status = %d 0x%x %s\n", + i2->netlog2_pdc_connection_status, + i2->netlog2_pdc_connection_status, + libnetapi_errstr(i2->netlog2_pdc_connection_status)); + + break; + case 3: + i3 = (struct NETLOGON_INFO_3 *)buffer; + + printf("Flags: %x\n", i3->netlog1_flags); + printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts); + + break; + case 4: + i4 = (struct NETLOGON_INFO_4 *)buffer; + + printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name); + printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name); + + break; + default: + break; + } + + out: + NetApiBufferFree(buffer); + libnetapi_free(ctx); + poptFreeContext(pc); + + return status; +} diff --git a/source3/lib/netapi/examples/netlogon/nltest.c b/source3/lib/netapi/examples/netlogon/nltest.c new file mode 100644 index 0000000000..a9fe6dec9f --- /dev/null +++ b/source3/lib/netapi/examples/netlogon/nltest.c @@ -0,0 +1,251 @@ +/* + * Samba Unix/Linux SMB client library + * Distributed SMB/CIFS Server Management Utility + * Nltest netlogon testing tool + * + * Copyright (C) Guenther Deschner 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <netapi.h> + +#include "common.h" + +enum { + OPT_DBFLAG = 1, + OPT_SC_QUERY, + OPT_SC_RESET, + OPT_SC_VERIFY, + OPT_SC_CHANGE_PWD +}; + +/**************************************************************** +****************************************************************/ + +static void print_result(uint32_t level, + uint8_t *buffer) +{ + struct NETLOGON_INFO_1 *i1 = NULL; + struct NETLOGON_INFO_2 *i2 = NULL; + struct NETLOGON_INFO_3 *i3 = NULL; + struct NETLOGON_INFO_4 *i4 = NULL; + + if (!buffer) { + return; + } + + switch (level) { + case 1: + i1 = (struct NETLOGON_INFO_1 *)buffer; + + printf("Flags: %x\n", i1->netlog1_flags); + printf("Connection Status Status = %d 0x%x %s\n", + i1->netlog1_pdc_connection_status, + i1->netlog1_pdc_connection_status, + libnetapi_errstr(i1->netlog1_pdc_connection_status)); + + break; + case 2: + i2 = (struct NETLOGON_INFO_2 *)buffer; + + printf("Flags: %x\n", i2->netlog2_flags); + printf("Trusted DC Name %s\n", i2->netlog2_trusted_dc_name); + printf("Trusted DC Connection Status Status = %d 0x%x %s\n", + i2->netlog2_tc_connection_status, + i2->netlog2_tc_connection_status, + libnetapi_errstr(i2->netlog2_tc_connection_status)); + printf("Trust Verification Status Status = %d 0x%x %s\n", + i2->netlog2_pdc_connection_status, + i2->netlog2_pdc_connection_status, + libnetapi_errstr(i2->netlog2_pdc_connection_status)); + + break; + case 3: + i3 = (struct NETLOGON_INFO_3 *)buffer; + + printf("Flags: %x\n", i3->netlog1_flags); + printf("Logon Attempts: %d\n", i3->netlog3_logon_attempts); + + break; + case 4: + i4 = (struct NETLOGON_INFO_4 *)buffer; + + printf("Trusted DC Name %s\n", i4->netlog4_trusted_dc_name); + printf("Trusted Domain Name %s\n", i4->netlog4_trusted_domain_name); + + break; + default: + break; + } +} + +/**************************************************************** +****************************************************************/ + +int main(int argc, const char **argv) +{ + int opt; + NET_API_STATUS status; + struct libnetapi_ctx *ctx = NULL; + const char *server_name = NULL; + char *opt_domain = NULL; + int opt_dbflag = 0; + uint32_t query_level; + uint8_t *buffer = NULL; + + poptContext pc; + struct poptOption long_options[] = { + POPT_AUTOHELP + {"dbflag", 0, POPT_ARG_INT, &opt_dbflag, OPT_DBFLAG, "New Debug Flag", "HEXFLAGS"}, + {"sc_query", 0, POPT_ARG_STRING, &opt_domain, OPT_SC_QUERY, "Query secure channel for domain on server", "DOMAIN"}, + {"sc_reset", 0, POPT_ARG_STRING, &opt_domain, OPT_SC_RESET, "Reset secure channel for domain on server to dcname", "DOMAIN"}, + {"sc_verify", 0, POPT_ARG_STRING, &opt_domain, OPT_SC_VERIFY, "Verify secure channel for domain on server", "DOMAIN"}, + {"sc_change_pwd", 0, POPT_ARG_STRING, &opt_domain, OPT_SC_CHANGE_PWD, "Change a secure channel password for domain on server", "DOMAIN"}, + POPT_COMMON_LIBNETAPI_EXAMPLES + POPT_TABLEEND + }; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + pc = poptGetContext("nltest", argc, argv, long_options, 0); + + poptSetOtherOptionHelp(pc, "server_name"); + while((opt = poptGetNextOpt(pc)) != -1) { + } + + if (!poptPeekArg(pc)) { + poptPrintHelp(pc, stderr, 0); + goto done; + } + server_name = poptGetArg(pc); + + if (argc == 1) { + poptPrintHelp(pc, stderr, 0); + goto done; + } + + if (!server_name || poptGetArg(pc)) { + poptPrintHelp(pc, stderr, 0); + goto done; + } + + if ((server_name[0] == '/' && server_name[1] == '/') || + (server_name[0] == '\\' && server_name[1] == '\\')) { + server_name += 2; + } + + poptResetContext(pc); + + while ((opt = poptGetNextOpt(pc)) != -1) { + switch (opt) { + + case OPT_DBFLAG: + query_level = 1; + status = I_NetLogonControl2(server_name, + NETLOGON_CONTROL_SET_DBFLAG, + query_level, + (uint8_t *)opt_dbflag, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + break; + case OPT_SC_QUERY: + query_level = 2; + status = I_NetLogonControl2(server_name, + NETLOGON_CONTROL_TC_QUERY, + query_level, + (uint8_t *)opt_domain, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + break; + case OPT_SC_VERIFY: + query_level = 2; + status = I_NetLogonControl2(server_name, + NETLOGON_CONTROL_TC_VERIFY, + query_level, + (uint8_t *)opt_domain, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + break; + case OPT_SC_RESET: + query_level = 2; + status = I_NetLogonControl2(server_name, + NETLOGON_CONTROL_REDISCOVER, + query_level, + (uint8_t *)opt_domain, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + break; + case OPT_SC_CHANGE_PWD: + query_level = 1; + status = I_NetLogonControl2(server_name, + NETLOGON_CONTROL_CHANGE_PASSWORD, + query_level, + (uint8_t *)opt_domain, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + break; + default: + poptPrintHelp(pc, stderr, 0); + goto done; + } + } + + print_result(query_level, buffer); + + printf("The command completed successfully\n"); + status = 0; + + done: + + printf("\n"); + libnetapi_free(ctx); + poptFreeContext(pc); + + return status; +} diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 004fd3aff6..77ed2e8485 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -784,12 +784,12 @@ WERROR NetGroupAddUser_r(struct libnetapi_ctx *ctx, &rids, &types); if (!NT_STATUS_IS_OK(status)) { - werr = WERR_GROUP_NOT_FOUND; + werr = WERR_GROUPNOTFOUND; goto done; } if (types.ids[0] != SID_NAME_DOM_GRP) { - werr = WERR_GROUP_NOT_FOUND; + werr = WERR_GROUPNOTFOUND; goto done; } @@ -905,12 +905,12 @@ WERROR NetGroupDelUser_r(struct libnetapi_ctx *ctx, &rids, &types); if (!NT_STATUS_IS_OK(status)) { - werr = WERR_GROUP_NOT_FOUND; + werr = WERR_GROUPNOTFOUND; goto done; } if (types.ids[0] != SID_NAME_DOM_GRP) { - werr = WERR_GROUP_NOT_FOUND; + werr = WERR_GROUPNOTFOUND; goto done; } diff --git a/source3/lib/netapi/libnetapi.c b/source3/lib/netapi/libnetapi.c index 6e366673f1..336ab26854 100644 --- a/source3/lib/netapi/libnetapi.c +++ b/source3/lib/netapi/libnetapi.c @@ -2441,3 +2441,97 @@ NET_API_STATUS NetShutdownAbort(const char * server_name /* [in] */) return r.out.result; } +/**************************************************************** + I_NetLogonControl +****************************************************************/ + +NET_API_STATUS I_NetLogonControl(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t **buffer /* [out] [ref] */) +{ + struct I_NetLogonControl r; + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + /* In parameters */ + r.in.server_name = server_name; + r.in.function_code = function_code; + r.in.query_level = query_level; + + /* Out parameters */ + r.out.buffer = buffer; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(I_NetLogonControl, &r); + } + + if (LIBNETAPI_LOCAL_SERVER(server_name)) { + werr = I_NetLogonControl_l(ctx, &r); + } else { + werr = I_NetLogonControl_r(ctx, &r); + } + + r.out.result = W_ERROR_V(werr); + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(I_NetLogonControl, &r); + } + + return r.out.result; +} + +/**************************************************************** + I_NetLogonControl2 +****************************************************************/ + +NET_API_STATUS I_NetLogonControl2(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t *data /* [in] [ref] */, + uint8_t **buffer /* [out] [ref] */) +{ + struct I_NetLogonControl2 r; + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + /* In parameters */ + r.in.server_name = server_name; + r.in.function_code = function_code; + r.in.query_level = query_level; + r.in.data = data; + + /* Out parameters */ + r.out.buffer = buffer; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_IN_DEBUG(I_NetLogonControl2, &r); + } + + if (LIBNETAPI_LOCAL_SERVER(server_name)) { + werr = I_NetLogonControl2_l(ctx, &r); + } else { + werr = I_NetLogonControl2_r(ctx, &r); + } + + r.out.result = W_ERROR_V(werr); + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_OUT_DEBUG(I_NetLogonControl2, &r); + } + + return r.out.result; +} + diff --git a/source3/lib/netapi/libnetapi.h b/source3/lib/netapi/libnetapi.h index 3eab6e61ab..2711558dbc 100644 --- a/source3/lib/netapi/libnetapi.h +++ b/source3/lib/netapi/libnetapi.h @@ -440,4 +440,21 @@ WERROR NetShutdownAbort_r(struct libnetapi_ctx *ctx, struct NetShutdownAbort *r); WERROR NetShutdownAbort_l(struct libnetapi_ctx *ctx, struct NetShutdownAbort *r); +NET_API_STATUS I_NetLogonControl(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t **buffer /* [out] [ref] */); +WERROR I_NetLogonControl_r(struct libnetapi_ctx *ctx, + struct I_NetLogonControl *r); +WERROR I_NetLogonControl_l(struct libnetapi_ctx *ctx, + struct I_NetLogonControl *r); +NET_API_STATUS I_NetLogonControl2(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t *data /* [in] [ref] */, + uint8_t **buffer /* [out] [ref] */); +WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx, + struct I_NetLogonControl2 *r); +WERROR I_NetLogonControl2_l(struct libnetapi_ctx *ctx, + struct I_NetLogonControl2 *r); #endif /* __LIBNETAPI_LIBNETAPI__ */ diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index e3ab03eadc..96cf225d0c 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. * NetApi Support - * Copyright (C) Guenther Deschner 2007-2008 + * Copyright (C) Guenther Deschner 2007-2009 * * 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 @@ -1257,8 +1257,56 @@ struct FILE_INFO_3 { const char * fi3_username; }; +struct NETLOGON_INFO_1 { + uint32_t netlog1_flags; + NET_API_STATUS netlog1_pdc_connection_status; +}; + +struct NETLOGON_INFO_2 { + uint32_t netlog2_flags; + NET_API_STATUS netlog2_pdc_connection_status; + const char * netlog2_trusted_dc_name; + NET_API_STATUS netlog2_tc_connection_status; +}; + +struct NETLOGON_INFO_3 { + uint32_t netlog1_flags; + uint32_t netlog3_logon_attempts; + uint32_t netlog3_reserved1; + uint32_t netlog3_reserved2; + uint32_t netlog3_reserved3; + uint32_t netlog3_reserved4; + uint32_t netlog3_reserved5; +}; + +struct NETLOGON_INFO_4 { + const char * netlog4_trusted_dc_name; + const char * netlog4_trusted_domain_name; +}; + #endif /* _HEADER_libnetapi */ +#ifndef _HEADER_netlogon + +#define NETLOGON_CONTROL_QUERY ( 0x00000001 ) +#define NETLOGON_CONTROL_REPLICATE ( 0x00000002 ) +#define NETLOGON_CONTROL_SYNCHRONIZE ( 0x00000003 ) +#define NETLOGON_CONTROL_PDC_REPLICATE ( 0x00000004 ) +#define NETLOGON_CONTROL_REDISCOVER ( 0x00000005 ) +#define NETLOGON_CONTROL_TC_QUERY ( 0x00000006 ) +#define NETLOGON_CONTROL_TRANSPORT_NOTIFY ( 0x00000007 ) +#define NETLOGON_CONTROL_FIND_USER ( 0x00000008 ) +#define NETLOGON_CONTROL_CHANGE_PASSWORD ( 0x00000009 ) +#define NETLOGON_CONTROL_TC_VERIFY ( 0x0000000A ) +#define NETLOGON_CONTROL_FORCE_DNS_REG ( 0x0000000B ) +#define NETLOGON_CONTROL_QUERY_DNS_REG ( 0x0000000C ) +#define NETLOGON_CONTROL_BACKUP_CHANGE_LOG ( 0x0000FFFC ) +#define NETLOGON_CONTROL_TRUNCATE_LOG ( 0x0000FFFD ) +#define NETLOGON_CONTROL_SET_DBFLAG ( 0x0000FFFE ) +#define NETLOGON_CONTROL_BREAKPOINT ( 0x0000FFFF ) + +#endif /* _HEADER_netlogon */ + /**************************************************************** ****************************************************************/ @@ -2481,6 +2529,48 @@ NET_API_STATUS NetShutdownInit(const char * server_name /* [in] */, NET_API_STATUS NetShutdownAbort(const char * server_name /* [in] */); +/************************************************************//** + * + * I_NetLogonControl + * + * @brief Control various aspects of the NETLOGON service + * + * @param[in] server_name The server name to connect to + * @param[in] function_code The function code to call on the server + * @param[in] query_level The level of the NETLOGON_INFO structure returned + * @param[out] buffer The returned buffer containing the NETLOGON_INFO structure + * @return NET_API_STATUS + * + * example netlogon/netlogon_control.c + ***************************************************************/ + +NET_API_STATUS I_NetLogonControl(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t **buffer /* [out] [ref] */); + +/************************************************************//** + * + * I_NetLogonControl2 + * + * @brief Control various aspects of the NETLOGON service + * + * @param[in] server_name The server name to connect to + * @param[in] function_code The function code to call on the server + * @param[in] query_level The level of the NETLOGON_INFO structure returned + * @param[in] data The buffer containing information related to the function code + * @param[out] buffer The returned buffer containing the NETLOGON_INFO structure + * @return NET_API_STATUS + * + * example netlogon/netlogon_control2.c + ***************************************************************/ + +NET_API_STATUS I_NetLogonControl2(const char * server_name /* [in] */, + uint32_t function_code /* [in] */, + uint32_t query_level /* [in] */, + uint8_t *data /* [in] [ref] */, + uint8_t **buffer /* [out] [ref] */); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/source3/lib/netapi/netlogon.c b/source3/lib/netapi/netlogon.c new file mode 100644 index 0000000000..082938cadc --- /dev/null +++ b/source3/lib/netapi/netlogon.c @@ -0,0 +1,240 @@ +/* + * Unix SMB/CIFS implementation. + * NetApi LogonControl Support + * Copyright (C) Guenther Deschner 2009 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" + +#include "librpc/gen_ndr/libnetapi.h" +#include "lib/netapi/netapi.h" +#include "lib/netapi/netapi_private.h" +#include "lib/netapi/libnetapi.h" + +static WERROR construct_data(enum netr_LogonControlCode function_code, + const uint8_t *data_in, + union netr_CONTROL_DATA_INFORMATION *data_out) +{ + switch (function_code) { + case NETLOGON_CONTROL_QUERY: + case NETLOGON_CONTROL_REDISCOVER: + case NETLOGON_CONTROL_TC_QUERY: + case NETLOGON_CONTROL_CHANGE_PASSWORD: + case NETLOGON_CONTROL_TC_VERIFY: + data_out->domain = (const char *)data_in; + break; + case NETLOGON_CONTROL_FIND_USER: + data_out->user = (const char *)data_in; + break; + case NETLOGON_CONTROL_SET_DBFLAG: + data_out->debug_level = atoi((const char *)data_in); + break; + default: + return WERR_INVALID_PARAM; + } + + return WERR_OK; +} + +static WERROR construct_buffer(TALLOC_CTX *mem_ctx, + uint32_t level, + union netr_CONTROL_QUERY_INFORMATION *q, + uint8_t **buffer) +{ + struct NETLOGON_INFO_1 *i1; + struct NETLOGON_INFO_2 *i2; + struct NETLOGON_INFO_3 *i3; + struct NETLOGON_INFO_4 *i4; + + if (!q) { + return WERR_INVALID_PARAM; + } + + switch (level) { + case 1: + i1 = talloc(mem_ctx, struct NETLOGON_INFO_1); + W_ERROR_HAVE_NO_MEMORY(i1); + + i1->netlog1_flags = q->info1->flags; + i1->netlog1_pdc_connection_status = W_ERROR_V(q->info1->pdc_connection_status); + + *buffer = (uint8_t *)i1; + + break; + case 2: + i2 = talloc(mem_ctx, struct NETLOGON_INFO_2); + W_ERROR_HAVE_NO_MEMORY(i2); + + i2->netlog2_flags = q->info2->flags; + i2->netlog2_pdc_connection_status = W_ERROR_V(q->info2->pdc_connection_status); + i2->netlog2_trusted_dc_name = talloc_strdup(mem_ctx, q->info2->trusted_dc_name); + i2->netlog2_tc_connection_status = W_ERROR_V(q->info2->tc_connection_status); + + *buffer = (uint8_t *)i2; + + break; + case 3: + i3 = talloc(mem_ctx, struct NETLOGON_INFO_3); + W_ERROR_HAVE_NO_MEMORY(i3); + + i3->netlog1_flags = q->info3->flags; + i3->netlog3_logon_attempts = q->info3->logon_attempts; + i3->netlog3_reserved1 = q->info3->unknown1; + i3->netlog3_reserved2 = q->info3->unknown2; + i3->netlog3_reserved3 = q->info3->unknown3; + i3->netlog3_reserved4 = q->info3->unknown4; + i3->netlog3_reserved5 = q->info3->unknown5; + + *buffer = (uint8_t *)i3; + + break; + case 4: + i4 = talloc(mem_ctx, struct NETLOGON_INFO_4); + W_ERROR_HAVE_NO_MEMORY(i4); + + i4->netlog4_trusted_dc_name = talloc_strdup(mem_ctx, q->info4->trusted_dc_name); + i4->netlog4_trusted_domain_name = talloc_strdup(mem_ctx, q->info4->trusted_domain_name); + + *buffer = (uint8_t *)i4; + + break; + default: + return WERR_UNKNOWN_LEVEL; + } + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +WERROR I_NetLogonControl_r(struct libnetapi_ctx *ctx, + struct I_NetLogonControl *r) +{ + WERROR werr; + NTSTATUS status; + struct rpc_pipe_client *pipe_cli = NULL; + union netr_CONTROL_QUERY_INFORMATION query; + + werr = libnetapi_open_pipe(ctx, r->in.server_name, + &ndr_table_netlogon.syntax_id, + &pipe_cli); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + status = rpccli_netr_LogonControl(pipe_cli, ctx, + r->in.server_name, + r->in.function_code, + r->in.query_level, + &query, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + werr = construct_buffer(ctx, r->in.query_level, &query, + r->out.buffer); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + done: + return werr; +} + +/**************************************************************** +****************************************************************/ + +WERROR I_NetLogonControl_l(struct libnetapi_ctx *ctx, + struct I_NetLogonControl *r) +{ + LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl); +} + +/**************************************************************** +****************************************************************/ + +WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx, + struct I_NetLogonControl2 *r) +{ + WERROR werr; + NTSTATUS status; + struct rpc_pipe_client *pipe_cli = NULL; + union netr_CONTROL_DATA_INFORMATION data; + union netr_CONTROL_QUERY_INFORMATION query; + + werr = construct_data(r->in.function_code, r->in.data, &data); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + werr = libnetapi_open_pipe(ctx, r->in.server_name, + &ndr_table_netlogon.syntax_id, + &pipe_cli); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + switch (r->in.function_code) { + case NETLOGON_CONTROL_TC_VERIFY: + case NETLOGON_CONTROL_SET_DBFLAG: + status = rpccli_netr_LogonControl2Ex(pipe_cli, ctx, + r->in.server_name, + r->in.function_code, + r->in.query_level, + &data, + &query, + &werr); + break; + default: + status = rpccli_netr_LogonControl2(pipe_cli, ctx, + r->in.server_name, + r->in.function_code, + r->in.query_level, + &data, + &query, + &werr); + break; + } + + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + werr = construct_buffer(ctx, r->in.query_level, &query, + r->out.buffer); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + + done: + return werr; +} + +/**************************************************************** +****************************************************************/ + +WERROR I_NetLogonControl2_l(struct libnetapi_ctx *ctx, + struct I_NetLogonControl2 *r) +{ + LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, I_NetLogonControl2); +} diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index c96801a72b..7287e3d998 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -721,9 +721,18 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) rc = ldap_initialize(ldap_struct, uri); if (rc) { DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc))); + return rc; } - return rc; + if (lp_ldap_ref_follow() != Auto) { + rc = ldap_set_option(*ldap_struct, LDAP_OPT_REFERRALS, + lp_ldap_ref_follow() ? LDAP_OPT_ON : LDAP_OPT_OFF); + if (rc != LDAP_SUCCESS) + DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n", + ldap_err2string(rc))); + } + + return LDAP_SUCCESS; #else /* Parse the string manually */ @@ -774,7 +783,6 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri) } #endif /* HAVE_LDAP_INITIALIZE */ - /* now set connection timeout */ #ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */ { @@ -1046,12 +1054,18 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_ int version; if (!ldap_state->anonymous && !ldap_state->bind_dn) { + char *bind_dn = NULL; + char *bind_secret = NULL; /* get the default dn and password only if they are not set already */ - if (!fetch_ldap_pw(&ldap_state->bind_dn, &ldap_state->bind_secret)) { + if (!fetch_ldap_pw(&bind_dn, &bind_secret)) { DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n")); return LDAP_INVALID_CREDENTIALS; } + smbldap_set_creds(ldap_state, false, bind_dn, bind_secret); + SAFE_FREE(bind_dn); + memset(bind_secret, '\0', strlen(bind_secret)); + SAFE_FREE(bind_secret); } /* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite diff --git a/source3/lib/system.c b/source3/lib/system.c index 2c6894ff94..f9cd4a2355 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -702,7 +702,7 @@ FILE *sys_fopen(const char *path, const char *type) A flock() wrapper that will perform the kernel flock. ********************************************************************/ -void kernel_flock(int fd, uint32 share_mode) +void kernel_flock(int fd, uint32 share_mode, uint32 access_mask) { #if HAVE_KERNEL_SHARE_MODES int kernel_mode = 0; diff --git a/source3/lib/util_reg.c b/source3/lib/util_reg.c index 1e1bcfeb10..ca46f86f69 100644 --- a/source3/lib/util_reg.c +++ b/source3/lib/util_reg.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../librpc/gen_ndr/ndr_winreg.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY @@ -75,38 +76,86 @@ const char *reg_type_lookup(enum winreg_Type type) WERROR reg_pull_multi_sz(TALLOC_CTX *mem_ctx, const void *buf, size_t len, uint32 *num_values, char ***values) { - const smb_ucs2_t *p = (const smb_ucs2_t *)buf; - *num_values = 0; + DATA_BLOB blob; + const char **vals; + int i; - /* - * Make sure that a talloc context for the strings retrieved exists - */ + blob = data_blob_const((uint8_t *)buf, len); - if (!(*values = TALLOC_ARRAY(mem_ctx, char *, 1))) { + if (!pull_reg_multi_sz(mem_ctx, &blob, &vals)) { return WERR_NOMEM; } - len /= 2; /* buf is a set of UCS2 strings */ + for (i=0; vals[i]; i++) { + ;; + } - while (len > 0) { - char *val; - size_t dstlen, thislen; + *num_values = i; + *values = (char **)vals; - thislen = strnlen_w(p, len) + 1; - if (!convert_string_talloc(*values, CH_UTF16LE, CH_UNIX, - p, thislen*2, (void *)&val, &dstlen, true)) { - TALLOC_FREE(*values); - return WERR_NOMEM; - } + return WERR_OK; +} - ADD_TO_ARRAY(*values, char *, val, values, num_values); - if (*values == NULL) { - return WERR_NOMEM; - } +/******************************************************************* + push a string in unix charset into a REG_SZ UCS2 null terminated blob + ********************************************************************/ - p += thislen; - len -= thislen; +bool push_reg_sz(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char *s) +{ + union winreg_Data data; + enum ndr_err_code ndr_err; + data.string = s; + ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL, &data, REG_SZ, + (ndr_push_flags_fn_t)ndr_push_winreg_Data); + return NDR_ERR_CODE_IS_SUCCESS(ndr_err); +} + +/******************************************************************* + push a string_array in unix charset into a REG_MULTI_SZ UCS2 double-null + terminated blob + ********************************************************************/ + +bool push_reg_multi_sz(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, const char **a) +{ + union winreg_Data data; + enum ndr_err_code ndr_err; + data.string_array = a; + ndr_err = ndr_push_union_blob(blob, mem_ctx, NULL, &data, REG_MULTI_SZ, + (ndr_push_flags_fn_t)ndr_push_winreg_Data); + return NDR_ERR_CODE_IS_SUCCESS(ndr_err); +} + +/******************************************************************* + pull a string in unix charset out of a REG_SZ UCS2 null terminated blob + ********************************************************************/ + +bool pull_reg_sz(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char **s) +{ + union winreg_Data data; + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL, &data, REG_SZ, + (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; } + *s = data.string; + return true; +} - return WERR_OK; +/******************************************************************* + pull a string_array in unix charset out of a REG_MULTI_SZ UCS2 double-null + terminated blob + ********************************************************************/ + +bool pull_reg_multi_sz(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, const char ***a) +{ + union winreg_Data data; + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_union_blob(blob, mem_ctx, NULL, &data, REG_MULTI_SZ, + (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + *a = data.string_array; + return true; } diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 7d80b3cdea..f53ef94d69 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -256,41 +256,6 @@ char *skip_unibuf(char *src, size_t len) return src; } -/* Copy a string from little-endian or big-endian unicode source (depending - * on flags) to internal samba format destination - */ - -int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags) -{ - if (!src) { - dest[0] = 0; - return 0; - } - if(dest_len==-1) { - dest_len=MAXUNI-3; - } - return pull_ucs2(NULL, dest, src, dest_len, src_len, flags|STR_UNICODE|STR_NOALIGN); -} - -/* Copy a string from little-endian or big-endian unicode source (depending - * on flags) to internal samba format destination. Allocates on talloc ctx. - */ - -int rpcstr_pull_talloc(TALLOC_CTX *ctx, - char **dest, - void *src, - int src_len, - int flags) -{ - return pull_ucs2_base_talloc(ctx, - NULL, - dest, - src, - src_len, - flags|STR_UNICODE|STR_NOALIGN); - -} - /* Converts a string from internal samba format to unicode */ |