1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-08 05:57:51 +03:00

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)
This commit is contained in:
Andrew Bartlett 2001-12-05 11:00:26 +00:00
parent 0d09562eed
commit 8ba00d147b
14 changed files with 386 additions and 403 deletions

View File

@ -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 \ 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_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 rpc_client/cli_pipe.o libsmb/cli_pipe_util.o
LIBMSRPC_PICOBJ = $(LIBMSRPC_OBJ:.o=.po) 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_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 rpc_client/cli_spoolss_notify.o
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.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/posix_acls.o \
smbd/process.o smbd/service.o smbd/error.o \ smbd/process.o smbd/service.o smbd/error.o \
printing/printfsp.o lib/util_seaccess.o smbd/srvstr.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_OBJ = printing/pcap.o printing/print_svid.o \
printing/print_cups.o printing/print_generic.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 MSDFS_OBJ = msdfs/msdfs.o
SMBD_OBJ = $(SMBD_OBJ1) $(MSDFS_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \ 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) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(QUOTAOBJS) $(OPLOCK_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_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \ nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
@ -248,7 +254,7 @@ NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \ 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) \ web/swat.o web/neg_lang.o $(PRINTING_OBJ) $(LIBSMB_OBJ) $(LOCKING_OBJ) \
$(PARAM_OBJ) $(PASSDB_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \ $(PARAM_OBJ) $(PASSDB_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_OBJ) $(PLAINTEXT_AUTH_OBJ) \
smbwrapper/shared.o smbwrapper/shared.o
@ -275,8 +281,7 @@ TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \ SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) \
$(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\ $(LIBSMB_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ)\
$(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ)
libsmb/cli_lsarpc.o libsmb/cli_samr.o libsmb/cli_pipe_util.o
PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \ PDBEDIT_OBJ = utils/pdbedit.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ) $(GROUPDB_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 \ NET_OBJ = utils/net.o utils/net_ads.o utils/net_rap.o utils/net_rpc.o \
utils/net_rpc_join.o \ utils/net_rpc_join.o \
$(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \ $(LIBSMB_OBJ) $(LIBMSRPC_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) \
$(GROUPDB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(GROUPDB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
$(NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ)
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)

View File

@ -1648,4 +1648,10 @@ typedef struct {
void *cd_direct, *cd_pull, *cd_push; void *cd_direct, *cd_pull, *cd_push;
} *smb_iconv_t; } *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 */ #endif /* _SMB_H */

View File

@ -2,9 +2,12 @@
Unix SMB/Netbios implementation. Unix SMB/Netbios implementation.
Version 1.9. Version 1.9.
NT Domain Authentication SMB / MSRPC client 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) Luke Kenneth Casson Leighton 1996-2000
Copyright (C) Tim Potter 2001 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 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 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: done:
return result; 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;
}

View File

@ -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);
}

View File

