diff options
-rw-r--r-- | source3/lib/netapi/examples/Makefile.in | 16 | ||||
-rw-r--r-- | source3/lib/netapi/examples/getjoinableous/getjoinableous.c | 104 | ||||
-rw-r--r-- | source3/lib/netapi/joindomain.c | 192 |
3 files changed, 309 insertions, 3 deletions
diff --git a/source3/lib/netapi/examples/Makefile.in b/source3/lib/netapi/examples/Makefile.in index c2f453dedc..86e1b1bc2f 100644 --- a/source3/lib/netapi/examples/Makefile.in +++ b/source3/lib/netapi/examples/Makefile.in @@ -5,7 +5,7 @@ KRB5LIBS=@KRB5_LIBS@ LDAP_LIBS=@LDAP_LIBS@ LIBS=@LIBS@ -lnetapi DEVELOPER_CFLAGS=@DEVELOPER_CFLAGS@ -FLAGS=@CFLAGS@ $(GTK_FLAGS) +FLAGS=-I../ -L../../../bin @CFLAGS@ $(GTK_FLAGS) CC=@CC@ LDFLAGS=@PIE_LDFLAGS@ @LDFLAGS@ DYNEXP=@DYNEXP@ @@ -36,8 +36,12 @@ MAKEDIR = || exec false; \ GETDC_OBJ = getdc/getdc.o NETDOMJOIN_OBJ = netdomjoin/netdomjoin.o NETDOMJOIN_GUI_OBJ = netdomjoin-gui/netdomjoin-gui.o +GETJOINABLEOUS_OBJ = getjoinableous/getjoinableous.o -PROGS = bin/getdc@EXEEXT@ bin/netdomjoin@EXEEXT@ bin/netdomjoin-gui@EXEEXT@ +PROGS = bin/getdc@EXEEXT@ \ + bin/netdomjoin@EXEEXT@ \ + bin/netdomjoin-gui@EXEEXT@ \ + bin/getjoinableous@EXEEXT@ all: $(PROGS) @@ -45,6 +49,10 @@ bin/getdc@EXEEXT@: $(GETDC_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(GETDC_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) +bin/getjoinableous@EXEEXT@: $(GETJOINABLEOUS_OBJ) + @echo Linking $@ + @$(CC) $(FLAGS) -o $@ $(GETJOINABLEOUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) + bin/netdomjoin@EXEEXT@: $(NETDOMJOIN_OBJ) @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(NETDOMJOIN_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) @@ -54,4 +62,6 @@ bin/netdomjoin-gui@EXEEXT@: $(NETDOMJOIN_GUI_OBJ) @$(CC) $(FLAGS) $(GTK_FLAGS) -o $@ $(NETDOMJOIN_GUI_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(GTK_LIBS) clean: - @rm -f $(PROGS) + -rm -f $(PROGS) + -rm -f core */*~ *~ \ + */*.o */*/*.o */*/*/*.o \ diff --git a/source3/lib/netapi/examples/getjoinableous/getjoinableous.c b/source3/lib/netapi/examples/getjoinableous/getjoinableous.c new file mode 100644 index 0000000000..5a3366c9dc --- /dev/null +++ b/source3/lib/netapi/examples/getjoinableous/getjoinableous.c @@ -0,0 +1,104 @@ +/* + * Unix SMB/CIFS implementation. + * Join Support (cmdline + netapi) + * Copyright (C) Guenther Deschner 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * 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 <string.h> +#include <stdio.h> + +#include <netapi.h> + +char *get_string_param(const char *param) +{ + char *p; + + p = strchr(param, '='); + if (!p) { + return NULL; + } + + return (p+1); +} + +int main(int argc, char **argv) +{ + NET_API_STATUS status; + const char *server_name = NULL; + const char *domain_name = NULL; + const char *account = NULL; + const char *password = NULL; + const char **ous = NULL; + uint32_t num_ous = 0; + struct libnetapi_ctx *ctx = NULL; + int i; + + status = libnetapi_init(&ctx); + if (status != 0) { + return status; + } + + if (argc < 2) { + printf("usage: getjoinableous\n"); + printf("\t<hostname> [domain=DOMAIN] <user=USER> <password=PASSWORD>\n"); + return 0; + } + + if (argc > 2) { + server_name = argv[1]; + } + + for (i=0; i<argc; i++) { + if (strncasecmp(argv[i], "domain", strlen("domain"))== 0) { + domain_name = get_string_param(argv[i]); + } + if (strncasecmp(argv[i], "user", strlen("user"))== 0) { + account = get_string_param(argv[i]); + libnetapi_set_username(ctx, account); + } + if (strncasecmp(argv[i], "password", strlen("password"))== 0) { + password = get_string_param(argv[i]); + libnetapi_set_password(ctx, password); + } + if (strncasecmp(argv[i], "debug", strlen("debug"))== 0) { + const char *str = NULL; + str = get_string_param(argv[i]); + libnetapi_set_debuglevel(ctx, str); + } + } + + status = NetGetJoinableOUs(server_name, + domain_name, + account, + password, + &num_ous, + &ous); + if (status != 0) { + printf("failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + } else { + printf("Successfully queried joinable ous:\n"); + for (i=0; i<num_ous; i++) { + printf("ou: %s\n", ous[i]); + } + } + + NetApiBufferFree(ous); + + libnetapi_free(ctx); + + return status; +} diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c index 43662b3ffa..cbfc6c01e3 100644 --- a/source3/lib/netapi/joindomain.c +++ b/source3/lib/netapi/joindomain.c @@ -546,3 +546,195 @@ NET_API_STATUS NetGetJoinInformation(const char *server_name, return NET_API_STATUS_SUCCESS; } + +/**************************************************************** +****************************************************************/ + +static WERROR NetGetJoinableOUsLocal(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + NTSTATUS status; + ADS_STATUS ads_status; + ADS_STRUCT *ads = NULL; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED | + DS_RETURN_DNS_NAME; + + status = dsgetdcname(ctx, NULL, domain, + NULL, NULL, flags, &info); + if (!NT_STATUS_IS_OK(status)) { + libnetapi_set_error_string(ctx, "%s", + get_friendly_nt_error_msg(status)); + return ntstatus_to_werror(status); + } + + ads = ads_init(domain, domain, info->domain_controller_name); + if (!ads) { + return WERR_GENERAL_FAILURE; + } + + SAFE_FREE(ads->auth.user_name); + if (account) { + ads->auth.user_name = SMB_STRDUP(account); + } else if (ctx->username) { + ads->auth.user_name = SMB_STRDUP(ctx->username); + } + + SAFE_FREE(ads->auth.password); + if (password) { + ads->auth.password = SMB_STRDUP(password); + } else if (ctx->password) { + ads->auth.password = SMB_STRDUP(ctx->password); + } + + ads_status = ads_connect(ads); + if (!ADS_ERR_OK(ads_status)) { + ads_destroy(&ads); + return WERR_DEFAULT_JOIN_REQUIRED; + } + + ads_status = ads_get_joinable_ous(ads, ctx, + (char ***)ous, + (size_t *)ou_count); + if (!ADS_ERR_OK(ads_status)) { + ads_destroy(&ads); + return WERR_DEFAULT_JOIN_REQUIRED; + } + + ads_destroy(&ads); + return WERR_OK; +} + +/**************************************************************** +****************************************************************/ + +static WERROR NetGetJoinableOUsRemote(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + struct wkssvc_PasswordBuffer *encrypted_password = NULL; + NTSTATUS status; + WERROR werr; + + status = cli_full_connection(&cli, NULL, server_name, + NULL, 0, + "IPC$", "IPC", + ctx->username, + ctx->workgroup, + ctx->password, + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_WKSSVC, + &status); + if (!pipe_cli) { + werr = ntstatus_to_werror(status); + goto done; + } + + if (password) { + encode_wkssvc_join_password_buffer(ctx, + password, + &cli->user_session_key, + &encrypted_password); + } + + status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx, + server_name, + domain, + account, + encrypted_password, + ou_count, + ous, + &werr); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + done: + if (cli) { + cli_shutdown(cli); + } + + return werr; +} + +/**************************************************************** +****************************************************************/ + +static WERROR libnetapi_NetGetJoinableOUs(struct libnetapi_ctx *ctx, + const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + if (!server_name || is_myname_or_ipaddr(server_name)) { + return NetGetJoinableOUsLocal(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); + } + + return NetGetJoinableOUsRemote(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); +} + +/**************************************************************** + NetGetJoinableOUs +****************************************************************/ + +NET_API_STATUS NetGetJoinableOUs(const char *server_name, + const char *domain, + const char *account, + const char *password, + uint32_t *ou_count, + const char ***ous) +{ + struct libnetapi_ctx *ctx = NULL; + NET_API_STATUS status; + WERROR werr; + + status = libnetapi_getctx(&ctx); + if (status != 0) { + return status; + } + + werr = libnetapi_NetGetJoinableOUs(ctx, + server_name, + domain, + account, + password, + ou_count, + ous); + if (!W_ERROR_IS_OK(werr)) { + return W_ERROR_V(werr); + } + + return NET_API_STATUS_SUCCESS; +} |