* sync more files from 3.0
[ira/wip.git] / source3 / utils / net.c
index 704b886d7298333a4b1b9a5d105dff1c4e7ca466..42966b4f830887e22c2018dbf0121952f6c05d4d 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 = "";
+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 pstring global_myname;
 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
   call the specified usage function 
@@ -121,7 +141,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, 0, NULL);
+                                       opt_password, 0, Undefined, NULL);
        
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -151,7 +171,7 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
                                        server_ip, opt_port,
                                        "IPC$", "IPC",  
                                        "", "",
-                                       "", 0, NULL);
+                                       "", 0, Undefined, NULL);
        
        if (NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
@@ -161,6 +181,27 @@ NTSTATUS connect_to_ipc_anonymous(struct cli_state **c,
        }
 }
 
+/****************************************************************************
+ Use the local machine's password for this session
+****************************************************************************/
+int net_use_machine_password(void) 
+{
+       char *user_name = NULL;
+
+       if (!secrets_init()) {
+               d_printf("ERROR: Unable to open secrets database\n");
+               exit(1);
+       }
+
+       user_name = NULL;
+       opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+       if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
+               return -1;
+       }
+       opt_user_name = user_name;
+       return 0;
+}
+
 BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_name)
 {
 
@@ -180,23 +221,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 ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
                                return False;
                                
                        *server_name = strdup(dc_name);
+                       *server_ip = pdc_ip;
                }
                
        } else if (flags & NET_FLAGS_DMB) {
@@ -234,28 +271,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, const char *domain_name)
+BOOL net_find_pdc(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)) {
-               fstring dc_name;
-               if (addr_count < 1) {
-                       return False;
-               }
-                       
-               *server_ip = *ip_list;
-               
+       if (get_pdc_ip(domain_name, server_ip)) {
                if (is_zero_ip(*server_ip))
                        return False;
                
-               if (!lookup_dc_name(global_myname, domain_name, server_ip, dc_name))
+               if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
                        return False;
                        
-               safe_strcpy(server_name, dc_name, FSTRING_LEN);
-               return True;
-       else
+               return True;    
+       } 
+       else
                return False;
 }
 
@@ -315,11 +342,44 @@ static int net_join(int argc, const char **argv)
                if (net_ads_join(argc, argv) == 0)
                        return 0;
                else
-                       d_printf("ADS join did not work, trying RPC...\n");
+                       d_printf("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)
+{
+       if (net_ads_check() == 0)
+               return net_ads_changetrustpw(argc, argv);
+
+       return net_rpc_changetrustpw(argc, argv);
+}
+
+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 (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
+                           d_printf("Unable to write the machine account password in the secrets database");
+                           return 1;
+               }
+               else {
+                   d_printf("Modified trust account password in secrets database\n");
+               }
+       }
+       else {
+               d_printf("Machine account password change requires the -f flag.\n");
+               d_printf("Do NOT use this function unless you know what it does!\n");
+               d_printf("This function will change the ADS Domain member machine account password in the secrets.tdb file!\n");
+       }
+
+        return 0;
+}
+
 static int net_share(int argc, const char **argv)
 {
        if (net_rpc_check(0))
@@ -347,7 +407,7 @@ static int net_getlocalsid(int argc, const char **argv)
                name = argv[0];
         }
        else {
-               name = global_myname;
+               name = global_myname();
        }
 
        if (!secrets_fetch_domain_sid(name, &sid)) {
@@ -371,7 +431,7 @@ static int net_setlocalsid(int argc, const char **argv)
                return 1;
        }
 
-       if (!secrets_store_domain_sid(global_myname, &sid)) {
+       if (!secrets_store_domain_sid(global_myname(), &sid)) {
                DEBUG(0,("Can't store domain SID as a pdc/bdc.\n"));
                return 1;
        }
@@ -384,24 +444,68 @@ 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)) {
+       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);
+       d_printf("SID for domain %s is: %s\n", global_myname(), sid_str);
 
-       if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
+       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", lp_workgroup(), sid_str);
+       d_printf("SID for domain %s is: %s\n", opt_workgroup, sid_str);
 
        return 0;
 }
 
