s3:pylibsmb: Add .unlink() API to SMB Py bindings
[samba.git] / source3 / utils / net.c
index e7edb6e7f62515a445c8a137f65a6462743963f9..8350e8c0967b81783b58630f5e9bcc5111589366 100644 (file)
 /*****************************************************/
 
 #include "includes.h"
-#include "popt_common.h"
+#include "popt_common_cmdline.h"
 #include "utils/net.h"
 #include "secrets.h"
 #include "lib/netapi/netapi.h"
 #include "../libcli/security/security.h"
 #include "passdb.h"
 #include "messages.h"
+#include "cmdline_contexts.h"
+#include "lib/gencache.h"
+#include "auth/credentials/credentials.h"
 
 #ifdef WITH_FAKE_KASERVER
 #include "utils/net_afs.h"
@@ -91,13 +94,104 @@ static void set_line_buffering(FILE *f)
        setvbuf(f, NULL, _IOLBF, 0);
 }
 
+static int net_primarytrust_dumpinfo(struct net_context *c, int argc,
+                                    const char **argv)
+{
+       int role = lp_server_role();
+       const char *domain = lp_workgroup();
+       struct secrets_domain_info1 *info = NULL;
+       bool include_secrets = c->opt_force;
+       char *str = NULL;
+       NTSTATUS status;
+
+       if (role >= ROLE_ACTIVE_DIRECTORY_DC) {
+               d_printf(_("net primarytrust dumpinfo is only supported "
+                        "on a DOMAIN_MEMBER for now.\n"));
+               return 1;
+       }
+
+       if (c->opt_stdin) {
+               set_line_buffering(stdin);
+               set_line_buffering(stdout);
+               set_line_buffering(stderr);
+       }
+
+       status = secrets_fetch_or_upgrade_domain_info(domain,
+                                                     talloc_tos(),
+                                                     &info);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr,
+                         _("Unable to fetch the information for domain[%s] "
+                         "in the secrets database.\n"),
+                         domain);
+               return 1;
+       }
+
+       str = secrets_domain_info_string(info, info, domain, include_secrets);
+       if (str == NULL) {
+               d_fprintf(stderr, "secrets_domain_info_string() failed.\n");
+               return 1;
+       }
+
+       d_printf("%s", str);
+       if (!c->opt_force) {
+               d_printf(_("The password values are only included using "
+                        "-f flag.\n"));
+       }
+
+       TALLOC_FREE(info);
+       return 0;
+}
+
+/**
+ * Entrypoint for 'net primarytrust' code.
+ *
+ * @param argc Standard argc.
+ * @param argv Standard argv without initial components.
+ *
+ * @return Integer status (0 means success).
+ */
+
+static int net_primarytrust(struct net_context *c, int argc, const char **argv)
+{
+       struct functable func[] = {
+               {
+                       "dumpinfo",
+                       net_primarytrust_dumpinfo,
+                       NET_TRANSPORT_LOCAL,
+                       N_("Dump the details of the workstation trust"),
+                       N_("  net [options] primarytrust dumpinfo'\n"
+                          "    Dump the details of the workstation trust "
+                          "in secrets.tdb.\n"
+                          "    Requires the -f flag to include the password values.")
+               },
+               {NULL, NULL, 0, NULL, NULL}
+       };
+
+       return net_run_function(c, argc, argv, "net primarytrust", func);
+}
+
 static int net_changesecretpw(struct net_context *c, int argc,
                              const char **argv)
 {
         char *trust_pw;
-        enum netr_SchannelType sec_channel_type = SEC_CHAN_WKSTA;
+       int role = lp_server_role();
+
+       if (role != ROLE_DOMAIN_MEMBER) {
+               d_printf(_("Machine account password change only supported on a DOMAIN_MEMBER.\n"
+                          "Do NOT use this function unless you know what it does!\n"
+                          "This function will change the ADS Domain member "
+                          "machine account password in the secrets.tdb file!\n"));
+               return 1;
+       }
 
        if(c->opt_force) {
+               struct secrets_domain_info1 *info = NULL;
+               struct secrets_domain_info1_change *prev = NULL;
+               NTSTATUS status;
+               struct timeval tv = timeval_current();
+               NTTIME now = timeval_to_nttime(&tv);
+
                if (c->opt_stdin) {
                        set_line_buffering(stdin);
                        set_line_buffering(stdout);
@@ -105,15 +199,43 @@ static int net_changesecretpw(struct net_context *c, int argc,
                }
 
                trust_pw = get_pass(_("Enter machine password: "), c->opt_stdin);
-
-               if (!secrets_store_machine_password(trust_pw, lp_workgroup(), sec_channel_type)) {
+               if (trust_pw == NULL) {
                            d_fprintf(stderr,
-                                     _("Unable to write the machine account password in the secrets database"));
+                                     _("Error in reading machine password\n"));
                            return 1;
                }
-               else {
-                   d_printf(_("Modified trust account password in secrets database\n"));
+
+               status = secrets_prepare_password_change(lp_workgroup(),
+                                                        "localhost",
+                                                        trust_pw,
+                                                        talloc_tos(),
+                                                        &info, &prev);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_fprintf(stderr,
+                               _("Unable to write the machine account password in the secrets database"));
+                       return 1;
+               }
+               if (prev != NULL) {
+                       d_fprintf(stderr,
+                               _("Pending machine account password change found - aborting."));
+                       status = secrets_failed_password_change("localhost",
+                                               NT_STATUS_REQUEST_NOT_ACCEPTED,
+                                               NT_STATUS_NOT_COMMITTED,
+                                               info);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               d_fprintf(stderr,
+                                       _("Failed to abort machine account password change"));
+                       }
+                       return 1;
+               }
+               status = secrets_finish_password_change("localhost", now, info);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_fprintf(stderr,
+                               _("Unable to write the machine account password in the secrets database"));
+                       return 1;
                }
+
+               d_printf(_("Modified trust account password in secrets database\n"));
        }
        else {
                d_printf(_("Machine account password change requires the -f flag.\n"
@@ -151,9 +273,9 @@ static int net_setauthuser(struct net_context *c, int argc, const char **argv)
                                    "        Delete the auth user setting.\n"));
                        return 1;
                }
