r23779: Change from v2 or later to v3 or later.
[sfrench/samba-autobuild/.git] / source / utils / net.c
index fcc8b4abe1d8a6adc0eeacc8cab7f9ff9f40e3ee..34f580f4d1c058c43f203ddade03b316fc157a2a 100644 (file)
@@ -13,7 +13,7 @@
 
    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
 
    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 2 of the License, or
+   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,
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -38,7 +38,7 @@
 /*****************************************************/
 
 #include "includes.h"
 /*****************************************************/
 
 #include "includes.h"
-#include "../utils/net.h"
+#include "utils/net.h"
 
 /***********************************************************************/
 /* Beginning of internationalization section.  Translatable constants  */
 
 /***********************************************************************/
 /* Beginning of internationalization section.  Translatable constants  */
@@ -65,22 +65,32 @@ const char *opt_workgroup = NULL;
 int opt_long_list_entries = 0;
 int opt_reboot = 0;
 int opt_force = 0;
 int opt_long_list_entries = 0;
 int opt_reboot = 0;
 int opt_force = 0;
+int opt_stdin = 0;
 int opt_port = 0;
 int opt_port = 0;
+int opt_verbose = 0;
 int opt_maxusers = -1;
 const char *opt_comment = "";
 int opt_maxusers = -1;
 const char *opt_comment = "";
-const char *opt_container = "cn=Users";
+const char *opt_container = NULL;
 int opt_flags = -1;
 int opt_timeout = 0;
 const char *opt_target_workgroup = NULL;
 int opt_machine_pass = 0;
 BOOL opt_localgroup = False;
 BOOL opt_domaingroup = False;
 int opt_flags = -1;
 int opt_timeout = 0;
 const char *opt_target_workgroup = NULL;
 int opt_machine_pass = 0;
 BOOL opt_localgroup = False;
 BOOL opt_domaingroup = False;
+static BOOL do_talloc_report=False;
 const char *opt_newntname = "";
 int opt_rid = 0;
 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;
+BOOL opt_testmode = False;
 
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
 
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
+extern struct in_addr loopback_ip;
 extern BOOL AllowDebugChange;
 
 uint32 get_sec_channel_type(const char *param) 
 extern BOOL AllowDebugChange;
 
 uint32 get_sec_channel_type(const char *param) 
@@ -121,56 +131,90 @@ int net_run_function(int argc, const char **argv, struct functable *table,
                if (StrCaseCmp(argv[0], table[i].funcname) == 0)
                        return table[i].fn(argc-1, argv+1);
        }
                if (StrCaseCmp(argv[0], table[i].funcname) == 0)
                        return table[i].fn(argc-1, argv+1);
        }
-       d_printf("No command: %s\n", argv[0]);
+       d_fprintf(stderr, "No command: %s\n", argv[0]);
        return usage_fn(argc, argv);
 }
 
        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\ipc$  
+connect to \\server\service 
 ****************************************************************************/
 ****************************************************************************/
-NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
-                                       const char *server_name)
+
+NTSTATUS connect_to_service(struct cli_state **c, struct in_addr *server_ip,
+                                       const char *server_name, 
+                                       const char *service_name, 
+                                       const char *service_type)
 {
        NTSTATUS nt_status;
 
        if (!opt_password && !opt_machine_pass) {
                char *pass = getpass("Password:");
                if (pass) {
 {
        NTSTATUS nt_status;
 
        if (!opt_password && !opt_machine_pass) {
                char *pass = getpass("Password:");
                if (pass) {
-                       opt_password = strdup(pass);
+                       opt_password = SMB_STRDUP(pass);
                }
        }
                }
        }
-       
-       nt_status = cli_full_connection(c, opt_requester_name, server_name, 
+
+       nt_status = cli_full_connection(c, NULL, server_name, 
                                        server_ip, opt_port,
                                        server_ip, opt_port,
-                                       "IPC$", "IPC",  
+                                       service_name, service_type,  
                                        opt_user_name, opt_workgroup,
                                        opt_password, 0, Undefined, NULL);
                                        opt_user_name, opt_workgroup,
                                        opt_password, 0, Undefined, NULL);
-       
+
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        } else {
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        } else {
-               DEBUG(1,("Cannot connect to server.  Error was %s\n", 
-                        nt_errstr(nt_status)));
+               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))
 
                /* Display a nicer message depending on the result */
 
                if (NT_STATUS_V(nt_status) == 
                    NT_STATUS_V(NT_STATUS_LOGON_FAILURE))
