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/netapi | |
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/netapi')
-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 |
9 files changed, 1006 insertions, 6 deletions
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); +} |