Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[pandora-kernel.git] / fs / cifs / sess.c
index 7202d53..7584646 100644 (file)
@@ -90,7 +90,9 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
        } */
        /* copy user */
        if(ses->userName == NULL) {
-               /* BB what about null user mounts - check that we do this BB */
+               /* null user mount */
+               *bcc_ptr = 0;
+               *(bcc_ptr+1) = 0;
        } else { /* 300 should be long enough for any conceivable user name */
                bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
                                          300, nls_cp);
@@ -98,10 +100,13 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
        bcc_ptr += 2 * bytes_ret;
        bcc_ptr += 2; /* account for null termination */
        /* copy domain */
-       if(ses->domainName == NULL)
-               bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
-                                         "CIFS_LINUX_DOM", 32, nls_cp);
-       else
+       if(ses->domainName == NULL) {
+               /* Sending null domain better than using a bogus domain name (as
+               we did briefly in 2.6.18) since server will use its default */
+               *bcc_ptr = 0;
+               *(bcc_ptr+1) = 0;
+               bytes_ret = 0;
+       } else
                bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 
                                          256, nls_cp);
        bcc_ptr += 2 * bytes_ret;
@@ -111,7 +116,7 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
        bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
                                  nls_cp);
        bcc_ptr += 2 * bytes_ret;
-       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
+       bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
                                  32, nls_cp);
        bcc_ptr += 2 * bytes_ret;
        bcc_ptr += 2; /* trailing null */
@@ -144,13 +149,11 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
 
         /* copy domain */
        
-        if(ses->domainName == NULL) {
-                strcpy(bcc_ptr, "CIFS_LINUX_DOM");
-               bcc_ptr += 14;  /* strlen(CIFS_LINUX_DOM) */
-       } else {
+        if(ses->domainName != NULL) {
                 strncpy(bcc_ptr, ses->domainName, 256); 
                bcc_ptr += strnlen(ses->domainName, 256);
-       }
+       } /* else we will send a null domain name 
+            so the server will default to its own domain */
        *bcc_ptr = 0;
        bcc_ptr++;
 
@@ -158,8 +161,8 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
 
        strcpy(bcc_ptr, "Linux version ");
        bcc_ptr += strlen("Linux version ");
-       strcpy(bcc_ptr, system_utsname.release);
-       bcc_ptr += strlen(system_utsname.release) + 1;
+       strcpy(bcc_ptr, init_utsname()->release);
+       bcc_ptr += strlen(init_utsname()->release) + 1;
 
        strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
        bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
@@ -179,11 +182,14 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
        cFYI(1,("bleft %d",bleft));
 
 
-       /* word align, if bytes remaining is not even */
-       if(bleft % 2) {
-               bleft--;
-               data++;
-       }
+       /* SMB header is unaligned, so cifs servers word align start of
+          Unicode strings */
+       data++;
+       bleft--; /* Windows servers do not always double null terminate
+                   their final Unicode string - in which case we
+                   now will not attempt to decode the byte of junk
+                   which follows it */
+                   
        words_left = bleft / 2;
 
        /* save off server operating system */
@@ -268,6 +274,10 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
        ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
        if(ses->serverOS)
                strncpy(ses->serverOS, bcc_ptr, len);
+       if(strncmp(ses->serverOS, "OS/2",4) == 0) {
+                       cFYI(1,("OS/2 server"));
+                       ses->flags |= CIFS_SES_OS2;
+       }
 
        bcc_ptr += len + 1;
        bleft -= len + 1;
@@ -290,16 +300,11 @@ static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo
         if(len > bleft)
                 return rc;
 
-        if(ses->serverDomain)
-                kfree(ses->serverDomain);
-
-        ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
-        if(ses->serverOS)
-                strncpy(ses->serverOS, bcc_ptr, len);
-
-        bcc_ptr += len + 1;
-       bleft -= len + 1;
-
+       /* No domain field in LANMAN case. Domain is
+          returned by old servers in the SMB negprot response */
+       /* BB For newer servers which do not support Unicode,
+          but thus do return domain here we could add parsing
+          for it later, but it is not very important */
        cFYI(1,("ascii: bytes left %d",bleft));
 
        return rc;
@@ -366,18 +371,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
        str_area = kmalloc(2000, GFP_KERNEL);
        bcc_ptr = str_area;
 
+       ses->flags &= ~CIFS_SES_LANMAN;
+
        if(type == LANMAN) {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                char lnm_session_key[CIFS_SESS_KEY_SIZE];
 
                /* no capabilities flags in old lanman negotiation */
 
-               pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE
+               pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE)
                /* BB calculate hash with password */
                /* and copy into bcc */
 
                calc_lanman_hash(ses, lnm_session_key);
-
+               ses->flags |= CIFS_SES_LANMAN; 
 /* #ifdef CONFIG_CIFS_DEBUG2
                cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
                        CIFS_SESS_KEY_SIZE);