@ -78,27 +78,6 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
return NT_STATUS_OK; return NT_STATUS_OK;
} }
/****************************************************************************
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. NT login - interactive.
*NEVER* use this code. This method of doing a logon (sending the cleartext *NEVER* use this code. This method of doing a logon (sending the cleartext

View File

@ -260,76 +260,6 @@ BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_
return valid_chal; 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 LSA SAM Logon internal - interactive or network. Does level 2 or 3 but always
returns level 3. returns level 3.

View File

@ -6,6 +6,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997, * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997. * Copyright (C) Paul Ashton 1997.
* Copyright (C) Jeremy Allison 1998. * Copyright (C) Jeremy Allison 1998.
* Copyright (C) Andrew Bartlett 2001.
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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. Change the domain password on the PDC.
**********************************************************/ **********************************************************/
static BOOL modify_trust_password( char *domain, char *remote_machine, static NTSTATUS modify_trust_password( char *domain, char *remote_machine,
unsigned char orig_trust_passwd_hash[16], unsigned char orig_trust_passwd_hash[16])
unsigned char new_trust_passwd_hash[16])
{ {
struct cli_state cli; struct cli_state *cli;
NTSTATUS result;
DOM_SID domain_sid; DOM_SID domain_sid;
struct in_addr dest_ip;
NTSTATUS nt_status;
/* /*
* Ensure we have the domain SID for this domain. * Ensure we have the domain SID for this domain.
@ -44,81 +45,21 @@ static BOOL modify_trust_password( char *domain, char *remote_machine,
if (!secrets_fetch_domain_sid(domain, &domain_sid)) { if (!secrets_fetch_domain_sid(domain, &domain_sid)) {
DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n")); DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n"));
return False; return NT_STATUS_UNSUCCESSFUL;
} }
ZERO_STRUCT(cli); if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
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)); DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
cli_shutdown(&cli); return NT_STATUS_UNSUCCESSFUL;
return False;
} }
if (ismyip(cli.dest_ip)) { if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname, remote_machine,
DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \ &dest_ip, 0,
to ourselves.\n", remote_machine)); "IPC$", "IPC",
cli_shutdown(&cli); "", "",
return False; "", 0))) {
} DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine));
return NT_STATUS_UNSUCCESSFUL;
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 (!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 (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;
} }
/* /*
@ -126,68 +67,41 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
* Now start the NT Domain stuff :-). * 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 \ DEBUG(0,("modify_trust_password: unable to open the domain client session to \
machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); machine %s. Error was : %s.\n", remote_machine, cli_errstr(cli)));
cli_nt_session_close(&cli); cli_nt_session_close(cli);
cli_ulogoff(&cli); cli_ulogoff(cli);
cli_shutdown(&cli); cli_shutdown(cli);
return False; return NT_STATUS_UNSUCCESSFUL;
} }
result = cli_nt_setup_creds(&cli, orig_trust_passwd_hash); nt_status = trust_pw_change_and_store_it(cli, cli->mem_ctx,
orig_trust_passwd_hash);
if (!NT_STATUS_IS_OK(result)) { cli_nt_session_close(cli);
DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \ cli_ulogoff(cli);
%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result))); cli_shutdown(cli);
cli_nt_session_close(&cli); return nt_status;
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;
} }
/************************************************************************ /************************************************************************
Change the trust account password for a domain. 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; fstring remote_machine;
unsigned char old_trust_passwd_hash[16]; unsigned char old_trust_passwd_hash[16];
unsigned char new_trust_passwd_hash[16];
time_t lct; time_t lct;
BOOL res = False; NTSTATUS res = NT_STATUS_UNSUCCESSFUL;
if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) { if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
DEBUG(0,("change_trust_account_password: unable to read the machine \ DEBUG(0,("change_trust_account_password: unable to read the machine \
account password for domain %s.\n", domain)); 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 && while(remote_machine_list &&
next_token(&remote_machine_list, remote_machine, next_token(&remote_machine_list, remote_machine,
LIST_SEP, sizeof(remote_machine))) { LIST_SEP, sizeof(remote_machine))) {
@ -215,8 +129,8 @@ account password for domain %s.\n", domain));
fstring dc_name; fstring dc_name;
if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name)) if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name))
continue; continue;
if((res = modify_trust_password( domain, dc_name, if(NT_STATUS_IS_OK(res = modify_trust_password( domain, dc_name,
old_trust_passwd_hash, new_trust_passwd_hash))) old_trust_passwd_hash)))
break; break;
} }
@ -224,27 +138,15 @@ account password for domain %s.\n", domain));
} else { } else {
res = modify_trust_password( domain, remote_machine, res = modify_trust_password( domain, remote_machine,
old_trust_passwd_hash, new_trust_passwd_hash); 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); if (!NT_STATUS_IS_OK(res)) {
memset(old_trust_passwd_hash, 0, 16);
DEBUG(0,("%s : change_trust_account_password: Failed to change password for \ DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
domain %s.\n", timestring(False), domain)); domain %s.\n", timestring(False), domain));
return False; }
return res;
} }

View File

@ -743,11 +743,16 @@ 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. Inits a NET_Q_SRV_PWSET.
********************************************************************/ ********************************************************************/
void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 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 nt_cypher[16]) 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")); 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); init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd));

View File

@ -163,7 +163,7 @@ static BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **se
if (!*server_name) { if (!*server_name) {
*server_name = strdup(inet_ntoa(dest_ip)); *server_name = strdup(inet_ntoa(dest_ip));
} }
} else if (server_name) { } else if (*server_name) {
/* resolve the IP address */ /* resolve the IP address */
if (!resolve_name(*server_name, server_ip, 0x20)) { if (!resolve_name(*server_name, server_ip, 0x20)) {
DEBUG(1,("Unable to resolve server name\n")); DEBUG(1,("Unable to resolve server name\n"));
@ -404,6 +404,8 @@ static struct functable net_func[] = {
*p2 = 0; *p2 = 0;
} }
strupper(global_myname);
load_interfaces(); load_interfaces();
rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage); rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);

View File

@ -26,13 +26,13 @@
For example, localhost is insane for a 'join' operation. 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 */ /* We want to find the PDC only */
#define NET_FLAGS_PDC 4 #define NET_FLAGS_PDC 8
/* We want an anonymous connection */ /* We want an anonymous connection */
#define NET_FLAGS_ANONYMOUS 5 #define NET_FLAGS_ANONYMOUS 16
extern int opt_maxusers; extern int opt_maxusers;

View File

@ -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); password = strdup(tmp_password);
if (!(ads = ads_startup())) return -1; if (!(ads = ads_startup())) return -1;

View File

