net: Move net_run_function/net_run_function2 to net_util.c
[samba.git] / source3 / utils / net.c
index 8015358f7de361d781f8a8ed8097e40f87324df4..e0edeef61008827ad27c4de45af109266b9a44e9 100644 (file)
@@ -1,29 +1,33 @@
-/* 
-   Samba Unix/Linux SMB client library 
-   Distributed SMB/CIFS Server Management Utility 
+/*
+   Samba Unix/Linux SMB client library
+   Distributed SMB/CIFS Server Management Utility
    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
    Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
    Copyright (C) 2001 Andrew Bartlett (abartlet@samba.org)
+   Copyright (C) 2008 Kai Blin (kai@samba.org)
 
    Originally written by Steve and Jim. Largely rewritten by tridge in
    November 2001.
 
    Reworked again by abartlet in December 2001
 
 
    Originally written by Steve and Jim. Largely rewritten by tridge in
    November 2001.
 
    Reworked again by abartlet in December 2001
 
+   Another overhaul, moving functionality into plug-ins loaded on demand by Kai
+   in May 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 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.
    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/>.  */
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
 /*****************************************************/
 /*                                                   */
 /*   Distributed SMB/CIFS Server Management Utility  */
 /*****************************************************/
 /*                                                   */
 /*   Distributed SMB/CIFS Server Management Utility  */
 #include "includes.h"
 #include "utils/net.h"
 
 #include "includes.h"
 #include "utils/net.h"
 
+extern bool AllowDebugChange;
+
+#ifdef WITH_FAKE_KASERVER
+#include "utils/net_afs.h"
+#endif
+
 /***********************************************************************/
 /* Beginning of internationalization section.  Translatable constants  */
 /* should be kept in this area and referenced in the rest of the code. */
 /***********************************************************************/
 /* Beginning of internationalization section.  Translatable constants  */
 /* should be kept in this area and referenced in the rest of the code. */
 #define YES_STRING              "Yes"
 #define NO_STRING               "No"
 
 #define YES_STRING              "Yes"
 #define NO_STRING               "No"
 
-/************************************************************************************/
-/*                       end of internationalization section                        */
-/************************************************************************************/
-
-/* Yes, these buggers are globals.... */
-const char *opt_requester_name = NULL;
-const char *opt_host = NULL;
-const char *opt_password = NULL;
-const char *opt_user_name = NULL;
-bool opt_user_specified = False;
-const char *opt_workgroup = NULL;
-int opt_long_list_entries = 0;
-int opt_reboot = 0;
-int opt_force = 0;
-int opt_stdin = 0;
-int opt_port = 0;
-int opt_verbose = 0;
-int opt_maxusers = -1;
-const char *opt_comment = "";
-const char *opt_container = NULL;
-int opt_flags = -1;
-int opt_timeout = 0;
-const char *opt_target_workgroup = NULL;
-int opt_machine_pass = 0;
-int opt_localgroup = False;
-int opt_domaingroup = False;
-static int do_talloc_report=False;
-const char *opt_newntname = "";
-int opt_rid = 0;
-int opt_acls = 0;
-int opt_attrs = 0;
-int opt_timestamps = 0;
-const char *opt_exclude = NULL;
-const char *opt_destination = NULL;
-int opt_testmode = False;
-
-int opt_have_ip = False;
-struct sockaddr_storage opt_dest_ip;
-
-extern bool AllowDebugChange;
+/***********************************************************************/
+/* end of internationalization section                                 */
+/***********************************************************************/
 
 
-uint32 get_sec_channel_type(const char *param) 
+uint32 get_sec_channel_type(const char *param)
 {
        if (!(param && *param)) {
                return get_default_sec_channel();
 {
        if (!(param && *param)) {
                return get_default_sec_channel();
@@ -102,7 +75,7 @@ uint32 get_sec_channel_type(const char *param)
                        return SEC_CHAN_BDC;
                } else if (strequal(param, "MEMBER")) {
                        return SEC_CHAN_WKSTA;
                        return SEC_CHAN_BDC;
                } else if (strequal(param, "MEMBER")) {
                        return SEC_CHAN_WKSTA;
-#if 0                  
+#if 0
                } else if (strequal(param, "DOMAIN")) {
                        return SEC_CHAN_DOMAIN;
 #endif
                } else if (strequal(param, "DOMAIN")) {
                        return SEC_CHAN_DOMAIN;
 #endif
@@ -112,471 +85,12 @@ uint32 get_sec_channel_type(const char *param)
        }
 }
 
        }
 }
 
