This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[nivanova/samba-autobuild/.git] / source3 / utils / net.c
index 9e4c5e52c9e50936fd3d787835b829988a3b7747..7588771fbc3f16aefec2950a0e14447f9bb96006 100644 (file)
 /************************************************************************************/
 
 /* Yes, these buggers are globals.... */
-char *opt_requester_name = NULL;
-char *opt_host = NULL; 
-char *opt_password = NULL;
-char *opt_user_name = 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;
-char *opt_workgroup = NULL;
+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 = "";
+char *opt_container = "cn=Users";
 int opt_flags = -1;
 int opt_jobid = 0;
 int opt_timeout = 0;
-char *opt_target_workgroup = NULL;
+const char *opt_target_workgroup = NULL;
+static int opt_machine_pass = 0;
 
 BOOL opt_have_ip = False;
 struct in_addr opt_dest_ip;
 
-extern pstring global_myname;
 extern BOOL AllowDebugChange;
 
 /*
@@ -120,7 +121,7 @@ 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);
+                                       opt_password, 0, NULL);
        
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -150,7 +151,7 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
                                        server_ip, opt_port,
                                        "IPC$", "IPC",  
                                        "", "",
-                                       "");
+                                       "", 0, NULL);
        
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -179,23 +180,19 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
                        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 False;
-                       }
                        
-                       *server_ip = *ip_list;
-                       
-                       if (is_zero_ip(*server_ip))
+                       if (is_zero_ip(pdc_ip))
                                return False;
                        
-                       if (!lookup_dc_name(global_myname, opt_target_workgroup, server_ip, dc_name))
+                       if (!lookup_dc_name(global_myname(), opt_target_workgroup, &pdc_ip, dc_name))
                                return False;
                                
                        *server_name = strdup(dc_name);
+                       *server_ip = pdc_ip;
                }
                
        } else if (flags & NET_FLAGS_DMB) {
@@ -233,26 +230,18 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
 }
 
 
-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;
-
-       if (get_dc_list(True /* PDC only*/, domain_name, &ip_list, &addr_count)) {
+       if (get_pdc_ip(domain_name, server_ip)) {
                fstring dc_name;
-               if (addr_count < 1) {
-                       return False;
-               }
                        
-               *server_ip = *ip_list;
-               
                if (is_zero_ip(*server_ip))
                        return False;
                
-               if (!lookup_dc_name(global_myname, domain_name, server_ip, dc_name))
+               if (!lookup_dc_name(global_myname(), domain_name, server_ip, dc_name))
                        return False;
                        
-               safe_strcpy(server_name, dc_name, FSTRING_LEN);
+               fstrcpy(server_name, dc_name);
                return True;
        } else
                return False;
@@ -276,8 +265,13 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
        } else {
                nt_status = connect_to_ipc(&cli, &server_ip, server_name);
        }
+
        SAFE_FREE(server_name);
-       return cli;
+       if (NT_STATUS_IS_OK(nt_status)) {
+               return cli;
+       } else {
+               return NULL;
+       }
 }
 
 static int net_user(int argc, const char **argv)
@@ -323,12 +317,157 @@ static int net_share(int argc, const char **argv)
 
 static int net_file(int argc, const char **argv)
 {
-       /* only file list is implemented in RPC */
-       if (argc == 0 && net_rpc_check(0))
+       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
+ */
+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(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;
+}
+
+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, MAPPING_WITHOUT_PRIV))
+               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)
+{
+       uint32 rid;
+
+       if (argc != 0) {
+               DEBUG(0, ("usage: net initrid\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 */
 static struct functable net_func[] = {
        {"RPC", net_rpc},
@@ -352,6 +491,11 @@ static struct functable net_func[] = {
        {"TIME", net_time},
        {"LOOKUP", net_lookup},
        {"JOIN", net_join},
+       {"CACHE", net_cache},
+       {"GETLOCALSID", net_getlocalsid},
+       {"SETLOCALSID", net_setlocalsid},
+       {"GETDOMAINSID", net_getdomainsid},
+       {"MAXRID", net_maxrid},
 
        {"HELP", net_help},
        {NULL, NULL}
@@ -381,9 +525,8 @@ 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_STRING,    &debuglevel},
-               {"debuglevel",  'd', POPT_ARG_STRING,    &debuglevel},
                {"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},
@@ -392,6 +535,9 @@ 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},
+               {NULL, 0, POPT_ARG_INCLUDE_TABLE, popt_common_version},
                { 0, 0, 0, 0}
        };
 
@@ -425,8 +571,10 @@ static struct functable net_func[] = {
                        }
                        break;
                default:
-                       d_printf("\nInvalid option %c (%d)\n", (char)opt, opt);
+                       d_printf("\nInvalid option %s: %s\n", 
+                                poptBadOption(pc, 0), poptStrerror(opt));
                        net_help(argc, argv);
+                       exit(1);
                }
        }
 
@@ -446,7 +594,7 @@ static struct functable net_func[] = {
                        break;
                }
        }
-        
+
        if (!opt_requester_name) {
                static fstring myname;
                get_myname(myname);
@@ -462,22 +610,33 @@ static struct functable net_func[] = {
        }
        
        if (!opt_target_workgroup) {
-               opt_target_workgroup = lp_workgroup();
+               opt_target_workgroup = strdup(lp_workgroup());
        }
        
-       if (!*global_myname) {
-               char *p2;
-
-               fstrcpy(global_myname, myhostname());
-               p2 = strchr_m(global_myname, '.');
-               if (p2) 
-                        *p2 = 0;
-       }
-       
-       strupper(global_myname);
+       if (!init_names())
+               exit(1);
 
        load_interfaces();
 
+       if (opt_machine_pass) {
+               char *user;
+               /* 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(&user,"%s$", global_myname());
+               opt_user_name = user;
+               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));