summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/lib/charcnv.c60
-rw-r--r--source3/lib/util.c1
-rw-r--r--source3/libsmb/smbdes.c6
-rw-r--r--source3/passdb/smbpass.c12
-rw-r--r--source3/smbd/chgpasswd.c83
-rw-r--r--source3/smbd/ipc.c30
-rw-r--r--source3/smbd/server.c7
8 files changed, 195 insertions, 8 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d0376fb9fe..d6027e3716 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -45,6 +45,9 @@ void add_char_string(char *s);
BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
BOOL chgpasswd(char *name,char *oldpass,char *newpass);
+BOOL check_lanman_password(char *user, unsigned char *pass1,
+ unsigned char *pass2, struct smb_passwd **psmbpw);
+BOOL change_lanman_password(struct smb_passwd *smbpw, char *pass1, char *pass2);
/*The following definitions come from client.c */
@@ -1268,6 +1271,7 @@ struct shmem_ops *sysv_shm_open(int ronly);
void E_P16(unsigned char *p14,unsigned char *p16);
void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
+void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index e1a7ac01db..f5d28baee4 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -98,6 +98,62 @@ update_map("\257\275\261\245\346\206\352\251\263\210\361\344\363\242\266\230");
update_map("\274\253\277\276");
}
+/* Init for russian language (iso8859-5) */
+
+/* Added by Max Khon <max@iclub.nsu.ru> */
+
+static void init_iso8859_5()
+{
+ int i;
+ if (!mapsinited) initmaps();
+
+ /* Do not map undefined characters to some accidental code */
+ for (i = 128; i < 256; i++)
+ {
+ unix2dos[i] = CTRLZ;
+ dos2unix[i] = CTRLZ;
+ }
+
+/* MSDOS Code Page 866 -> ISO8859-5 */
+update_map("\200\260\201\261\202\262\203\263\204\264\205\265\206\266\207\267");
+update_map("\210\270\211\271\212\272\213\273\214\274\215\275\216\276\217\277");
+update_map("\220\300\221\301\222\302\223\303\224\304\225\305\226\306\227\307");
+update_map("\230\310\231\311\232\312\233\313\234\314\235\315\236\316\237\317");
+update_map("\240\320\241\321\242\322\243\323\244\324\245\325\246\326\247\327");
+update_map("\250\330\251\331\252\332\253\333\254\334\255\335\256\336\257\337");
+update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
+update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
+update_map("\360\241\361\361\362\244\363\364\364\247\365\367\366\256\367\376");
+update_map("\374\360\377\240");
+}
+
+/* Init for russian language (koi8) */
+
+static void init_koi8_r()
+{
+ if (!mapsinited) initmaps();
+
+ /* There aren't undefined characters between 128 and 255 */
+
+/* MSDOS Code Page 866 -> KOI8-R */
+update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
+update_map("\210\302\211\301\212\305\213\337\214\334\215\333\216\335\217\336");
+update_map("\220\260\221\261\222\262\223\364\224\376\225\371\226\373\227\367");
+update_map("\230\363\231\362\232\377\233\365\234\370\235\375\236\372\237\366");
+update_map("\240\315\241\272\242\325\243\361\244\326\245\311\246\270\247\267");
+update_map("\250\273\251\324\252\323\253\310\254\276\255\275\256\274\257\306");
+update_map("\260\307\261\314\262\265\263\360\264\266\265\271\266\321\267\322");
+update_map("\270\313\271\317\272\320\273\312\274\330\275\327\276\316\277\374");
+update_map("\300\356\301\240\302\241\303\346\304\244\305\245\306\344\307\243");
+update_map("\310\345\311\250\312\251\313\252\314\253\315\254\316\255\317\256");
+update_map("\320\257\321\357\322\340\323\341\324\342\325\343\326\246\327\242");
+update_map("\330\354\331\353\332\247\333\350\334\355\335\351\336\347\337\352");
+update_map("\340\236\341\200\342\201\343\226\344\204\345\205\346\224\347\203");
+update_map("\350\225\351\210\352\211\353\212\354\213\355\214\356\215\357\216");
+update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
+update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
+}
+
/*
* Convert unix to dos
*/
@@ -156,6 +212,10 @@ void interpret_character_set(char *str)
init_iso8859_1();
} else if (strequal (str, "iso8859-2")) {
init_iso8859_2();
+ } else if (strequal (str, "iso8859-5")) {
+ init_iso8859_5();
+ } else if (strequal (str, "koi8-r")) {
+ init_koi8_r();
} else {
DEBUG(0,("unrecognized character set\n"));
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 403ebb73eb..1aa88c0708 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -3731,6 +3731,7 @@ char *automount_server(char *user_name)
home_server_len = sizeof(pstring);
}
strncpy(server_name, nis_result, home_server_len);
+ server_name[home_server_len] = '\0';
}
#else
/* use the local machine name instead of the auto-map server */
diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index c3cc2c7133..7446f31e15 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/libsmb/smbdes.c
@@ -317,6 +317,12 @@ void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
smbhash(p24+16, c8, p21+14, 1);
}
+void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
+{
+ smbhash(out, in, p14, 0);
+ smbhash(out+8, in+8, p14+7, 0);
+}
+
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
{
unsigned char buf[8];
diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c
index 4109383fb4..188bf1b71d 100644
--- a/source3/passdb/smbpass.c
+++ b/source3/passdb/smbpass.c
@@ -788,12 +788,15 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
return False;
}
+ /* The following check is wrong - the NT hash is optional. */
+#if 0
if (*p == '*' || *p == 'X')
{
fclose(fp);
pw_file_unlock(lockfd);
return False;
}
+#endif
/* whew. entry is correctly formed. */
@@ -838,19 +841,20 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
{
sprintf(&ascii_p16[i*2], "%02X", (uchar) pwd->smb_passwd[i]);
}
+ /* Add on the NT md4 hash */
+ ascii_p16[32] = ':';
+ wr_len = 65;
if (pwd->smb_nt_passwd != NULL)
{
- /* Add on the NT md4 hash */
- ascii_p16[32] = ':';
for (i = 0; i < 16; i++)
{
sprintf(&ascii_p16[(i*2)+33], "%02X", (uchar) pwd->smb_nt_passwd[i]);
}
- wr_len = 65;
}
else
{
- wr_len = 32;
+ /* No NT hash - write out an 'invalid' string. */
+ strcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
}
#ifdef DEBUG_PASSWORD
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 17401410ce..1502cd1219 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -398,3 +398,86 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass)
return(False);
}
#endif
+
+/***********************************************************
+ Code to check the lanman hashed password.
+************************************************************/
+
+BOOL check_lanman_password(char *user, unsigned char *pass1,
+ unsigned char *pass2, struct smb_passwd **psmbpw)
+{
+ unsigned char unenc_new_pw[16];
+ unsigned char unenc_old_pw[16];
+ struct smb_passwd *smbpw;
+
+ *psmbpw = NULL;
+
+ become_root(0);
+ smbpw = get_smbpwd_entry(user, 0);
+ unbecome_root(0);
+
+ if(smbpw == NULL)
+ {
+ DEBUG(0,("check_lanman_password: get_smbpwd_entry returned NULL\n"));
+ return False;
+ }
+
+ if(smbpw->smb_passwd == NULL)
+ {
+ DEBUG(0,("check_lanman_password: no lanman password !\n"));
+ return False;
+ }
+
+ /* Get the new lanman hash. */
+ D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
+
+ /* Use this to get the old lanman hash. */
+ 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))
+ {
+ DEBUG(0,("check_lanman_password: old password doens't match.\n"));
+ return False;
+ }
+
+ *psmbpw = smbpw;
+ return True;
+}
+
+/***********************************************************
+ Code to change the lanman hashed password.
+ It nulls out the NT hashed password as it will
+ no longer be valid.
+************************************************************/
+
+BOOL change_lanman_password(struct smb_passwd *smbpw, char *pass1, char *pass2)
+{
+ char unenc_new_pw[16];
+ BOOL ret;
+
+ if(smbpw == NULL)
+ {
+ DEBUG(0,("change_lanman_password: get_smbpwd_entry returned NULL\n"));
+ return False;
+ }
+
+ if(smbpw->smb_passwd == NULL)
+ {
+ DEBUG(0,("change_lanman_password: no lanman password !\n"));
+ return False;
+ }
+
+ /* Get the new lanman hash. */
+ D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
+
+ smbpw->smb_passwd = unenc_new_pw;
+ smbpw->smb_nt_passwd = NULL; /* We lose the NT hash. Sorry. */
+
+ /* Now write it into the file. */
+ become_root(0);
+ ret = mod_smbpwd_entry(smbpw);
+ unbecome_root(0);
+
+ return ret;
+}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index ee2aec8c22..e3db823a9d 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -1141,7 +1141,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
uint32 servertype = IVAL(p,4);
char *p2;
int data_len, fixed_len, string_len;
- int f_len, s_len;
+ int f_len = 0, s_len = 0;
struct srv_info_struct *servers=NULL;
int counted=0,total=0;
int i,missed;
@@ -1421,7 +1421,7 @@ static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data,
int total=0,counted=0;
int i;
int data_len, fixed_len, string_len;
- int f_len, s_len;
+ int f_len = 0, s_len = 0;
if (!prefix_ok(str1,"WrLeh")) return False;
if (!check_share_info(uLevel,str2)) return False;
@@ -1532,8 +1532,8 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
p = skip_string(p,1);
- StrnCpy(pass1,p,16);
- StrnCpy(pass2,p+16,16);
+ memcpy(pass1,p,16);
+ memcpy(pass2,p+16,16);
*rparam_len = 4;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -1545,12 +1545,34 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
DEBUG(3,("Set password for <%s>\n",user));
+ /*
+ * Attempt the plaintext password change first.
+ * Older versions of Windows seem to do this.
+ */
+
if (password_ok(user,pass1,strlen(pass1),NULL) &&
chgpasswd(user,pass1,pass2))
{
SSVAL(*rparam,0,NERR_Success);
}
+ /*
+ * If the plaintext change failed, attempt
+ * the encrypted. NT will generate this
+ * after trying the samr method.
+ */
+
+ if(SVAL(*rparam,0) != NERR_Success)
+ {
+ struct smb_passwd *smbpw = NULL;
+
+ if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &smbpw) &&
+ change_lanman_password(smbpw,(unsigned char *)pass1,(unsigned char *)pass2))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ }
+
bzero(pass1,sizeof(fstring));
bzero(pass2,sizeof(fstring));
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index bf635fc27a..751039070f 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1637,6 +1637,13 @@ BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op)
{
DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \
batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode));
+#if 0
+ /*
+ * This next line is a test that allows the deny-mode
+ * processing to be skipped. JRA.
+ */
+ continue;
+#endif
}
else
{