-/*
-  run a function from a function table. If not found then
-  call the specified usage function 
-*/
-int net_run_function(int argc, const char **argv, struct functable *table, 
-                    int (*usage_fn)(int argc, const char **argv))
-{
-       int i;
-       
-       if (argc < 1) {
-               d_printf("\nUsage: \n");
-               return usage_fn(argc, argv);
-       }
-       for (i=0; table[i].funcname; i++) {
-               if (StrCaseCmp(argv[0], table[i].funcname) == 0)
-                       return table[i].fn(argc-1, argv+1);
-       }
-       d_fprintf(stderr, "No command: %s\n", argv[0]);
-       return usage_fn(argc, argv);
-}
-
-/*
- * run a function from a function table.
- */
-int net_run_function2(int argc, const char **argv, const char *whoami,
-                     struct functable2 *table)
-{
-       int i;
-
-       if (argc != 0) {
-               for (i=0; table[i].funcname; i++) {
-                       if (StrCaseCmp(argv[0], table[i].funcname) == 0)
-                               return table[i].fn(argc-1, argv+1);
-               }
-       }
-
-       for (i=0; table[i].funcname != NULL; i++) {
-               d_printf("%s %-15s %s\n", whoami, table[i].funcname,
-                        table[i].helptext);
-       }
-
-       return -1;
-}
-
-/****************************************************************************
- Connect to \\server\service.
-****************************************************************************/
-
-NTSTATUS connect_to_service(struct cli_state **c,
-                                       struct sockaddr_storage *server_ss,
-                                       const char *server_name,
-                                       const char *service_name,
-                                       const char *service_type)
-{
-       NTSTATUS nt_status;
-
-       opt_password = net_prompt_pass(opt_user_name);
-       if (!opt_password) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       nt_status = cli_full_connection(c, NULL, server_name,
-                                       server_ss, opt_port,
-                                       service_name, service_type,
-                                       opt_user_name, opt_workgroup,
-                                       opt_password, 0, Undefined, NULL);
-       if (NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       } else {
-               d_fprintf(stderr, "Could not connect to server %s\n", server_name);
-
-               /* Display a nicer message depending on the result */
-
-               if (NT_STATUS_V(nt_status) ==
-                   NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
-                       d_fprintf(stderr, "The username or password was not correct.\n");
-
-               if (NT_STATUS_V(nt_status) ==
-                   NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
-                       d_fprintf(stderr, "The account was locked out.\n");
-
-               if (NT_STATUS_V(nt_status) ==
-                   NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
-                       d_fprintf(stderr, "The account was disabled.\n");
-
-               return nt_status;
-       }
-}
-
-/****************************************************************************
- Connect to \\server\ipc$.
-****************************************************************************/
-
-NTSTATUS connect_to_ipc(struct cli_state **c,
-                       struct sockaddr_storage *server_ss,
-                       const char *server_name)
+static int net_changetrustpw(struct net_context *c, int argc, const char **argv)
 {
 {
-       return connect_to_service(c, server_ss, server_name, "IPC$", "IPC");
-}
+       if (net_ads_check_our_domain(c) == 0)
+               return net_ads_changetrustpw(c, argc, argv);
 
 
-/****************************************************************************
- Connect to \\server\ipc$ anonymously.
-****************************************************************************/
-
-NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
-                               struct sockaddr_storage *server_ss,
-                               const char *server_name)
-{
-       NTSTATUS nt_status;
-
-       nt_status = cli_full_connection(c, opt_requester_name, server_name,
-                                       server_ss, opt_port,
-                                       "IPC$", "IPC",
-                                       "", "",
-                                       "", 0, Undefined, NULL);
-
-       if (NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       } else {
-               DEBUG(1,("Cannot connect to server (anonymously).  Error was %s\n", nt_errstr(nt_status)));
-               return nt_status;
-       }
-}
-
-/****************************************************************************
- Return malloced user@realm for krb5 login.
-****************************************************************************/
-
-static char *get_user_and_realm(const char *username)
-{
-       char *user_and_realm = NULL;
-
-       if (!username) {
-               return NULL;
-       }
-       if (strchr_m(username, '@')) {
-               user_and_realm = SMB_STRDUP(username);
-       } else {
-               if (asprintf(&user_and_realm, "%s@%s", username, lp_realm()) == -1) {
-                       user_and_realm = NULL;
-               }
-       }
-       return user_and_realm;
-}
-
-/****************************************************************************
- Connect to \\server\ipc$ using KRB5.
-****************************************************************************/
-
-NTSTATUS connect_to_ipc_krb5(struct cli_state **c,
-                       struct sockaddr_storage *server_ss,
-                       const char *server_name)
-{
-       NTSTATUS nt_status;
-       char *user_and_realm = NULL;
-
-       opt_password = net_prompt_pass(opt_user_name);
-       if (!opt_password) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       user_and_realm = get_user_and_realm(opt_user_name);
-       if (!user_and_realm) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       nt_status = cli_full_connection(c, NULL, server_name,
-                                       server_ss, opt_port,
-                                       "IPC$", "IPC",
-                                       user_and_realm, opt_workgroup,
-                                       opt_password, CLI_FULL_CONNECTION_USE_KERBEROS, 
-                                       Undefined, NULL);
-
-       SAFE_FREE(user_and_realm);
-
-       if (NT_STATUS_IS_OK(nt_status)) {
-               return nt_status;
-       } else {
-               DEBUG(1,("Cannot connect to server using kerberos.  Error was %s\n", nt_errstr(nt_status)));
-               return nt_status;
-       }
-}
-
-/**
- * Connect a server and open a given pipe
- *
- * @param cli_dst              A cli_state 
- * @param pipe                 The pipe to open
- * @param got_pipe             boolean that stores if we got a pipe
- *
- * @return Normal NTSTATUS return.
- **/
-NTSTATUS connect_dst_pipe(struct cli_state **cli_dst, struct rpc_pipe_client **pp_pipe_hnd, int pipe_num)
-{
-       NTSTATUS nt_status;
-       char *server_name = SMB_STRDUP("127.0.0.1");
-       struct cli_state *cli_tmp = NULL;
-       struct rpc_pipe_client *pipe_hnd = NULL;
-
-       if (server_name == NULL) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       if (opt_destination) {
-               SAFE_FREE(server_name);
-               if ((server_name = SMB_STRDUP(opt_destination)) == NULL) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-       }
-
-       /* make a connection to a named pipe */
-       nt_status = connect_to_ipc(&cli_tmp, NULL, server_name);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               SAFE_FREE(server_name);
-               return nt_status;
-       }
-
-       pipe_hnd = cli_rpc_pipe_open_noauth(cli_tmp, pipe_num, &nt_status);
-       if (!pipe_hnd) {
-               DEBUG(0, ("couldn't not initialize pipe\n"));
-               cli_shutdown(cli_tmp);
-               SAFE_FREE(server_name);
-               return nt_status;
-       }
-
-       *cli_dst = cli_tmp;
-       *pp_pipe_hnd = pipe_hnd;
-       SAFE_FREE(server_name);
-
-       return nt_status;
-}
-
-/****************************************************************************
- Use the local machine account (krb) and password for this session.
-****************************************************************************/
-
-int net_use_krb_machine_account(void) 
-{
-       char *user_name = NULL;
-
-       if (!secrets_init()) {
-               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
-               exit(1);
-       }
-
-       opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
-       if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
-               return -1;
-       }
-       opt_user_name = user_name;
-       return 0;
-}
-
-/****************************************************************************
- Use the machine account name and password for this session.
-****************************************************************************/
-
-int net_use_machine_account(void)
-{
-       char *user_name = NULL;
-
-       if (!secrets_init()) {
-               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
-               exit(1);
-       }
-
-       opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
-       if (asprintf(&user_name, "%s$", global_myname()) == -1) {
-               return -1;
-       }
-       opt_user_name = user_name;
-       return 0;
-}
-
-bool net_find_server(const char *domain,
-                       unsigned flags,
-                       struct sockaddr_storage *server_ss,
-                       char **server_name)
-{
-       const char *d = domain ? domain : opt_target_workgroup;
-
-       if (opt_host) {
-               *server_name = SMB_STRDUP(opt_host);
-       }
-
-       if (opt_have_ip) {
-               *server_ss = opt_dest_ip;
-               if (!*server_name) {
-                       char addr[INET6_ADDRSTRLEN];
-                       print_sockaddr(addr, sizeof(addr), &opt_dest_ip);
-                       *server_name = SMB_STRDUP(addr);
-               }
-       } else if (*server_name) {
-               /* resolve the IP address */
-               if (!resolve_name(*server_name, server_ss, 0x20))  {
-                       DEBUG(1,("Unable to resolve server name\n"));
-                       return false;
-               }
-       } else if (flags & NET_FLAGS_PDC) {
-               fstring dc_name;
-               struct sockaddr_storage pdc_ss;
-
-               if (!get_pdc_ip(d, &pdc_ss)) {
-                       DEBUG(1,("Unable to resolve PDC server address\n"));
-                       return false;
-               }
-
-               if (is_zero_addr(&pdc_ss)) {
-                       return false;
-               }
-
-               if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) {
-                       return False;
-               }
-
-               *server_name = SMB_STRDUP(dc_name);
-               *server_ss = pdc_ss;
-       } else if (flags & NET_FLAGS_DMB) {
-               struct sockaddr_storage msbrow_ss;
-               char addr[INET6_ADDRSTRLEN];
-
-               /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
-               if (!resolve_name(d, &msbrow_ss, 0x1B))  {
-                       DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
-                       return false;
-               }
-               *server_ss = msbrow_ss;
-               print_sockaddr(addr, sizeof(addr), server_ss);
-               *server_name = SMB_STRDUP(addr);
-       } else if (flags & NET_FLAGS_MASTER) {
-               struct sockaddr_storage brow_ss;
-               char addr[INET6_ADDRSTRLEN];
-               if (!resolve_name(d, &brow_ss, 0x1D))  {
-                               /* go looking for workgroups */
-                       DEBUG(1,("Unable to resolve master browser via name lookup\n"));
-                       return false;
-               }
-               *server_ss = brow_ss;
-               print_sockaddr(addr, sizeof(addr), server_ss);
-               *server_name = SMB_STRDUP(addr);
-       } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
-               if (!interpret_string_addr(server_ss,
-                                       "127.0.0.1", AI_NUMERICHOST)) {
-                       DEBUG(1,("Unable to resolve 127.0.0.1\n"));
-                       return false;
-               }
-               *server_name = SMB_STRDUP("127.0.0.1");
-       }
-
-       if (!server_name || !*server_name) {
-               DEBUG(1,("no server to connect to\n"));
-               return False;
-       }
-
-       return True;
-}
-
-bool net_find_pdc(struct sockaddr_storage *server_ss,
-               fstring server_name,
-               const char *domain_name)
-{
-       if (!get_pdc_ip(domain_name, server_ss)) {
-               return false;
-       }
-       if (is_zero_addr(server_ss)) {
-               return false;
-       }
-
-       if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) {
-               return false;
-       }
-
-       return true;
-}
-
-NTSTATUS net_make_ipc_connection(unsigned flags, struct cli_state **pcli)
-{
-       return net_make_ipc_connection_ex(NULL, NULL, NULL, flags, pcli);
-}
-
-NTSTATUS net_make_ipc_connection_ex(const char *domain, const char *server,
-                                    struct sockaddr_storage *pss, unsigned flags,
-                                   struct cli_state **pcli)
-{
-       char *server_name = NULL;
-       struct sockaddr_storage server_ss;
-       struct cli_state *cli = NULL;
-       NTSTATUS nt_status;
-
-       if ( !server || !pss ) {
-               if (!net_find_server(domain, flags, &server_ss, &server_name)) {
-                       d_fprintf(stderr, "Unable to find a suitable server\n");
-                       nt_status = NT_STATUS_UNSUCCESSFUL;
-                       goto done;
-               }
-       } else {
-               server_name = SMB_STRDUP( server );
-               server_ss = *pss;
-       }
-
-       if (flags & NET_FLAGS_ANONYMOUS) {
-               nt_status = connect_to_ipc_anonymous(&cli, &server_ss, server_name);
-       } else {
-               nt_status = connect_to_ipc(&cli, &server_ss, server_name);
-       }
-
-       /* store the server in the affinity cache if it was a PDC */
-
-       if ( (flags & NET_FLAGS_PDC) && NT_STATUS_IS_OK(nt_status) )
-               saf_store( cli->server_domain, cli->desthost );
-
-       SAFE_FREE(server_name);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               d_fprintf(stderr, "Connection failed: %s\n",
-                         nt_errstr(nt_status));
-               cli = NULL;
-       }
-
-done:
-       if (pcli != NULL) {
-               *pcli = cli;
-       }
-       return nt_status;
-}
-
-static int net_user(int argc, const char **argv)
-{
-       if (net_ads_check() == 0)
-               return net_ads_user(argc, argv);
-
-       /* if server is not specified, default to PDC? */
-       if (net_rpc_check(NET_FLAGS_PDC))
-               return net_rpc_user(argc, argv);
-
-       return net_rap_user(argc, argv);
-}
-
-static int net_group(int argc, const char **argv)
-{
-       if (net_ads_check() == 0)
-               return net_ads_group(argc, argv);
-
-       if (argc == 0 && net_rpc_check(NET_FLAGS_PDC))
-               return net_rpc_group(argc, argv);
-
-       return net_rap_group(argc, argv);
-}
-
-static int net_join(int argc, const char **argv)
-{
-       if (net_ads_check_our_domain() == 0) {
-               if (net_ads_join(argc, argv) == 0)
-                       return 0;
-               else
-                       d_fprintf(stderr, "ADS join did not work, falling back to RPC...\n");
-       }
-       return net_rpc_join(argc, argv);
-}
-
-static int net_changetrustpw(int argc, const char **argv)
-{
-       if (net_ads_check_our_domain() == 0)
-               return net_ads_changetrustpw(argc, argv);
-
-       return net_rpc_changetrustpw(argc, argv);
+       return net_rpc_changetrustpw(c, argc, argv);
 }
 
 static void set_line_buffering(FILE *f)
 }
 
 static void set_line_buffering(FILE *f)
