#include "includes.h"
#include "utils/net.h"
+#include "libsmb/namequery.h"
#include "rpc_client/cli_pipe.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/ndr_samr_c.h"
#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"
#include "nsswitch/libwbclient/wbclient.h"
#include "passdb.h"
#include "../libcli/smb/smbXcli_base.h"
+#include "libsmb/dsgetdcname.h"
static int net_mode_share;
static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask);
* @brief RPC based subcommands for the 'net' utility.
*
* This file should contain much of the functionality that used to
- * be found in rpcclient, execpt that the commands should change
- * less often, and the fucntionality should be sane (the user is not
+ * be found in rpcclient, except that the commands should change
+ * less often, and the functionality should be sane (the user is not
* expected to know a rid/sid before they conduct an operation etc.)
*
* @todo Perhaps eventually these should be split out into a number
union lsa_PolicyInformation *info = NULL;
struct dcerpc_binding_handle *b;
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
&lsa_pipe);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, _("Could not initialise lsa pipe\n"));
&& (ndr_syntax_id_equal(&table->syntax_id,
&ndr_table_netlogon.syntax_id))) {
/* Always try and create an schannel netlogon pipe. */
+ TALLOC_FREE(c->netlogon_creds);
nt_status = cli_rpc_pipe_open_schannel(
- cli, table, NCACN_NP,
- DCERPC_AUTH_LEVEL_PRIVACY, domain_name,
- &pipe_hnd);
+ cli, c->msg_ctx, table, NCACN_NP,
+ domain_name,
+ &pipe_hnd, c, &c->netlogon_creds);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise schannel netlogon pipe. Error was %s\n",
nt_errstr(nt_status) ));
cli, table,
(conn_flags & NET_FLAGS_TCP) ?
NCACN_IP_TCP : NCACN_NP,
+ CRED_DONT_USE_KERBEROS,
DCERPC_AUTH_TYPE_NTLMSSP,
DCERPC_AUTH_LEVEL_PRIVACY,
smbXcli_conn_remote_name(cli->conn),
c->opt_password, &pipe_hnd);
} else {
nt_status = cli_rpc_pipe_open_noauth(
- cli, &table->syntax_id,
+ cli, table,
&pipe_hnd);
}
if (!NT_STATUS_IS_OK(nt_status)) {
}
/**
- * Force a change of the trust acccount password.
+ * Force a change of the trust account password.
*
* All parameters are provided by the run_rpc_command function, except for
* argc, argv which are passed through.
const char **argv)
{
NTSTATUS status;
+ const char *dcname = NULL;
+
+ if (cli == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
- status = trust_pw_find_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup);
+ dcname = smbXcli_conn_remote_name(cli->conn);
+
+ status = trust_pw_change(c->netlogon_creds,
+ c->msg_ctx,
+ pipe_hnd->binding_handle,
+ c->opt_target_workgroup,
+ dcname,
+ true); /* force */
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, _("Failed to change machine account password: %s\n"),
nt_errstr(status));
}
/**
- * Force a change of the trust acccount password.
+ * Force a change of the trust account password.
*
* @param argc Standard main() style argc.
* @param argv Standard main() style argv. Initial components are already
}
/**
- * 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.
+ * This uses 'machinename' as the initial 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.syntax_id,
- &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;
}
/*
- check what type of join - if the user want's to join as
+ check what type of join - if the user wants to join as
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
- */
+ pw = talloc_strndup(r, lp_netbios_name(), 14);
+ if (pw == NULL) {
+ werr = WERR_NOT_ENOUGH_MEMORY;
+ goto fail;
+ }
- trust_passwd[14] = '\0';
+ 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_NOT_ENOUGH_MEMORY;
+ 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;
- E_md4hash(trust_passwd, orig_trust_passwd_hash);
+ werr = libnet_Join(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto fail;
+ }
- 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);
+ /* Check the short name of the domain */
- if (NT_STATUS_IS_OK(result))
- printf(_("Joined domain %s.\n"), c->opt_target_workgroup);
+ 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());
+ }
+ d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
- 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;
+ 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);
}
- return result;
+ /* print out informative error string in case there is one */
+ if (r->out.error_string != NULL) {
+ d_printf("%s\n", r->out.error_string);
+ }
+
+ TALLOC_FREE(mem_ctx);
+
+ return 0;
+
+fail:
+ if (c->opt_flags & NET_FLAGS_EXPECT_FALLBACK) {
+ goto cleanup;
+ }
+
+ /* 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));
+
+cleanup:
+ TALLOC_FREE(mem_ctx);
+
+ return -1;
}
/**
- * Join a domain, the old way.
+ * check that a join is OK
*
- * @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)
*
- * @return A shell status integer (0 for success).
**/
-
-static int net_rpc_perform_oldjoin(struct net_context *c, int argc, const char **argv)
+int net_rpc_testjoin(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);
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ const char *domain = c->opt_target_workgroup;
+ const char *dc = c->opt_host;
+
+ if (c->display_usage) {
+ d_printf("Usage\n"
+ "net rpc testjoin\n"
+ " Test if a join is OK\n");
+ return 0;
+ }
+
+ mem_ctx = talloc_init("net_rpc_testjoin");
+ if (!mem_ctx) {
+ return -1;
+ }
+
+ if (!dc) {
+ struct netr_DsRGetDCNameInfo *info;
+
+ if (!c->msg_ctx) {
+ d_fprintf(stderr, _("Could not initialise message context. "
+ "Try running as root\n"));
+ talloc_destroy(mem_ctx);
+ return -1;
+ }
+
+ status = dsgetdcname(mem_ctx,
+ c->msg_ctx,
+ domain,
+ NULL,
+ NULL,
+ DS_RETURN_DNS_NAME,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_destroy(mem_ctx);
+ return -1;
+ }
+
+ dc = strip_hostname(info->dc_unc);
+ }
+
+ /* Display success or failure */
+ status = libnet_join_ok(c->msg_ctx,
+ c->opt_workgroup,
+ dc,
+ c->opt_kerberos);
+ if (!NT_STATUS_IS_OK(status)) {
+ fprintf(stderr,"Join to domain '%s' is not valid: %s\n",
+ domain, nt_errstr(status));
+ talloc_destroy(mem_ctx);
+ return -1;
+ }
+
+ printf("Join to '%s' is OK\n",domain);
+ talloc_destroy(mem_ctx);
+
+ return 0;
}
/**
- * 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".
+ * Join a domain using the administrator username and password
*
- * @param argc Standard main() style argc.
- * @param argv Standard main() style argv. Initial components are already
- * stripped.
+ * @param argc Standard main() style argc
+ * @param argc Standard main() style argv. Initial components are already
+ * stripped. Currently not used.
+ * @return A shell status integer (0 for success)
*
- * @return A shell status integer (0 for success).
**/
-static int net_rpc_oldjoin(struct net_context *c, int argc, const char **argv)
+static int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv)
{
- int rc = -1;
+ 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;
if (c->display_usage) {
- d_printf( "%s\n"
- "net rpc oldjoin\n"
- " %s\n",
- _("Usage:"),
- _("Join a domain the old way"));
+ d_printf("Usage:\n"
+ "net rpc join\n"
+ " Join a domain the new way\n");
return 0;
}
- rc = net_rpc_perform_oldjoin(c, argc, argv);
+ mem_ctx = talloc_init("net_rpc_join_newstyle");
+ if (!mem_ctx) {
+ return -1;
+ }
- if (rc) {
- d_fprintf(stderr, _("Failed to join domain\n"));
+ werr = libnet_init_JoinCtx(mem_ctx, &r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto fail;
}
- return rc;
+ /*
+ check what type of join - if the user wants to join as
+ a BDC, the server must agree that we are a BDC.
+ */
+ if (argc >= 0) {
+ sec_chan_type = get_sec_channel_type(argv[0]);
+ } else {
+ sec_chan_type = get_sec_channel_type(NULL);
+ }
+
+ if (!c->msg_ctx) {
+ d_fprintf(stderr, _("Could not initialise message context. "
+ "Try running as root\n"));
+ werr = WERR_ACCESS_DENIED;
+ 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 = c->opt_user_name;
+ r->in.admin_password = net_prompt_pass(c, c->opt_user_name);
+ r->in.debug = true;
+ r->in.use_kerberos = c->opt_kerberos;
+ r->in.modify_config = modify_config;
+ r->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
+ WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
+ WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
+
+ werr = libnet_Join(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto fail;
+ }
+
+ /* Check the short name of the domain */
+
+ 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());
+ }
+
+ d_printf("Using short domain name -- %s\n", r->out.netbios_domain_name);
+
+ 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);
+ }
+
+ /* print out informative error string in case there is one */
+ if (r->out.error_string != NULL) {
+ d_printf("%s\n", r->out.error_string);
+ }
+
+ TALLOC_FREE(mem_ctx);
+
+ return 0;
+
+fail:
+ /* issue an overall failure message at the end. */
+ d_printf("Failed to join domain: %s\n",
+ r && r->out.error_string ? r->out.error_string :
+ get_friendly_werror_msg(werr));
+
+ TALLOC_FREE(mem_ctx);
+
+ return -1;
}
/**
int net_rpc_join(struct net_context *c, int argc, const char **argv)
{
+ int ret;
+
if (c->display_usage) {
d_printf("%s\n%s",
_("Usage:"),
return -1;
}
- if ((net_rpc_perform_oldjoin(c, argc, argv) == 0))
+ c->opt_flags |= NET_FLAGS_EXPECT_FALLBACK;
+ ret = net_rpc_oldjoin(c, argc, argv);
+ c->opt_flags &= ~NET_FLAGS_EXPECT_FALLBACK;
+ if (ret == 0) {
return 0;
+ }
return net_rpc_join_newstyle(c, argc, argv);
}
struct policy_handle connect_pol, domain_pol, user_pol;
NTSTATUS status, result;
struct dom_sid sid;
- uint32 rid;
+ uint32_t rid;
enum lsa_SidType type;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
ZERO_STRUCT(domain_pol);
ZERO_STRUCT(user_pol);
- status = net_rpc_lookup_name(c, mem_ctx, rpc_pipe_np_smb_conn(pipe_hnd),
+ status = net_rpc_lookup_name(c, mem_ctx, ctx->cli,
argv[0], NULL, NULL, &sid, &type);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, _("Could not lookup %s: %s\n"), argv[0],
NTSTATUS status, result;
const char *username;
const char *oldval = "unknown";
- uint32 oldflags, newflags;
+ uint32_t oldflags, newflags;
bool newval;
union samr_UserInfo *info = NULL;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
d_fprintf(stderr, _("Lookup of '%s' failed\n"),argv[0]);
goto done;
}
+ if (group_rids.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
+ if (name_types.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
switch (name_types.ids[0])
{
NTSTATUS status, result;
struct dcerpc_binding_handle *b;
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
&pipe_hnd);
if (!NT_STATUS_IS_OK(status)) {
goto done;
{
struct policy_handle connect_pol, domain_pol;
NTSTATUS status, result;
- uint32 group_rid;
+ uint32_t group_rid;
struct policy_handle group_pol;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
member);
goto done;
}
+ if (rids.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
+ if (rid_types.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
status = dcerpc_samr_OpenGroup(b, mem_ctx,
&domain_pol,
}
static NTSTATUS rpc_add_aliasmem(struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- const struct dom_sid *alias_sid,
- const char *member)
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *alias_sid,
+ const char *member)
{
struct policy_handle connect_pol, domain_pol;
NTSTATUS status, result;
- uint32 alias_rid;
+ uint32_t alias_rid;
struct policy_handle alias_pol;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
return NT_STATUS_UNSUCCESSFUL;
}
- result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
+ result = get_sid_from_name(cli, mem_ctx,
member, &member_sid, &member_type);
if (!NT_STATUS_IS_OK(result)) {
}
if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_add_aliasmem(pipe_hnd, mem_ctx,
+ NTSTATUS result = rpc_add_aliasmem(pipe_hnd, cli, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
{
struct policy_handle connect_pol, domain_pol;
NTSTATUS status, result;
- uint32 group_rid;
+ uint32_t group_rid;
struct policy_handle group_pol;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
member);
goto done;
}
+ if (rids.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
+ if (rid_types.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
status = dcerpc_samr_OpenGroup(b, mem_ctx,
&domain_pol,
}
static NTSTATUS rpc_del_aliasmem(struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- const struct dom_sid *alias_sid,
- const char *member)
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *alias_sid,
+ const char *member)
{
struct policy_handle connect_pol, domain_pol;
NTSTATUS status, result;
- uint32 alias_rid;
+ uint32_t alias_rid;
struct policy_handle alias_pol;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
if (!sid_split_rid(&sid, &alias_rid))
return NT_STATUS_UNSUCCESSFUL;
- result = get_sid_from_name(rpc_pipe_np_smb_conn(pipe_hnd), mem_ctx,
+ result = get_sid_from_name(cli, mem_ctx,
member, &member_sid, &member_type);
if (!NT_STATUS_IS_OK(result)) {
}
if (group_type == SID_NAME_ALIAS) {
- NTSTATUS result = rpc_del_aliasmem(pipe_hnd, mem_ctx,
+ NTSTATUS result = rpc_del_aliasmem(pipe_hnd, cli, mem_ctx,
&group_sid, argv[1]);
if (!NT_STATUS_IS_OK(result)) {
{
struct policy_handle connect_pol, domain_pol;
NTSTATUS status, result;
- uint32 start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
+ uint32_t start_idx=0, max_entries=250, num_entries, i, loop_count = 0;
struct samr_SamArray *groups = NULL;
bool global = false;
bool local = false;
const char *domain_name,
const struct dom_sid *domain_sid,
struct policy_handle *domain_pol,
- uint32 rid)
+ uint32_t rid)
{
NTSTATUS result, status;
struct policy_handle group_pol;
- uint32 num_members, *group_rids;
+ uint32_t num_members, *group_rids;
int i;
struct samr_RidAttrArray *rids = NULL;
struct lsa_Strings names;
if (!NT_STATUS_IS_OK(result)) {
return result;
}
-
+ if (names.count != this_time) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (types.count != this_time) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
/* We only have users as members, but make the output
the same as the output of alias members */
}
static NTSTATUS rpc_list_alias_members(struct net_context *c,
- struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- struct policy_handle *domain_pol,
- uint32 rid)
+ struct rpc_pipe_client *pipe_hnd,
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ struct policy_handle *domain_pol,
+ uint32_t rid)
{
NTSTATUS result, status;
struct rpc_pipe_client *lsa_pipe;
struct policy_handle alias_pol, lsa_pol;
- uint32 num_members;
+ uint32_t num_members;
struct dom_sid *alias_sids;
char **domains;
char **names;
return NT_STATUS_OK;
}
- result = cli_rpc_pipe_open_noauth(rpc_pipe_np_smb_conn(pipe_hnd),
- &ndr_table_lsarpc.syntax_id,
+ result = cli_rpc_pipe_open_noauth(cli,
+ &ndr_table_lsarpc,
&lsa_pipe);
if (!NT_STATUS_IS_OK(result)) {
d_fprintf(stderr, _("Couldn't open LSA pipe. Error was %s\n"),
if (rids.count != 1) {
d_fprintf(stderr, _("Couldn't find group %s\n"),
argv[0]);
- return result;
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (rid_types.count != 1) {
+ d_fprintf(stderr, _("Couldn't find group %s\n"),
+ argv[0]);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
+
if (rid_types.ids[0] == SID_NAME_DOM_GRP) {
return rpc_list_group_members(c, pipe_hnd, mem_ctx, domain_name,
domain_sid, &domain_pol,
}
if (rid_types.ids[0] == SID_NAME_ALIAS) {
- return rpc_list_alias_members(c, pipe_hnd, mem_ctx, &domain_pol,
+ return rpc_list_alias_members(c, pipe_hnd, cli, mem_ctx, &domain_pol,
rids.ids[0]);
}
NET_API_STATUS status;
char *sharename;
char *path;
- uint32 type = STYPE_DISKTREE; /* only allow disk shares to be added */
- uint32 num_users=0, perms=0;
+ uint32_t type = STYPE_DISKTREE; /* only allow disk shares to be added */
+ uint32_t num_users=0, perms=0;
char *password=NULL; /* don't allow a share password */
struct SHARE_INFO_2 i2;
uint32_t parm_error = 0;
static WERROR get_share_info(struct net_context *c,
struct rpc_pipe_client *pipe_hnd,
TALLOC_CTX *mem_ctx,
- uint32 level,
+ uint32_t level,
int argc,
const char **argv,
struct srvsvc_NetShareInfoCtr *info_ctr)
{
NTSTATUS status;
- status = cli_tree_connect(cli, netname, "A:", "", 0);
+ status = cli_tree_connect(cli, netname, "A:", NULL);
if (!NT_STATUS_IS_OK(status)) {
d_printf(_("skipping [%s]: not a file share.\n"), netname);
return false;
}
static bool check_share_sanity(struct net_context *c, struct cli_state *cli,
- const char *netname, uint32 type)
+ const char *netname, uint32_t type)
{
/* only support disk shares */
if (! ( type == STYPE_DISKTREE || type == (STYPE_DISKTREE | STYPE_HIDDEN)) ) {
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct srvsvc_NetShareInfoCtr ctr_src;
- uint32 i;
+ uint32_t i;
struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
- uint32 level = 502; /* includes secdesc */
+ uint32_t level = 502; /* includes secdesc */
uint32_t parm_error = 0;
struct dcerpc_binding_handle *b;
WERROR result;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct srvsvc_NetShareInfoCtr ctr_src;
- uint32 i;
- uint32 level = 502;
+ uint32_t i;
+ uint32_t level = 502;
struct copy_clistate cp_clistate;
bool got_src_share = false;
bool got_dst_share = false;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
struct srvsvc_NetShareInfoCtr ctr_src;
union srvsvc_NetShareInfo info;
- uint32 i;
+ uint32_t i;
struct rpc_pipe_client *srvsvc_pipe = NULL;
struct cli_state *cli_dst = NULL;
- uint32 level = 502; /* includes secdesc */
+ uint32_t level = 502; /* includes secdesc */
uint32_t parm_error = 0;
struct dcerpc_binding_handle *b;
struct full_alias {
struct dom_sid sid;
- uint32 num_members;
+ uint32_t num_members;
struct dom_sid *members;
};
/*
* Add an alias to the static list.
*/
-static void push_alias(TALLOC_CTX *mem_ctx, struct full_alias *alias)
+static void push_alias(struct full_alias *alias)
{
- if (server_aliases == NULL)
- server_aliases = SMB_MALLOC_ARRAY(struct full_alias, 100);
+ size_t array_size;
+
+ if (server_aliases == NULL) {
+ server_aliases = talloc_array(NULL, struct full_alias, 100);
+ if (server_aliases == NULL) {
+ smb_panic("talloc_array failed");
+ }
+ }
+
+ array_size = talloc_array_length(server_aliases);
+ if (array_size == num_server_aliases) {
+ server_aliases = talloc_realloc(NULL, server_aliases,
+ struct full_alias, array_size + 100);
+ if (server_aliases == NULL) {
+ smb_panic("talloc_realloc failed");
+ }
+ }
server_aliases[num_server_aliases] = *alias;
num_server_aliases += 1;
struct policy_handle *connect_pol,
const struct dom_sid *domain_sid)
{
- uint32 start_idx, max_entries, num_entries, i;
+ uint32_t start_idx, max_entries, num_entries, i;
struct samr_SamArray *groups = NULL;
NTSTATUS result, status;
struct policy_handle domain_pol;
sid_compose(&alias.sid, domain_sid,
groups->entries[i].idx);
- push_alias(mem_ctx, &alias);
+ push_alias(&alias);
}
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
*/
static void show_userlist(struct rpc_pipe_client *pipe_hnd,
- TALLOC_CTX *mem_ctx,
- const char *netname,
- int num_tokens,
- struct user_token *tokens)
+ struct cli_state *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *netname,
+ int num_tokens,
+ struct user_token *tokens)
{
uint16_t fnum;
struct security_descriptor *share_sd = NULL;
struct security_descriptor *root_sd = NULL;
- struct cli_state *cli = rpc_pipe_np_smb_conn(pipe_hnd);
int i;
union srvsvc_NetShareInfo info;
WERROR result;
NTSTATUS status;
- uint16 cnum;
+ struct smbXcli_tcon *orig_tcon = NULL;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
status = dcerpc_srvsvc_NetShareGetInfo(b, mem_ctx,
&result);
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) {
- DEBUG(1, ("Coult not query secdesc for share %s\n",
+ DEBUG(1, ("Could not query secdesc for share %s\n",
netname));
return;
}
netname));
}
- cnum = cli_state_get_tid(cli);
+ if (cli_state_has_tcon(cli)) {
+ orig_tcon = cli_state_save_tcon(cli);
+ if (orig_tcon == NULL) {
+ return;
+ }
+ }
- if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", "", 0))) {
+ if (!NT_STATUS_IS_OK(cli_tree_connect(cli, netname, "A:", NULL))) {
+ cli_state_restore_tcon(cli, orig_tcon);
return;
}
if (!NT_STATUS_IS_OK(cli_ntcreate(cli, "\\", 0, READ_CONTROL_ACCESS, 0,
- FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum))) {
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN, 0x0, 0x0, &fnum, NULL))) {
cli_query_secdesc(cli, fnum, mem_ctx, &root_sd);
}
for (i=0; i<num_tokens; i++) {
- uint32 acc_granted;
+ uint32_t acc_granted;
if (share_sd != NULL) {
status = se_access_check(share_sd, &tokens[i].token,
if (fnum != (uint16_t)-1)
cli_close(cli, fnum);
cli_tdis(cli);
- cli_state_set_tid(cli, cnum);
+ cli_state_restore_tcon(cli, orig_tcon);
return;
}
d_printf("%s\n", netname);
- show_userlist(pipe_hnd, mem_ctx, netname,
+ show_userlist(pipe_hnd, cli, mem_ctx, netname,
num_tokens, tokens);
}
done:
free_user_token(&tokens[i].token);
}
SAFE_FREE(tokens);
+ TALLOC_FREE(server_aliases);
return nt_status;
}
static int rpc_file_user(struct net_context *c, int argc, const char **argv)
{
NET_API_STATUS status;
- uint32 preferred_len = 0xffffffff, i;
+ uint32_t preferred_len = 0xffffffff, i;
char *username=NULL;
uint32_t total_entries = 0;
uint32_t entries_read = 0;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
WERROR result;
const char *msg = N_("This machine will be shutdown shortly");
- uint32 timeout = 20;
+ uint32_t timeout = 20;
struct lsa_StringLarge msg_string;
struct dcerpc_binding_handle *b = pipe_hnd->binding_handle;
const char **argv)
{
const char *msg = N_("This machine will be shutdown shortly");
- uint32 timeout = 20;
+ uint32_t timeout = 20;
struct lsa_StringLarge msg_string;
NTSTATUS result;
WERROR werr;
NTSTATUS status, result;
char *acct_name;
struct lsa_String lsa_acct_name;
- uint32 acb_info;
- uint32 acct_flags=0;
- uint32 user_rid;
+ uint32_t acb_info;
+ uint32_t acct_flags=0;
+ uint32_t user_rid;
uint32_t access_granted = 0;
union samr_UserInfo info;
unsigned int orig_timeout;
acct_name, nt_errstr(result) );
goto done;
}
+ if (user_rids.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
+ if (name_types.count != 1) {
+ status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ goto done;
+ }
status = dcerpc_samr_OpenUser(b, mem_ctx,
&domain_pol,
/* Try netr_GetDcName */
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon.syntax_id,
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_netlogon,
&netr);
if (!NT_STATUS_IS_OK(status)) {
return status;
* Call LsaOpenPolicy and LsaQueryInfo
*/
- nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+ nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
&pipe_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n", nt_errstr(nt_status) ));
return -1;
};
- nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+ nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
&pipe_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
return -1;
};
- nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
+ nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
&pipe_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise lsa pipe. Error was %s\n",
/*
* Open \PIPE\samr and get needed policy handles
*/
- nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id,
+ nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr,
&pipe_hnd);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Could not initialise samr pipe. Error was %s\n", nt_errstr(nt_status)));
return false;
status = cli_connect_nb(server_name, &server_ss, 0, 0x20,
- lp_netbios_name(), SMB_SIGNING_DEFAULT,
+ lp_netbios_name(), SMB_SIGNING_IPC_DEFAULT,
0, &cli);
if (!NT_STATUS_IS_OK(status)) {
return false;
return ret;
}
-/* dump sam database via samsync rpc calls */
-static int rpc_samdump(struct net_context *c, int argc, const char **argv) {
- if (c->display_usage) {
- d_printf( "%s\n"
- "net rpc samdump\n"
- " %s\n",
- _("Usage:"),
- _("Dump remote SAM database"));
- return 0;
- }
-
- return run_rpc_command(c, NULL, &ndr_table_netlogon,
- NET_FLAGS_ANONYMOUS,
- rpc_samdump_internals, argc, argv);
-}
-
/* syncronise sam database via samsync rpc calls */
static int rpc_vampire(struct net_context *c, int argc, const char **argv)
{
struct functable func[] = {
- {
- "ldif",
- rpc_vampire_ldif,
- NET_TRANSPORT_RPC,
- N_("Dump remote SAM database to ldif"),
- N_("net rpc vampire ldif\n"
- " Dump remote SAM database to LDIF file or "
- "stdout")
- },
{
"keytab",
rpc_vampire_keytab,
N_("net rpc shutdown\n"
" Shutdown a remote server")
},
- {
- "samdump",
- rpc_samdump,
- NET_TRANSPORT_RPC,
- N_("Dump SAM data of remote NT PDC"),
- N_("net rpc samdump\n"
- " Dump SAM data of remote NT PDC")
- },
{
"vampire",
rpc_vampire,