1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +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 used to be commit 6a7164233e)
This commit is contained in:
Jeremy Allison 1998-04-29 22:27:26 +00:00
parent e305c2c9e2
commit 90177708aa
7 changed files with 344 additions and 48 deletions

View File

@ -1773,6 +1773,7 @@ BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
BOOL mod_smbpwd_entry(struct smb_passwd* pwd); BOOL mod_smbpwd_entry(struct smb_passwd* pwd);
void *machine_password_lock( char *domain, char *name, BOOL update); void *machine_password_lock( char *domain, char *name, BOOL update);
BOOL machine_password_unlock( void *token ); BOOL machine_password_unlock( void *token );
BOOL machine_password_delete( char *domain, char *name );
BOOL get_machine_account_password( void *mach_tok, unsigned char *ret_pwd, BOOL get_machine_account_password( void *mach_tok, unsigned char *ret_pwd,
time_t *last_change_time); time_t *last_change_time);
BOOL set_machine_account_password( void *mach_tok, unsigned char *md4_new_pwd); BOOL set_machine_account_password( void *mach_tok, unsigned char *md4_new_pwd);

View File

@ -2144,8 +2144,7 @@ static void lp_add_auto_services(char *str)
{ {
char *s; char *s;
char *p; char *p;
int homes = lp_servicenumber(HOMES_NAME); int homes, printers;
int printers = lp_servicenumber(PRINTERS_NAME);
if (!str) if (!str)
return; return;
@ -2153,6 +2152,9 @@ static void lp_add_auto_services(char *str)
s = strdup(str); s = strdup(str);
if (!s) return; if (!s) return;
homes = lp_servicenumber(HOMES_NAME);
printers = lp_servicenumber(PRINTERS_NAME);
for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
{ {
char *home = get_home_dir(p); char *home = get_home_dir(p);

View File

@ -80,7 +80,7 @@ static BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
(*plock_depth)++; (*plock_depth)++;
if(pw_file_lock_depth == 0) { if(pw_file_lock_depth == 0) {
if (do_pw_lock(fd, secs, type)) { if (!do_pw_lock(fd, secs, type)) {
DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n", DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
strerror(errno))); strerror(errno)));
return False; return False;
@ -135,7 +135,7 @@ void *startsmbpwent(BOOL update)
/* Set a 16k buffer to do more efficient reads */ /* Set a 16k buffer to do more efficient reads */
setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf)); setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
if (!pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0), 5, &pw_file_lock_depth)) if (!pw_file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, &pw_file_lock_depth))
{ {
DEBUG(0, ("startsmbpwent: unable to lock file %s\n", pfile)); DEBUG(0, ("startsmbpwent: unable to lock file %s\n", pfile));
fclose(fp); fclose(fp);
@ -774,7 +774,7 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
lockfd = fileno(fp); lockfd = fileno(fp);
if (!pw_file_lock(lockfd, F_RDLCK | F_WRLCK, 5, &pw_file_lock_depth)) { if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile)); DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile));
fclose(fp); fclose(fp);
return False; return False;
@ -1075,6 +1075,35 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
static int mach_passwd_lock_depth; static int mach_passwd_lock_depth;
/************************************************************************
Routine to get the name for a machine account file.
************************************************************************/
static void get_machine_account_file_name( char *domain, char *name, char *mac_file)
{
unsigned int mac_file_len;
char *p;
pstrcpy(mac_file, lp_smb_passwd_file());
p = strrchr(mac_file, '/');
if(p != NULL)
*++p = '\0';
mac_file_len = strlen(mac_file);
if (sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6 < 0)
{
DEBUG(0,("machine_password_lock: path %s too long to add machine details.\n",
mac_file));
return;
}
strcat(mac_file, domain);
strcat(mac_file, ".");
strcat(mac_file, name);
strcat(mac_file, ".mac");
}
/************************************************************************ /************************************************************************
Routine to lock the machine account password file for a domain. Routine to lock the machine account password file for a domain.
************************************************************************/ ************************************************************************/
@ -1083,41 +1112,27 @@ void *machine_password_lock( char *domain, char *name, BOOL update)
{ {
FILE *fp; FILE *fp;
pstring mac_file; pstring mac_file;
unsigned int mac_file_len;
char *p;
if(mach_passwd_lock_depth == 0) { if(mach_passwd_lock_depth == 0) {
pstrcpy(mac_file, lp_smb_passwd_file()); get_machine_account_file_name( domain, name, mac_file);
p = strrchr(mac_file, '/');
if(p != NULL)
*++p = '\0';
mac_file_len = strlen(mac_file);
if (sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6 < 0)
{
DEBUG(0,("machine_password_lock: path %s too long to add machine details.\n",
mac_file));
return NULL;
}
strcat(mac_file, domain);
strcat(mac_file, ".");
strcat(mac_file, name);
strcat(mac_file, ".mac");
if((fp = fopen(mac_file, "r+b")) == NULL) { if((fp = fopen(mac_file, "r+b")) == NULL) {
DEBUG(0,("machine_password_lock: cannot open file %s - Error was %s.\n", if(errno == ENOENT && update) {
mac_file, strerror(errno) )); fp = fopen(mac_file, "w+b");
return NULL; }
if(fp == NULL) {
DEBUG(0,("machine_password_lock: cannot open file %s - Error was %s.\n",
mac_file, strerror(errno) ));
return NULL;
}
} }
chmod(mac_file, 0600); chmod(mac_file, 0600);
} }
if(!pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0), if(!pw_file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK),
60, &mach_passwd_lock_depth)) 60, &mach_passwd_lock_depth))
{ {
DEBUG(0,("machine_password_lock: cannot lock file %s\n", mac_file)); DEBUG(0,("machine_password_lock: cannot lock file %s\n", mac_file));
@ -1141,6 +1156,18 @@ BOOL machine_password_unlock( void *token )
return ret; return ret;
} }
/************************************************************************
Routine to delete the machine account password file for a domain.
************************************************************************/
BOOL machine_password_delete( char *domain, char *name )
{
pstring mac_file;
get_machine_account_file_name( domain, name, mac_file);
return (unlink( mac_file ) == 0);
}
/************************************************************************ /************************************************************************
Routine to get the machine account password for a domain. Routine to get the machine account password for a domain.
The user of this function must have locked the machine password file. The user of this function must have locked the machine password file.

View File

@ -90,7 +90,7 @@ BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
#endif #endif
/* Process the new password. */ /* Process the new password. */
cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 0); cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1);
/* send client srv_pwset challenge */ /* send client srv_pwset challenge */
return cli_net_srv_pwset(cli, processed_new_pwd); return cli_net_srv_pwset(cli, processed_new_pwd);