@@ -584,19 +98,20 @@ static void set_line_buffering(FILE *f)
        setvbuf(f, NULL, _IOLBF, 0);
 }
 
        setvbuf(f, NULL, _IOLBF, 0);
 }
 
-static int net_changesecretpw(int argc, const char **argv)
+static int net_changesecretpw(struct net_context *c, int argc,
+                             const char **argv)
 {
         char *trust_pw;
         uint32 sec_channel_type = SEC_CHAN_WKSTA;
 
 {
         char *trust_pw;
         uint32 sec_channel_type = SEC_CHAN_WKSTA;
 
-       if(opt_force) {
-               if (opt_stdin) {
+       if(c->opt_force) {
+               if (c->opt_stdin) {
                        set_line_buffering(stdin);
                        set_line_buffering(stdout);
                        set_line_buffering(stderr);
                }
 
                        set_line_buffering(stdin);
                        set_line_buffering(stdout);
                        set_line_buffering(stderr);
                }
 
-               trust_pw = get_pass("Enter machine password: ", opt_stdin);
+               trust_pw = get_pass("Enter machine password: ", c->opt_stdin);
 
                if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
                            d_fprintf(stderr, "Unable to write the machine account password in the secrets database");
 
                if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
                            d_fprintf(stderr, "Unable to write the machine account password in the secrets database");
@@ -615,24 +130,10 @@ static int net_changesecretpw(int argc, const char **argv)
         return 0;
 }
 
         return 0;
 }
 
-static int net_share(int argc, const char **argv)
-{
-       if (net_rpc_check(0))
-               return net_rpc_share(argc, argv);
-       return net_rap_share(argc, argv);
-}
-
-static int net_file(int argc, const char **argv)
-{
-       if (net_rpc_check(0))
-               return net_rpc_file(argc, argv);
-       return net_rap_file(argc, argv);
-}
-
 /*
  Retrieve our local SID or the SID for the specified name
  */
 /*
  Retrieve our local SID or the SID for the specified name
  */
-static int net_getlocalsid(int argc, const char **argv)
+static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
 {
         DOM_SID sid;
        const char *name;
 {
         DOM_SID sid;
        const char *name;
@@ -645,7 +146,7 @@ static int net_getlocalsid(int argc, const char **argv)
                name = global_myname();
        }
 
                name = global_myname();
        }
 
-       if(!initialize_password_db(False, NULL)) {
+       if(!initialize_password_db(false, NULL)) {
                DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
                          "backend knowledge (such as the sid stored in LDAP)\n"));
        }
                DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
                          "backend knowledge (such as the sid stored in LDAP)\n"));
        }
