trying to get HEAD building again. If you want the code
[tprouty/samba.git] / source3 / utils / net.c
index 8e73a7c60d11463c64694b322a565c84252d2a09..e643a3d10d7a2b69dca5358dea9e888a5e1299d1 100644 (file)
@@ -1,6 +1,5 @@
 /* 
    Samba Unix/Linux SMB client library 
-   Version 3.0
    Distributed SMB/CIFS Server Management Utility 
    Copyright (C) 2001 Steve French  (sfrench@us.ibm.com)
    Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com)
 /*                       end of internationalization section                        */
 /************************************************************************************/
 
-extern int optind, opterr, optopt;
-
 /* Yes, these buggers are globals.... */
-char *opt_requester_name = NULL;
-char *opt_host = NULL; 
-char *opt_password = NULL;
-char *opt_user_name = NULL;
-char *opt_workgroup = NULL;
+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_port = 0;
 int opt_maxusers = -1;
-char *opt_comment = "";
+const char *opt_comment = "";
+const char *opt_container = "cn=Users";
 int opt_flags = -1;
-int opt_jobid = 0;
-char *opt_target_workgroup = NULL;
+int opt_timeout = 0;
+const char *opt_target_workgroup = NULL;
+static int opt_machine_pass = 0;
+
+BOOL opt_have_ip = False;
+struct in_addr opt_dest_ip;
+
+/*****************************************************************************
+ stubb functions
+****************************************************************************/
+
+void become_root( void )
+{
+        return;
+}
 
-static BOOL got_pass = False;
-static BOOL have_ip = False;
-static struct in_addr dest_ip;
+void unbecome_root( void )
+{
+        return;
+}
 
-extern pstring global_myname;
+
+uint32 get_sec_channel_type(const char *param) 
+{
+       if (!(param && *param)) {
+               return get_default_sec_channel();
+       } else {
+               if (strcasecmp(param, "PDC")==0) {
+                       return SEC_CHAN_BDC;
+               } else if (strcasecmp(param, "BDC")==0) {
+                       return SEC_CHAN_BDC;
+               } else if (strcasecmp(param, "MEMBER")==0) {
+                       return SEC_CHAN_WKSTA;
+#if 0                  
+               } else if (strcasecmp(param, "DOMAIN")==0) {
+                       return SEC_CHAN_DOMAIN;
+#endif
+               } else {
+                       return get_default_sec_channel();
+               }
+       }
+}
 
 /*
   run a function from a function table. If not found then
@@ -103,71 +138,94 @@ int net_run_function(int argc, const char **argv, struct functable *table,
 /****************************************************************************
 connect to \\server\ipc$  
 ****************************************************************************/
