charcnv.c: Added codepage 866 support onto the file system. Patch
authorJeremy Allison <jra@samba.org>
Sat, 17 Jan 1998 07:08:21 +0000 (07:08 +0000)
committerJeremy Allison <jra@samba.org>
Sat, 17 Jan 1998 07:08:21 +0000 (07:08 +0000)
from Max Khon <max@iclub.nsu.ru>.
chgpasswd.c: Allow old RAP change password to work with encrypted
passwords. Samba can now allow Windows 95/NT clients to securely
change the Lanman password ! (But not the NT hash - that gets lost).
ipc.c:
smbdes.c:
smbpass.c: Support for the above.
server.c: #ifdef'ed out fix for NT redirector bug.
util.c: Fix NIS bug with server name.
Jeremy.
(This used to be commit cd9fad92d0316e5a0007ba3c5668906dc2f011f1)

source3/include/proto.h
source3/lib/charcnv.c
source3/lib/util.c
source3/libsmb/smbdes.c
source3/passdb/smbpass.c
source3/smbd/chgpasswd.c
source3/smbd/ipc.c
source3/smbd/server.c

index d0376fb9fe0e180b25bcc4253fff7109b54c24a6..d6027e37167d4b6b8fa3282e99d1f6bb5dc998d6 100644 (file)
@@ -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);
 
index e1a7ac01db522c0727cbabca599fbfab95611a11..f5d28baee46e81ee77cdc525e85644fb480ff7a8 100644 (file)
@@ -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"));
     }
index 403ebb73eb857f373854fe730cfb1b6e4adc3797..1aa88c070868f07871210aa82e06605fa7e6fb19 100644 (file)
@@ -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 */
index c3cc2c71337c9f611a5ad6f563f764a6c78941d3..7446f31e152e05199e23bb64e0b06711a11fcaa6 100644 (file)
@@ -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];
index 4109383fb4795ab3159f49a198e8a5cb36720541..188bf1b71d3bf0b80dadab8c5358feeb90a90851 100644 (file)
@@ -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
index 17401410cec14043130fa1318533399a427b820b..1502cd1219f6748546c40e1804c0947c17abe0f7 100644 (file)
@@ -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;
+}
index ee2aec8c220c8a7557ed7aa135eaf49d07041f3d..e3db823a9df896623ff06fb848c8188c34d49197 100644 (file)
@@ -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));         
         
index bf635fc27ad2b9091ffcb3e216a1735fc9b622ca..751039070f7bf0e330e779f93674a15ed58fb2f0 100644 (file)
@@ -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
           {