1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-06 16:23:49 +03:00

Makefile: Added files to smbpasswd.c.

loadparm.c: Patch from tim@quiknet.com for static string problems.
server.c: Setup global_myname.
smbpass.c: Fix up locking. Add machine_password_delete() call.
smbpasswd.c: Added provisional code to add to a domain.
lib/rpc/client/cli_login.c: Fixed incorrect cred_hash3 call when setting machine password.
lib/rpc/server/srv_netlog.c: Fixed incorrect cred_hash3 call when setting machine password.
Jeremy.
This commit is contained in:
Jeremy Allison
-
parent c6c22df201
commit 6a7164233e
7 changed files with 344 additions and 48 deletions

View File

@@ -19,7 +19,11 @@
#include "includes.h"
extern pstring myhostname;
extern pstring global_myname;
extern fstring global_myworkgroup;
static char *prog_name;
/*********************************************************
Print command usage on stderr and die.
@@ -29,12 +33,224 @@ static void usage(char *name, BOOL is_root)
{
if(is_root)
fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-a] [-d] [-m] [-n] [username] [password]\n\
%s: [-R <name resolve order>] [-D DEBUGLEVEL] [-r machine] [username] [password]\n%s: [-h]\n", name, name, name);
%s: [-R <name resolve order>] [-D DEBUGLEVEL] [-j DOMAINNAME] [-r machine] [username] [password]\n%s: [-h]\n", name, name, name);
else
fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [password]\n", name);
exit(1);
}
/*********************************************************
Join a domain.
**********************************************************/
static int setup_account( char *domain, char *remote_machine,
unsigned char orig_machine_passwd_hash[16],
unsigned char new_machine_passwd_hash[16])
{
struct in_addr dest_ip;
struct cli_state cli;
memset(&cli, '\0', sizeof(struct cli_state));
if(cli_initialise(&cli) == False) {
fprintf(stderr, "%s: unable to initialize client connection.\n", prog_name);
return 1;
}
if(!resolve_name( remote_machine, &dest_ip)) {
fprintf(stderr, "%s: Can't resolve address for %s\n", prog_name, remote_machine);
return 1;
}
if (ismyip(dest_ip)) {
fprintf(stderr,"%s: Machine %s is one of our addresses. Cannot add to ourselves.\n", prog_name,
remote_machine);
return 1;
}
if (!cli_connect(&cli, remote_machine, &dest_ip)) {
fprintf(stderr, "%s: unable to connect to SMB server on \
machine %s. Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) );
return 1;
}
if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) {
fprintf(stderr, "%s: machine %s rejected the session setup. \
Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
return 1;
}
cli.protocol = PROTOCOL_NT1;
if (!cli_negprot(&cli)) {
fprintf(stderr, "%s: machine %s rejected the negotiate protocol. \
Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
return 1;
}
if (cli.protocol != PROTOCOL_NT1) {
fprintf(stderr, "%s: machine %s didn't negotiate NT protocol.\n", prog_name, remote_machine);
cli_shutdown(&cli);
return 1;
}
/*
* Do an anonymous session setup.
*/
if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
fprintf(stderr, "%s: machine %s rejected the session setup. \
Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
return 1;
}
if (!(cli.sec_mode & 1)) {
fprintf(stderr, "%s: machine %s isn't in user level security mode\n", prog_name, remote_machine);
cli_shutdown(&cli);
return 1;
}
if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
fprintf(stderr, "%s: machine %s rejected the tconX on the IPC$ share. \
Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
return 1;
}
/*
* 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) == False) {
fprintf(stderr, "%s: unable to open the domain client session to \
machine %s. Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return 1;
}
if(cli_nt_setup_creds(&cli, orig_machine_passwd_hash) == False) {
fprintf(stderr, "%s: unable to setup the PDC credentials to machine \
%s. Error was : %s.\n", prog_name, remote_machine, cli_errstr(&cli));
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return 1;
}
if( cli_nt_srv_pwset( &cli,new_machine_passwd_hash ) == False) {
fprintf(stderr, "%s: unable to change password for machine %s in domain \
%s to Domain controller %s. Error was %s.\n", prog_name, global_myname, domain, remote_machine,
cli_errstr(&cli));
cli_close(&cli, cli.nt_pipe_fnum);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return 1;
}
cli_nt_session_close(&cli);
cli_ulogoff(&cli);
cli_shutdown(&cli);
return 0;
}
/*********************************************************
Join a domain.
**********************************************************/
static int join_domain( char *domain, char *remote)
{
fstring remote_machine;
char *p;
fstring machine_passwd;
unsigned char machine_passwd_hash[16];
unsigned char new_machine_passwd_hash[16];
void *vp;
int ret = 1;
fstrcpy(remote_machine, remote ? remote : "");
fstrcpy(machine_passwd, global_myname);
strlower(machine_passwd);
E_md4hash( machine_passwd, machine_passwd_hash);
generate_random_buffer( new_machine_passwd_hash, 16, True);
/* Ensure that we are not trying to join a
domain if we are locally set up as a domain
controller. */
if(lp_domain_controller() && strequal(lp_workgroup(), domain)) {
fprintf(stderr, "%s: Cannot join domain %s as we already configured as domain controller \
for that domain.\n", prog_name, domain);
return 1;
}
/*
* Write the new machine password.
*/
/*
* Get the machine account password.
*/
if((vp = machine_password_lock( domain, global_myname, True)) == NULL) {
fprintf(stderr, "%s: unable to open the machine account password file for \
machine %s in domain %s.\n", prog_name, global_myname, domain);
return 1;
}
if(!set_machine_account_password( vp, new_machine_passwd_hash)) {
fprintf(stderr, "%s: unable to read the machine account password for \
machine %s in domain %s.\n", prog_name, global_myname, domain);
machine_password_unlock(vp);
return 1;
}
machine_password_unlock(vp);
/*
* If we are given a remote machine assume this is the PDC.
*/
if(remote != NULL) {
strupper(remote_machine);
ret = setup_account( domain, remote_machine, machine_passwd_hash, new_machine_passwd_hash);
if(ret == 0)
printf("%s: Joined domain %s.\n", prog_name, domain);
} else {
/*
* Treat each name in the 'password server =' line as a potential
* PDC/BDC. Contact each in turn and try and authenticate and
* change the machine account password.
*/
p = lp_passwordserver();
if(!*p)
fprintf(stderr, "%s: No password server list given in smb.conf - \
unable to join domain.\n", prog_name);
while(p && next_token( &p, remote_machine, LIST_SEP)) {
strupper(remote_machine);
if(setup_account( domain, remote_machine, machine_passwd_hash, new_machine_passwd_hash) == 0) {
printf("%s: Joined domain %s.\n", prog_name, domain);
return 0;
}
}
}
if(ret) {
machine_password_delete( domain, global_myname);
fprintf(stderr,"%s: Unable to join domain %s.\n", prog_name, domain);
}
return ret;
}
/*********************************************************
Start here.
**********************************************************/
@@ -44,7 +260,6 @@ int main(int argc, char **argv)
extern char *optarg;
extern int optind;
extern int DEBUGLEVEL;
char *prog_name;
int real_uid;
struct passwd *pwd;
fstring old_passwd;
@@ -59,11 +274,13 @@ int main(int argc, char **argv)
BOOL is_root = False;
pstring user_name;
char *remote_machine = NULL;
BOOL add_user = False;
BOOL got_new_pass = False;
BOOL machine_account = False;
BOOL disable_user = False;
BOOL set_no_password = False;
BOOL add_user = False;
BOOL got_new_pass = False;
BOOL machine_account = False;
BOOL disable_user = False;
BOOL set_no_password = False;
BOOL joining_domain = False;
char *new_domain = NULL;
pstring servicesf = CONFIGFILE;
void *vp;
@@ -84,7 +301,26 @@ int main(int argc, char **argv)
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", prog_name, servicesf);
}
if(!get_myname(myhostname,NULL)) {
fprintf(stderr, "%s: unable to get my hostname.\n", prog_name );
exit(1);
}
/*
* Set the machine NETBIOS name if not already
* set from the config file.
*/
if (!*global_myname)
{
fstrcpy( global_myname, myhostname );
p = strchr( global_myname, '.' );
if (p)
*p = 0;
}
strupper( global_myname );
codepage_initialise(lp_client_code_page());
/* Get the real uid */
@@ -98,7 +334,7 @@ int main(int argc, char **argv)
is_root = (real_uid == 0);
while ((ch = getopt(argc, argv, "adhmnr:R:D:")) != EOF) {
while ((ch = getopt(argc, argv, "adhmnj:r:R:D:")) != EOF) {
switch(ch) {
case 'a':
if(is_root)
@@ -139,6 +375,14 @@ int main(int argc, char **argv)
} else
usage(prog_name, is_root);
break;
case 'j':
if(is_root) {
new_domain = optarg;
strupper(new_domain);
joining_domain = True;
} else
usage(prog_name, is_root);
break;
case 'h':
default:
usage(prog_name, is_root);
@@ -149,13 +393,24 @@ int main(int argc, char **argv)
argv += optind;
/*
* Ensure add_user and remote machine are
* Ensure add_user and either remote machine or join domain are
* not both set.
*/
if(add_user && (remote_machine != NULL))
if(add_user && ((remote_machine != NULL) || joining_domain))
usage(prog_name, True);
if( is_root ) {
/*
* Deal with joining a domain.
*/
if(joining_domain && argc != 0)
usage(prog_name, True);
if(joining_domain) {
return join_domain( new_domain, remote_machine);
}
if(is_root) {
/*
* Deal with root - can add a user, but only locally.
@@ -297,11 +552,6 @@ int main(int argc, char **argv)
struct cli_state cli;
struct in_addr ip;
if(get_myname(global_myname,NULL) == False) {
fprintf(stderr, "%s: unable to get my hostname.\n", prog_name );
exit(1);
}
if(!resolve_name( remote_machine, &ip)) {
fprintf(stderr, "%s: unable to find an IP address for machine %s.\n",
prog_name, remote_machine );