This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "includes.h"
#include "utils/net.h"
* @return A shell status integer (0 for success)
*
**/
-static int net_rpc_join_ok(const char *domain)
+int net_rpc_join_ok(const char *domain, const char *server, struct in_addr *ip )
{
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
struct cli_state *cli = NULL;
struct rpc_pipe_client *pipe_hnd = NULL;
- int retval = 1;
- NTSTATUS ret;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ NTSTATUS ntret = NT_STATUS_UNSUCCESSFUL;
/* Connect to remote machine */
- if (!(cli = net_make_ipc_connection(NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC))) {
- return 1;
+ if (!(cli = net_make_ipc_connection_ex(domain, server, ip, (NET_FLAGS_ANONYMOUS|NET_FLAGS_PDC)))) {
+ return -1;
}
- pipe_hnd = cli_rpc_pipe_open_schannel(cli, PI_NETLOGON,
- PIPE_AUTH_LEVEL_PRIVACY,
- domain, &ret);
+ /* Setup the creds as though we're going to do schannel... */
+ netlogon_pipe = get_schannel_session_key(cli, domain, &neg_flags, &ntret);
+
+ /* We return NT_STATUS_INVALID_NETWORK_RESPONSE if the server is refusing
+ to negotiate schannel, but the creds were set up ok. That'll have to do. */
+
+ if (!netlogon_pipe) {
+ if (NT_STATUS_EQUAL(ntret, NT_STATUS_INVALID_NETWORK_RESPONSE)) {
+ cli_shutdown(cli);
+ return 0;
+ } else {
+ DEBUG(0,("net_rpc_join_ok: failed to get schannel session "
+ "key from server %s for domain %s. Error was %s\n",
+ cli->desthost, domain, nt_errstr(ntret) ));
+ cli_shutdown(cli);
+ return -1;
+ }
+ }
- if (!pipe_hnd) {
- DEBUG(0,("Error connecting to NETLOGON pipe. Error was %s\n", nt_errstr(ret) ));
- goto done;
+ /* Only do the rest of the schannel test if the client is allowed to do this. */
+ if (!lp_client_schannel()) {
+ cli_shutdown(cli);
+ /* We're good... */
+ return 0;
}
- retval = 0; /* Success! */
-
-done:
+ pipe_hnd = cli_rpc_pipe_open_schannel_with_key(cli, PI_NETLOGON,
+ PIPE_AUTH_LEVEL_PRIVACY,
+ domain, netlogon_pipe->dc, &ntret);
+
+ if (!pipe_hnd) {
+ DEBUG(0,("net_rpc_join_ok: failed to open schannel session "
+ "on netlogon pipe to server %s for domain %s. Error was %s\n",
+ cli->desthost, domain, nt_errstr(ntret) ));
+ cli_shutdown(cli);
+ return -1;
+ }
cli_shutdown(cli);
- return retval;
+ return 0;
}
/**
struct cli_state *cli;
TALLOC_CTX *mem_ctx;
uint32 acb_info = ACB_WSTRUST;
- uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
+ uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|(lp_client_schannel() ? NETLOGON_NEG_SCHANNEL : 0);
uint32 sec_channel_type;
struct rpc_pipe_client *pipe_hnd = NULL;
- struct rpc_pipe_client *netlogon_schannel_pipe = NULL;
/* rpc variables */
NTSTATUS result;
int retval = 1;
- char *domain;
+ char *domain = NULL;
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
char *acct_name;
5, &domain, &domain_sid),
"error querying info policy");
- rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
+ rpccli_lsa_Close(pipe_hnd, mem_ctx, &lsa_pol);
cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
+ /* Bail out if domain didn't get set. */
+ if (!domain) {
+ DEBUG(0, ("Could not get domain name.\n"));
+ goto done;
+ }
+
/* Create domain user */
pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result);
if (!pipe_hnd) {
"could not open domain");
/* Create domain user */
- acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname());
+ if ((acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname())) == NULL) {
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
strlower_m(acct_name);
const_acct_name = acct_name;
goto done;
}
- netlogon_schannel_pipe = cli_rpc_pipe_open_schannel_with_key(cli,
+ /* We can only check the schannel connection if the client is allowed
+ to do this and the server supports it. If not, just assume success
+ (after all the rpccli_netlogon_setup_creds() succeeded, and we'll
+ do the same again (setup creds) in net_rpc_join_ok(). JRA. */
+
+ if (lp_client_schannel() && (neg_flags & NETLOGON_NEG_SCHANNEL)) {
+ struct rpc_pipe_client *netlogon_schannel_pipe =
+ cli_rpc_pipe_open_schannel_with_key(cli,
PI_NETLOGON,
PIPE_AUTH_LEVEL_PRIVACY,
domain,
pipe_hnd->dc,
&result);
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n",
- nt_errstr(result)));
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0, ("Error in domain join verification (schannel setup failed): %s\n\n",
+ nt_errstr(result)));
- if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
- (sec_channel_type == SEC_CHAN_BDC) ) {
- d_fprintf(stderr, "Please make sure that no computer account\n"
- "named like this machine (%s) exists in the domain\n",
- global_myname());
- }
+ if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) &&
+ (sec_channel_type == SEC_CHAN_BDC) ) {
+ d_fprintf(stderr, "Please make sure that no computer account\n"
+ "named like this machine (%s) exists in the domain\n",
+ global_myname());
+ }
- goto done;
+ goto done;
+ }
+ cli_rpc_pipe_close(netlogon_schannel_pipe);
}
cli_rpc_pipe_close(pipe_hnd);
- cli_rpc_pipe_close(netlogon_schannel_pipe);
/* Now store the secret in the secrets database */
}
/* double-check, connection from scratch */
- retval = net_rpc_join_ok(domain);
+ retval = net_rpc_join_ok(domain, cli->desthost, &cli->dest_ip);
done:
/* Display success or failure */
- if (retval != 0) {
- fprintf(stderr,"Unable to join domain %s.\n",domain);
- } else {
- printf("Joined domain %s.\n",domain);
+ if (domain) {
+ if (retval != 0) {
+ fprintf(stderr,"Unable to join domain %s.\n",domain);
+ } else {
+ printf("Joined domain %s.\n",domain);
+ }
}
cli_shutdown(cli);
char *domain = smb_xstrdup(opt_target_workgroup);
/* Display success or failure */
- if (net_rpc_join_ok(domain) != 0) {
+ if (net_rpc_join_ok(domain, NULL, NULL) != 0) {
fprintf(stderr,"Join to domain '%s' is not valid\n",domain);
free(domain);
return -1;