RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
BOOL ntlmssp_auth;
BOOL ntlmssp_validated;
unsigned char ntlmssp_hash[258];
+ uint32 ntlmssp_seq_num;
fstring user_name;
fstring domain;
fstring wks;
BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
-size_t cli_write(struct cli_state *cli,
+ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
char *buf, off_t offset, size_t size);
BOOL cli_getattrE(struct cli_state *cli, int fd,
void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16], BOOL unicode);
+BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode);
/*The following definitions come from libsmb/smberr.c */
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len);
void smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
+BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai);
void make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len,
uint32 ptr);
void smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
void make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
char *signature, uint32 msg_type);
void smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth);
char *domain, char *user, char *wks,
uint32 neg_flags);
void smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 *seq_num);
void make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
uint32 ver, uint32 crc32, uint32 seq_num);
void smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
/*The following definitions come from rpc_server/srv_ldap_helpers.c */
+void ldap_helper_dummy(void);
/*The following definitions come from rpc_server/srv_lsa.c */
BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
-BOOL check_lanman_password(char *user, unsigned char *pass1,
- unsigned char *pass2, struct smb_passwd **psmbpw);
-BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsigned char *pass2);
-BOOL check_oem_password(char *user, unsigned char *data,
+BOOL check_lanman_password(char *user, uchar *pass1,
+ uchar *pass2, struct smb_passwd **psmbpw);
+BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2);
+BOOL pass_oem_change(char *user,
+ uchar *lmdata, uchar *lmhash,
+ uchar *ntdata, uchar *nthash);
+BOOL check_oem_password(char *user,
+ uchar *lmdata, uchar *lmhash,
+ uchar *ntdata, uchar *nthash,
struct smb_passwd **psmbpw, char *new_passwd,
int new_passwd_size);
BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override);
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest);
void add_session_user(char *user);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
-BOOL smb_password_ok(struct smb_passwd *smb_pass,
+BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24]);
BOOL pass_check_smb(char *user, char *domain,
- char *challenge, char *lm_pwd, char *nt_pwd,
+ uchar *chal, char *lm_pwd, char *nt_pwd,
struct passwd *pwd);
BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd);
BOOL user_ok(char *user,int snum);
nexti = (nexti+1)%8;
- DEBUG(10, ("unistrn2: "));
-
for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
{
- DEBUG(10, ("%4x ", *buf));
*p = *buf;
}
- DEBUG(10,("\n"));
-
*p = 0;
return lbuf;
}
nexti = (nexti+1)%8;
- DEBUG(10, ("unistr2: "));
-
for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
{
- DEBUG(10, ("%4x ", *buf));
*p = *buf;
}
- DEBUG(10,("\n"));
-
*p = 0;
return lbuf;
}
if (p == NULL) return 0;
- DEBUG(10, ("struni2: "));
-
if (buf != NULL)
{
for (; *buf && len < MAXUNI-2; len++, p++, buf++)
{
- DEBUG(10, ("%2x ", *buf));
*p = *buf;
}
-
- DEBUG(10,("\n"));
}
*p = 0;
#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
struct rlimit rlp;
getrlimit(RLIMIT_NOFILE, &rlp);
+ /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
+ * account for the extra fd we need
+ * as well as the log files and standard
+ * handles etc. */
rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
setrlimit(RLIMIT_NOFILE, &rlp);
getrlimit(RLIMIT_NOFILE, &rlp);
return requested_max;
#endif
}
-
SSVAL(p, 0, cli->pid);
SIVAL(p, 2, offset);
SIVAL(p, 6, len);
-
cli_send_smb(cli);
cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
0x0004 use raw named pipe protocol
0x0008 start of message mode named pipe protocol
****************************************************************************/
-size_t cli_write(struct cli_state *cli,
+ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
char *buf, off_t offset, size_t size)
{
#endif
}
-BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16], BOOL unicode)
+BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode)
{
int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
RPC_AUTH_NTLMSSP_CHK chk;
uint32 crc32;
int data_len = len - 0x18 - auth_len - 8;
- char *reply_data = (uchar*)mem_data(&rdata->data, 0x18);
+ char *reply_data = mem_data(&rdata->data, 0x18);
BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
-/* RPC_HDR_AUTH rhdr_auth;
- prs_struct auth_req;
- prs_init(&auth_req , 0x10, 4, 0, True);
- smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
- prs_mem_free(&auth_req);
+ if (reply_data == NULL) return False;
-*/
if (auth_seal)
{
DEBUG(10,("rpc_auth_pipe: seal\n"));
dump_data(100, reply_data, data_len);
}
+ if (auth_verify || auth_seal)
+ {
+ RPC_HDR_AUTH rhdr_auth;
+ prs_struct auth_req;
+ char *data = mem_data(&rdata->data, len - auth_len - 8);
+ prs_init(&auth_req , 0x08, 4, 0, True);
+ memcpy(auth_req.data->data, data, 8);
+ smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
+ prs_mem_free(&auth_req);
+
+ if (!rpc_hdr_auth_chk(&rhdr_auth))
+ {
+ return False;
+ }
+ }
+
if (auth_verify)
{
prs_struct auth_verf;
char *data = (uchar*)mem_data(&rdata->data, len - auth_len);
- prs_init(&auth_verf, 0x08, 4, 0, True);
+ if (data == NULL) return False;
+
DEBUG(10,("rpc_auth_pipe: verify\n"));
dump_data(100, data, auth_len);
- NTLMSSPcalc(cli->ntlmssp_hash, data + 4, auth_len - 4);
+ NTLMSSPcalc(cli->ntlmssp_hash, (uchar*)(data+4), auth_len - 4);
+ prs_init(&auth_verf, 0x08, 4, 0, True);
memcpy(auth_verf.data->data, data, 16);
smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
dump_data(100, data, auth_len);
if (auth_verify)
{
crc32 = crc32_calc_buffer(data_len, reply_data);
- if (chk.crc32 != crc32 ||
- chk.ver != NTLMSSP_SIGN_VERSION ||
- chk.seq_num != cli->ntlmssp_seq_num++)
+ if (!rpc_auth_ntlmssp_chk(&chk, crc32 , &cli->ntlmssp_seq_num))
{
- DEBUG(5,("rpc_auth_pipe: verify failed - crc %x ver %x seq %d\n",
- crc32, NTLMSSP_SIGN_VERSION, cli->ntlmssp_seq_num));
- DEBUG(5,("rpc_auth_pipe: verify expect - crc %x ver %x seq %d\n",
- chk.crc32, chk.ver, chk.seq_num));
return False;
}
}
BOOL ret;
BOOL auth_verify;
BOOL auth_seal;
- uint32 crc32 = 0;
+ uint32 crc32;
auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
- bzero(lm_hash, sizeof(lm_hash));
NTLMSSPhash(cli->ntlmssp_hash, p24);
+ bzero(lm_hash, sizeof(lm_hash));
/* this is a hack due to limitations in rpc_api_pipe */
prs_init(&dataa, mem_buf_len(hdra.data), 4, 0x0, False);
prs_uint32("unknown ", ps, depth, &(rai->unknown )); /* 0x0014a0c0 */
}
+/*******************************************************************
+checks an RPC_HDR_AUTH structure.
+********************************************************************/
+BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai)
+{
+ return (rai->auth_type == 0x0a && rai->auth_level == 0x06);
+}
+
/*******************************************************************
creates an RPC_HDR_AUTH structure.
********************************************************************/
prs_uint32("unknown ", ps, depth, &(rai->unknown )); /* 0x0014a0c0 */
}
+/*******************************************************************
+checks an RPC_AUTH_VERIFIER structure.
+********************************************************************/
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type)
+{
+ return (strequal(rav->signature, signature) && rav->msg_type == msg_type);
+}
+
/*******************************************************************
creates an RPC_AUTH_VERIFIER structure.
********************************************************************/
}
}
+/*******************************************************************
+checks an RPC_AUTH_NTLMSSP_CHK structure.
+********************************************************************/
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 *seq_num)
+{
+ if (chk == NULL || seq_num == NULL)
+ {
+ return False;
+ }
+
+ if (chk->crc32 != crc32 ||
+ chk->ver != NTLMSSP_SIGN_VERSION ||
+ chk->seq_num != (*seq_num))
+ {
+ DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
+ crc32, NTLMSSP_SIGN_VERSION, (*seq_num)-1));
+ DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
+ chk->crc32, chk->ver, chk->seq_num));
+ return False;
+ }
+ (*seq_num)++;
+ return True;
+}
+
/*******************************************************************
creates an RPC_AUTH_NTLMSSP_CHK structure.
********************************************************************/
#else /* USE_LDAP */
/* this keeps fussy compilers happy */
- void ldap_helper_dummy(void);
- void ldap_helper_dummy(void) {}
+void ldap_helper_dummy(void)
+{}
#endif /* USE_LDAP */
DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
- /* oops! */
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ if (!pass_oem_change(user_name,
+ q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
+ q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
+ {
+ status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ }
make_samr_r_chgpasswd_user(&r_u, status);
{
uchar lm_owf[24];
uchar nt_owf[24];
+ struct smb_passwd *smb_pass = NULL;
DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf));
#ifdef DEBUG_PASSWORD
- DEBUG(100,("lm, nt owfs:\n"));
+ DEBUG(100,("lm, nt owfs, chal\n"));
dump_data(100, lm_owf, sizeof(lm_owf));
dump_data(100, nt_owf, sizeof(nt_owf));
+ dump_data(100, p->ntlmssp_chal.challenge, 8);
#endif
become_root(True);
p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain,
- p->ntlmssp_chal.challenge, lm_owf, nt_owf, NULL);
+ p->ntlmssp_chal.challenge, (uchar*)lm_owf, (uchar*)nt_owf, NULL);
+ smb_pass = getsmbpwnam(p->user_name);
unbecome_root(True);
+ if (p->ntlmssp_validated && smb_pass != NULL && smb_pass->smb_passwd)
+ {
+ uchar p24[24];
+ NTLMSSPOWFencrypt(smb_pass->smb_passwd, lm_owf, p24);
+ NTLMSSPhash(p->ntlmssp_hash, p24);
+ p->ntlmssp_seq_num = 0;
+ }
+ else
+ {
+ p->ntlmssp_validated = False;
+ }
+
return p->ntlmssp_validated;
}
static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
{
- p->ntlmssp_auth = False;
-
DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
- if (p->hdr.auth_len != 0)
- {
- /* decode the authentication verifier response */
- smb_io_rpc_hdr_autha("", &p->autha_info, pd, 0);
- if (pd->offset == 0) return False;
+ if (p->hdr.auth_len == 0) return False;
- p->ntlmssp_auth = p->auth_info.auth_type = 0x0a;
-
- if (p->ntlmssp_auth)
- {
- smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0);
- if (pd->offset == 0) return False;
+ /* decode the authentication verifier response */
+ smb_io_rpc_hdr_autha("", &p->autha_info, pd, 0);
+ if (pd->offset == 0) return False;
- p->ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP");
- }
+ if (!rpc_hdr_auth_chk(&(p->auth_info))) return False;
- if (p->ntlmssp_auth)
- {
- if (!api_pipe_ntlmssp(p, pd)) return False;
- }
- }
+ smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0);
+ if (pd->offset == 0) return False;
- return p->ntlmssp_auth;
+ if (!rpc_auth_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False;
+
+ return api_pipe_ntlmssp(p, pd);
}
static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd)
{
+ BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
+ int data_len;
+ int auth_len;
+ uint32 old_offset;
+ uint32 crc32;
+
+ auth_len = p->hdr.auth_len;
+
+ if (auth_len != 16 && auth_verify)
+ {
+ return False;
+ }
+
+ data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+
+ DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+
+ if (auth_seal)
+ {
+ char *data = (uchar*)mem_data(&pd->data, pd->offset);
+ DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset));
+ NTLMSSPcalc(p->ntlmssp_hash, data, data_len);
+ crc32 = crc32_calc_buffer(data_len, data);
+ }
+
+ /*** skip the data, record the offset so we can restore it again */
+ old_offset = pd->offset;
+
+ if (auth_seal || auth_verify)
+ {
+ pd->offset += data_len;
+ smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, pd, 0);
+ }
+
+ if (auth_verify)
+ {
+ char *req_data = (uchar*)mem_data(&pd->data, pd->offset + 4);
+ DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4));
+ NTLMSSPcalc(p->ntlmssp_hash, req_data, 12);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), pd, 0);
+
+ if (!rpc_auth_ntlmssp_chk(&(p->ntlmssp_chk), crc32,
+ &(p->ntlmssp_seq_num)))
+ {
+ return False;
+ }
+ }
+
+ pd->offset = old_offset;
+
return True;
}
}
case RPC_REQUEST:
{
- reply = api_pipe_request (p, pd);
+ if (p->ntlmssp_auth && !p->ntlmssp_validated)
+ {
+ /* authentication _was_ requested
+ and it failed. sorry, no deal!
+ */
+ reply = False;
+ }
+ else
+ {
+ /* read the rpc header */
+ smb_io_rpc_hdr_req("req", &(p->hdr_req), pd, 0);
+ reply = api_pipe_request(p, pd);
+ }
break;
}
case RPC_BINDRESP: /* not the real name! */
{
reply = api_pipe_bind_auth_resp(p, pd);
+ p->ntlmssp_auth = reply;
break;
}
}
+ if (!reply)
+ {
+ DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
+ }
return reply;
}
return False;
}
- /* read the rpc header */
- smb_io_rpc_hdr_req("req", &(p->hdr_req), data, 0);
-
/* interpret the command */
if (!api_rpc_command(p, rpc_name, api_rpc_cmds, data))
{
grantpt(master);
unlockpt(master);
*slave = ptsname(master);
- if(*slave == NULL) {
+ if (*slave == NULL) {
DEBUG(0,("findpty: Unable to create master/slave pty pair.\n"));
return -1;
} else {
int gid;
int uid;
- if(pass == NULL) {
+ if (pass == NULL) {
DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n",
name));
return False;
}
/* make us completely into the right uid */
- if(!as_root) {
+ if (!as_root) {
#ifdef HAVE_SETRESUID
setresgid(0,0,0);
setresuid(0,0,0);
if (!strequal(chatbuf,"."))
ok = expect(master,chatbuf,buf);
- if(lp_passwd_chat_debug())
+ if (lp_passwd_chat_debug())
DEBUG(100,("talktochild: chatbuf=[%s] responsebuf=[%s]\n",chatbuf,buf));
if (!ok) {
if (!strequal(chatbuf,"."))
writestring(master,chatbuf);
- if(lp_passwd_chat_debug())
+ if (lp_passwd_chat_debug())
DEBUG(100,("talktochild: sendbuf=[%s]\n",chatbuf));
}
/* make sure it doesn't freeze */
alarm(20);
- if(as_root)
+ if (as_root)
become_root(False);
DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,(int)getuid(),(int)getgid()));
chstat = dochild(master, slavedev, name, passwordprogram, as_root);
- if(as_root)
+ if (as_root)
unbecome_root(False);
}
- if(chstat)
+ if (chstat)
DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
return (chstat);
}
len = strlen(oldpass);
for(i = 0; i < len; i++) {
- if(iscntrl((int)oldpass[i])) {
+ if (iscntrl((int)oldpass[i])) {
DEBUG(0,("chat_with_program: oldpass contains control characters (disallowed).\n"));
return False;
}
len = strlen(newpass);
for(i = 0; i < len; i++) {
- if(iscntrl((int)newpass[i])) {
+ if (iscntrl((int)newpass[i])) {
DEBUG(0,("chat_with_program: newpass contains control characters (disallowed).\n"));
return False;
}
Code to check the lanman hashed password.
************************************************************/
-BOOL check_lanman_password(char *user, unsigned char *pass1,
- unsigned char *pass2, struct smb_passwd **psmbpw)
+BOOL check_lanman_password(char *user, uchar *pass1,
+ uchar *pass2, struct smb_passwd **psmbpw)
{
- unsigned char unenc_new_pw[16];
- unsigned char unenc_old_pw[16];
- unsigned char null_pw[16];
+ uchar unenc_new_pw[16];
+ uchar unenc_old_pw[16];
+ uchar null_pw[16];
struct smb_passwd *smbpw;
*psmbpw = NULL;
smbpw = getsmbpwnam(user);
unbecome_root(0);
- if(smbpw == NULL)
+ if (smbpw == NULL)
{
DEBUG(0,("check_lanman_password: getsmbpwnam returned NULL\n"));
return False;
}
- if(smbpw->acct_ctrl & ACB_DISABLED)
+ if (smbpw->acct_ctrl & ACB_DISABLED)
{
DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
return False;
}
- if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
+ if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
{
- unsigned char no_pw[14];
+ uchar no_pw[14];
memset(no_pw, '\0', 14);
E_P16((uchar *)no_pw, (uchar *)null_pw);
smbpw->smb_passwd = null_pw;
D_P16(unenc_new_pw, pass1, unenc_old_pw);
/* Check that the two old passwords match. */
- if(memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
+ if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
{
DEBUG(0,("check_lanman_password: old password doesn't match.\n"));
return False;
no longer be valid.
************************************************************/
-BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsigned char *pass2)
+BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2)
{
- unsigned char unenc_new_pw[16];
- unsigned char null_pw[16];
+ uchar unenc_new_pw[16];
+ uchar null_pw[16];
BOOL ret;
- if(smbpw == NULL)
+ if (smbpw == NULL)
{
DEBUG(0,("change_lanman_password: no smb password entry.\n"));
return False;
}
- if(smbpw->acct_ctrl & ACB_DISABLED)
+ if (smbpw->acct_ctrl & ACB_DISABLED)
{
DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->smb_name));
return False;
}
- if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
+ if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
{
- unsigned char no_pw[14];
+ uchar no_pw[14];
memset(no_pw, '\0', 14);
E_P16((uchar *)no_pw, (uchar *)null_pw);
smbpw->smb_passwd = null_pw;
}
/***********************************************************
- Code to check the OEM hashed password.
+ Code to check and change the OEM hashed password.
************************************************************/
-
-BOOL check_oem_password(char *user, unsigned char *data,
- struct smb_passwd **psmbpw, char *new_passwd,
- int new_passwd_size)
+BOOL pass_oem_change(char *user,
+ uchar *lmdata, uchar *lmhash,
+ uchar *ntdata, uchar *nthash)
{
- struct smb_passwd *smbpw = NULL;
- int new_pw_len;
- fstring upper_case_new_passwd;
- unsigned char new_p16[16];
- unsigned char unenc_old_pw[16];
- unsigned char null_pw[16];
-
- become_root(0);
- *psmbpw = smbpw = getsmbpwnam(user);
- unbecome_root(0);
-
- if(smbpw == NULL)
- {
- DEBUG(0,("check_oem_password: getsmbpwnam returned NULL\n"));
- return False;
- }
-
- if(smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
- return False;
- }
-
- if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
- {
- unsigned char no_pw[14];
- memset(no_pw, '\0', 14);
- E_P16((uchar *)no_pw, (uchar *)null_pw);
- smbpw->smb_passwd = null_pw;
- } else if (smbpw->smb_passwd == NULL) {
- DEBUG(0,("check_oem_password: no lanman password !\n"));
- return False;
- }
-
- /*
- * Call the hash function to get the new password.
- */
- SamOEMhash( (unsigned char *)data, (unsigned char *)smbpw->smb_passwd, True);
-
- /*
- * The length of the new password is in the last 4 bytes of
- * the data buffer.
- */
- new_pw_len = IVAL(data,512);
- if(new_pw_len < 0 || new_pw_len > new_passwd_size - 1) {
- DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
- return False;
- }
-
- memcpy(new_passwd, &data[512-new_pw_len], new_pw_len);
- new_passwd[new_pw_len] = '\0';
-
- /*
- * To ensure we got the correct new password, hash it and
- * use it as a key to test the passed old password.
- */
-
- memset(upper_case_new_passwd, '\0', sizeof(upper_case_new_passwd));
- fstrcpy(upper_case_new_passwd, new_passwd);
- strupper(upper_case_new_passwd);
-
- E_P16((uchar *)upper_case_new_passwd, new_p16);
-
- /*
- * Now use new_p16 as the key to see if the old
- * password matches.
- */
- D_P16(new_p16, &data[516], unenc_old_pw);
+ fstring new_passwd;
+ struct smb_passwd *sampw;
+ BOOL ret = check_oem_password( user, lmdata, lmhash, ntdata, nthash,
+ &sampw,
+ new_passwd, sizeof(new_passwd));
+
+ /*
+ * At this point we have the new case-sensitive plaintext
+ * password in the fstring new_passwd. If we wanted to synchronise
+ * with UNIX passwords we would call a UNIX password changing
+ * function here. However it would have to be done as root
+ * as the plaintext of the old users password is not
+ * available. JRA.
+ */
+
+ if ( ret && lp_unix_password_sync())
+ {
+ ret = chgpasswd(user,"", new_passwd, True);
+ }
+
+ if (ret)
+ {
+ ret = change_oem_password( sampw, new_passwd, False );
+ }
+
+ memset(new_passwd, 0, sizeof(new_passwd));
+
+ return ret;
+}
- if(memcmp(smbpw->smb_passwd, unenc_old_pw, 16)) {
- DEBUG(0,("check_oem_password: old password doesn't match.\n"));
- return False;
- }
+/***********************************************************
+ Code to check the OEM hashed password.
- memset(upper_case_new_passwd, '\0', strlen(upper_case_new_passwd));
+ this function ignores the 516 byte nt OEM hashed password
+ but does use the lm OEM password to check the nt hashed-hash.
- return True;
+************************************************************/
+BOOL check_oem_password(char *user,
+ uchar *lmdata, uchar *lmhash,
+ uchar *ntdata, uchar *nthash,
+ struct smb_passwd **psmbpw, char *new_passwd,
+ int new_passwd_size)
+{
+ struct smb_passwd *smbpw = NULL;
+ int new_pw_len;
+ uchar new_ntp16[16];
+ uchar unenc_old_ntpw[16];
+ uchar new_p16[16];
+ uchar unenc_old_pw[16];
+ uchar null_pw[16];
+ uchar null_ntpw[16];
+ uchar no_pw[2];
+ BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);
+
+ become_root(False);
+ *psmbpw = smbpw = getsmbpwnam(user);
+ unbecome_root(False);
+
+ if (smbpw == NULL)
+ {
+ DEBUG(0,("check_oem_password: getsmbpwnam returned NULL\n"));
+ return False;
+ }
+
+ if (smbpw->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
+ return False;
+ }
+
+ /* construct a null password (in case one is needed */
+ no_pw[0] = 0;
+ no_pw[1] = 0;
+ nt_lm_owf_gen(no_pw, null_ntpw, null_pw);
+
+ /* check for null passwords */
+ if (smbpw->smb_passwd == NULL)
+ {
+ if (smbpw->acct_ctrl & ACB_PWNOTREQ)
+ {
+ smbpw->smb_passwd = null_pw;
+ }
+ else
+ {
+ DEBUG(0,("check_oem_password: no lanman password !\n"));
+ return False;
+ }
+ }
+
+ if (smbpw->smb_nt_passwd == NULL && nt_pass_set)
+ {
+ if (smbpw->acct_ctrl & ACB_PWNOTREQ)
+ {
+ smbpw->smb_nt_passwd = null_pw;
+ }
+ else
+ {
+ DEBUG(0,("check_oem_password: no ntlm password !\n"));
+ return False;
+ }
+ }
+
+ /*
+ * Call the hash function to get the new password.
+ */
+ SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True);
+
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+
+ new_pw_len = IVAL(lmdata, 512);
+ if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
+ {
+ DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
+ return False;
+ }
+
+ if (nt_pass_set)
+ {
+ /*
+ * nt passwords are in unicode
+ */
+ int uni_pw_len = new_pw_len;
+ char *pw;
+ new_pw_len /= 2;
+ pw = unistrn2((uint16*)(&lmdata[512-uni_pw_len]), new_pw_len);
+ memcpy(new_passwd, pw, new_pw_len+1);
+ }
+ else
+ {
+ memcpy(new_passwd, &lmdata[512-new_pw_len], new_pw_len);
+ new_passwd[new_pw_len] = '\0';
+ }
+
+ /*
+ * To ensure we got the correct new password, hash it and
+ * use it as a key to test the passed old password.
+ */
+
+ nt_lm_owf_gen(new_passwd, new_ntp16, new_p16);
+
+ if (!nt_pass_set)
+ {
+ /*
+ * Now use new_p16 as the key to see if the old
+ * password matches.
+ */
+ D_P16(new_p16 , lmhash, unenc_old_pw);
+
+ if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
+ {
+ DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
+ return False;
+ }
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
+#endif
+ return True;
+ }
+
+ /*
+ * Now use new_p16 as the key to see if the old
+ * password matches.
+ */
+ D_P16(new_ntp16, lmhash, unenc_old_pw);
+ D_P16(new_ntp16, nthash, unenc_old_ntpw);
+
+ if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
+ {
+ DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
+ return False;
+ }
+
+ if (memcmp(smbpw->smb_nt_passwd, unenc_old_ntpw, 16))
+ {
+ DEBUG(0,("check_oem_password: old nt password doesn't match.\n"));
+ return False;
+ }
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
+#endif
+ return True;
}
/***********************************************************
{
int ret;
fstring upper_case_new_passwd;
- unsigned char new_nt_p16[16];
- unsigned char new_p16[16];
+ uchar new_nt_p16[16];
+ uchar new_p16[16];
memset(upper_case_new_passwd, '\0', sizeof(upper_case_new_passwd));
fstrcpy(upper_case_new_passwd, new_passwd);
int *rdata_len,int *rparam_len)
{
fstring user;
- fstring new_passwd;
- struct smb_passwd *sampw = NULL;
char *p = param + 2;
- int ret = True;
-
*rparam_len = 2;
*rparam = REALLOC(*rparam,*rparam_len);
*/
(void)Get_Pwnam( user, True);
- if(check_oem_password( user, (unsigned char *)data, &sampw,
- new_passwd, (int)sizeof(new_passwd)) == False) {
- return True;
- }
-
- /*
- * At this point we have the new case-sensitive plaintext
- * password in the fstring new_passwd. If we wanted to synchronise
- * with UNIX passwords we would call a UNIX password changing
- * function here. However it would have to be done as root
- * as the plaintext of the old users password is not
- * available. JRA.
- */
-
- if(lp_unix_password_sync())
- ret = chgpasswd(user,"", new_passwd, True);
-
- if(ret && change_oem_password( sampw, new_passwd, False)) {
+ if (pass_oem_change(user, (uchar*) data, &data[516], NULL, NULL))
+ {
SSVAL(*rparam,0,NERR_Success);
}
Do a specific test for an smb password being correct, given a smb_password and
the lanman and NT responses.
****************************************************************************/
-
-BOOL smb_password_ok(struct smb_passwd *smb_pass,
+BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
uchar lm_pass[24], uchar nt_pass[24])
{
uchar challenge[8];
return(False);
}
- if (!last_challenge(challenge)) {
- DEBUG(1,("no challenge done - password failed\n"));
- return False;
+ if (chal == NULL)
+ {
+ DEBUG(5,("use last SMBnegprot challenge\n"));
+ if (!last_challenge(challenge))
+ {
+ DEBUG(1,("no challenge done - password failed\n"));
+ return False;
+ }
+ }
+ else
+ {
+ DEBUG(5,("challenge received\n"));
+ memcpy(challenge, chal, 8);
}
if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) {
return True if the password is correct, False otherwise
****************************************************************************/
BOOL pass_check_smb(char *user, char *domain,
- char *challenge, char *lm_pwd, char *nt_pwd,
+ uchar *chal, char *lm_pwd, char *nt_pwd,
struct passwd *pwd)
{
struct passwd *pass;
return(True);
}
- if (smb_password_ok(smb_pass, (uchar *)lm_pwd, (uchar *)nt_pwd))
+ if (smb_password_ok(smb_pass, chal, (uchar *)lm_pwd, (uchar *)nt_pwd))
{
return(True);
}
return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
}
- if (!smb_password_ok(smb_trust_acct, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
+ if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
{
DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);