s3-rpc_client: support AES encryption in netr_ServerPasswordSet2 client.
[kai/samba.git] / source3 / utils / net_dom.c
index 30993ae2fa7742df290b762633c9cd129d702c1b..b2f02a4f4f7645cf0553070b3ec0f6a152e918a3 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Samba Unix/Linux SMB client library
    net dom commands for remote join/unjoin
-   Copyright (C) 2007 Günther Deschner
+   Copyright (C) 2007,2009 Günther Deschner
 
    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
 
 #include "includes.h"
 #include "utils/net.h"
+#include "../librpc/gen_ndr/ndr_initshutdown.h"
+#include "../librpc/gen_ndr/ndr_winreg.h"
 #include "lib/netapi/netapi.h"
+#include "lib/netapi/netapi_net.h"
+#include "libsmb/libsmb.h"
 
-static int net_dom_usage(int argc, const char **argv)
+int net_dom_usage(struct net_context *c, int argc, const char **argv)
 {
-       d_printf("usage: net dom join "
-                "<domain=DOMAIN> <ou=OU> <account=ACCOUNT> <password=PASSWORD> <reboot>\n");
-       d_printf("usage: net dom unjoin "
-                "<account=ACCOUNT> <password=PASSWORD> <reboot>\n");
+       d_printf("%s\n%s",
+               _("Usage:"),
+               _("net dom join "
+                  "<domain=DOMAIN> <ou=OU> <account=ACCOUNT> "
+                  "<password=PASSWORD> <reboot>\n  Join a remote machine\n"));
+       d_printf("%s\n%s",
+                _("Usage:"),
+                _("net dom unjoin "
+                  "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
+                  "  Unjoin a remote machine\n"));
+       d_printf("%s\n%s",
+                _("Usage:"),
+                _("net dom renamecomputer "
+                  "<newname=NEWNAME> "
+                  "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
+                  "  Rename joined computer\n"));
 
        return -1;
 }
 