@@ -665,12 +166,12 @@ static int net_getlocalsid(int argc, const char **argv)
                DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
                return 1;
        }
                DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
                return 1;
        }
-       sid_to_string(sid_str, &sid);
+       sid_to_fstring(sid_str, &sid);
        d_printf("SID for domain %s is: %s\n", name, sid_str);
        return 0;
 }
 
        d_printf("SID for domain %s is: %s\n", name, sid_str);
        return 0;
 }
 
-static int net_setlocalsid(int argc, const char **argv)
+static int net_setlocalsid(struct net_context *c, int argc, const char **argv)
 {
        DOM_SID sid;
 
 {
        DOM_SID sid;
 
@@ -690,7 +191,7 @@ static int net_setlocalsid(int argc, const char **argv)
        return 0;
 }
 
        return 0;
 }
 
-static int net_setdomainsid(int argc, const char **argv)
+static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
 {
        DOM_SID sid;
 
 {
        DOM_SID sid;
 
@@ -710,14 +211,21 @@ static int net_setdomainsid(int argc, const char **argv)
        return 0;
 }
 
        return 0;
 }
 
-static int net_getdomainsid(int argc, const char **argv)
+static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
 {
        DOM_SID domain_sid;
        fstring sid_str;
 
 {
        DOM_SID domain_sid;
        fstring sid_str;
 
-       if(!initialize_password_db(False, NULL)) {
-               DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n"
-                         "backend knowledge (such as the sid stored in LDAP)\n"));
+       if (argc > 0) {
+               d_printf("usage: net getdomainsid\n");
+               return 1;
+       }
+
+       if(!initialize_password_db(false, NULL)) {
+               DEBUG(0, ("WARNING: Could not open passdb - domain SID may "
+                         "not reflect passdb\n"
+                         "backend knowledge (such as the SID stored in "
+                         "LDAP)\n"));
        }
 
        /* first check to see if we can even access secrets, so we don't
        }
 
        /* first check to see if we can even access secrets, so we don't
@@ -736,102 +244,20 @@ static int net_getdomainsid(int argc, const char **argv)
                d_fprintf(stderr, "Could not fetch local SID\n");
                return 1;
        }
                d_fprintf(stderr, "Could not fetch local SID\n");
                return 1;
        }
-       sid_to_string(sid_str, &domain_sid);
-       d_printf("SID for domain %s is: %s\n", global_myname(), sid_str);
+       sid_to_fstring(sid_str, &domain_sid);
+       d_printf("SID for local machine %s is: %s\n", global_myname(), sid_str);
 
 
-       if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) {
+       if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
                d_fprintf(stderr, "Could not fetch domain SID\n");
                return 1;
        }
 
                d_fprintf(stderr, "Could not fetch domain SID\n");
                return 1;
        }
 
-       sid_to_string(sid_str, &domain_sid);
-       d_printf("SID for domain %s is: %s\n", opt_workgroup, sid_str);
-
-       return 0;
-}
-
-#ifdef WITH_FAKE_KASERVER
-
-int net_help_afs(int argc, const char **argv)
-{
-       d_printf("  net afs key filename\n"
-                "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n");
-       d_printf("  net afs impersonate <user> <cell>\n"
-                "\tCreates a token for user@cell\n\n");
-       return -1;
-}
-
-static int net_afs_key(int argc, const char **argv)
-{
-       int fd;
-       struct afs_keyfile keyfile;
-
-       if (argc != 2) {
-               d_printf("usage: 'net afs key <keyfile> cell'\n");
-               return -1;
-       }
-
-       if (!secrets_init()) {
-               d_fprintf(stderr, "Could not open secrets.tdb\n");
-               return -1;
-       }
-
-       if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
-               d_fprintf(stderr, "Could not open %s\n", argv[0]);
-               return -1;
-       }
-
-       if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
-               d_fprintf(stderr, "Could not read keyfile\n");
-               return -1;
-       }
-
-       if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
-               d_fprintf(stderr, "Could not write keyfile to secrets.tdb\n");
-               return -1;
-       }
+       sid_to_fstring(sid_str, &domain_sid);
+       d_printf("SID for domain %s is: %s\n", c->opt_workgroup, sid_str);
 
        return 0;
 }
 
 
        return 0;
 }
 
-static int net_afs_impersonate(int argc, const char **argv)
-{
-       char *token;
-
-       if (argc != 2) {
-               fprintf(stderr, "Usage: net afs impersonate <user> <cell>\n");
-               exit(1);
-       }
-
-       token = afs_createtoken_str(argv[0], argv[1]);
-
-       if (token == NULL) {
-               fprintf(stderr, "Could not create token\n");
-               exit(1);
-       }
-
-       if (!afs_settoken_str(token)) {
-               fprintf(stderr, "Could not set token into kernel\n");
-               exit(1);
-       }
-
-       printf("Success: %s@%s\n", argv[0], argv[1]);
-       return 0;
-}
-
-static int net_afs(int argc, const char **argv)
-{
-       struct functable func[] = {
-               {"key", net_afs_key},
-               {"impersonate", net_afs_impersonate},
-               {"help", net_help_afs},
-               {NULL, NULL}
-       };
-       return net_run_function(argc, argv, func, net_help_afs);
-}
-
-#endif /* WITH_FAKE_KASERVER */
-
 static bool search_maxrid(struct pdb_search *search, const char *type,
                          uint32 *max_rid)
 {
 static bool search_maxrid(struct pdb_search *search, const char *type,
                          uint32 *max_rid)
 {
@@ -840,14 +266,14 @@ static bool search_maxrid(struct pdb_search *search, const char *type,
 
        if (search == NULL) {
                d_fprintf(stderr, "get_maxrid: Could not search %s\n", type);
 
        if (search == NULL) {
                d_fprintf(stderr, "get_maxrid: Could not search %s\n", type);
-               return False;
+               return false;
        }
 
        num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
        for (i=0; i<num_entries; i++)
                *max_rid = MAX(*max_rid, entries[i].rid);
        pdb_search_destroy(search);
        }
 
        num_entries = pdb_search_entries(search, 0, 0xffffffff, &entries);
        for (i=0; i<num_entries; i++)
                *max_rid = MAX(*max_rid, entries[i].rid);
        pdb_search_destroy(search);
-       return True;
+       return true;
 }
 
 static uint32 get_maxrid(void)
 }
 
 static uint32 get_maxrid(void)
@@ -863,11 +289,11 @@ static uint32 get_maxrid(void)
        if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
                           "aliases", &max_rid))
                return 0;
        if (!search_maxrid(pdb_search_aliases(get_global_sam_sid()),
                           "aliases", &max_rid))
                return 0;