-static struct cli_state *connect_to_ipc(struct in_addr *server_ip, const char *server_name)
+NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
+                                       const char *server_name)
 {
-       struct cli_state *c;
        NTSTATUS nt_status;
 
-       if (!got_pass) {
+       if (!opt_password) {
                char *pass = getpass("Password:");
                if (pass) {
                        opt_password = strdup(pass);
                }
        }
        
-       nt_status = cli_full_connection(&c, opt_requester_name, server_name, 
+       nt_status = cli_full_connection(c, opt_requester_name, server_name, 
                                        server_ip, opt_port,
                                        "IPC$", "IPC",  
                                        opt_user_name, opt_workgroup,
-                                       opt_password, strlen(opt_password));
+                                       opt_password, 0, NULL);
        
        if (NT_STATUS_IS_OK(nt_status)) {
-               return c;
+               return nt_status;
        } else {
-               DEBUG(1,("Cannot connect to server.  Error was %s\n", get_nt_error_msg(nt_status)));
-               return NULL;
+               DEBUG(1,("Cannot connect to server.  Error was %s\n", 
+                        nt_errstr(nt_status)));
+
+               /* 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");
+
+               return nt_status;
        }
 }
 
-struct cli_state *net_make_ipc_connection(unsigned flags)
+/****************************************************************************
+connect to \\server\ipc$ anonymously
+****************************************************************************/
+NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
+                       struct in_addr *server_ip, const char *server_name)
+{
+       NTSTATUS nt_status;
+
+       nt_status = cli_full_connection(c, opt_requester_name, server_name, 
+                                       server_ip, opt_port,
+                                       "IPC$", "IPC",  
+                                       "", "",
+                                       "", 0, 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;
+       }
+}
+
+BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
 {
-       char *server_name = NULL;
-       struct in_addr server_ip;
-       struct cli_state *cli;
 
        if (opt_host) {
-               server_name = strdup(opt_host);
+               *server_name = strdup(opt_host);
        }               
 
-       if (have_ip) {
-               server_ip = dest_ip;
-               if (!server_name) {
-                       server_name = strdup(inet_ntoa(dest_ip));
+       if (opt_have_ip) {
+               *server_ip = opt_dest_ip;
+               if (!*server_name) {
+                       *server_name = strdup(inet_ntoa(opt_dest_ip));
                }
-       } else if (server_name) {
+       } else if (*server_name) {
                /* resolve the IP address */
-               if (!resolve_name(server_name, &server_ip, 0x20))  {
+               if (!resolve_name(*server_name, server_ip, 0x20))  {
                        DEBUG(1,("Unable to resolve server name\n"));
-                       return NULL;
+                       return False;
                }
        } else if (flags & NET_FLAGS_PDC) {
-               struct in_addr *ip_list;
-               int addr_count;
-               if (get_dc_list(True /* PDC only*/, opt_target_workgroup, &ip_list, &addr_count)) {
+               struct in_addr pdc_ip;
+
+               if (get_pdc_ip(opt_target_workgroup, &pdc_ip)) {
                        fstring dc_name;
-                       if (addr_count < 1) {
-                               return NULL;
-                       }
-                       
-                       server_ip = *ip_list;
                        
-                       if (is_zero_ip(server_ip))
-                               return NULL;
+                       if (is_zero_ip(pdc_ip))
+                               return False;
                        
-                       if (!lookup_dc_name(global_myname, opt_target_workgroup, &server_ip, dc_name))
-                               return NULL;
+                       if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
+                               return False;
                                
-                       server_name = strdup(dc_name);
+                       *server_name = strdup(dc_name);
+                       *server_ip = pdc_ip;
                }
                
        } else if (flags & NET_FLAGS_DMB) {
@@ -175,75 +233,278 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
                /*  if (!resolve_name(MSBROWSE, &msbrow_ip, 1)) */
                if (!resolve_name(opt_target_workgroup, &msbrow_ip, 0x1B))  {
                        DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
-                       return NULL;
+                       return False;
                } else {
-                       server_ip = msbrow_ip;
+                       *server_ip = msbrow_ip;
                }
-               server_name = strdup(inet_ntoa(dest_ip));
+               *server_name = strdup(inet_ntoa(opt_dest_ip));
        } else if (flags & NET_FLAGS_MASTER) {
                struct in_addr brow_ips;
                if (!resolve_name(opt_target_workgroup, &brow_ips, 0x1D))  {
                                /* go looking for workgroups */
                        DEBUG(1,("Unable to resolve master browser via name lookup\n"));
-                       return NULL;
+                       return False;
                } else {
-                       server_ip = brow_ips;
+                       *server_ip = brow_ips;
                }
-               server_name = strdup(inet_ntoa(dest_ip));
+               *server_name = strdup(inet_ntoa(opt_dest_ip));
        } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) {
                extern struct in_addr loopback_ip;
-               server_ip = loopback_ip;
-               server_name = strdup("127.0.0.1");
+               *server_ip = loopback_ip;
+               *server_name = strdup("127.0.0.1");
        }
 
-       if (!server_name) {
+       if (!server_name || !*server_name) {
                DEBUG(1,("no server to connect to\n"));
+               return False;
+       }
+
+       return True;
+}
+
+
+BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
+{
+       if (get_pdc_ip(domain_name, server_ip)) {
+               if (is_zero_ip(*server_ip))
+                       return False;
+               
+               if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
+                       return False;
+                       
+               return True;    
+       } 
+       else
+               return False;
+}
+
+
+struct cli_state *net_make_ipc_connection(unsigned flags)
+{
+       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;
        }
 
-       cli = connect_to_ipc(&server_ip, server_name);
+       if (flags & NET_FLAGS_ANONYMOUS) {
+               nt_status = connect_to_ipc_anonymous(&cli, &server_ip, server_name);
+       } else {
+               nt_status = connect_to_ipc(&cli, &server_ip, server_name);
+       }
+
        SAFE_FREE(server_name);
-       if(!cli) {
-               d_printf("\nUnable to connect to target server\n");
+       if (NT_STATUS_IS_OK(nt_status)) {
+               return cli;
+       } else {
                return NULL;
        }
-       return cli;
 }
 
+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);
 
-static int net_usage(int argc, const char **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)
 {
-       d_printf("  net ads [command]\tto run ADS commands\n"\
-                "  net rap [command]\tto run RAP (pre-RPC) commands\n"\
-                "  net rpc [command]\tto run RPC commands\n"\
-                "  net rap help\n"\
-                "\nType \"net help <option>\" to get more information on that option\n");
-       return -1;
+       if (net_ads_check() == 0) {
+               if (net_ads_join(argc, argv) == 0)
+                       return 0;
+               else
+                       d_printf("ADS join did not work, trying RPC...\n");
+       }
+       return net_rpc_join(argc, argv);
 }
 
-static int help_usage(int argc, const char **argv)
+static int net_changetrustpw(int argc, const char **argv)
 {
-       d_printf("\n"\
-"Usage: net help <function>\n"\
-"\n"\
-"Valid functions are:\n"\
-"  RPC RAP ADS\n");
-       return -1;
+       if (net_ads_check() == 0)
+               return net_ads_changetrustpw(argc, argv);
+
+       return net_rpc_changetrustpw(argc, argv);
+}
+
+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);
 }
 
 /*
-  handle "net help *" subcommands
-*/
-static int net_help(int argc, const char **argv)
+ Retrieve our local SID or the SID for the specified name
+ */
+static int net_getlocalsid(int argc, const char **argv)
+{
+        DOM_SID sid;
+       const char *name;
+       fstring sid_str;
+
+       if (argc >= 1) {
+               name = argv[0];
+        }
+       else {
+               name = global_myname();
+       }
+
+       if (!secrets_fetch_domain_sid(name, &sid)) {
+               DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));      
+               return 1;
+       }
+       sid_to_string(sid_str, &sid);
+       d_printf("SID for domain %s is: %s\n", name, sid_str);
+       return 0;
+}
+
+static int net_setlocalsid(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 setlocalsid S-1-5-21-x-y-z\n");
+               return 1;
+       }
+
+       if (!secrets_store_domain_sid(global_myname(), &sid)) {
+               DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
+               return 1;
+       }
+
+       return 0;
+}
+
+static int net_getdomainsid(int argc, const char **argv)
+{
+       DOM_SID domain_sid;
+       fstring sid_str;
+
+       if (!secrets_fetch_domain_sid(global_myname(), &domain_sid)) {
+               d_printf("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)) {
+               d_printf("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;
+}
+
+static uint32 get_maxrid(void)
+{
+       SAM_ACCOUNT *pwd = NULL;
+       uint32 max_rid = 0;
+       GROUP_MAP *map = NULL;
+       int num_entries = 0;
+       int i;
+
+       if (!pdb_setsampwent(False)) {
+               DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
+               return 0;
+       }
+
+       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;
+               }
+
+               if (rid > max_rid)
+                       max_rid = rid;
+
+               DEBUG(1,("%d is user '%s'\n", rid, pdb_get_username(pwd)));
+               pdb_free_sam(&pwd);
+       }
+
+       pdb_endsampwent();
+       pdb_free_sam(&pwd);
+
+       if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
+                                   ENUM_ONLY_MAPPED))
+               return max_rid;
+
+       for (i = 0; i < num_entries; i++) {
+               uint32 rid;
+
+               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));
+
+               if (rid > max_rid)
+                       max_rid = rid;
+       }
+
+       SAFE_FREE(map);
+
+       return max_rid;
+}
+
+static int net_maxrid(int argc, const char **argv)
 {
-       struct functable func[] = {
-               {"ADS", net_ads_usage}, 
-               {"RAP", net_rap_usage},
-               {"RPC", net_rpc_usage},
-               {"HELP", help_usage},
-               {NULL, NULL}};
-
-       return net_run_function(argc, argv, func, help_usage);
+       uint32 rid;
+
+       if (argc != 0) {
+               DEBUG(0, ("usage: net maxrid\n"));
+               return 1;
+       }
+
+       if ((rid = get_maxrid()) == 0) {
+               DEBUG(0, ("can't get current maximum rid\n"));
+               return 1;
+       }
+
+       d_printf("Currently used maximum rid: %d\n", rid);
+
+       return 0;
 }
 
 /* main function table */
