summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in29
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/libsmb/cli_netlogon.c83
-rw-r--r--source3/libsmb/trust_passwd.c116
-rw-r--r--source3/rpc_client/cli_login.c21
-rw-r--r--source3/rpc_client/cli_netlogon.c70
-rw-r--r--source3/rpc_client/cli_trust.c184
-rw-r--r--source3/rpc_parse/parse_net.c9
-rw-r--r--source3/utils/net.c4
-rw-r--r--source3/utils/net.h6
-rw-r--r--source3/utils/net_ads.c2
-rw-r--r--source3/utils/net_rpc.c68
-rw-r--r--source3/utils/net_rpc_join.c6
-rw-r--r--source3/utils/smbpasswd.c179
14 files changed, 383 insertions, 400 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index eaa225cd04..2a7294b0f5 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -148,7 +148,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
LIBMSRPC_OBJ = libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_spoolss.o \
libsmb/cli_netlogon.o libsmb/cli_srvsvc.o libsmb/cli_dfs.o \
- libsmb/cli_reg.o \
+ libsmb/cli_reg.o libsmb/trust_passwd.o\
rpc_client/cli_pipe.o libsmb/cli_pipe_util.o
LIBMSRPC_PICOBJ = $(LIBMSRPC_OBJ:.o=.po)
@@ -175,7 +175,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_net.o \
RPC_CLIENT_OBJ = rpc_client/cli_netlogon.o rpc_client/cli_pipe.o \
- rpc_client/cli_login.o rpc_client/cli_trust.o \
+ rpc_client/cli_login.o \
rpc_client/cli_spoolss_notify.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
@@ -214,7 +214,12 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/posix_acls.o \
smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o smbd/srvstr.o \
- smbd/build_options.o
+ smbd/build_options.o \
+ rpc_client/cli_trust.o \
+ rpc_client/cli_netlogon.o \
+ rpc_client/cli_login.o \
+ rpc_client/cli_spoolss_notify.o
+
PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
printing/print_cups.o printing/print_generic.o \
@@ -225,10 +230,11 @@ PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o
MSDFS_OBJ = msdfs/msdfs.o
SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(RPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
+ $(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_OBJ) \
- $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ)
+ $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) $(LIBMSRPC_OBJ)
+
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
@@ -248,9 +254,9 @@ NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
web/swat.o web/neg_lang.o $(PRINTING_OBJ) $(LIBSMB_OBJ) $(LOCKING_OBJ) \
- $(PARAM_OBJ) $(PASSDB_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
- smbwrapper/shared.o
+ $(PARAM_OBJ) $(PASSDB_OBJ) \
+ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
+ smbwrapper/shared.o
SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
$(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
@@ -275,8 +281,7 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
- $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ) \
- libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_pipe_util.o
+ $(UBIQX_OBJ) $(LIB_OBJ)
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ)
@@ -322,8 +327,8 @@ CLIENT_OBJ = client/client.o client/clitar.o \
NET_OBJ = utils/net.o utils/net_ads.o utils/net_rap.o utils/net_rpc.o \
utils/net_rpc_join.o \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
- $(GROUPDB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
- $(NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ)
+ $(GROUPDB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 0ac2118b94..fa4cec4bdb 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1648,4 +1648,10 @@ typedef struct {
void *cd_direct, *cd_pull, *cd_push;
} *smb_iconv_t;
+/* The maximum length of a trust account password.
+ Used when we randomly create it, 15 char passwords
+ exceed NT4's max password length */
+
+#define DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH 14
+
#endif /* _SMB_H */
diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c
index 7499d9ca7b..d20e466cc9 100644
--- a/source3/libsmb/cli_netlogon.c
+++ b/source3/libsmb/cli_netlogon.c
@@ -2,9 +2,12 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001
+ Copyright (C) Paul Ashton 1997.
+ Copyright (C) Jeremy Allison 1998.
+ Copyright (C) Andrew Bartlett 2001.
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
@@ -492,3 +495,81 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx,
done:
return result;
}
+
+/***************************************************************************
+LSA Server Password Set.
+****************************************************************************/
+
+NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ char* machine_name, uint8 hashed_mach_pwd[16])
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ DOM_CRED new_clnt_cred;
+ NET_Q_SRV_PWSET q_s;
+ uint16 sec_chan_type = 2;
+ NTSTATUS nt_status;
+ char *mach_acct;
+
+ gen_next_creds( cli, &new_clnt_cred);
+
+ prs_init(&buf , 1024, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api NET_SRV_PWSET */
+
+ mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name);
+
+ if (!mach_acct) {
+ DEBUG(0,("talloc_asprintf failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
+ cli->srv_name_slash, mach_acct, sec_chan_type, machine_name,
+ credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
+
+ /* store the parameters */
+ init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key,
+ mach_acct, sec_chan_type, machine_name,
+ &new_clnt_cred, (char *)hashed_mach_pwd);
+
+ /* turn parameters into data stream */
+ if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) {
+ DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
+ {
+ NET_R_SRV_PWSET r_s;
+
+ if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ nt_status = r_s.status;
+
+ if (!NT_STATUS_IS_OK(r_s.status))
+ {
+ /* report error code */
+ DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(nt_status)));
+ return nt_status;
+ }
+
+ /* Update the credentials. */
+ if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
+ {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
+password ?).\n", cli->desthost ));
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ return nt_status;
+}
+
diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c
new file mode 100644
index 0000000000..7f7a5d29dc
--- /dev/null
+++ b/source3/libsmb/trust_passwd.c
@@ -0,0 +1,116 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 3.0
+ * Routines to change
+ * Copyright (C) Andrew Bartlett 2001.
+ *
+ * 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
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * 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.
+ */
+
+#include "includes.h"
+
+extern pstring global_myname;
+
+/*********************************************************
+ Change the domain password on the PDC.
+
+ Just changes the password betwen the two values specified.
+
+ Caller must have the cli connected to the netlogon pipe
+ already.
+**********************************************************/
+static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ unsigned char orig_trust_passwd_hash[16],
+ unsigned char new_trust_passwd_hash[16])
+{
+ NTSTATUS result;
+ result = new_cli_nt_setup_creds(cli, orig_trust_passwd_hash);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n",
+ get_nt_error_msg(result)));
+ return result;
+ }
+
+ result = cli_net_srv_pwset(cli, mem_ctx, global_myname, new_trust_passwd_hash);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
+ get_nt_error_msg(result)));
+ }
+ return result;
+}
+
+/*********************************************************
+ Change the domain password on the PDC.
+ Store the password ourselves, but use the supplied password
+ Caller must have already setup the connection to the NETLOGON pipe
+**********************************************************/
+
+NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ unsigned char orig_trust_passwd_hash[16])
+{
+ unsigned char new_trust_passwd_hash[16];
+ char *new_trust_passwd;
+ char *str;
+ NTSTATUS nt_status;
+
+ /* Create a random machine account password */
+ str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ new_trust_passwd = talloc_strdup(mem_ctx, str);
+
+ E_md4hash((uchar *)new_trust_passwd, new_trust_passwd_hash);
+
+ nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
+ new_trust_passwd_hash);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(3,("%s : change_trust_account_password: Changed password.\n", timestring(False)));
+ /*
+ * Return the result of trying to write the new password
+ * back into the trust account file.
+ */
+ if (!secrets_store_machine_password(new_trust_passwd)) {
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ return nt_status;
+}
+
+/*********************************************************
+ Change the domain password on the PDC.
+ Do most of the legwork ourselfs. Caller must have
+ already setup the connection to the NETLOGON pipe
+**********************************************************/
+
+NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *domain)
+{
+ unsigned char old_trust_passwd_hash[16];
+ char *up_domain;
+
+ up_domain = talloc_strdup(mem_ctx, domain);
+
+ if (!secrets_fetch_trust_account_password(domain,
+ old_trust_passwd_hash,
+ NULL)) {
+ DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash);
+
+}
+
diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c
index e5c221690d..be32533541 100644
--- a/source3/rpc_client/cli_login.c
+++ b/source3/rpc_client/cli_login.c
@@ -79,27 +79,6 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
}
/****************************************************************************
- Set machine password.
- ****************************************************************************/
-
-BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
-{
- unsigned char processed_new_pwd[16];
-
- DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__));
-
-#ifdef DEBUG_PASSWORD
- dump_data(6, (char *)new_hashof_mach_pwd, 16);
-#endif
-
- /* Process the new password. */
- cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1);
-
- /* send client srv_pwset challenge */
- return cli_net_srv_pwset(cli, processed_new_pwd);
-}
-
-/****************************************************************************
NT login - interactive.
*NEVER* use this code. This method of doing a logon (sending the cleartext
password equivalents, protected by the session key) is inherently insecure
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 869de91c80..8a2d8e28cc 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -260,76 +260,6 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
return valid_chal;
}
-
-/***************************************************************************
-LSA Server Password Set.
-****************************************************************************/
-
-BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
-{
- prs_struct rbuf;
- prs_struct buf;
- DOM_CRED new_clnt_cred;
- NET_Q_SRV_PWSET q_s;
- BOOL ok = False;
- uint16 sec_chan_type = 2;
-
- gen_next_creds( cli, &new_clnt_cred);
-
- prs_init(&buf , 1024, cli->mem_ctx, MARSHALL);
- prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL);
-
- /* create and send a MSRPC command with api NET_SRV_PWSET */
-
- DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
- credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
-
- /* store the parameters */
- init_q_srv_pwset(&q_s, cli->srv_name_slash,
- cli->mach_acct, sec_chan_type, global_myname,
- &new_clnt_cred, (char *)hashed_mach_pwd);
-
- /* turn parameters into data stream */
- if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) {
- DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
- {
- NET_R_SRV_PWSET r_s;
-
- ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
-
- if (ok && !NT_STATUS_IS_OK(r_s.status))
- {
- /* report error code */
- DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
- ok = False;
- }
-
- /* Update the credentials. */
- if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
- {
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- ok = False;
- }
- }
-
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
-
- return ok;
-}
-
/***************************************************************************
LSA SAM Logon internal - interactive or network. Does level 2 or 3 but always
returns level 3.
diff --git a/source3/rpc_client/cli_trust.c b/source3/rpc_client/cli_trust.c
index c910e2f334..fbb75573cb 100644
--- a/source3/rpc_client/cli_trust.c
+++ b/source3/rpc_client/cli_trust.c
@@ -6,6 +6,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 1998.
+ * Copyright (C) Andrew Bartlett 2001.
*
* 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
@@ -30,13 +31,13 @@ extern pstring global_myname;
Change the domain password on the PDC.
**********************************************************/
-static BOOL modify_trust_password( char *domain, char *remote_machine,
- unsigned char orig_trust_passwd_hash[16],
- unsigned char new_trust_passwd_hash[16])
+static NTSTATUS modify_trust_password( char *domain, char *remote_machine,
+ unsigned char orig_trust_passwd_hash[16])
{
- struct cli_state cli;
- NTSTATUS result;
+ struct cli_state *cli;
DOM_SID domain_sid;
+ struct in_addr dest_ip;
+ NTSTATUS nt_status;
/*
* Ensure we have the domain SID for this domain.
@@ -44,150 +45,63 @@ static BOOL modify_trust_password( char *domain, char *remote_machine,
if (!secrets_fetch_domain_sid(domain, &domain_sid)) {
DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n"));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
- ZERO_STRUCT(cli);
- if(cli_initialise(&cli) == NULL) {
- DEBUG(0,("modify_trust_password: unable to initialize client connection.\n"));
- return False;
- }
-
- if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
- DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (ismyip(cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
-to ourselves.\n", remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
+ if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
+ DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
+ return NT_STATUS_UNSUCCESSFUL;
}
- if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \
-session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- cli.protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(&cli)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
+ if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname, remote_machine,
+ &dest_ip, 0,
+ "IPC$", "IPC",
+ "", "",
+ "", 0))) {
+ DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine));
+ return NT_STATUS_UNSUCCESSFUL;
}
-
- if (cli.protocol != PROTOCOL_NT1) {
- DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!(cli.sec_mode & 1)) {
- DEBUG(0,("modify_trust_password: machine %s isn't in user level security mode\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
+
/*
* Ok - we have an anonymous connection to the IPC$ share.
* Now start the NT Domain stuff :-).
*/
- if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
+ if(cli_nt_session_open(cli, PIPE_NETLOGON) == False) {
DEBUG(0,("modify_trust_password: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli)));
+ cli_nt_session_close(cli);
+ cli_ulogoff(cli);
+ cli_shutdown(cli);
+ return NT_STATUS_UNSUCCESSFUL;
}
-
- result = cli_nt_setup_creds(&cli, orig_trust_passwd_hash);
-
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) {
- DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
-%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine,
- cli_errstr(&cli)));
- cli_close(&cli, cli.nt_pipe_fnum);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
-
- return True;
+ nt_status = trust_pw_change_and_store_it(cli, cli->mem_ctx,
+ orig_trust_passwd_hash);
+
+ cli_nt_session_close(cli);
+ cli_ulogoff(cli);
+ cli_shutdown(cli);
+ return nt_status;
}
/************************************************************************
Change the trust account password for a domain.
- The user of this function must have locked the trust password file for
- update.
************************************************************************/
-BOOL change_trust_account_password( char *domain, char *remote_machine_list)
+NTSTATUS change_trust_account_password( char *domain, char *remote_machine_list)
{
fstring remote_machine;
unsigned char old_trust_passwd_hash[16];
- unsigned char new_trust_passwd_hash[16];
time_t lct;
- BOOL res = False;
+ NTSTATUS res = NT_STATUS_UNSUCCESSFUL;
if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
DEBUG(0,("change_trust_account_password: unable to read the machine \
account password for domain %s.\n", domain));
- return False;
+ return NT_STATUS_UNSUCCESSFUL;
}
- /*
- * Create the new (random) password.
- */
- generate_random_buffer( new_trust_passwd_hash, 16, True);
-
while(remote_machine_list &&
next_token(&remote_machine_list, remote_machine,
LIST_SEP, sizeof(remote_machine))) {
@@ -215,36 +129,24 @@ account password for domain %s.\n", domain));
fstring dc_name;
if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name))
continue;
- if((res = modify_trust_password( domain, dc_name,
- old_trust_passwd_hash, new_trust_passwd_hash)))
+ if(NT_STATUS_IS_OK(res = modify_trust_password( domain, dc_name,
+ old_trust_passwd_hash)))
break;
}
SAFE_FREE(ip_list);
} else {
- res = modify_trust_password( domain, remote_machine,
- old_trust_passwd_hash, new_trust_passwd_hash);
+ res = modify_trust_password( domain, remote_machine,
+ old_trust_passwd_hash);
}
- if(res) {
- DEBUG(0,("%s : change_trust_account_password: Changed password for \
-domain %s.\n", timestring(False), domain));
- /*
- * Return the result of trying to write the new password
- * back into the trust account file.
- */
- res = secrets_store_trust_account_password(domain, new_trust_passwd_hash);
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
- return res;
- }
}
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
-
- DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
+ if (!NT_STATUS_IS_OK(res)) {
+ DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
domain %s.\n", timestring(False), domain));
- return False;
+ }
+
+ return res;
}
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
index e3f7ea5d9a..5c8da80c01 100644
--- a/source3/rpc_parse/parse_net.c
+++ b/source3/rpc_parse/parse_net.c
@@ -743,10 +743,15 @@ BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
Inits a NET_Q_SRV_PWSET.
********************************************************************/
-void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
+void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *sess_key, char *acct_name,
+ uint16 sec_chan, char *comp_name, DOM_CRED *cred, char hashed_mach_pwd[16])
{
+ unsigned char nt_cypher[16];
+
DEBUG(5,("init_q_srv_pwset\n"));
+
+ /* Process the new password. */
+ cred_hash3( nt_cypher, hashed_mach_pwd, sess_key, 1);
init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
diff --git a/source3/utils/net.c b/source3/utils/net.c
index e20833bc0b..5efd79fa5b 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -163,7 +163,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se
if (!*server_name) {
*server_name = strdup(inet_ntoa(dest_ip));
}
- } else if (server_name) {
+ } else if (*server_name) {
/* resolve the IP address */
if (!resolve_name(*server_name, server_ip, 0x20)) {
DEBUG(1,("Unable to resolve server name\n"));
@@ -404,6 +404,8 @@ static struct functable net_func[] = {
*p2 = 0;
}
+ strupper(global_myname);
+
load_interfaces();
rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);
diff --git a/source3/utils/net.h b/source3/utils/net.h
index bdc4a08868..e912efe09e 100644
--- a/source3/utils/net.h
+++ b/source3/utils/net.h
@@ -26,13 +26,13 @@
For example, localhost is insane for a 'join' operation.
*/
-#define NET_FLAGS_LOCALHOST_DEFAULT_INSANE 3
+#define NET_FLAGS_LOCALHOST_DEFAULT_INSANE 4
/* We want to find the PDC only */
-#define NET_FLAGS_PDC 4
+#define NET_FLAGS_PDC 8
/* We want an anonymous connection */
-#define NET_FLAGS_ANONYMOUS 5
+#define NET_FLAGS_ANONYMOUS 16
extern int opt_maxusers;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index c956d9bb65..cecfb6a4d0 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -166,7 +166,7 @@ static int net_ads_join(int argc, const char **argv)
}
- tmp_password = generate_random_str(15);
+ tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
password = strdup(tmp_password);
if (!(ads = ads_startup())) return -1;
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index b1a9ad4aa9..97a1a1d342 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -81,11 +81,11 @@ static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
}
-static int run_rpc_command(const char *pipe_name,
+static int run_rpc_command(const char *pipe_name, int conn_flags,
rpc_command_fn fn,
int argc, const char **argv)
{
- struct cli_state *cli = net_make_ipc_connection(0);
+ struct cli_state *cli = net_make_ipc_connection(conn_flags);
TALLOC_CTX *mem_ctx;
NTSTATUS nt_status;
DOM_SID *domain_sid = net_get_remote_domain_sid(cli);
@@ -103,6 +103,8 @@ static int run_rpc_command(const char *pipe_name,
nt_status = fn(domain_sid, cli, mem_ctx, argc, argv);
+ DEBUG(5, ("rpc command function returned %s\n", get_nt_error_msg(nt_status)));
+
if (cli->nt_pipe_fnum)
cli_nt_session_close(cli);
@@ -160,9 +162,62 @@ static NTSTATUS rpc_user_add_internals(const DOM_SID *domain_sid, struct cli_sta
return result;
}
+static NTSTATUS rpc_changetrustpw_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv) {
+
+ return trust_pw_find_change_and_store_it(cli, mem_ctx, opt_target_workgroup);
+}
+
+static int rpc_changetrustpw(int argc, const char **argv)
+{
+ return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_changetrustpw_internals,
+ argc, argv);
+}
+
+static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ int argc, const char **argv) {
+
+ extern pstring global_myname;
+ fstring trust_passwd;
+ unsigned char orig_trust_passwd_hash[16];
+
+ fstrcpy(trust_passwd, global_myname);
+ strlower(trust_passwd);
+ E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
+
+ return trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
+}
+
+static int rpc_join_oldstyle(int argc, const char **argv)
+{
+ return run_rpc_command(PIPE_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
+ argc, argv);
+}
+
+static int rpc_join_usage(int argc, const char **argv)
+{
+ d_printf(" net rpc join \t to join a domain with admin username & password\n");
+ d_printf(" net rpc join oldstyle \t to join a domain created in server manager\n");
+ return -1;
+}
+
+static int rpc_join(int argc, const char **argv)
+{
+ struct functable func[] = {
+ {"oldstyle", rpc_join_oldstyle},
+ {NULL, NULL}
+ };
+
+ if (argc == 0) {
+ return net_rpc_join(argc, argv);
+ }
+
+ return net_run_function(argc, argv, func, rpc_join_usage);
+}
+
static int rpc_user_add(int argc, const char **argv)
{
- return run_rpc_command(PIPE_SAMR, rpc_user_add_internals,
+ return run_rpc_command(PIPE_SAMR, 0, rpc_user_add_internals,
argc, argv);
}
@@ -188,15 +243,18 @@ static int rpc_user(int argc, const char **argv)
int net_rpc_usage(int argc, const char **argv)
{
- d_printf(" net rpc join \tto join a domin \n");
+ d_printf(" net rpc join \tto join a domain \n");
+ d_printf(" net rpc user \tto add, delete and list users\n");
+ d_printf(" net rpc changetrustpw \tto change the trust account password\n");
return -1;
}
int net_rpc(int argc, const char **argv)
{
struct functable func[] = {
- {"join", net_rpc_join},
+ {"join", rpc_join},
{"user", rpc_user},
+ {"changetrustpw", rpc_changetrustpw},
{NULL, NULL}
};
return net_run_function(argc, argv, func, net_rpc_usage);
diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c
index 463de61b05..2b73117c38 100644
--- a/source3/utils/net_rpc_join.c
+++ b/source3/utils/net_rpc_join.c
@@ -191,7 +191,7 @@ int net_rpc_join(int argc, const char **argv)
{
char *str;
- str = generate_random_str(15);
+ str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
clear_trust_password = strdup(str);
}
@@ -256,8 +256,6 @@ int net_rpc_join(int argc, const char **argv)
strupper(domain);
- secrets_init();
-
if (!secrets_store_domain_sid(domain, &domain_sid)) {
DEBUG(0, ("error storing domain sid for %s\n", domain));
goto done;
@@ -284,7 +282,7 @@ int net_rpc_join(int argc, const char **argv)
goto done;
}
- CHECK_RPC_ERR(cli_nt_setup_creds(cli, stored_md4_trust_password),
+ CHECK_RPC_ERR(new_cli_nt_setup_creds(cli, stored_md4_trust_password),
"error in domain join verification");
retval = 0; /* Success! */
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 92136bea7a..e076687c4f 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -50,7 +50,6 @@ static void usage(void)
printf("extra options when run by root or in local mode:\n");
printf(" -L local mode (must be first option)\n");
printf(" -R ORDER name resolve order\n");
- printf(" -j DOMAIN join domain name\n");
printf(" -a add user\n");
printf(" -x delete user\n");
printf(" -d disable user\n");
@@ -61,67 +60,6 @@ static void usage(void)
exit(1);
}
-/*********************************************************
-Join a domain.
-**********************************************************/
-static int join_domain(char *domain, char *remote)
-{
- pstring remote_machine;
- fstring trust_passwd;
- unsigned char orig_trust_passwd_hash[16];
- BOOL ret;
-
- pstrcpy(remote_machine, remote ? remote : "");
- fstrcpy(trust_passwd, global_myname);
- strlower(trust_passwd);
- E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
-
- /* Ensure that we are not trying to join a
- domain if we are locally set up as a domain
- controller. */
-
- if(strequal(remote, global_myname)) {
- fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
- return 1;
- }
-
- /*
- * Write the old machine account password.
- */
-
- if(!secrets_store_trust_account_password(domain, orig_trust_passwd_hash)) {
- fprintf(stderr, "Unable to write the machine account password for \
-machine %s in domain %s.\n", global_myname, domain);
- return 1;
- }
-
- /*
- * If we are given a remote machine assume this is the PDC.
- */
-
- if(remote == NULL) {
- pstrcpy(remote_machine, lp_passwordserver());
- }
-
- if(!*remote_machine) {
- fprintf(stderr, "No password server list given in smb.conf - \
-unable to join domain.\n");
- return 1;
- }
-
- ret = change_trust_account_password( domain, remote_machine);
-
- if(!ret) {
- trust_password_delete(domain);
- fprintf(stderr,"Unable to join domain %s.\n",domain);
- } else {
- printf("Joined domain %s.\n",domain);
- }
-
- return (int)ret;
-}
-
-
static void set_line_buffering(FILE *f)
{
setvbuf(f, NULL, _IOLBF, 0);
@@ -241,11 +179,10 @@ static int process_root(int argc, char *argv[])
{
struct passwd *pwd;
int result = 0, ch;
- BOOL joining_domain = False, got_pass = False, got_username = False;
+ BOOL got_pass = False, got_username = False;
int local_flags = LOCAL_SET_PASSWORD;
BOOL stdin_passwd_get = False;
fstring user_name, user_password;
- char *new_domain = NULL;
char *new_passwd = NULL;
char *old_passwd = NULL;
char *remote_machine = NULL;
@@ -255,7 +192,7 @@ static int process_root(int argc, char *argv[])
user_name[0] = '\0';
- while ((ch = getopt(argc, argv, "axdehmnj:r:sR:D:U:L")) != EOF) {
+ while ((ch = getopt(argc, argv, "axdehmnjr:sR:D:U:L")) != EOF) {
switch(ch) {
case 'L':
local_mode = True;
@@ -278,14 +215,9 @@ static int process_root(int argc, char *argv[])
case 'm':
local_flags |= LOCAL_TRUST_ACCOUNT;
break;
- case 'n':
- local_flags |= LOCAL_SET_NO_PASSWORD;
- local_flags &= ~LOCAL_SET_PASSWORD;
- break;
case 'j':
- new_domain = optarg;
- strupper(new_domain);
- joining_domain = True;
+ d_printf("See 'net rpc join' for this functionality\n");
+ exit(1);
break;
case 'r':
remote_machine = optarg;
@@ -334,48 +266,16 @@ static int process_root(int argc, char *argv[])
*/
if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) ||
((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) &&
- ((remote_machine != NULL) || joining_domain))) {
+ (remote_machine != NULL))) {
usage();
}
/* Only load interfaces if we are doing network operations. */
- if (joining_domain || remote_machine) {
+ if (remote_machine) {
load_interfaces();
}
- /* Join a domain */
-
- if (joining_domain) {
-
- if (argc != 0)
- usage();
-
- /* Are we joining by specifing an admin username and
- password? */
-
- if (user_name[0]) {
-
- /* Get administrator password if not specified */
-
- if (!got_pass) {
- char *pass = getpass("Password: ");
-
- if (pass)
- pstrcpy(user_password, pass);
- }
-
- d_printf("use net rpc join to do this now.\n");
- return 1;
-
- } else {
-
- /* Or just with the server manager? */
-
- return join_domain(new_domain, remote_machine);
- }
- }
-
/*
* Deal with root - can add a user, but only locally.
*/
@@ -435,45 +335,46 @@ static int process_root(int argc, char *argv[])
slprintf(buf, sizeof(buf)-1, "%s$", user_name);
fstrcpy(user_name, buf);
- }
-
- if (remote_machine != NULL) {
- old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
- }
-
- if (!(local_flags & LOCAL_SET_PASSWORD)) {
-
- /*
- * If we are trying to enable a user, first we need to find out
- * if they are using a modern version of the smbpasswd file that
- * disables a user by just writing a flag into the file. If so
- * then we can re-enable a user without prompting for a new
- * password. If not (ie. they have a no stored password in the
- * smbpasswd file) then we need to prompt for a new password.
- */
-
- if(local_flags & LOCAL_ENABLE_USER) {
- SAM_ACCOUNT *sampass = NULL;
- BOOL ret;
+ } else {
+
+ if (remote_machine != NULL) {
+ old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
+ }
+
+ if (!(local_flags & LOCAL_SET_PASSWORD)) {
+
+ /*
+ * If we are trying to enable a user, first we need to find out
+ * if they are using a modern version of the smbpasswd file that
+ * disables a user by just writing a flag into the file. If so
+ * then we can re-enable a user without prompting for a new
+ * password. If not (ie. they have a no stored password in the
+ * smbpasswd file) then we need to prompt for a new password.
+ */
- pdb_init_sam(&sampass);
- ret = pdb_getsampwnam(sampass, user_name);
- if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) {
- local_flags |= LOCAL_SET_PASSWORD;
+ if(local_flags & LOCAL_ENABLE_USER) {
+ SAM_ACCOUNT *sampass = NULL;
+ BOOL ret;
+
+ pdb_init_sam(&sampass);
+ ret = pdb_getsampwnam(sampass, user_name);
+ if((sampass != False) && (pdb_get_lanman_passwd(sampass) == NULL)) {
+ local_flags |= LOCAL_SET_PASSWORD;
+ }
+ pdb_free_sam(&sampass);
}
- pdb_free_sam(&sampass);
}
- }
-
- if(local_flags & LOCAL_SET_PASSWORD) {
- new_passwd = prompt_for_new_password(stdin_passwd_get);
- if(!new_passwd) {
- fprintf(stderr, "Unable to get new password.\n");
- exit(1);
+ if(local_flags & LOCAL_SET_PASSWORD) {
+ new_passwd = prompt_for_new_password(stdin_passwd_get);
+
+ if(!new_passwd) {
+ fprintf(stderr, "Unable to get new password.\n");
+ exit(1);
+ }
}
}
-
+
if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) {
fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
result = 1;