-                       d_printf("The username or password was not correct.\n");
+                       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))
 
                if (NT_STATUS_V(nt_status) == 
                    NT_STATUS_V(NT_STATUS_ACCOUNT_LOCKED_OUT))
-                       d_printf("The account was locked out.\n");
+                       d_fprintf(stderr, "The account was locked out.\n");
 
                if (NT_STATUS_V(nt_status) == 
                    NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
 
                if (NT_STATUS_V(nt_status) == 
                    NT_STATUS_V(NT_STATUS_ACCOUNT_DISABLED))
-                       d_printf("The account was disabled.\n");
+                       d_fprintf(stderr, "The account was disabled.\n");
 
                return nt_status;
        }
 }
 
 
                return nt_status;
        }
 }
 
+
+/****************************************************************************
+connect to \\server\ipc$  
+****************************************************************************/
+NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
+                                       const char *server_name)
+{
+       return connect_to_service(c, server_ip, server_name, "IPC$", "IPC");
+}
+
 /****************************************************************************
 connect to \\server\ipc$ anonymously
 ****************************************************************************/
 /****************************************************************************
 connect to \\server\ipc$ anonymously
 ****************************************************************************/
@@ -194,14 +238,124 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
- Use the local machine's password for this session
+ 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 in_addr *server_ip, const char *server_name)
+{
+       NTSTATUS nt_status;
+       char *user_and_realm = NULL;
+
+       if (!opt_password && !opt_machine_pass) {
+               char *pass = getpass("Password:");
+               if (pass) {
+                       opt_password = SMB_STRDUP(pass);
+               }
+       }
+
+       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_ip, 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's password for this session.
+****************************************************************************/
+
 int net_use_machine_password(void) 
 {
        char *user_name = NULL;
 
        if (!secrets_init()) {
 int net_use_machine_password(void) 
 {
        char *user_name = NULL;
 
        if (!secrets_init()) {
-               d_printf("ERROR: Unable to open secrets database\n");
+               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
                exit(1);
        }
 
                exit(1);
        }
 
@@ -214,17 +368,18 @@ int net_use_machine_password(void)
        return 0;
 }
 
        return 0;
 }
 
-BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
+BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_ip, char **server_name)
 {
 {
+       const char *d = domain ? domain : opt_target_workgroup;
 
        if (opt_host) {
 
        if (opt_host) {
-               *server_name = strdup(opt_host);
+               *server_name = SMB_STRDUP(opt_host);
        }               
 
        if (opt_have_ip) {
                *server_ip = opt_dest_ip;
                if (!*server_name) {
        }               
 
        if (opt_have_ip) {
                *server_ip = opt_dest_ip;
                if (!*server_name) {
-                       *server_name = strdup(inet_ntoa(opt_dest_ip));
+                       *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
                }
        } else if (*server_name) {
                /* resolve the IP address */
                }
        } else if (*server_name) {
                /* resolve the IP address */
@@ -235,43 +390,41 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
        } else if (flags & NET_FLAGS_PDC) {
                struct in_addr pdc_ip;
 
        } else if (flags & NET_FLAGS_PDC) {
                struct in_addr pdc_ip;
 
-               if (get_pdc_ip(opt_target_workgroup, &pdc_ip)) {
+               if (get_pdc_ip(d, &pdc_ip)) {
                        fstring dc_name;
                        
                        if (is_zero_ip(pdc_ip))
                                return False;
                        
                        fstring dc_name;
                        
                        if (is_zero_ip(pdc_ip))
                                return False;
                        
-                       if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
+                       if ( !name_status_find(d, 0x1b, 0x20, pdc_ip, dc_name) )
                                return False;
                                
                                return False;
                                
-                       *server_name = strdup(dc_name);
+                       *server_name = SMB_STRDUP(dc_name);
                        *server_ip = pdc_ip;
                }
                        *server_ip = pdc_ip;
                }
-               
        } else if (flags & NET_FLAGS_DMB) {
                struct in_addr msbrow_ip;
                /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
        } else if (flags & NET_FLAGS_DMB) {
                struct in_addr msbrow_ip;
                /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
-               if (!resolve_name(opt_target_workgroup, &msbrow_ip, 0x1B))  {
+               if (!resolve_name(d, &msbrow_ip, 0x1B))  {
                        DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
                        return False;
                } else {
                        *server_ip = msbrow_ip;
                }
                        DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
                        return False;
                } else {
                        *server_ip = msbrow_ip;
                }
-               *server_name = strdup(inet_ntoa(opt_dest_ip));
+               *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
        } else if (flags & NET_FLAGS_MASTER) {
                struct in_addr brow_ips;
        } else if (flags & NET_FLAGS_MASTER) {
                struct in_addr brow_ips;
-               if (!resolve_name(opt_target_workgroup, &brow_ips, 0x1D))  {
+               if (!resolve_name(d, &brow_ips, 0x1D))  {
                                /* go looking for workgroups */
                        DEBUG(1,("Unable to resolve master browser via name lookup\n"));
                        return False;
                } else {
                        *server_ip = brow_ips;
                }
                                /* go looking for workgroups */
                        DEBUG(1,("Unable to resolve master browser via name lookup\n"));
                        return False;
                } else {
                        *server_ip = brow_ips;
                }
-               *server_name = strdup(inet_ntoa(opt_dest_ip));
+               *server_name = SMB_STRDUP(inet_ntoa(opt_dest_ip));
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
-               extern struct in_addr loopback_ip;
                *server_ip = loopback_ip;
                *server_ip = loopback_ip;
-               *server_name = strdup("127.0.0.1");
+               *server_name = SMB_STRDUP("127.0.0.1");
        }
 
        if (!server_name || !*server_name) {
        }
 
        if (!server_name || !*server_name) {
@@ -298,17 +451,27 @@ BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *do
                return False;
 }
 
                return False;
 }
 
+struct cli_state *net_make_ipc_connection( unsigned flags )
+{
+       return net_make_ipc_connection_ex( NULL, NULL, NULL, flags );
+}
 
 
-struct cli_state *net_make_ipc_connection(unsigned flags)
+struct cli_state *net_make_ipc_connection_ex( const char *domain, const char *server,
+                                              struct in_addr *ip, unsigned flags)
 {
        char *server_name = NULL;
        struct in_addr server_ip;
        struct cli_state *cli = NULL;
        NTSTATUS nt_status;
 
 {
        char *server_name = NULL;
        struct in_addr server_ip;
        struct cli_state *cli = NULL;
        NTSTATUS nt_status;
 
-       if (!net_find_server(flags, &server_ip, &server_name)) {
-               d_printf("\nUnable to find a suitable server\n");
-               return NULL;
+       if ( !server || !ip ) {
+               if (!net_find_server(domain, flags, &server_ip, &server_name)) {
+                       d_fprintf(stderr, "Unable to find a suitable server\n");
+                       return NULL;
+               }
+       } else {
+               server_name = SMB_STRDUP( server );
+               server_ip = *ip;
        }
 
        if (flags & NET_FLAGS_ANONYMOUS) {
        }
 
        if (flags & NET_FLAGS_ANONYMOUS) {
@@ -317,10 +480,17 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
                nt_status = connect_to_ipc(&cli, &server_ip, server_name);
        }
 
                nt_status = connect_to_ipc(&cli, &server_ip, 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)) {
                return cli;
        } else {
        SAFE_FREE(server_name);
        if (NT_STATUS_IS_OK(nt_status)) {
                return cli;
        } else {
+               d_fprintf(stderr, "Connection failed: %s\n",
+                         nt_errstr(nt_status));
                return NULL;
        }
 }
                return NULL;
        }
 }
@@ -350,33 +520,44 @@ static int net_group(int argc, const char **argv)
 
 static int net_join(int argc, const char **argv)
 {
 
 static int net_join(int argc, const char **argv)
 {
-       if (net_ads_check() == 0) {
+       if (net_ads_check_our_domain() == 0) {
                if (net_ads_join(argc, argv) == 0)
                        return 0;
                else
                if (net_ads_join(argc, argv) == 0)
                        return 0;
                else
-                       d_printf("ADS join did not work, falling back to RPC...\n");
+                       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)
 {
        }
        return net_rpc_join(argc, argv);
 }
 
 static int net_changetrustpw(int argc, const char **argv)
 {
-       if (net_ads_check() == 0)
+       if (net_ads_check_our_domain() == 0)
                return net_ads_changetrustpw(argc, argv);
 
        return net_rpc_changetrustpw(argc, argv);
 }
 
                return net_ads_changetrustpw(argc, argv);
 
        return net_rpc_changetrustpw(argc, argv);
 }
 
+static void set_line_buffering(FILE *f)
+{
+       setvbuf(f, NULL, _IOLBF, 0);
+}
+
 static int net_changesecretpw(int argc, const char **argv)
 {
         char *trust_pw;
         uint32 sec_channel_type = SEC_CHAN_WKSTA;
 
        if(opt_force) {
 static int net_changesecretpw(int argc, const char **argv)
 {
         char *trust_pw;
         uint32 sec_channel_type = SEC_CHAN_WKSTA;
 
        if(opt_force) {
-               trust_pw = getpass("Enter machine password: ");
+               if (opt_stdin) {
+                       set_line_buffering(stdin);
+                       set_line_buffering(stdout);
+                       set_line_buffering(stderr);
+               }
+
+               trust_pw = get_pass("Enter machine password: ", opt_stdin);
 
                if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
 
                if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
-                           d_printf("Unable to write the machine account password in the secrets database");
+                           d_fprintf(stderr, "Unable to write the machine account password in the secrets database");
                            return 1;
                }
                else {
                            return 1;
                }
                else {
@@ -422,16 +603,24 @@ static int net_getlocalsid(int argc, const char **argv)
                name = global_myname();
        }
 
                name = global_myname();
        }
 
-       if(!initialize_password_db(False)) {
+       if(!initialize_password_db(False, NULL)) {
                DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
 
                DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
 
+       /* first check to see if we can even access secrets, so we don't
+          panic when we can't. */
+
+       if (!secrets_init()) {
+               d_fprintf(stderr, "Unable to open secrets.tdb.  Can't fetch domain SID for name: %s\n", name);
+               return 1;
+       }
+
        /* Generate one, if it doesn't exist */
        get_global_sam_sid();
 
        if (!secrets_fetch_domain_sid(name, &sid)) {
        /* Generate one, if it doesn't exist */
        get_global_sam_sid();
 
        if (!secrets_fetch_domain_sid(name, &sid)) {
-               DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));      
+               DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
                return 1;
        }
        sid_to_string(sid_str, &sid);
                return 1;
        }
        sid_to_string(sid_str, &sid);
@@ -459,12 +648,32 @@ static int net_setlocalsid(int argc, const char **argv)
        return 0;
 }
 
        return 0;
 }
 
+static int net_setdomainsid(int argc, const char **argv)
+{
+       DOM_SID sid;
+
+       if ( (argc != 1)
+            || (strncmp(argv[0], "S-1-5-21-", strlen("S-1-5-21-")) != 0)
+            || (!string_to_sid(&sid, argv[0]))
+            || (sid.num_auths != 4)) {
+               d_printf("usage: net setdomainsid S-1-5-21-x-y-z\n");
+               return 1;
+       }
+
+       if (!secrets_store_domain_sid(lp_workgroup(), &sid)) {
+               DEBUG(0,("Can't store domain SID.\n"));
+               return 1;
+       }
+
+       return 0;
+}
+
 static int net_getdomainsid(int argc, const char **argv)
 {
        DOM_SID domain_sid;
        fstring sid_str;
 
 static int net_getdomainsid(int argc, const char **argv)
 {
        DOM_SID domain_sid;
        fstring sid_str;
 
-       if(!initialize_password_db(False)) {
+       if(!initialize_password_db(False, NULL)) {
                DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
                DEBUG(0, ("WARNING: Could not open passdb - domain sid may not reflect passdb\n"
                          "backend knowlege (such as the sid stored in LDAP)\n"));
        }
@@ -473,14 +682,14 @@ static int net_getdomainsid(int argc, const char **argv)
        get_global_sam_sid();
 
        if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
        get_global_sam_sid();
 
        if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
-               d_printf("Could not fetch local SID\n");
+               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);
 
        if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) {
                return 1;
        }
        sid_to_string(sid_str, &domain_sid);
        d_printf("SID for domain %s is: %s\n", global_myname(), sid_str);
 
        if (!secrets_fetch_domain_sid(opt_workgroup, &domain_sid)) {
-               d_printf("Could not fetch domain SID\n");
+               d_fprintf(stderr, "Could not fetch domain SID\n");
                return 1;
        }
 
                return 1;
        }
 
@@ -492,104 +701,118 @@ static int net_getdomainsid(int argc, const char **argv)
 
 #ifdef WITH_FAKE_KASERVER
 
 
 #ifdef WITH_FAKE_KASERVER
 
-int net_afskey_usage(int argc, const char **argv)
+int net_help_afs(int argc, const char **argv)
 {
 {
-       d_printf("  net afskey filename\n"
+       d_printf("  net afs key filename\n"
                 "\tImports a OpenAFS KeyFile into our secrets.tdb\n\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;
 }
 
        return -1;
 }
 
-static int net_afskey(int argc, const char **argv)
+static int net_afs_key(int argc, const char **argv)
 {
        int fd;
        struct afs_keyfile keyfile;
 
        if (argc != 2) {
 {
        int fd;
        struct afs_keyfile keyfile;
 
        if (argc != 2) {
-               d_printf("usage: 'net afskey <keyfile> cell'\n");
+               d_printf("usage: 'net afs key <keyfile> cell'\n");
                return -1;
        }
 
        if (!secrets_init()) {
                return -1;
        }
 
        if (!secrets_init()) {
-               d_printf("Could not open secrets.tdb\n");
+               d_fprintf(stderr, "Could not open secrets.tdb\n");
                return -1;
        }
 
        if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
                return -1;
        }
 
        if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
-               d_printf("Could not open %s\n", argv[0]);
+               d_fprintf(stderr, "Could not open %s\n", argv[0]);
                return -1;
        }
 
        if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
                return -1;
        }
 
        if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
-               d_printf("Could not read keyfile\n");
+               d_fprintf(stderr, "Could not read keyfile\n");
                return -1;
        }
 
        if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
                return -1;
        }
 
        if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
-               d_printf("Could not write keyfile to secrets.tdb\n");
+               d_fprintf(stderr, "Could not write keyfile to secrets.tdb\n");
                return -1;
        }
 
        return 0;
 }
 
                return -1;
        }
 
        return 0;
 }
 