@@ -251,6 +512,33 @@ static struct functable net_func[] = {
        {"RPC", net_rpc},
        {"RAP", net_rap},
        {"ADS", net_ads},
+
+       /* eventually these should auto-choose the transport ... */
+       {"FILE", net_file},
+       {"SHARE", net_share},
+       {"SESSION", net_rap_session},
+       {"SERVER", net_rap_server},
+       {"DOMAIN", net_rap_domain},
+       {"PRINTQ", net_rap_printq},
+       {"USER", net_user},
+       {"GROUP", net_group},
+       {"GROUPMAP", net_groupmap},
+       {"VALIDATE", net_rap_validate},
+       {"GROUPMEMBER", net_rap_groupmember},
+       {"ADMIN", net_rap_admin},
+       {"SERVICE", net_rap_service},   
+       {"PASSWORD", net_rap_password},
+       {"CHANGETRUSTPW", net_changetrustpw},
+       {"TIME", net_time},
+       {"LOOKUP", net_lookup},
+       {"JOIN", net_join},
+       {"CACHE", net_cache},
+       {"GETLOCALSID", net_getlocalsid},
+       {"SETLOCALSID", net_setlocalsid},
+       {"GETDOMAINSID", net_getdomainsid},
+       {"MAXRID", net_maxrid},
+       {"IDMAP", net_idmap},
+
        {"HELP", net_help},
        {NULL, NULL}
 };