-int net_help_dom(int argc, const char **argv)
+static int net_dom_unjoin(struct net_context *c, int argc, const char **argv)
 {
-       d_printf("net dom join"\
-               "\n  Join a remote machine\n");
-       d_printf("net dom unjoin"\
-               "\n  Unjoin a remote machine\n");
-
-       return -1;
-}
-
-static int net_dom_unjoin(int argc, const char **argv)
-{
-       struct libnetapi_ctx *ctx = NULL;
        const char *server_name = NULL;
        const char *account = NULL;
        const char *password = NULL;
-       uint32_t unjoin_flags = WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE |
-                               WKSSVC_JOIN_FLAGS_JOIN_TYPE;
+       uint32_t unjoin_flags = NETSETUP_ACCT_DELETE |
+                               NETSETUP_JOIN_DOMAIN |
+                               NETSETUP_IGNORE_UNSUPPORTED_FLAGS;
        struct cli_state *cli = NULL;
-       bool reboot = false;
+       bool do_reboot = false;
        NTSTATUS ntstatus;
        NET_API_STATUS status;
        int ret = -1;
        int i;
 
-       if (argc < 1) {
-               return net_dom_usage(argc, argv);
+       if (argc < 1 || c->display_usage) {
+               return net_dom_usage(c, argc, argv);
        }
 
-       if (opt_host) {
-               server_name = opt_host;
+       if (c->opt_host) {
+               server_name = c->opt_host;
        }
 
        for (i=0; i<argc; i++) {
@@ -78,46 +84,41 @@ static int net_dom_unjoin(int argc, const char **argv)
                        }
                }
                if (strequal(argv[i], "reboot")) {
-                       reboot = true;
+                       do_reboot = true;
                }
        }
 
-       if (reboot) {
-               ntstatus = net_make_ipc_connection_ex(opt_workgroup, server_name,
-                                                     NULL, 0, &cli);
+       if (do_reboot) {
+               ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
+                                                     server_name, NULL, 0,
+                                                     &cli);
                if (!NT_STATUS_IS_OK(ntstatus)) {
                        return -1;
                }
        }
 
-       status = libnetapi_init(&ctx);
-       if (status != 0) {
-               return -1;
-       }
-
-       libnetapi_set_username(ctx, opt_user_name);
-       libnetapi_set_password(ctx, opt_password);
-
        status = NetUnjoinDomain(server_name, account, password, unjoin_flags);
        if (status != 0) {
-               printf("Failed to unjoin domain: %s\n",
-                       libnetapi_errstr(status));
+               printf(_("Failed to unjoin domain: %s\n"),
+                       libnetapi_get_error_string(c->netapi_ctx, status));
                goto done;
        }
 
-       if (reboot) {
-               opt_comment = "Shutting down due to a domain membership change";
-               opt_reboot = true;
-               opt_timeout = 30;
+       if (do_reboot) {
+               c->opt_comment = _("Shutting down due to a domain membership "
+                                  "change");
+               c->opt_reboot = true;
+               c->opt_timeout = 30;
 
-               ret = run_rpc_command(cli, PI_INITSHUTDOWN, 0,
-                                     rpc_init_shutdown_internals,
+               ret = run_rpc_command(c, cli,
+                                     &ndr_table_initshutdown,
+                                     0, rpc_init_shutdown_internals,
                                      argc, argv);
                if (ret == 0) {
                        goto done;
                }
 
-               ret = run_rpc_command(cli, PI_WINREG, 0,
+               ret = run_rpc_command(c, cli, &ndr_table_winreg, 0,
                                      rpc_reg_shutdown_internals,
                                      argc, argv);
                goto done;
@@ -130,37 +131,35 @@ static int net_dom_unjoin(int argc, const char **argv)
                cli_shutdown(cli);
        }
 
-       /* libnetapi_free(ctx); */
        return ret;
 }
 
-static int net_dom_join(int argc, const char **argv)
+static int net_dom_join(struct net_context *c, int argc, const char **argv)
 {
-       struct libnetapi_ctx *ctx = NULL;
        const char *server_name = NULL;
        const char *domain_name = NULL;
        const char *account_ou = NULL;
        const char *Account = NULL;
        const char *password = NULL;
-       uint32_t join_flags = WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
-                             WKSSVC_JOIN_FLAGS_JOIN_TYPE;
+       uint32_t join_flags = NETSETUP_ACCT_CREATE |
+                             NETSETUP_JOIN_DOMAIN;
        struct cli_state *cli = NULL;
-       bool reboot = false;
+       bool do_reboot = false;
        NTSTATUS ntstatus;
        NET_API_STATUS status;
        int ret = -1;
        int i;
 
-       if (argc < 1) {
-               return net_dom_usage(argc, argv);
+       if (argc < 1 || c->display_usage) {
+               return net_dom_usage(c, argc, argv);
        }
 
-       if (opt_host) {
-               server_name = opt_host;
+       if (c->opt_host) {
+               server_name = c->opt_host;
        }
 
-       if (opt_force) {
-               join_flags |= WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
+       if (c->opt_force) {
+               join_flags |= NETSETUP_DOMAIN_JOIN_IF_JOINED;
        }
 
        for (i=0; i<argc; i++) {
@@ -189,13 +188,14 @@ static int net_dom_join(int argc, const char **argv)
                        }
                }
                if (strequal(argv[i], "reboot")) {
-                       reboot = true;
+                       do_reboot = true;
                }
        }
 
-       if (reboot) {
-               ntstatus = net_make_ipc_connection_ex(opt_workgroup, server_name,
-                                                     NULL, 0, &cli);
+       if (do_reboot) {
+               ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
+                                                     server_name, NULL, 0,
+                                                     &cli);
                if (!NT_STATUS_IS_OK(ntstatus)) {
                        return -1;
                }
@@ -203,35 +203,125 @@ static int net_dom_join(int argc, const char **argv)
 
        /* check if domain is a domain or a workgroup */
 
-       status = libnetapi_init(&ctx);
+       status = NetJoinDomain(server_name, domain_name, account_ou,
+                              Account, password, join_flags);
        if (status != 0) {
-               return -1;
+               printf(_("Failed to join domain: %s\n"),
+                       libnetapi_get_error_string(c->netapi_ctx, status));
+               goto done;
        }
 
-       libnetapi_set_username(ctx, opt_user_name);
-       libnetapi_set_password(ctx, opt_password);
+       if (do_reboot) {
+               c->opt_comment = _("Shutting down due to a domain membership "
+                                  "change");
+               c->opt_reboot = true;
+               c->opt_timeout = 30;
 
-       status = NetJoinDomain(server_name, domain_name, account_ou,
-                              Account, password, join_flags);
+               ret = run_rpc_command(c, cli, &ndr_table_initshutdown, 0,
+                                     rpc_init_shutdown_internals,
+                                     argc, argv);
+               if (ret == 0) {
+                       goto done;
+               }
+
+               ret = run_rpc_command(c, cli, &ndr_table_winreg, 0,
+                                     rpc_reg_shutdown_internals,
+                                     argc, argv);
+               goto done;
+       }
+
+       ret = 0;
+
+ done:
+       if (cli) {
+               cli_shutdown(cli);
+       }
+
+       return ret;
+}
+
+static int net_dom_renamecomputer(struct net_context *c, int argc, const char **argv)
+{
+       const char *server_name = NULL;
+       const char *account = NULL;
+       const char *password = NULL;
+       const char *newname = NULL;
+       uint32_t rename_options = NETSETUP_ACCT_CREATE;
+       struct cli_state *cli = NULL;
+       bool do_reboot = false;
+       NTSTATUS ntstatus;
+       NET_API_STATUS status;
+       int ret = -1;
+       int i;
+
+       if (argc < 1 || c->display_usage) {
+               return net_dom_usage(c, argc, argv);
+       }
+
+       if (c->opt_host) {
+               server_name = c->opt_host;
+       }
+
+       for (i=0; i<argc; i++) {
+               if (strnequal(argv[i], "account", strlen("account"))) {
+                       account = get_string_param(argv[i]);
+                       if (!account) {
+                               return -1;
+                       }
+               }
+               if (strnequal(argv[i], "password", strlen("password"))) {
+                       password = get_string_param(argv[i]);
+                       if (!password) {
+                               return -1;
+                       }
+               }
+               if (strnequal(argv[i], "newname", strlen("newname"))) {
+                       newname = get_string_param(argv[i]);
+                       if (!newname) {
+                               return -1;
+                       }
+               }
+               if (strequal(argv[i], "reboot")) {
+                       do_reboot = true;
+               }
+       }
+
+       if (do_reboot) {
+               ntstatus = net_make_ipc_connection_ex(c, c->opt_workgroup,
+                                                     server_name, NULL, 0,
+                                                     &cli);
+               if (!NT_STATUS_IS_OK(ntstatus)) {
+                       return -1;
+               }
+       }
+
+       status = NetRenameMachineInDomain(server_name, newname,
+                                         account, password, rename_options);
        if (status != 0) {
-               printf("Failed to join domain: %s\n",
-                       libnetapi_errstr(status));
+               printf(_("Failed to rename machine: "));
+               if (status == W_ERROR_V(WERR_SETUP_NOT_JOINED)) {
+                       printf(_("Computer is not joined to a Domain\n"));
+                       goto done;
+               }
+               printf("%s\n",
+                       libnetapi_get_error_string(c->netapi_ctx, status));
                goto done;
        }
 
-       if (reboot) {
-               opt_comment = "Shutting down due to a domain membership change";
-               opt_reboot = true;
-               opt_timeout = 30;
+       if (do_reboot) {
+               c->opt_comment = _("Shutting down due to a computer rename");
+               c->opt_reboot = true;
+               c->opt_timeout = 30;
 
-               ret = run_rpc_command(cli, PI_INITSHUTDOWN, 0,
-                                     rpc_init_shutdown_internals,
+               ret = run_rpc_command(c, cli,
+                                     &ndr_table_initshutdown,
+                                     0, rpc_init_shutdown_internals,
                                      argc, argv);
                if (ret == 0) {
                        goto done;
                }
 
-               ret = run_rpc_command(cli, PI_WINREG, 0,
+               ret = run_rpc_command(c, cli, &ndr_table_winreg, 0,
                                      rpc_reg_shutdown_internals,
                                      argc, argv);
                goto done;
@@ -244,18 +334,56 @@ static int net_dom_join(int argc, const char **argv)
                cli_shutdown(cli);
        }
 
-       /* libnetapi_free(ctx); */
        return ret;
 }
 
-int net_dom(int argc, const char **argv)
+int net_dom(struct net_context *c, int argc, const char **argv)
 {
+       NET_API_STATUS status;
+
        struct functable func[] = {
-               {"JOIN", net_dom_join},
-               {"UNJOIN", net_dom_unjoin},
-               {"HELP", net_help_dom},
-               {NULL, NULL}
+               {
+                       "join",
+                       net_dom_join,
+                       NET_TRANSPORT_LOCAL,
+                       N_("Join a remote machine"),
+                       N_("net dom join <domain=DOMAIN> <ou=OU> "
+                          "<account=ACCOUNT> <password=PASSWORD> <reboot>\n"
+                          "  Join a remote machine")
+               },
+               {
+                       "unjoin",
+                       net_dom_unjoin,
+                       NET_TRANSPORT_LOCAL,
+                       N_("Unjoin a remote machine"),
+                       N_("net dom unjoin <account=ACCOUNT> "
+                          "<password=PASSWORD> <reboot>\n"
+                          "  Unjoin a remote machine")
+               },
+               {
+                       "renamecomputer",
+                       net_dom_renamecomputer,
+                       NET_TRANSPORT_LOCAL,
+                       N_("Rename a computer that is joined to a domain"),
+                       N_("net dom renamecomputer <newname=NEWNAME> "
+                          "<account=ACCOUNT> <password=PASSWORD> "
+                          "<reboot>\n"
+                          "  Rename joined computer")
+               },
+
+               {NULL, NULL, 0, NULL, NULL}
        };
 
-       return net_run_function(argc, argv, func, net_dom_usage);
+       status = libnetapi_net_init(&c->netapi_ctx);
+       if (status != 0) {
+               return -1;
+       }
+
+       libnetapi_set_username(c->netapi_ctx, c->opt_user_name);
+       libnetapi_set_password(c->netapi_ctx, c->opt_password);
+       if (c->opt_kerberos) {
+               libnetapi_set_use_kerberos(c->netapi_ctx);
+       }
+
+       return net_run_function(c, argc, argv, "net dom", func);
 }