-#endif /* WITH_FAKE_KASERVER */
-
-static uint32 get_maxrid(void)
+static int net_afs_impersonate(int argc, const char **argv)
 {
 {
-       SAM_ACCOUNT *pwd = NULL;
-       uint32 max_rid = 0;
-       GROUP_MAP *map = NULL;
-       int num_entries = 0;
-       int i;
+       char *token;
 
 
-       if (!pdb_setsampwent(False)) {
-               DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
-               return 0;
+       if (argc != 2) {
+               fprintf(stderr, "Usage: net afs impersonate <user> <cell>\n");
+               exit(1);
        }
 
        }
 
-       for (; (NT_STATUS_IS_OK(pdb_init_sam(&pwd))) 
-                    && pdb_getsampwent(pwd) == True; pwd=NULL) {
-               uint32 rid;
-
-               if (!sid_peek_rid(pdb_get_user_sid(pwd), &rid)) {
-                       DEBUG(0, ("can't get RID for user '%s'\n",
-                                 pdb_get_username(pwd)));
-                       pdb_free_sam(&pwd);
-                       continue;
-               }
+       token = afs_createtoken_str(argv[0], argv[1]);
 
 
-               if (rid > max_rid)
-                       max_rid = rid;
+       if (token == NULL) {
+               fprintf(stderr, "Could not create token\n");
+               exit(1);
+       }
 
 
-               DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd)));
-               pdb_free_sam(&pwd);
+       if (!afs_settoken_str(token)) {
+               fprintf(stderr, "Could not set token into kernel\n");
+               exit(1);
        }
 
        }
 
