diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/utils/net_rpc.c | 182 |
1 files changed, 84 insertions, 98 deletions
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 488167cb39..fc779a3b45 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -37,6 +37,8 @@ #include "secrets.h" #include "lib/netapi/netapi.h" #include "lib/netapi/netapi_net.h" +#include "librpc/gen_ndr/libnet_join.h" +#include "libnet/libnet_join.h" #include "rpc_client/init_lsa.h" #include "../libcli/security/security.h" #include "libsmb/libsmb.h" @@ -314,48 +316,46 @@ int net_rpc_changetrustpw(struct net_context *c, int argc, const char **argv) } /** - * Join a domain, the old way. + * Join a domain, the old way. This function exists to allow + * the message to be displayed when oldjoin was explicitly + * requested, but not when it was implied by "net rpc join". * * This uses 'machinename' as the inital password, and changes it. * * The password should be created with 'server manager' or equiv first. * - * All parameters are provided by the run_rpc_command function, except for - * argc, argv which are passed through. - * - * @param domain_sid The domain sid acquired from the remote server. - * @param cli A cli_state connected to the server. - * @param mem_ctx Talloc context, destroyed on completion of the function. * @param argc Standard main() style argc. * @param argv Standard main() style argv. Initial components are already * stripped. * - * @return Normal NTSTATUS return. + * @return A shell status integer (0 for success). **/ -static NTSTATUS rpc_oldjoin_internals(struct net_context *c, - const struct dom_sid *domain_sid, - const char *domain_name, - struct cli_state *cli, - struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, - int argc, - const char **argv) +static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv) { + struct libnet_JoinCtx *r = NULL; + TALLOC_CTX *mem_ctx; + WERROR werr; + const char *domain = lp_workgroup(); /* FIXME */ + bool modify_config = lp_config_backend_is_registry(); + enum netr_SchannelType sec_chan_type; + char *pw = NULL; - fstring trust_passwd; - unsigned char orig_trust_passwd_hash[16]; - NTSTATUS result; - enum netr_SchannelType sec_channel_type; + if (c->display_usage) { + d_printf("Usage:\n" + "net rpc oldjoin\n" + " Join a domain the old way\n"); + return 0; + } - result = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon, - &pipe_hnd); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("rpc_oldjoin_internals: netlogon pipe open to machine %s failed. " - "error was %s\n", - smbXcli_conn_remote_name(cli->conn), - nt_errstr(result) )); - return result; + mem_ctx = talloc_init("net_rpc_oldjoin"); + if (!mem_ctx) { + return -1; + } + + werr = libnet_init_JoinCtx(mem_ctx, &r); + if (!W_ERROR_IS_OK(werr)) { + goto fail; } /* @@ -363,92 +363,78 @@ static NTSTATUS rpc_oldjoin_internals(struct net_context *c, a BDC, the server must agree that we are a BDC. */ if (argc >= 0) { - sec_channel_type = get_sec_channel_type(argv[0]); + sec_chan_type = get_sec_channel_type(argv[0]); } else { - sec_channel_type = get_sec_channel_type(NULL); + sec_chan_type = get_sec_channel_type(NULL); } - fstrcpy(trust_passwd, lp_netbios_name()); - if (!strlower_m(trust_passwd)) { - return NT_STATUS_UNSUCCESSFUL; + if (!c->msg_ctx) { + d_fprintf(stderr, _("Could not initialise message context. " + "Try running as root\n")); + werr = WERR_ACCESS_DENIED; + goto fail; } - /* - * Machine names can be 15 characters, but the max length on - * a password is 14. --jerry - */ - - trust_passwd[14] = '\0'; - - E_md4hash(trust_passwd, orig_trust_passwd_hash); - - result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup, - lp_netbios_name(), - orig_trust_passwd_hash, - sec_channel_type); - - if (NT_STATUS_IS_OK(result)) - printf(_("Joined domain %s.\n"), c->opt_target_workgroup); + pw = talloc_strndup(r, lp_netbios_name(), 14); + if (pw == NULL) { + werr = WERR_NOMEM; + goto fail; + } + r->in.msg_ctx = c->msg_ctx; + r->in.domain_name = domain; + r->in.secure_channel_type = sec_chan_type; + r->in.dc_name = c->opt_host; + r->in.admin_account = ""; + r->in.admin_password = strlower_talloc(r, pw); + if (r->in.admin_password == NULL) { + werr = WERR_NOMEM; + goto fail; + } + r->in.debug = true; + r->in.modify_config = modify_config; + r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE | + WKSSVC_JOIN_FLAGS_JOIN_UNSECURE | + WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED; - if (!secrets_store_domain_sid(c->opt_target_workgroup, domain_sid)) { - DEBUG(0, ("error storing domain sid for %s\n", c->opt_target_workgroup)); - result = NT_STATUS_UNSUCCESSFUL; + werr = libnet_Join(mem_ctx, r); + if (!W_ERROR_IS_OK(werr)) { + goto fail; } - return result; -} + /* Check the short name of the domain */ -/** - * Join a domain, the old way. - * - * @param argc Standard main() style argc. - * @param argv Standard main() style argv. Initial components are already - * stripped. - * - * @return A shell status integer (0 for success). - **/ + if (!modify_config && !strequal(lp_workgroup(), r->out.netbios_domain_name)) { + d_printf("The workgroup in %s does not match the short\n", get_dyn_CONFIGFILE()); + d_printf("domain name obtained from the server.\n"); + d_printf("Using the name [%s] from the server.\n", r->out.netbios_domain_name); + d_printf("You should set \"workgroup = %s\" in %s.\n", + r->out.netbios_domain_name, get_dyn_CONFIGFILE()); + } -static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv) -{ - return run_rpc_command(c, NULL, &ndr_table_netlogon, - NET_FLAGS_NO_PIPE | NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, - rpc_oldjoin_internals, - argc, argv); -} + d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name); -/** - * Join a domain, the old way. This function exists to allow - * the message to be displayed when oldjoin was explicitly - * requested, but not when it was implied by "net rpc join". - * - * @param argc Standard main() style argc. - * @param argv Standard main() style argv. Initial components are already - * stripped. - * - * @return A shell status integer (0 for success). - **/ + if (r->out.dns_domain_name) { + d_printf("Joined '%s' to realm '%s'\n", r->in.machine_name, + r->out.dns_domain_name); + } else { + d_printf("Joined '%s' to domain '%s'\n", r->in.machine_name, + r->out.netbios_domain_name); + } -static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv) -{ - int rc = -1; + TALLOC_FREE(mem_ctx); - if (c->display_usage) { - d_printf( "%s\n" - "net rpc oldjoin\n" - " %s\n", - _("Usage:"), - _("Join a domain the old way")); - return 0; - } + return 0; - rc = net_rpc_perform_oldjoin(c, argc, argv); +fail: + /* issue an overall failure message at the end. */ + d_fprintf(stderr, _("Failed to join domain: %s\n"), + r && r->out.error_string ? r->out.error_string : + get_friendly_werror_msg(werr)); - if (rc) { - d_fprintf(stderr, _("Failed to join domain\n")); - } + TALLOC_FREE(mem_ctx); - return rc; + return -1; } /** @@ -492,7 +478,7 @@ int net_rpc_join(struct net_context *c, int argc, const char **argv) return -1; } - if ((net_rpc_perform_oldjoin(c, argc, argv) == 0)) + if ((net_rpc_oldjoin(c, argc, argv) == 0)) return 0; return net_rpc_join_newstyle(c, argc, argv); |