View File

@ -402,7 +402,7 @@ static void api_net_srv_pwset( int uid,
DEBUG(100,("%02X ", q_a.pwd[i])); DEBUG(100,("%02X ", q_a.pwd[i]));
DEBUG(100,("\n")); DEBUG(100,("\n"));
cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 1); cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
/* lies! nt and lm passwords are _not_ the same: don't care */ /* lies! nt and lm passwords are _not_ the same: don't care */
smb_pass->smb_passwd = pwd; smb_pass->smb_passwd = pwd;

View File

@ -26,6 +26,7 @@ pstring servicesf = CONFIGFILE;
extern pstring debugf; extern pstring debugf;
extern pstring sesssetup_user; extern pstring sesssetup_user;
extern fstring global_myworkgroup; extern fstring global_myworkgroup;
extern pstring global_myname;
char *InBuffer = NULL; char *InBuffer = NULL;
char *OutBuffer = NULL; char *OutBuffer = NULL;
@ -4942,6 +4943,21 @@ static void init_structs(void )
int i; int i;
get_myname(myhostname,NULL); get_myname(myhostname,NULL);
/*
* Set the machine NETBIOS name if not already
* set from the config file.
*/
if (!*global_myname)
{
char *p;
fstrcpy( global_myname, myhostname );
p = strchr( global_myname, '.' );
if (p)
*p = 0;
}
strupper( global_myname );
for (i=0;i<MAX_CONNECTIONS;i++) for (i=0;i<MAX_CONNECTIONS;i++)
{ {
Connections[i].open = False; Connections[i].open = False;

View File

@ -19,7 +19,11 @@
#include "includes.h" #include "includes.h"
extern pstring myhostname;
extern pstring global_myname; extern pstring global_myname;
extern fstring global_myworkgroup;
static char *prog_name;
/********************************************************* /*********************************************************
Print command usage on stderr and die. Print command usage on stderr and die.
@ -29,12 +33,224 @@ static void usage(char *name, BOOL is_root)
{ {
if(is_root) if(is_root)
fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-a] [-d] [-m] [-n] [username] [password]\n\ 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 else
fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [password]\n", name); fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [password]\n", name);
exit(1); 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. Start here.
**********************************************************/ **********************************************************/
@ -44,7 +260,6 @@ int main(int argc, char **argv)
extern char *optarg; extern char *optarg;
extern int optind; extern int optind;
extern int DEBUGLEVEL; extern int DEBUGLEVEL;
char *prog_name;
int real_uid; int real_uid;
struct passwd *pwd; struct passwd *pwd;
fstring old_passwd; fstring old_passwd;
@ -59,11 +274,13 @@ int main(int argc, char **argv)
BOOL is_root = False; BOOL is_root = False;
pstring user_name; pstring user_name;
char *remote_machine = NULL; char *remote_machine = NULL;
BOOL add_user = False; BOOL add_user = False;
BOOL got_new_pass = False; BOOL got_new_pass = False;
BOOL machine_account = False; BOOL machine_account = False;
BOOL disable_user = False; BOOL disable_user = False;
BOOL set_no_password = False; BOOL set_no_password = False;
BOOL joining_domain = False;
char *new_domain = NULL;
pstring servicesf = CONFIGFILE; pstring servicesf = CONFIGFILE;
void *vp; void *vp;
@ -84,7 +301,26 @@ int main(int argc, char **argv)
if (!lp_load(servicesf,True,False,False)) { if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", prog_name, servicesf); 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()); codepage_initialise(lp_client_code_page());
/* Get the real uid */ /* Get the real uid */
@ -98,7 +334,7 @@ int main(int argc, char **argv)
is_root = (real_uid == 0); 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) { switch(ch) {
case 'a': case 'a':
if(is_root) if(is_root)
@ -139,6 +375,14 @@ int main(int argc, char **argv)
} else } else
usage(prog_name, is_root); usage(prog_name, is_root);
break; break;
case 'j':
if(is_root) {
new_domain = optarg;
strupper(new_domain);
joining_domain = True;
} else
usage(prog_name, is_root);
break;
case 'h': case 'h':
default: default:
usage(prog_name, is_root); usage(prog_name, is_root);
@ -149,13 +393,24 @@ int main(int argc, char **argv)
argv += optind; argv += optind;
/* /*
* Ensure add_user and remote machine are * Ensure add_user and either remote machine or join domain are
* not both set. * not both set.
*/ */
if(add_user && (remote_machine != NULL))
if(add_user && ((remote_machine != NULL) || joining_domain))
usage(prog_name, True); 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. * 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 cli_state cli;
struct in_addr ip; 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)) { if(!resolve_name( remote_machine, &ip)) {
fprintf(stderr, "%s: unable to find an IP address for machine %s.\n", fprintf(stderr, "%s: unable to find an IP address for machine %s.\n",
prog_name, remote_machine ); prog_name, remote_machine );