cifs: store password in tcon
authorJeff Layton <jlayton@redhat.com>
Sat, 6 Dec 2008 01:41:21 +0000 (20:41 -0500)
committerSteve French <sfrench@us.ibm.com>
Fri, 26 Dec 2008 02:29:11 +0000 (02:29 +0000)
cifs: store password in tcon

Each tcon has its own password for share-level security. Store it in
the tcon and wipe it clean and free it when freeing the tcon. When
doing the tree connect with share-level security, use the tcon password
instead of the session password.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/misc.c

index 0fb934d..94c1ca0 100644 (file)
@@ -242,6 +242,7 @@ struct cifsTconInfo {
        struct cifsSesInfo *ses;        /* pointer to session associated with */
        char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
        char *nativeFileSystem;
+       char *password;         /* for share-level security */
        __u16 tid;              /* The 2 byte tree id */
        __u16 Flags;            /* optional support bits */
        enum statusEnum tidStatus;
index 3a84a37..3caadf1 100644 (file)
@@ -2282,9 +2282,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 
                /* volume_info->password freed at unmount */
                if (volume_info->password) {
-                       pSesInfo->password = volume_info->password;
-                       /* set to NULL to prevent freeing on exit */
-                       volume_info->password = NULL;
+                       pSesInfo->password = kstrdup(volume_info->password,
+                                                    GFP_KERNEL);
+                       if (!pSesInfo->password) {
+                               rc = -ENOMEM;
+                               goto mount_fail_check;
+                       }
                }
                if (volume_info->username)
                        strncpy(pSesInfo->userName, volume_info->username,
@@ -2324,7 +2327,16 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                rc = -ENOMEM;
                                goto mount_fail_check;
                        }
+
                        tcon->ses = pSesInfo;
+                       if (volume_info->password) {
+                               tcon->password = kstrdup(volume_info->password,
+                                                        GFP_KERNEL);
+                               if (!tcon->password) {
+                                       rc = -ENOMEM;
+                                       goto mount_fail_check;
+                               }
+                       }
 
                        /* check for null share name ie connect to dfs root */
                        if ((strchr(volume_info->UNC + 3, '\\') == NULL)
@@ -3532,15 +3544,14 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                   NTLMv2 password here) */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
                if ((extended_security & CIFSSEC_MAY_LANMAN) &&
-                       (ses->server->secType == LANMAN))
-                       calc_lanman_hash(ses->password, ses->server->cryptKey,
+                   (ses->server->secType == LANMAN))
+                       calc_lanman_hash(tcon->password, ses->server->cryptKey,
                                         ses->server->secMode &
                                            SECMODE_PW_ENCRYPT ? true : false,
                                         bcc_ptr);
                else
 #endif /* CIFS_WEAK_PW_HASH */
-               SMBNTencrypt(ses->password,
-                            ses->server->cryptKey,
+               SMBNTencrypt(tcon->password, ses->server->cryptKey,
                             bcc_ptr);
 
                bcc_ptr += CIFS_SESS_KEY_SIZE;
index 7c3f4b9..a051360 100644 (file)
@@ -132,6 +132,10 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
        }
        atomic_dec(&tconInfoAllocCount);
        kfree(buf_to_free->nativeFileSystem);
+       if (buf_to_free->password) {
+               memset(buf_to_free->password, 0, strlen(buf_to_free->password));
+               kfree(buf_to_free->password);
+       }
        kfree(buf_to_free);
 }