+#ifdef WITH_FAKE_KASERVER
+
+int net_afskey_usage(int argc, const char **argv)
+{
+       d_printf("  net afskey filename\n"
+                "\tImports a OpenAFS KeyFile into our secrets.tdb\n\n");
+       return -1;
+}
+
+static int net_afskey(int argc, const char **argv)
+{
+       int fd;
+       struct afs_keyfile keyfile;
+
+       if (argc != 2) {
+               d_printf("usage: 'net afskey <keyfile> cell'\n");
+               return -1;
+       }
+
+       if (!secrets_init()) {
+               d_printf("Could not open secrets.tdb\n");
+               return -1;
+       }
+
+       if ((fd = open(argv[0], O_RDONLY, 0)) < 0) {
+               d_printf("Could not open %s\n", argv[0]);
+               return -1;
+       }
+
+       if (read(fd, &keyfile, sizeof(keyfile)) != sizeof(keyfile)) {
+               d_printf("Could not read keyfile\n");
+               return -1;
+       }
+
+       if (!secrets_store_afs_keyfile(argv[1], &keyfile)) {
+               d_printf("Could not write keyfile to secrets.tdb\n");
+               return -1;
+       }
+
+       return 0;
+}
+
+#endif /* WITH_FAKE_KASERVER */
+
 static uint32 get_maxrid(void)
 {
        SAM_ACCOUNT *pwd = NULL;
@@ -437,7 +541,7 @@ static uint32 get_maxrid(void)
        pdb_free_sam(&pwd);
 
        if (!pdb_enum_group_mapping(SID_NAME_UNKNOWN, &map, &num_entries,
-                                   ENUM_ONLY_MAPPED, MAPPING_WITHOUT_PRIV))
+                                   ENUM_ONLY_MAPPED))
                return max_rid;
 
        for (i = 0; i < num_entries; i++) {
@@ -466,7 +570,7 @@ static int net_maxrid(int argc, const char **argv)
        uint32 rid;
 
        if (argc != 0) {
-               DEBUG(0, ("usage: net initrid\n"));
+               DEBUG(0, ("usage: net maxrid\n"));
                return 1;
        }
 
@@ -495,11 +599,14 @@ 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},
+       {"CHANGESECRETPW", net_changesecretpw},
        {"TIME", net_time},
        {"LOOKUP", net_lookup},
        {"JOIN", net_join},
@@ -508,6 +615,10 @@ static struct functable net_func[] = {
        {"SETLOCALSID", net_setlocalsid},
        {"GETDOMAINSID", net_getdomainsid},
        {"MAXRID", net_maxrid},
+       {"IDMAP", net_idmap},
+#ifdef WITH_FAKE_KASERVER
+       {"AFSKEY", net_afskey},
+#endif
 
        {"HELP", net_help},
        {NULL, NULL}
@@ -525,34 +636,33 @@ 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}
        };
 
        zero_ip(&opt_dest_ip);
 
+       /* set default debug level to 0 regardless of what smb.conf sets */
+       DEBUGLEVEL_CLASS[DBGC_ALL] = 0;
        dbf = x_stderr;
        
        pc = poptGetContext(NULL, argc, (const char **) argv, long_options, 
@@ -581,20 +691,21 @@ 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);       
-
-       argv_new = (const char **)poptGetArgs(pc);
+       
+       /*
+        * Don't load debug level from smb.conf. It should be
+        * set by cmdline arg or remain default (0)
+        */
+       AllowDebugChange = False;
+       lp_load(dyn_CONFIGFILE,True,False,False);
+       
+       argv_new = (const char **)poptGetArgs(pc);
 
        argc_new = argc;
        for (i=0; i<argc; i++) {
@@ -615,41 +726,31 @@ 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;
-
-               pstrcpy(global_myname, myhostname());
-               p2 = strchr_m(global_myname, '.');
-               if (p2) 
-                        *p2 = 0;
-       }
-       
-       strupper(global_myname);
+       if (!init_names())
+               exit(1);
 
        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) {
                /* 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);
-               }
+               net_use_machine_password();
+       }
 
-               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);
-               }
+       if (!opt_password) {
+               opt_password = getenv("PASSWD");
        }
         
        rc = net_run_function(argc_new-1, argv_new+1, net_func, net_help);