@@ -267,33 +555,32 @@ static struct functable net_func[] = {
        int argc_new = 0;
        const char ** argv_new;
        poptContext pc;
-       static char *servicesf = dyn_CONFIGFILE;
-       static int debuglevel;
 
        struct poptOption long_options[] = {
-               {"help",        'h', POPT_ARG_NONE,   0,     'h'},
-               {"workgroup",   'w', POPT_ARG_STRING, &opt_target_workgroup},
+               {"help",        'h', POPT_ARG_NONE,   0, 'h'},
+               {"workgroup",   'w', POPT_ARG_STRING, &opt_target_workgroup},
+               {"user",        'U', POPT_ARG_STRING, &opt_user_name, 'U'},
+               {"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},
+               {"timeout",     't', POPT_ARG_INT,    &opt_timeout},
+               {"machine-pass",'P', POPT_ARG_NONE,   &opt_machine_pass},
                {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
-               {"user",        'U', POPT_ARG_STRING, &opt_user_name, 'U'},
-               {"ipaddress",   'I', POPT_ARG_STRING, 0,     'I'},
-               {"port",        'p', POPT_ARG_INT,    &opt_port},
-               {"myname",      'n', POPT_ARG_STRING, &opt_requester_name},
-               {"conf",        's', POPT_ARG_STRING, &servicesf},
-               {"debug",       'd', POPT_ARG_INT,    &debuglevel, 'd'},
-               {"debuglevel",  'd', POPT_ARG_INT,    &debuglevel, 'd'},
-               {"server",      'S', POPT_ARG_STRING, &opt_host},
-               {"comment",     'C', POPT_ARG_STRING, &opt_comment},
-               {"maxusers",    'M', POPT_ARG_INT,    &opt_maxusers},
-               {"flags",       'F', POPT_ARG_INT,    &opt_flags},
-               {"jobid",       'j', POPT_ARG_INT,    &opt_jobid},
-               {"long",        'l', POPT_ARG_NONE,   &opt_long_list_entries},
+               POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
        };
 
-       got_pass = 0;
-       zero_ip(&dest_ip);
+       zero_ip(&opt_dest_ip);
 
-       dbf = x_stdout;
+       dbf = x_stderr;
        
        pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
                            POPT_CONTEXT_KEEP_FIRST);
@@ -301,34 +588,34 @@ static struct functable net_func[] = {
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt) {
                case 'h':
-                       net_usage(argc, argv);
+                       net_help(argc, argv);
                        exit(0);
                        break;
                case 'I':
-                       dest_ip = *interpret_addr2(poptGetOptArg(pc));
-                       if (is_zero_ip(dest_ip))
+                       opt_dest_ip = *interpret_addr2(poptGetOptArg(pc));
+                       if (is_zero_ip(opt_dest_ip))
                                d_printf("\nInvalid ip address specified\n");
                        else
-                               have_ip = True;
+                               opt_have_ip = True;
                        break;
                case 'U':
+                       opt_user_specified = True;
                        opt_user_name = strdup(opt_user_name);
                        p = strchr(opt_user_name,'%');
                        if (p) {
                                *p = 0;
                                opt_password = p+1;
-                               got_pass = 1;
                        }
                        break;
                default:
-                       d_printf("\nInvalid option %c (%d)\n", (char)opt, opt);
-                       net_usage(argc, argv);
+                       d_printf("\nInvalid option %s: %s\n", 
+                                poptBadOption(pc, 0), poptStrerror(opt));
+                       net_help(argc, argv);
+                       exit(1);
                }
        }
-
-       DEBUGLEVEL = debuglevel;
-
-       lp_load(servicesf,True,False,False);       
+       
+       lp_load(dyn_CONFIGFILE,True,False,False);       
 
        argv_new = (const char **)poptGetArgs(pc);
 
@@ -339,7 +626,7 @@ static struct functable net_func[] = {
                        break;
                }
        }
