diff options
| author | Andrew Bartlett <abartlet@samba.org> | 2001-12-05 11:00:26 +0000 | 
|---|---|---|
| committer | Andrew Bartlett <abartlet@samba.org> | 2001-12-05 11:00:26 +0000 | 
| commit | 8ba00d147bbdb705b411e182433632c81a036188 (patch) | |
| tree | ebbeb3b46c5cb3a2da025a324b1cc31f8af182ac | |
| parent | 0d09562eed608941b2bee29e37d7ea4ba33582c3 (diff) | |
| download | samba-8ba00d147bbdb705b411e182433632c81a036188.tar.gz samba-8ba00d147bbdb705b411e182433632c81a036188.tar.bz2 samba-8ba00d147bbdb705b411e182433632c81a036188.zip  | |
OK.  Smbpasswd -j is DEAD.
This moves the rest of the functionality into the 'net rpc join' code.
Futhermore, this moves that entire area over to the libsmb codebase, rather
than the crufty old rpc_client stuff.
I have also fixed up the smbpasswd -a -m bug in the process.
We also have a new 'net rpc changetrustpw' that can be called from a
cron-job to regularly change the trust account password, for sites
that run winbind but not smbd.
With a little more work, we can kill rpc_client from smbd entirly!
(It is mostly the domain auth stuff - which I can rework - and the
spoolss stuff that sombody else will need to look over).
Andrew Bartlett
(This used to be commit 575897e879fc175ba702adf245384033342c903d)
| -rw-r--r-- | source3/Makefile.in | 29 | ||||
| -rw-r--r-- | source3/include/smb.h | 6 | ||||
| -rw-r--r-- | source3/libsmb/cli_netlogon.c | 83 | ||||
| -rw-r--r-- | source3/libsmb/trust_passwd.c | 116 | ||||
| -rw-r--r-- | source3/rpc_client/cli_login.c | 21 | ||||
| -rw-r--r-- | source3/rpc_client/cli_netlogon.c | 70 | ||||
| -rw-r--r-- | source3/rpc_client/cli_trust.c | 184 | ||||
| -rw-r--r-- | source3/rpc_parse/parse_net.c | 9 | ||||
| -rw-r--r-- | source3/utils/net.c | 4 | ||||
| -rw-r--r-- | source3/utils/net.h | 6 | ||||
| -rw-r--r-- | source3/utils/net_ads.c | 2 | ||||
| -rw-r--r-- | source3/utils/net_rpc.c | 68 | ||||
| -rw-r--r-- | source3/utils/net_rpc_join.c | 6 | ||||
| -rw-r--r-- | source3/utils/smbpasswd.c | 179 | 
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;  | 
