Add net getlocalsid [name]
[jra/samba/.git] / source3 / utils / net.c
index a8ef721512994ccf8200c7cffea35704f169e33f..800aeded0a607bb4ee8693fa7af964105d215e34 100644 (file)
@@ -72,33 +72,13 @@ int opt_flags = -1;
 int opt_jobid = 0;
 int opt_timeout = 0;
 char *opt_target_workgroup = NULL;
+static int opt_machine_pass = 0;
 
-static BOOL got_pass = False;
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
 extern pstring global_myname;
-
-int net_common_flags_usage(int argc, const char **argv)
-{
-
-       d_printf("Valid targets: choose one (none defaults to localhost)\n");
-       d_printf("\t-S or --server=<server>\t\tserver name\n");
-       d_printf("\t-I or --ipaddress=<ipaddr>\taddress of target server\n");
-       d_printf("\t-w or --workgroup=<wg>\t\ttarget workgroup or domain\n");
-
-       d_printf("\n");
-       d_printf("Valid miscellaneous options are:\n"); /* misc options */
-       d_printf("\t-p or --port=<port>\tconnection port on target server\n");
-       d_printf("\t-W or --myworkgroup=<wg>\tclient workgroup\n");
-       d_printf("\t-d or --debug=<level>\t\tdebug level (0-10)\n");
-       d_printf("\t-n or --myname=<name>\t\tclient name\n");
-       d_printf("\t-U or --user=<name>\t\tuser name\n");
-       d_printf("\t-s or --conf=<path>\t\tpathname of smb.conf file\n");
-       d_printf("\t-l or --long\t\t\tDisplay full information\n");
-       return -1;
-}
-
+extern BOOL AllowDebugChange;
 
 /*
   run a function from a function table. If not found then
@@ -130,7 +110,7 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
 {
        NTSTATUS nt_status;
 
-       if (!got_pass) {
+       if (!opt_password) {
                char *pass = getpass("Password:");
                if (pass) {
                        opt_password = strdup(pass);
@@ -141,13 +121,13 @@ NTSTATUS connect_to_ipc(struct cli_state **c, struct in_addr *server_ip,
                                        server_ip, opt_port,
                                        "IPC$", "IPC",  
                                        opt_user_name, opt_workgroup,
-                                       opt_password, strlen(opt_password));
+                                       opt_password, 0);
        
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        } else {
-               DEBUG(0,("Cannot connect to server.  Error was %s\n", 
-                        get_nt_error_msg(nt_status)));
+               DEBUG(1,("Cannot connect to server.  Error was %s\n", 
+                        nt_errstr(nt_status)));
 
                /* Display a nicer message depending on the result */
 
@@ -176,12 +156,12 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        } else {
-               DEBUG(0,("Cannot connect to server (anonymously).  Error was %s\n", get_nt_error_msg(nt_status)));
+               DEBUG(1,("Cannot connect to server (anonymously).  Error was %s\n", nt_errstr(nt_status)));
                return nt_status;
        }
 }
 
-static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
+BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
 {
 
        if (opt_host) {
@@ -254,7 +234,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se
 }
 
 
-BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, char *domain_name)
+BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
 {
        struct in_addr *ip_list;
        int addr_count;
@@ -301,62 +281,120 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
        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);
 