-       
+
        return max_rid;
 }
 
        return max_rid;
 }
 
-static int net_maxrid(int argc, const char **argv)
+static int net_maxrid(struct net_context *c, int argc, const char **argv)
 {
        uint32 rid;
 
 {
        uint32 rid;
 
@@ -886,33 +312,6 @@ static int net_maxrid(int argc, const char **argv)
        return 0;
 }
 
        return 0;
 }
 
-/****************************************************************************
-****************************************************************************/
-
-const char *net_prompt_pass(const char *user)
-{
-       char *prompt = NULL;
-       const char *pass = NULL;
-
-       if (opt_password) {
-               return opt_password;
-       }
-
-       if (opt_machine_pass) {
-               return NULL;
-       }
-
-       asprintf(&prompt, "Enter %s's password:", user);
-       if (!prompt) {
-               return NULL;
-       }
-
-       pass = getpass(prompt);
-       SAFE_FREE(prompt);
-
-       return pass;
-}
-
 /* main function table */
 static struct functable net_func[] = {
        {"RPC", net_rpc},
 /* main function table */
 static struct functable net_func[] = {
        {"RPC", net_rpc},
@@ -933,13 +332,14 @@ static struct functable net_func[] = {
        {"VALIDATE", net_rap_validate},
        {"GROUPMEMBER", net_rap_groupmember},
        {"ADMIN", net_rap_admin},
        {"VALIDATE", net_rap_validate},
        {"GROUPMEMBER", net_rap_groupmember},
        {"ADMIN", net_rap_admin},
-       {"SERVICE", net_rap_service},   
+       {"SERVICE", net_rap_service},
        {"PASSWORD", net_rap_password},
        {"CHANGETRUSTPW", net_changetrustpw},
        {"CHANGESECRETPW", net_changesecretpw},
        {"TIME", net_time},
        {"LOOKUP", net_lookup},
        {"JOIN", net_join},
        {"PASSWORD", net_rap_password},
        {"CHANGETRUSTPW", net_changetrustpw},
        {"CHANGESECRETPW", net_changesecretpw},
        {"TIME", net_time},
        {"LOOKUP", net_lookup},
        {"JOIN", net_join},
+       {"DOM", net_dom},
        {"CACHE", net_cache},
        {"GETLOCALSID", net_getlocalsid},
        {"SETLOCALSID", net_setlocalsid},
        {"CACHE", net_cache},
        {"GETLOCALSID", net_getlocalsid},
        {"SETLOCALSID", net_setlocalsid},
@@ -951,6 +351,7 @@ static struct functable net_func[] = {
        {"USERSHARE", net_usershare},
        {"USERSIDLIST", net_usersidlist},
        {"CONF", net_conf},
        {"USERSHARE", net_usershare},
        {"USERSIDLIST", net_usersidlist},
        {"CONF", net_conf},
+       {"REGISTRY", net_registry},
 #ifdef WITH_FAKE_KASERVER
        {"AFS", net_afs},
 #endif
 #ifdef WITH_FAKE_KASERVER
        {"AFS", net_afs},
 #endif
@@ -971,96 +372,101 @@ static struct functable net_func[] = {
        int argc_new = 0;
        const char ** argv_new;
        poptContext pc;
        int argc_new = 0;
        const char ** argv_new;
        poptContext pc;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct net_context *c = talloc_zero(frame, struct net_context);
 
        struct poptOption long_options[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
 
        struct poptOption long_options[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
-               {"workgroup",   'w', POPT_ARG_STRING, &opt_target_workgroup},
-               {"user",        'U', POPT_ARG_STRING, &opt_user_name, 'U'},
+               {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
+               {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
                {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
                {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
-               {"port",        'p', POPT_ARG_INT,    &opt_port},
-               {"myname",      'n', POPT_ARG_STRING, &opt_requester_name},
-               {"server",      'S', POPT_ARG_STRING, &opt_host},
-               {"container",   'c', POPT_ARG_STRING, &opt_container},
-               {"comment",     'C', POPT_ARG_STRING, &opt_comment},
-               {"maxusers",    'M', POPT_ARG_INT,    &opt_maxusers},
-               {"flags",       'F', POPT_ARG_INT,    &opt_flags},
-               {"long",        'l', POPT_ARG_NONE,   &opt_long_list_entries},
-               {"reboot",      'r', POPT_ARG_NONE,   &opt_reboot},
-               {"force",       'f', POPT_ARG_NONE,   &opt_force},
-               {"stdin",       'i', POPT_ARG_NONE,   &opt_stdin},
-               {"timeout",     't', POPT_ARG_INT,    &opt_timeout},
-               {"machine-pass",'P', POPT_ARG_NONE,   &opt_machine_pass},
-               {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
-               {"verbose",     'v', POPT_ARG_NONE,   &opt_verbose},
-               {"test",        'T', POPT_ARG_NONE,   &opt_testmode},
+               {"port",        'p', POPT_ARG_INT,    &c->opt_port},
+               {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
+               {"server",      'S', POPT_ARG_STRING, &c->opt_host},
+               {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
+               {"container",   'c', POPT_ARG_STRING, &c->opt_container},
+               {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
+               {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
+               {"flags",       'F', POPT_ARG_INT,    &c->opt_flags},
+               {"long",        'l', POPT_ARG_NONE,   &c->opt_long_list_entries},
+               {"reboot",      'r', POPT_ARG_NONE,   &c->opt_reboot},
+               {"force",       'f', POPT_ARG_NONE,   &c->opt_force},
+               {"stdin",       'i', POPT_ARG_NONE,   &c->opt_stdin},
+               {"timeout",     't', POPT_ARG_INT,    &c->opt_timeout},
+               {"machine-pass",'P', POPT_ARG_NONE,   &c->opt_machine_pass},
+               {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup},
+               {"verbose",     'v', POPT_ARG_NONE,   &c->opt_verbose},
+               {"test",        'T', POPT_ARG_NONE,   &c->opt_testmode},
                /* Options for 'net groupmap set' */
                /* Options for 'net groupmap set' */
-               {"local",       'L', POPT_ARG_NONE,   &opt_localgroup},
-               {"domain",      'D', POPT_ARG_NONE,   &opt_domaingroup},
-               {"ntname",      'N', POPT_ARG_STRING, &opt_newntname},
-               {"rid",         'R', POPT_ARG_INT,    &opt_rid},
+               {"local",       'L', POPT_ARG_NONE,   &c->opt_localgroup},
+               {"domain",      'D', POPT_ARG_NONE,   &c->opt_domaingroup},
+               {"ntname",      'N', POPT_ARG_STRING, &c->opt_newntname},
+               {"rid",         'R', POPT_ARG_INT,    &c->opt_rid},
                /* Options for 'net rpc share migrate' */
                /* Options for 'net rpc share migrate' */
-               {"acls",        0, POPT_ARG_NONE,     &opt_acls},
-               {"attrs",       0, POPT_ARG_NONE,     &opt_attrs},
-               {"timestamps",  0, POPT_ARG_NONE,     &opt_timestamps},
-               {"exclude",     'e', POPT_ARG_STRING, &opt_exclude},
-               {"destination", 0, POPT_ARG_STRING,   &opt_destination},
-               {"tallocreport", 0, POPT_ARG_NONE, &do_talloc_report},
+               {"acls",        0, POPT_ARG_NONE,     &c->opt_acls},
+               {"attrs",       0, POPT_ARG_NONE,     &c->opt_attrs},
+               {"timestamps",  0, POPT_ARG_NONE,     &c->opt_timestamps},
+               {"exclude",     'X', POPT_ARG_STRING, &c->opt_exclude},
+               {"destination", 0, POPT_ARG_STRING,   &c->opt_destination},
+               {"tallocreport", 0, POPT_ARG_NONE,    &c->do_talloc_report},
 
                POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
        };
 
 
                POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
        };
 
-       TALLOC_CTX *frame = talloc_stackframe();
 
 
-       zero_addr(&opt_dest_ip);
+       zero_addr(&c->opt_dest_ip);
 
        load_case_tables();
 
        /* set default debug level to 0 regardless of what smb.conf sets */
        DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
        dbf = x_stderr;
 
        load_case_tables();
 
        /* set default debug level to 0 regardless of what smb.conf sets */
        DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
        dbf = x_stderr;
-       
-       pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
+
+       pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
                            POPT_CONTEXT_KEEP_FIRST);
                            POPT_CONTEXT_KEEP_FIRST);
-       
+
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case 'h':
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case 'h':
-                       net_help(argc, argv);
+                       net_help(c, argc, argv);
                        exit(0);
                        break;
                        exit(0);
                        break;
+               case 'e':
+                       c->smb_encrypt = true;
+                       break;
                case 'I':
                case 'I':
-                       if (!interpret_string_addr(&opt_dest_ip,
+                       if (!interpret_string_addr(&c->opt_dest_ip,
                                                poptGetOptArg(pc), 0)) {
                                d_fprintf(stderr, "\nInvalid ip address specified\n");
                        } else {
                                                poptGetOptArg(pc), 0)) {
                                d_fprintf(stderr, "\nInvalid ip address specified\n");
                        } else {
-                               opt_have_ip = True;
+                               c->opt_have_ip = true;
                        }
                        break;
                case 'U':
                        }
                        break;
                case 'U':
-                       opt_user_specified = True;
-                       opt_user_name = SMB_STRDUP(opt_user_name);
-                       p = strchr(opt_user_name,'%');
+                       c->opt_user_specified = true;
+                       c->opt_user_name = SMB_STRDUP(c->opt_user_name);
+                       p = strchr(c->opt_user_name,'%');
                        if (p) {
                                *p = 0;
                        if (p) {
                                *p = 0;
-                               opt_password = p+1;
+                               c->opt_password = p+1;
                        }
                        break;
                default:
                        }
                        break;
                default:
-                       d_fprintf(stderr, "\nInvalid option %s: %s\n", 
+                       d_fprintf(stderr, "\nInvalid option %s: %s\n",
                                 poptBadOption(pc, 0), poptStrerror(opt));
                                 poptBadOption(pc, 0), poptStrerror(opt));
-                       net_help(argc, argv);
+                       net_help(c, argc, argv);
                        exit(1);
                }
        }
                        exit(1);
                }
        }
-       
+
        /*
         * Don't load debug level from smb.conf. It should be
         * set by cmdline arg or remain default (0)
         */
        /*
         * Don't load debug level from smb.conf. It should be
         * set by cmdline arg or remain default (0)
         */
-       AllowDebugChange = False;
-       lp_load(dyn_CONFIGFILE,True,False,False,True);
-       
+       AllowDebugChange = false;
+       lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
+
        argv_new = (const char **)poptGetArgs(pc);
 
        argc_new = argc;
        argv_new = (const char **)poptGetArgs(pc);
 
        argc_new = argc;
@@ -1071,49 +477,54 @@ static struct functable net_func[] = {
                }
        }
 
                }
        }
 
-       if (do_talloc_report) {
+       if (c->do_talloc_report) {
                talloc_enable_leak_report();
        }
 
                talloc_enable_leak_report();
        }
 
-       if (opt_requester_name) {
-               set_global_myname(opt_requester_name);
+       if (c->opt_requester_name) {
+               set_global_myname(c->opt_requester_name);
        }
 
        }
 
-       if (!opt_user_name && getenv("LOGNAME")) {
-               opt_user_name = getenv("LOGNAME");
+       if (!c->opt_user_name && getenv("LOGNAME")) {
+               c->opt_user_name = getenv("LOGNAME");
        }
 
        }
 
-       if (!opt_workgroup) {
-               opt_workgroup = smb_xstrdup(lp_workgroup());
+       if (!c->opt_workgroup) {
+               c->opt_workgroup = smb_xstrdup(lp_workgroup());
        }
        }
-       
-       if (!opt_target_workgroup) {
-               opt_target_workgroup = smb_xstrdup(lp_workgroup());
+
+       if (!c->opt_target_workgroup) {
+               c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
        }
        }
-       
+
        if (!init_names())
                exit(1);
 
        load_interfaces();
        if (!init_names())
                exit(1);
 
        load_interfaces();
-       
-       /* this makes sure that when we do things like call scripts, 
+
+       /* this makes sure that when we do things like call scripts,
           that it won't assert becouse we are not root */
        sec_init();
 
           that it won't assert becouse we are not root */
        sec_init();
 
-       if (opt_machine_pass) {
+       if (c->opt_machine_pass) {
                /* it is very useful to be able to make ads queries as the
                   machine account for testing purposes and for domain leave */
 
                /* it is very useful to be able to make ads queries as the
                   machine account for testing purposes and for domain leave */
 
-               net_use_krb_machine_account();
+               net_use_krb_machine_account(c);
        }
 
        }
 
-       if (!opt_password) {
-               opt_password = getenv("PASSWD");
+       if (!c->opt_password) {
+               c->opt_password = getenv("PASSWD");
        }
        }
-        
-       rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
-       
+
+       rc = net_run_function(c, argc_new-1, argv_new+1, net_func, net_help);
+
        DEBUG(2,("return code = %d\n", rc));
        DEBUG(2,("return code = %d\n", rc));
+
+       libnetapi_free(c->netapi_ctx);
+
+       poptFreeContext(pc);
+
        TALLOC_FREE(frame);
        return rc;
 }
        TALLOC_FREE(frame);
        return rc;
 }