Merge from HEAD - save the type of channel used to contact the DC.
[sfrench/samba-autobuild/.git] / source / utils / net.c
index 37ceadc37296d79f3c54bf297ba565db69a641ca..b404bac59522cabe098dfde756063ca9feb44952 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;
 const char *opt_workgroup = NULL;
 int opt_long_list_entries = 0;
@@ -67,17 +67,36 @@ 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;
 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 BOOL AllowDebugChange;
+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
@@ -240,7 +259,7 @@ BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *dom
                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;
@@ -307,6 +326,14 @@ static int net_join(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)
+               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))
@@ -321,6 +348,26 @@ static int net_file(int argc, const char **argv)
        return net_rap_file(argc, argv);
 }
 
+/***********************************************************
+ migrated functionality from smbgroupedit
+ **********************************************************/
+static int net_groupmap(int argc, const char **argv)
+{
+       if ( 0 == argc )
+               return net_help_groupmap( argc, argv );
+
+       if ( !StrCaseCmp( argv[0], "add" ) )
+               return net_groupmap_add(argc-1, argv+1);
+       else if ( !StrCaseCmp( argv[0], "modify" ) )
+               return net_groupmap_modify(argc-1, argv+1);
+       else if ( !StrCaseCmp( argv[0], "delete" ) )
+               return net_groupmap_delete(argc-1, argv+1);
+       else if ( !StrCaseCmp( argv[0], "list" ) )
+               return net_groupmap_list(argc-1, argv+1);
+       
+       return net_help_groupmap( argc, argv );
+}
+
 /*
  Retrieve our local SID or the SID for the specified name
  */
@@ -389,6 +436,84 @@ static int net_getdomainsid(int argc, const char **argv)
        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 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 */
 static struct functable net_func[] = {
        {"RPC", net_rpc},
@@ -404,11 +529,13 @@ static struct functable net_func[] = {
        {"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},
@@ -416,6 +543,7 @@ static struct functable net_func[] = {
        {"GETLOCALSID", net_getlocalsid},
        {"SETLOCALSID", net_setlocalsid},
        {"GETDOMAINSID", net_getdomainsid},
+       {"MAXRID", net_maxrid},
 
        {"HELP", net_help},
        {NULL, NULL}
@@ -433,29 +561,26 @@ static struct functable net_func[] = {
        int argc_new = 0;
        const char ** argv_new;
        poptContext pc;
-       static char *servicesf = dyn_CONFIGFILE;
-       static char *debuglevel = NULL;
 
        struct poptOption long_options[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
                {"workgroup",   'w', POPT_ARG_STRING, &opt_target_workgroup},
-               {"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},
                {"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},
-               {"jobid",       'j', POPT_ARG_INT,    &opt_jobid},
                {"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},
-               {"debuglevel",  'D', POPT_ARG_STRING, &debuglevel},
+               {"myworkgroup", 'W', POPT_ARG_STRING, &opt_workgroup},
+               POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
        };
 
@@ -489,18 +614,14 @@ 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);
                }
        }
-
-       if (debuglevel) {
-               debug_parse_levels(debuglevel);
-               AllowDebugChange = False;
-       }
-
-       lp_load(servicesf,True,False,False);       
+       
+       lp_load(dyn_CONFIGFILE,True,False,False);       
 
        argv_new = (const char **)poptGetArgs(pc);
 
@@ -523,11 +644,11 @@ 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 = strdup(lp_workgroup());
+               opt_target_workgroup = smb_xstrdup(lp_workgroup());
        }
        
        if (!init_names())
@@ -536,6 +657,7 @@ static struct functable net_func[] = {
        load_interfaces();
 
        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 */
 
@@ -544,13 +666,19 @@ static struct functable net_func[] = {
                        exit(1);
                }
 
-               asprintf(&opt_user_name,"%s$", global_myname());
-               opt_password = secrets_fetch_machine_password();
+               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);