summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/password.c215
1 files changed, 161 insertions, 54 deletions
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 04a1795e7f..d627edf1cd 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -1673,14 +1673,14 @@ BOOL check_hosts_equiv(char *user)
}
-static struct cli_state cli;
+static struct cli_state pw_cli;
/****************************************************************************
return the client state structure
****************************************************************************/
struct cli_state *server_client(void)
{
- return &cli;
+ return &pw_cli;
}
/****************************************************************************
@@ -1692,61 +1692,63 @@ struct cli_state *server_cryptkey(void)
struct in_addr dest_ip;
extern fstring local_machine;
char *p;
+ BOOL connected_ok = False;
- if (!cli_initialise(&cli))
+ if (!cli_initialise(&pw_cli))
return NULL;
-
- for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) {
- fstrcpy(desthost,p);
+
+ p = lp_passwordserver();
+ while(p && next_token( &p, desthost, LIST_SEP)) {
standard_sub_basic(desthost);
strupper(desthost);
if(!resolve_name( desthost, &dest_ip)) {
- DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",p));
+ DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
continue;
}
if (ismyip(dest_ip)) {
- DEBUG(1,("Password server loop - disabling password server %s\n",p));
+ DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
continue;
}
- if (cli_connect(&cli, desthost, &dest_ip)) {
- DEBUG(3,("connected to password server %s\n",p));
+ if (cli_connect(&pw_cli, desthost, &dest_ip)) {
+ DEBUG(3,("connected to password server %s\n",desthost));
+ connected_ok = True;
break;
}
}
- if (!p) {
- DEBUG(1,("password server not available\n"));
- cli_shutdown(&cli);
+ if (!connected_ok) {
+ DEBUG(0,("password server not available\n"));
+ cli_shutdown(&pw_cli);
return NULL;
}
- if (!cli_session_request(&cli, desthost, 0x20, local_machine)) {
+ if (!cli_session_request(&pw_cli, desthost, 0x20, local_machine)) {
DEBUG(1,("%s rejected the session\n",desthost));
- cli_shutdown(&cli);
+ cli_shutdown(&pw_cli);
return NULL;
}
DEBUG(3,("got session\n"));
- if (!cli_negprot(&cli)) {
+ if (!cli_negprot(&pw_cli)) {
DEBUG(1,("%s rejected the negprot\n",desthost));
- cli_shutdown(&cli);
+ cli_shutdown(&pw_cli);
return NULL;
}
- if (cli.protocol < PROTOCOL_LANMAN2 ||
- !(cli.sec_mode & 1)) {
+ if (pw_cli.protocol < PROTOCOL_LANMAN2 ||
+ !(pw_cli.sec_mode & 1)) {
DEBUG(1,("%s isn't in user level security mode\n",desthost));
- cli_shutdown(&cli);
+ cli_shutdown(&pw_cli);
return NULL;
}
DEBUG(3,("password server OK\n"));
- return &cli;
+ return &pw_cli;
}
/****************************************************************************
@@ -1759,8 +1761,8 @@ BOOL server_validate(char *user, char *domain,
extern fstring local_machine;
static unsigned char badpass[24];
- if (!cli.initialised) {
- DEBUG(1,("password server %s is not connected\n", cli.desthost));
+ if (!pw_cli.initialised) {
+ DEBUG(1,("password server %s is not connected\n", pw_cli.desthost));
return(False);
}
@@ -1781,17 +1783,17 @@ BOOL server_validate(char *user, char *domain,
* need to detect this as some versions of NT4.x are broken. JRA.
*/
- if (cli_session_setup(&cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass),
+ if (cli_session_setup(&pw_cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass),
domain)) {
- if ((SVAL(cli.inbuf,smb_vwv2) & 1) == 0) {
+ if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) == 0) {
DEBUG(0,("server_validate: password server %s allows users as non-guest \
-with a bad password.\n", cli.desthost));
+with a bad password.\n", pw_cli.desthost));
DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \
use this machine as the password server.\n"));
- cli_ulogoff(&cli);
+ cli_ulogoff(&pw_cli);
return False;
}
- cli_ulogoff(&cli);
+ cli_ulogoff(&pw_cli);
}
/*
@@ -1799,21 +1801,21 @@ use this machine as the password server.\n"));
* not guest enabled, we can try with the real password.
*/
- if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
- DEBUG(1,("password server %s rejected the password\n", cli.desthost));
+ if (!cli_session_setup(&pw_cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
+ DEBUG(1,("password server %s rejected the password\n", pw_cli.desthost));
return False;
}
/* if logged in as guest then reject */
- if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) {
- DEBUG(1,("password server %s gave us guest only\n", cli.desthost));
- cli_ulogoff(&cli);
+ if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) != 0) {
+ DEBUG(1,("password server %s gave us guest only\n", pw_cli.desthost));
+ cli_ulogoff(&pw_cli);
return(False);
}
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost));
- cli_ulogoff(&cli);
+ if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(1,("password server %s refused IPC$ connect\n", pw_cli.desthost));
+ cli_ulogoff(&pw_cli);
return False;
}
@@ -1827,43 +1829,48 @@ use this machine as the password server.\n"));
*/
if (lp_net_wksta_user_logon()) {
- DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli.desthost));
- if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) {
- DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost));
- cli_tdis(&cli);
- cli_ulogoff(&cli);
+ DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", pw_cli.desthost));
+ if (!cli_NetWkstaUserLogon(&pw_cli,user,local_machine)) {
+ DEBUG(1,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost));
+ cli_tdis(&pw_cli);
+ cli_ulogoff(&pw_cli);
return False;
}
- if (cli.privilages == 0) {
- DEBUG(1,("password server %s gave guest privilages\n", cli.desthost));
- cli_tdis(&cli);
- cli_ulogoff(&cli);
+ if (pw_cli.privilages == 0) {
+ DEBUG(1,("password server %s gave guest privilages\n", pw_cli.desthost));
+ cli_tdis(&pw_cli);
+ cli_ulogoff(&pw_cli);
return False;
}
- if (!strequal(cli.eff_name, user)) {
+ if (!strequal(pw_cli.eff_name, user)) {
DEBUG(1,("password server %s gave different username %s\n",
- cli.desthost,
- cli.eff_name));
- cli_tdis(&cli);
- cli_ulogoff(&cli);
+ pw_cli.desthost,
+ pw_cli.eff_name));
+ cli_tdis(&pw_cli);
+ cli_ulogoff(&pw_cli);
return False;
}
}
else {
- DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli.desthost));
+ DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", pw_cli.desthost));
}
- DEBUG(3,("password server %s accepted the password\n", cli.desthost));
+ DEBUG(3,("password server %s accepted the password\n", pw_cli.desthost));
- cli_tdis(&cli);
- cli_ulogoff(&cli);
+ cli_tdis(&pw_cli);
+ cli_ulogoff(&pw_cli);
return(True);
}
#ifdef DOMAIN_CLIENT
+/***********************************************************************
+ Do the same as security=server, but using NT Domain calls and a session
+ key from the machine password.
+************************************************************************/
+
BOOL domain_client_validate( char *user, char *domain,
char *smb_apasswd, int smb_apasslen,
char *smb_ntpasswd, int smb_ntpasslen)
@@ -1874,6 +1881,11 @@ BOOL domain_client_validate( char *user, char *domain,
unsigned char local_lm_response[24];
unsigned char local_nt_reponse[24];
BOOL encrypted = True;
+ fstring remote_machine;
+ char *p;
+ struct in_addr dest_ip;
+ struct cli_state cli;
+ BOOL connected_ok = False;
/*
* Check that the requested domain is not our own machine name.
@@ -1930,6 +1942,101 @@ BOOL domain_client_validate( char *user, char *domain,
* see if they were valid.
*/
+ /*
+ * Treat each name in the 'password server =' line as a potential
+ * PDC/BDC. Contact each in turn and try and authenticate.
+ */
+
+ p = lp_passwordserver();
+ while(p && next_token( &p, remote_machine, LIST_SEP)) {
+
+ standard_sub_basic(remote_machine);
+ strupper(remote_machine);
+
+ if(!resolve_name( remote_machine, &dest_ip)) {
+ DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine));
+ continue;
+ }
+
+ if (ismyip(dest_ip)) {
+ DEBUG(1,("domain_client_validate: Password server loop - not using password server %s\n",remote_machine));
+ continue;
+ }
+
+ memset(&cli, '\0', sizeof(struct cli_state));
+
+ if (!cli_connect(&cli, remote_machine, &dest_ip)) {
+ DEBUG(0,("domain_client_validate: unable to connect to SMB server on \
+machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ continue;
+ }
+
+ if (!cli_session_request(&cli, remote_machine, 0x20, myname)) {
+ DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ DEBUG(0,("domain_client_validate: machine %s rejected the negotiate protocol. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ if (cli.protocol != PROTOCOL_NT1) {
+ DEBUG(0,("domain_client_validate: machine %s didn't negotiate NT protocol.\n",
+ remote_machine));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ /*
+ * Do an anonymous session setup.
+ */
+
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ if (!(cli.sec_mode & 1)) {
+ DEBUG(1,("domain_client_validate: machine %s isn't in user level security mode\n",
+ remote_machine));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ DEBUG(0,("domain_client_validate: machine %s rejected the tconX on the IPC$ share. \
+Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
+ cli_shutdown(&cli);
+ continue;
+ }
+
+ /*
+ * We have an anonymous connection to IPC$.
+ */
+ connected_ok = True;
+ break;
+ }
+
+ if (!connected_ok) {
+ DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
+ cli_shutdown(&cli);
+ return False;
+ }
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
return False;
}
#endif /* DOMAIN_CLIENT */