-               secrets_delete(SECRETS_AUTH_USER);
-               secrets_delete(SECRETS_AUTH_DOMAIN);
-               secrets_delete(SECRETS_AUTH_PASSWORD);
+               secrets_delete_entry(SECRETS_AUTH_USER);
+               secrets_delete_entry(SECRETS_AUTH_DOMAIN);
+               secrets_delete_entry(SECRETS_AUTH_PASSWORD);
                return 0;
        }
 
@@ -237,7 +359,7 @@ static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
 {
         struct dom_sid sid;
        const char *name;
-       fstring sid_str;
+       struct dom_sid_buf sid_str;
 
        if (argc >= 1) {
                name = argv[0];
@@ -247,8 +369,8 @@ static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
        }
 
        if(!initialize_password_db(false, NULL)) {
-               DEBUG(0, ("WARNING: Could not open passdb - local sid may not reflect passdb\n"
-                         "backend knowledge (such as the sid stored in LDAP)\n"));
+               d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
+               return 1;
        }
 
        /* first check to see if we can even access secrets, so we don't
@@ -268,8 +390,9 @@ static int net_getlocalsid(struct net_context *c, int argc, const char **argv)
                DEBUG(0, ("Can't fetch domain SID for name: %s\n", name));
                return 1;
        }
-       sid_to_fstring(sid_str, &sid);
-       d_printf(_("SID for domain %s is: %s\n"), name, sid_str);
+       d_printf(_("SID for domain %s is: %s\n"),
+                name,
+                dom_sid_str_buf(&sid, &sid_str));
        return 0;
 }
 
@@ -318,7 +441,7 @@ static int net_setdomainsid(struct net_context *c, int argc, const char **argv)
 static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
 {
        struct dom_sid domain_sid;
-       fstring sid_str;
+       struct dom_sid_buf sid_str;
 
        if (argc > 0) {
                d_printf(_("Usage:"));
@@ -327,10 +450,8 @@ static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
        }
 
        if(!initialize_password_db(false, NULL)) {
-               DEBUG(0, ("WARNING: Could not open passdb - domain SID may "
-                         "not reflect passdb\n"
-                         "backend knowledge (such as the SID stored in "
-                         "LDAP)\n"));
+               d_fprintf(stderr, _("WARNING: Could not open passdb\n"));
+               return 1;
        }
 
        /* first check to see if we can even access secrets, so we don't
@@ -346,30 +467,32 @@ static int net_getdomainsid(struct net_context *c, int argc, const char **argv)
        /* Generate one, if it doesn't exist */
        get_global_sam_sid();
 
-       if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
-               d_fprintf(stderr, _("Could not fetch local SID\n"));
-               return 1;
+       if (!IS_DC) {
+               if (!secrets_fetch_domain_sid(lp_netbios_name(), &domain_sid)) {
+                       d_fprintf(stderr, _("Could not fetch local SID\n"));
+                       return 1;
+               }
+               d_printf(_("SID for local machine %s is: %s\n"),
+                        lp_netbios_name(),
+                        dom_sid_str_buf(&domain_sid, &sid_str));
        }
-       sid_to_fstring(sid_str, &domain_sid);
-       d_printf(_("SID for local machine %s is: %s\n"),
-                lp_netbios_name(), sid_str);
-
        if (!secrets_fetch_domain_sid(c->opt_workgroup, &domain_sid)) {
                d_fprintf(stderr, _("Could not fetch domain SID\n"));
                return 1;
        }
 
-       sid_to_fstring(sid_str, &domain_sid);
-       d_printf(_("SID for domain %s is: %s\n"), c->opt_workgroup, sid_str);
+       d_printf(_("SID for domain %s is: %s\n"),
+                c->opt_workgroup,
+                dom_sid_str_buf(&domain_sid, &sid_str));
 
        return 0;
 }
 
 static bool search_maxrid(struct pdb_search *search, const char *type,
-                         uint32 *max_rid)
+                         uint32_t *max_rid)
 {
        struct samr_displayentry *entries;
-       uint32 i, num_entries;
+       uint32_t i, num_entries;
 
        if (search == NULL) {
                d_fprintf(stderr, _("get_maxrid: Could not search %s\n"), type);
@@ -383,9 +506,9 @@ static bool search_maxrid(struct pdb_search *search, const char *type,
        return true;
 }
 
-static uint32 get_maxrid(void)
+static uint32_t get_maxrid(void)
 {
-       uint32 max_rid = 0;
+       uint32_t max_rid = 0;
 
        if (!search_maxrid(pdb_search_users(talloc_tos(), 0), "users", &max_rid))
                return 0;
@@ -403,7 +526,7 @@ static uint32 get_maxrid(void)
 
 static int net_maxrid(struct net_context *c, int argc, const char **argv)
 {
-       uint32 rid;
+       uint32_t rid;
 
        if (argc != 0) {
                d_fprintf(stderr, "%s net maxrid\n", _("Usage:"));
@@ -566,6 +689,14 @@ static struct functable net_func[] = {
                N_("  Use 'net help password' to get more information about "
                   "'net password' commands.")
        },
+       {
+               "primarytrust",
+               net_primarytrust,
+               NET_TRANSPORT_RPC,
+               N_("Run functions related to the primary workstation trust."),
+               N_("  Use 'net help primarytrust' to get more extensive information "
+                  "about 'net primarytrust' commands.")
+       },
        {       "changetrustpw",
                net_changetrustpw,
                NET_TRANSPORT_ADS | NET_TRANSPORT_RPC,
@@ -739,6 +870,22 @@ static struct functable net_func[] = {
                   "'net serverid' commands.")
        },
 
+       {       "notify",
+               net_notify,
+               NET_TRANSPORT_LOCAL,
+               N_("notifyd client code"),
+               N_("  Use 'net help notify' to get more information about "
+                  "'net notify' commands.")
+       },
+
+       {       "tdb",
+               net_tdb,
+               NET_TRANSPORT_LOCAL,
+               N_("Show information from tdb records"),
+               N_("  Use 'net help tdb' to get more information about "
+                  "'net tdb' commands.")
+       },
+
 #ifdef WITH_FAKE_KASERVER
        {       "afs",
                net_afs,
@@ -760,16 +907,37 @@ static struct functable net_func[] = {
 };
 
 
+static void get_credentials_file(struct net_context *c,
+                                const char *file)
+{
+       struct cli_credentials *cred = cli_credentials_init(c);
+
+       if (cred == NULL) {
+               d_printf("ERROR: Unable to allocate memory!\n");
+               exit(-1);
+       }
+
+       if (!cli_credentials_parse_file(cred, file, CRED_GUESS_FILE)) {
+               exit(-1);
+       }
+
+       c->opt_user_name = cli_credentials_get_username(cred);
+       c->opt_user_specified = (c->opt_user_name != NULL);
+       c->opt_password = cli_credentials_get_password(cred);
+       c->opt_target_workgroup = cli_credentials_get_domain(cred);
+}
+
 /****************************************************************************
   main program
 ****************************************************************************/
- int main(int argc, const char **argv)
+ int main(int argc, char **argv)
 {
        int opt,i;
        char *p;
        int rc = 0;
        int argc_new = 0;
        const char ** argv_new;
+       const char **argv_const = discard_const_p(const char *, argv);
        poptContext pc;
        TALLOC_CTX *frame = talloc_stackframe();
        struct net_context *c = talloc_zero(frame, struct net_context);
@@ -778,11 +946,12 @@ static struct functable net_func[] = {
                {"help",        'h', POPT_ARG_NONE,   0, 'h'},
                {"workgroup",   'w', POPT_ARG_STRING, &c->opt_target_workgroup},
                {"user",        'U', POPT_ARG_STRING, &c->opt_user_name, 'U'},
+               {"authentication-file", 'A', POPT_ARG_STRING, &c->opt_user_name, 'A', "Get the credentials from a file", "FILE"},
                {"ipaddress",   'I', POPT_ARG_STRING, 0,'I'},
                {"port",        'p', POPT_ARG_INT,    &c->opt_port},
                {"myname",      'n', POPT_ARG_STRING, &c->opt_requester_name},
                {"server",      'S', POPT_ARG_STRING, &c->opt_host},
-               {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport (UNIX extended servers only)") },
+               {"encrypt",     'e', POPT_ARG_NONE,   NULL, 'e', N_("Encrypt SMB transport") },
                {"container",   'c', POPT_ARG_STRING, &c->opt_container},
                {"comment",     'C', POPT_ARG_STRING, &c->opt_comment},
                {"maxusers",    'M', POPT_ARG_INT,    &c->opt_maxusers},
@@ -820,6 +989,16 @@ static struct functable net_func[] = {
                {"lock", 0, POPT_ARG_NONE,   &c->opt_lock},
                {"auto", 'a', POPT_ARG_NONE,   &c->opt_auto},
                {"repair", 0, POPT_ARG_NONE,   &c->opt_repair},
+               /* Options for 'net registry check'*/
+               {"reg-version", 0, POPT_ARG_INT, &c->opt_reg_version},
+               {"output", 'o', POPT_ARG_STRING, &c->opt_output},
+               {"wipe", 0, POPT_ARG_NONE, &c->opt_wipe},
+               /* Options for 'net registry import' */
+               {"precheck", 0, POPT_ARG_STRING, &c->opt_precheck},
+               /* Options for 'net ads join or leave' */
+               {"no-dns-updates", 0, POPT_ARG_NONE, &c->opt_no_dns_updates},
+               {"keep-account", 0, POPT_ARG_NONE, &c->opt_keep_account},
+               {"json", 0, POPT_ARG_NONE, &c->opt_json},
                POPT_COMMON_SAMBA
                { 0, 0, 0, 0}
        };
@@ -828,7 +1007,7 @@ static struct functable net_func[] = {
 
        setup_logging(argv[0], DEBUG_STDERR);
 
-       load_case_tables();
+       smb_init_locale();
 
        setlocale(LC_ALL, "");
 #if defined(HAVE_BINDTEXTDOMAIN)
@@ -842,7 +1021,7 @@ static struct functable net_func[] = {
        lp_set_cmdline("log level", "0");
        c->private_data = net_func;
 
-       pc = poptGetContext(NULL, argc, (const char **) argv, long_options,
+       pc = poptGetContext(NULL, argc, argv_const, long_options,
                            POPT_CONTEXT_KEEP_FIRST);
 
        while((opt = poptGetNextOpt(pc)) != -1) {
@@ -863,22 +1042,31 @@ static struct functable net_func[] = {
                        break;
                case 'U':
                        c->opt_user_specified = true;
-                       c->opt_user_name = SMB_STRDUP(c->opt_user_name);
+                       c->opt_user_name = talloc_strdup(c, c->opt_user_name);
                        p = strchr(c->opt_user_name,'%');
                        if (p) {
                                *p = 0;
                                c->opt_password = p+1;
                        }
                        break;
+               case 'A':
+                       get_credentials_file(c, c->opt_user_name);
+                       break;
                default:
                        d_fprintf(stderr, _("\nInvalid option %s: %s\n"),
                                 poptBadOption(pc, 0), poptStrerror(opt));
-                       net_help(c, argc, argv);
+                       net_help(c, argc, argv_const);
                        exit(1);
                }
        }
 
-       lp_load_global(get_dyn_CONFIGFILE());
+       c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE());
+
+       if (!lp_load_global(get_dyn_CONFIGFILE())) {
+               d_fprintf(stderr, "Can't load %s - run testparm to debug it\n",
+                         get_dyn_CONFIGFILE());
+               exit(1);
+       }
 
 #if defined(HAVE_BIND_TEXTDOMAIN_CODESET)
        /* Bind our gettext results to 'unix charset'
@@ -913,11 +1101,11 @@ static struct functable net_func[] = {
        }
 
        if (!c->opt_workgroup) {
-               c->opt_workgroup = smb_xstrdup(lp_workgroup());
+               c->opt_workgroup = talloc_strdup(c, lp_workgroup());
        }
 
        if (!c->opt_target_workgroup) {
-               c->opt_target_workgroup = smb_xstrdup(lp_workgroup());
+               c->opt_target_workgroup = talloc_strdup(c, lp_workgroup());
        }
 
        if (!init_names())
@@ -940,18 +1128,12 @@ static struct functable net_func[] = {
                c->opt_password = getenv("PASSWD");
        }
 
-       /* Failing to init the msg_ctx isn't a fatal error. Only
-          root-level things (joining/leaving domains etc.) will be denied. */
-
-       c->msg_ctx = messaging_init(c, procid_self(),
-                                   event_context_init(c));
+       popt_burn_cmdline_password(argc, argv);
 
        rc = net_run_function(c, argc_new-1, argv_new+1, "net", net_func);
 
        DEBUG(2,("return code = %d\n", rc));
 
-       gencache_stabilize();
-
        libnetapi_free(c->netapi_ctx);
 
        poptFreeContext(pc);