-static int net_usage(int argc, const char **argv)
+       return net_rap_user(argc, argv);
+}
+
+static int net_group(int argc, const char **argv)
 {
-       d_printf("  net time\t\t to view or set time information\n"\
-                "  net lookup\t\t to lookup host name or ip address\n"\
-                "\n"\
-                "  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"\
-                "\n"\
-                "Type \"net help <option>\" to get more information on that option\n");
-       return -1;
+       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 help_usage(int argc, const char **argv)
+static int net_join(int argc, const char **argv)
 {
-       d_printf(
-"\n"\
-"Usage: net help <function>\n"\
-"\n"\
-"Valid functions are:\n"\
-"  RPC RAP ADS FILE SHARE SESSION SERVER DOMAIN PRINTQ USER GROUP VALIDATE\n"\
-"  GROUPMEMBER ADMIN SERVICE PASSWORD TIME LOOKUP\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 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)
 {
-       struct functable func[] = {
-               {"ADS", net_ads_usage}, 
-               {"RAP", net_rap_help},
-               {"RPC", net_rpc_usage},
-
-               {"FILE", net_rap_file_usage},
-               {"SHARE", net_rap_share_usage},
-               {"SESSION", net_rap_session_usage},
-               {"SERVER", net_rap_server_usage},
-               {"DOMAIN", net_rap_domain_usage},
-               {"PRINTQ", net_rap_printq_usage},
-               {"USER", net_rap_user_usage},
-               {"GROUP", net_rap_group_usage},
-               {"VALIDATE", net_rap_validate_usage},
-               {"GROUPMEMBER", net_rap_groupmember_usage},
-               {"ADMIN", net_rap_admin_usage},
-               {"SERVICE", net_rap_service_usage},
-               {"PASSWORD", net_rap_password_usage},
-               {"TIME", net_time_usage},
-               {"LOOKUP", net_lookup_usage},
-
-               {"HELP", help_usage},
-               {NULL, NULL}};
-
-       return net_run_function(argc, argv, func, net_usage);
+        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(lp_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", lp_workgroup(), sid_str);
+
+       return 0;
 }
 
 /* main function table */
@@ -366,14 +404,14 @@ static struct functable net_func[] = {
        {"ADS", net_ads},
 
        /* eventually these should auto-choose the transport ... */
-       {"FILE", net_rap_file},
-       {"SHARE", net_rap_share},
+       {"FILE", net_file},
+       {"SHARE", net_share},
        {"SESSION", net_rap_session},
        {"SERVER", net_rap_server},
        {"DOMAIN", net_rap_domain},
        {"PRINTQ", net_rap_printq},
-       {"USER", net_rap_user},
-       {"GROUP", net_rap_group},
+       {"USER", net_user},
+       {"GROUP", net_group},
        {"VALIDATE", net_rap_validate},
        {"GROUPMEMBER", net_rap_groupmember},
        {"ADMIN", net_rap_admin},
@@ -381,6 +419,11 @@ static struct functable net_func[] = {
        {"PASSWORD", net_rap_password},
        {"TIME", net_time},
        {"LOOKUP", net_lookup},
+       {"JOIN", net_join},
+       {"CACHE", net_cache},
+       {"GETLOCALSID", net_getlocalsid},
+       {"SETLOCALSID", net_setlocalsid},
+       {"GETDOMAINSID", net_getdomainsid},
 
        {"HELP", net_help},
        {NULL, NULL}
@@ -399,7 +442,7 @@ static struct functable net_func[] = {
        const char ** argv_new;
        poptContext pc;
        static char *servicesf = dyn_CONFIGFILE;
-       static int debuglevel;
+       static char *debuglevel = NULL;
 
        struct poptOption long_options[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
@@ -410,8 +453,6 @@ static struct functable net_func[] = {
                {"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},
@@ -421,10 +462,11 @@ static struct functable net_func[] = {
                {"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},
+               {"debuglevel",  'D', POPT_ARG_STRING, &debuglevel},
                { 0, 0, 0, 0}
        };
 
-       got_pass = 0;
        zero_ip(&opt_dest_ip);
 
        dbf = x_stderr;
@@ -435,7 +477,7 @@ 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':
@@ -452,18 +494,21 @@ static struct functable net_func[] = {
                        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);
+                       net_help(argc, argv);
+                       exit(1);
                }
        }
 
-       lp_load(servicesf,True,False,False);       
+       if (debuglevel) {
+               debug_parse_levels(debuglevel);
+               AllowDebugChange = False;
+       }
 
-       DEBUGLEVEL = debuglevel;
+       lp_load(servicesf,True,False,False);       
 
        argv_new = (const char **)poptGetArgs(pc);
 
@@ -474,7 +519,7 @@ static struct functable net_func[] = {
                        break;
                }
        }
-        
+
        if (!opt_requester_name) {
                static fstring myname;
                get_myname(myname);
@@ -496,7 +541,7 @@ static struct functable net_func[] = {
        if (!*global_myname) {
                char *p2;
 
-               fstrcpy(global_myname, myhostname());
+               pstrcpy(global_myname, myhostname());
                p2 = strchr_m(global_myname, '.');
                if (p2) 
                         *p2 = 0;
@@ -506,7 +551,24 @@ static struct functable net_func[] = {
 
        load_interfaces();
 
-       rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);
+       if (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 */
+
+               if (!secrets_init()) {
+                       d_printf("ERROR: Unable to open secrets database\n");
+                       exit(1);
+               }
+
+               asprintf(&opt_user_name,"%s$", global_myname);
+               opt_password = secrets_fetch_machine_password();
+               if (!opt_password) {
+                       d_printf("ERROR: Unable to fetch machine password\n");
+                       exit(1);
+               }
+       }
+        
+       rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);
        
        DEBUG(2,("return code = %d\n", rc));
        return rc;