-       pdb_endsampwent();
-       pdb_free_sam(&pwd);
+       printf("Success: %s@%s\n", argv[0], argv[1]);
+       return 0;
+}
 
 
-       if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
-                                   ENUM_ONLY_MAPPED))
-               return max_rid;
+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);
+}
 
 
-       for (i = 0; i < num_entries; i++) {
-               uint32 rid;
+#endif /* WITH_FAKE_KASERVER */
 
 
-               if (!sid_peek_check_rid(get_global_sam_sid(), &map[i].sid,
-                                       &rid)) {
-                       DEBUG(3, ("skipping map for group '%s', SID %s\n",
-                                 map[i].nt_name,
-                                 sid_string_static(&map[i].sid)));
-                       continue;
-               }
-               DEBUG(1,("%d is group '%s'\n", rid, map[i].nt_name));
+static BOOL search_maxrid(struct pdb_search *search, const char *type,
+                         uint32 *max_rid)
+{
+       struct samr_displayentry *entries;
+       uint32 i, num_entries;
 
 
-               if (rid > max_rid)
-                       max_rid = rid;
+       if (search == NULL) {
+               d_fprintf(stderr, "get_maxrid: Could not search %s\n", type);
+               return False;
        }
 
        }
 
-       SAFE_FREE(map);
+       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;
+}
+
+static uint32 get_maxrid(void)
+{
+       uint32 max_rid = 0;
 
 
+       if (!search_maxrid(pdb_search_users(0), "users", &max_rid))
+               return 0;
+
+       if (!search_maxrid(pdb_search_groups(), "groups", &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;
 }
 
@@ -628,6 +851,7 @@ static struct functable net_func[] = {
        {"USER", net_user},
        {"GROUP", net_group},
        {"GROUPMAP", net_groupmap},
        {"USER", net_user},
        {"GROUP", net_group},
        {"GROUPMAP", net_groupmap},
+       {"SAM", net_sam},
        {"VALIDATE", net_rap_validate},
        {"GROUPMEMBER", net_rap_groupmember},
        {"ADMIN", net_rap_admin},
        {"VALIDATE", net_rap_validate},
        {"GROUPMEMBER", net_rap_groupmember},
        {"ADMIN", net_rap_admin},
@@ -641,14 +865,17 @@ static struct functable net_func[] = {
        {"CACHE", net_cache},
        {"GETLOCALSID", net_getlocalsid},
        {"SETLOCALSID", net_setlocalsid},
        {"CACHE", net_cache},
        {"GETLOCALSID", net_getlocalsid},
        {"SETLOCALSID", net_setlocalsid},
+       {"SETDOMAINSID", net_setdomainsid},
        {"GETDOMAINSID", net_getdomainsid},
        {"MAXRID", net_maxrid},
        {"IDMAP", net_idmap},
        {"STATUS", net_status},
        {"GETDOMAINSID", net_getdomainsid},
        {"MAXRID", net_maxrid},
        {"IDMAP", net_idmap},
        {"STATUS", net_status},
+       {"USERSHARE", net_usershare},
+       {"USERSIDLIST", net_usersidlist},
+       {"CONF", net_conf},
 #ifdef WITH_FAKE_KASERVER
 #ifdef WITH_FAKE_KASERVER
-       {"AFSKEY", net_afskey},
+       {"AFS", net_afs},
 #endif
 #endif
-       {"PRIV", net_priv},
 
        {"HELP", net_help},
        {NULL, NULL}
 
        {"HELP", net_help},
        {NULL, NULL}
@@ -682,15 +909,24 @@ static struct functable net_func[] = {
                {"long",        'l', POPT_ARG_NONE,   &opt_long_list_entries},
                {"reboot",      'r', POPT_ARG_NONE,   &opt_reboot},
                {"force",       'f', POPT_ARG_NONE,   &opt_force},
                {"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},
                {"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},
                /* 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},
                /* 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},
+               /* 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},
 
                POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
 
                POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
@@ -698,6 +934,8 @@ static struct functable net_func[] = {
 
        zero_ip(&opt_dest_ip);
 
 
        zero_ip(&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;
        /* set default debug level to 0 regardless of what smb.conf sets */
        DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
        dbf = x_stderr;
@@ -714,13 +952,13 @@ static struct functable net_func[] = {
                case 'I':
                        opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
                        if (is_zero_ip(opt_dest_ip))
                case 'I':
                        opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
                        if (is_zero_ip(opt_dest_ip))
-                               d_printf("\nInvalid ip address specified\n");
+                               d_fprintf(stderr, "\nInvalid ip address specified\n");
                        else
                                opt_have_ip = True;
                        break;
                case 'U':
                        opt_user_specified = True;
                        else
                                opt_have_ip = True;
                        break;
                case 'U':
                        opt_user_specified = True;
-                       opt_user_name = strdup(opt_user_name);
+                       opt_user_name = SMB_STRDUP(opt_user_name);
                        p = strchr(opt_user_name,'%');
                        if (p) {
                                *p = 0;
                        p = strchr(opt_user_name,'%');
                        if (p) {
                                *p = 0;
@@ -728,7 +966,7 @@ static struct functable net_func[] = {
                        }
                        break;
                default:
                        }
                        break;
                default:
-                       d_printf("\nInvalid option %s: %s\n", 
+                       d_fprintf(stderr, "\nInvalid option %s: %s\n", 
                                 poptBadOption(pc, 0), poptStrerror(opt));
                        net_help(argc, argv);
                        exit(1);
                                 poptBadOption(pc, 0), poptStrerror(opt));
                        net_help(argc, argv);
                        exit(1);
@@ -740,7 +978,7 @@ static struct functable net_func[] = {
         * set by cmdline arg or remain default (0)
         */
        AllowDebugChange = False;
         * set by cmdline arg or remain default (0)
         */
        AllowDebugChange = False;
-       lp_load(dyn_CONFIGFILE,True,False,False);
+       lp_load(dyn_CONFIGFILE,True,False,False,True);
        
        argv_new = (const char **)poptGetArgs(pc);
 
        
        argv_new = (const char **)poptGetArgs(pc);
 
@@ -752,10 +990,12 @@ static struct functable net_func[] = {
                }
        }
 
                }
        }
 
-       if (!opt_requester_name) {
-               static fstring myname;
-               get_myname(myname);
-               opt_requester_name = myname;
+       if (do_talloc_report) {
+               talloc_enable_leak_report();
+       }
+
+       if (opt_requester_name) {
+               set_global_myname(opt_requester_name);
        }
 
        if (!opt_user_name && getenv("LOGNAME")) {
        }
 
        if (!opt_user_name && getenv("LOGNAME")) {