@ -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, rpc_command_fn fn,
int argc, const char **argv) 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; TALLOC_CTX *mem_ctx;
NTSTATUS nt_status; NTSTATUS nt_status;
DOM_SID *domain_sid = net_get_remote_domain_sid(cli); 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); 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) if (cli->nt_pipe_fnum)
cli_nt_session_close(cli); 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; 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) 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); argc, argv);
} }
@ -188,15 +243,18 @@ static int rpc_user(int argc, const char **argv)
int net_rpc_usage(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; return -1;
} }
int net_rpc(int argc, const char **argv) int net_rpc(int argc, const char **argv)
{ {
struct functable func[] = { struct functable func[] = {
{"join", net_rpc_join}, {"join", rpc_join},
{"user", rpc_user}, {"user", rpc_user},
{"changetrustpw", rpc_changetrustpw},
{NULL, NULL} {NULL, NULL}
}; };
return net_run_function(argc, argv, func, net_rpc_usage); return net_run_function(argc, argv, func, net_rpc_usage);

View File

@ -191,7 +191,7 @@ int net_rpc_join(int argc, const char **argv)
{ {
char *str; char *str;
str = generate_random_str(15); str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
clear_trust_password = strdup(str); clear_trust_password = strdup(str);
} }
@ -256,8 +256,6 @@ int net_rpc_join(int argc, const char **argv)
strupper(domain); strupper(domain);
secrets_init();
if (!secrets_store_domain_sid(domain, &domain_sid)) { if (!secrets_store_domain_sid(domain, &domain_sid)) {
DEBUG(0, ("error storing domain sid for %s\n", domain)); DEBUG(0, ("error storing domain sid for %s\n", domain));
goto done; goto done;
@ -284,7 +282,7 @@ int net_rpc_join(int argc, const char **argv)
goto done; 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"); "error in domain join verification");
retval = 0; /* Success! */ retval = 0; /* Success! */

View File

@ -50,7 +50,6 @@ static void usage(void)
printf("extra options when run by root or in local mode:\n"); printf("extra options when run by root or in local mode:\n");
printf(" -L local mode (must be first option)\n"); printf(" -L local mode (must be first option)\n");
printf(" -R ORDER name resolve order\n"); printf(" -R ORDER name resolve order\n");
printf(" -j DOMAIN join domain name\n");
printf(" -a add user\n"); printf(" -a add user\n");
printf(" -x delete user\n"); printf(" -x delete user\n");
printf(" -d disable user\n"); printf(" -d disable user\n");
@ -61,67 +60,6 @@ static void usage(void)
exit(1); 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) static void set_line_buffering(FILE *f)
{ {
setvbuf(f, NULL, _IOLBF, 0); setvbuf(f, NULL, _IOLBF, 0);
@ -241,11 +179,10 @@ static int process_root(int argc, char *argv[])
{ {
struct passwd *pwd; struct passwd *pwd;
int result = 0, ch; 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; int local_flags = LOCAL_SET_PASSWORD;
BOOL stdin_passwd_get = False; BOOL stdin_passwd_get = False;
fstring user_name, user_password; fstring user_name, user_password;
char *new_domain = NULL;
char *new_passwd = NULL; char *new_passwd = NULL;
char *old_passwd = NULL; char *old_passwd = NULL;
char *remote_machine = NULL; char *remote_machine = NULL;
@ -255,7 +192,7 @@ static int process_root(int argc, char *argv[])
user_name[0] = '\0'; 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) { switch(ch) {
case 'L': case 'L':
local_mode = True; local_mode = True;
@ -278,14 +215,9 @@ static int process_root(int argc, char *argv[])
case 'm': case 'm':
local_flags |= LOCAL_TRUST_ACCOUNT; local_flags |= LOCAL_TRUST_ACCOUNT;
break; break;
case 'n':
local_flags |= LOCAL_SET_NO_PASSWORD;
local_flags &= ~LOCAL_SET_PASSWORD;
break;
case 'j': case 'j':
new_domain = optarg; d_printf("See 'net rpc join' for this functionality\n");
strupper(new_domain); exit(1);
joining_domain = True;
break; break;
case 'r': case 'r':
remote_machine = optarg; 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)) || if(((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) == (LOCAL_ADD_USER|LOCAL_DELETE_USER)) ||
((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && ((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) &&
((remote_machine != NULL) || joining_domain))) { (remote_machine != NULL))) {
usage(); usage();
} }
/* Only load interfaces if we are doing network operations. */ /* Only load interfaces if we are doing network operations. */
if (joining_domain || remote_machine) { if (remote_machine) {
load_interfaces(); 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. * Deal with root - can add a user, but only locally.
*/ */
@ -435,7 +335,7 @@ static int process_root(int argc, char *argv[])
slprintf(buf, sizeof(buf)-1, "%s$", user_name); slprintf(buf, sizeof(buf)-1, "%s$", user_name);
fstrcpy(user_name, buf); fstrcpy(user_name, buf);
} } else {
if (remote_machine != NULL) { if (remote_machine != NULL) {
old_passwd = get_pass("Old SMB password:",stdin_passwd_get); old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
@ -473,6 +373,7 @@ static int process_root(int argc, char *argv[])
exit(1); exit(1);
} }
} }
}
if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) { 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); fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);