-        
+
        if (!opt_requester_name) {
                static fstring myname;
                get_myname(myname);
@@ -351,25 +638,47 @@ static struct functable net_func[] = {
        }
 
        if (!opt_workgroup) {
-               opt_workgroup = lp_workgroup();
+               opt_workgroup = smb_xstrdup(lp_workgroup());
        }
        
        if (!opt_target_workgroup) {
-               opt_target_workgroup = lp_workgroup();
+               opt_target_workgroup = smb_xstrdup(lp_workgroup());
        }
        
-       if (!*global_myname) {
-               char *p2;
+       if (!init_names())
+               exit(1);
 
-               fstrcpy(global_myname, myhostname());
-               p2 = strchr_m(global_myname, '.');
-               if (p2) 
-                        *p2 = 0;
-       }
-       
        load_interfaces();
+       
+       /* this makes sure that when we do things like call scripts, 
+          that it won't assert becouse we are not root */
+       sec_init();
+
+       if (opt_machine_pass) {
+               char *user = NULL;
+               /* it is very useful to be able to make ads queries as the
+                  machine account for testing purposes and for domain leave */
+
+               if (!secrets_init()) {
+                       d_printf("ERROR: Unable to open secrets database\n");
+                       exit(1);
+               }
 
-       rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);
+               opt_password = secrets_fetch_machine_password(opt_workgroup, NULL, NULL);
+
+               asprintf(&user,"%s$", global_myname());
+               opt_user_name = user;
+               if (!opt_password) {
+                       d_printf("ERROR: Unable to fetch machine password\n");
+                       exit(1);
+               }
+       }
+
+       if (!opt_password) {
+               opt_password = getenv("PASSWD");
+       }
+        
+       rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
        
        DEBUG(2,("return code = %d\n", rc));
        return rc;