Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 13 Oct 2006 15:09:29 +0000 (08:09 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 13 Oct 2006 15:09:29 +0000 (08:09 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (27 commits)
  [CIFS] Missing flags2 for DFS
  [CIFS] Workaround incomplete byte length returned by some
  [CIFS] cifs Kconfig: don't select CONNECTOR
  [CIFS] Level 1 QPathInfo needed for proper OS2 support
  [CIFS] fix typo in previous patch
  [CIFS] Fix old DOS time conversion to handle timezone
  [CIFS] Do not need to adjust for Jan/Feb for leap day
  [CIFS] Fix leaps year calculation for years after 2100
  [CIFS] readdir (ffirst) enablement of accurate timestamps from legacy servers
  [CIFS] Fix compiler warning with previous patch
  [CIFS] Fix typo
  [CIFS] Allow for 15 minute TZs (e.g. Nepal) and be more explicit about
  [CIFS] Fix readdir of large directories for backlevel servers
  [CIFS] Allow LANMAN21 support even in both POSIX non-POSIX path
  [CIFS] Make use of newer QFSInfo dependent on capability bit instead of
  [CIFS] Do not send newer QFSInfo to legacy servers which can not support it
  [CIFS] Fix typo in name of new cifs_show_stats
  [CIFS] Rename server time zone field
  [CIFS] Handle legacy servers which return undefined time zone
  [CIFS] CIFS support for /proc/<pid>/mountstats part 1
  ...

Manual conflict resolution in fs/cifs/connect.c

20 files changed:
fs/Kconfig
fs/cifs/cifsacl.h
fs/cifs/cifsencrypt.h
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifspdu.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/md5.c
fs/cifs/md5.h
fs/cifs/misc.c
fs/cifs/netmisc.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/smbdes.c
fs/cifs/smbencrypt.c

index db4d13324c369eac7d1a77551679071aea7d07de..6a3df055280a01858d5925f491bcc33157498aab 100644 (file)
@@ -1986,7 +1986,7 @@ config CIFS_EXPERIMENTAL
 config CIFS_UPCALL
          bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
          depends on CIFS_EXPERIMENTAL
-         select CONNECTOR
+         depends on CONNECTOR
          help
            Enables an upcall mechanism for CIFS which will be used to contact
            userspace helper utilities to provide SPNEGO packaged Kerberos
index d0776ac2b8048938bcc58b0615b52b53e29a3c02..5eff35d6e564ac95550697f7b884a9612ac667ca 100644 (file)
@@ -31,8 +31,8 @@ struct cifs_sid {
 } __attribute__((packed));
 
 /* everyone */
-extern const struct cifs_sid sid_everyone;
+/* extern const struct cifs_sid sid_everyone;*/
 /* group users */
-extern const struct cifs_sid sid_user;
+/* extern const struct cifs_sid sid_user;*/
 
 #endif /* _CIFSACL_H */
index 03e359b3286117922f0a47aad41a9f1be1e6c823..152fa2dcfc6c70e80741f92be2e56ab7e5799226 100644 (file)
@@ -27,8 +27,6 @@ extern void mdfour(unsigned char *out, unsigned char *in, int n);
 /* smbdes.c */
 extern void E_P16(unsigned char *p14, unsigned char *p16);
 extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-extern void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
-extern void E_old_pw_hash(unsigned char *, unsigned char *, unsigned char *);
 
 
 
index c00c654f2e11c0ce9cdbb3d597bb1afe9e673ddb..84976cdbe7136c4b76ad0777c924d44fd4b613cd 100644 (file)
@@ -63,6 +63,7 @@ extern struct task_struct * oplockThread; /* remove sparse warning */
 struct task_struct * oplockThread = NULL;
 extern struct task_struct * dnotifyThread; /* remove sparse warning */
 struct task_struct * dnotifyThread = NULL;
+static struct super_operations cifs_super_ops; 
 unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
 module_param(CIFSMaxBufSize, int, 0);
 MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
@@ -198,10 +199,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
     /* Only need to call the old QFSInfo if failed
     on newer one */
     if(rc)
-       rc = CIFSSMBQFSInfo(xid, pTcon, buf);
+       if(pTcon->ses->capabilities & CAP_NT_SMBS)
+               rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
 
-       /* Old Windows servers do not support level 103, retry with level 
-          one if old server failed the previous call */ 
+       /* Some old Windows servers also do not support level 103, retry with
+          older level one if old server failed the previous call or we
+          bypassed it because we detected that this was an older LANMAN sess */
        if(rc)
                rc = SMBOldQFSInfo(xid, pTcon, buf);
        /*     
@@ -435,13 +438,21 @@ static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
        return;
 }
 
+#ifdef CONFIG_CIFS_STATS2
+static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
+{
+       /* BB FIXME */
+       return 0;
+}
+#endif
+
 static int cifs_remount(struct super_block *sb, int *flags, char *data)
 {
        *flags |= MS_NODIRATIME;
        return 0;
 }
 
-struct super_operations cifs_super_ops = {
+static struct super_operations cifs_super_ops = {
        .read_inode = cifs_read_inode,
        .put_super = cifs_put_super,
        .statfs = cifs_statfs,
@@ -454,6 +465,9 @@ struct super_operations cifs_super_ops = {
        .show_options = cifs_show_options,
        .umount_begin   = cifs_umount_begin,
        .remount_fs = cifs_remount,
+#ifdef CONFIG_CIFS_STATS2
+       .show_stats = cifs_show_stats,
+#endif
 };
 
 static int
@@ -495,7 +509,7 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
 {
        /* origin == SEEK_END => we must revalidate the cached file length */
-       if (origin == 2) {
+       if (origin == SEEK_END) {
                int retval = cifs_revalidate(file->f_dentry);
                if (retval < 0)
                        return (loff_t)retval;
@@ -903,7 +917,7 @@ init_cifs(void)
 #ifdef CONFIG_PROC_FS
        cifs_proc_init();
 #endif
-       INIT_LIST_HEAD(&GlobalServerList);      /* BB not implemented yet */
+/*     INIT_LIST_HEAD(&GlobalServerList);*/    /* BB not implemented yet */
        INIT_LIST_HEAD(&GlobalSMBSessionList);
        INIT_LIST_HEAD(&GlobalTreeConnectionList);
        INIT_LIST_HEAD(&GlobalOplock_Q);
@@ -931,6 +945,7 @@ init_cifs(void)
        GlobalCurrentXid = 0;
        GlobalTotalActiveXid = 0;
        GlobalMaxActiveXid = 0;
+       memset(Local_System_Name, 0, 15);
        rwlock_init(&GlobalSMBSeslock);
        spin_lock_init(&GlobalMid_Lock);
 
index bea875d9a46acda0578f7c92f7c84232824a0ff0..a243f779b363a9a9cff261f65f23027dc9e30c15 100644 (file)
@@ -36,7 +36,7 @@ extern const struct address_space_operations cifs_addr_ops;
 extern const struct address_space_operations cifs_addr_ops_smallbuf;
 
 /* Functions related to super block operations */
-extern struct super_operations cifs_super_ops;
+/* extern struct super_operations cifs_super_ops;*/
 extern void cifs_read_inode(struct inode *);
 extern void cifs_delete_inode(struct inode *);
 /* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
index b24006c47df10b720cf2d05e98bda80c124c19c2..74d3ccbb103bfdbaf82b56cb03272ceebf9c022e 100644 (file)
@@ -153,7 +153,7 @@ struct TCP_Server_Info {
        char sessid[4];         /* unique token id for this session */
        /* (returned on Negotiate */
        int capabilities; /* allow selective disabling of caps by smb sess */
-       __u16 timeZone;
+       int timeAdj;  /* Adjust for difference in server time zone in sec */
        __u16 CurrentMid;         /* multiplex id - rotating counter */
        char cryptKey[CIFS_CRYPTO_KEY_SIZE];
        /* 16th byte of RFC1001 workstation name is always null */
@@ -203,9 +203,14 @@ struct cifsSesInfo {
        char * domainName;
        char * password;
 };
-/* session flags */
+/* no more than one of the following three session flags may be set */
 #define CIFS_SES_NT4 1
-
+#define CIFS_SES_OS2 2
+#define CIFS_SES_W9X 4
+/* following flag is set for old servers such as OS2 (and Win95?)
+   which do not negotiate NTLM or POSIX dialects, but instead
+   negotiate one of the older LANMAN dialects */
+#define CIFS_SES_LANMAN 8
 /*
  * there is one of these for each connection to a resource on a particular
  * session 
@@ -512,7 +517,8 @@ require use of the stronger protocol */
  * This list helps improve performance and eliminate the messages indicating
  * that we had a communications error talking to the server in this list. 
  */
-GLOBAL_EXTERN struct servers_not_supported *NotSuppList;       /*@z4a */
+/* Feature not supported */
+/* GLOBAL_EXTERN struct servers_not_supported *NotSuppList; */
 
 /*
  * The following is a hash table of all the users we know about.
@@ -568,7 +574,6 @@ GLOBAL_EXTERN unsigned int lookupCacheEnabled;
 GLOBAL_EXTERN unsigned int extended_security;  /* if on, session setup sent 
                                with more secure ntlmssp2 challenge/resp */
 GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
-GLOBAL_EXTERN unsigned int secFlags;
 GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
 GLOBAL_EXTERN unsigned int CIFSMaxBufSize;  /* max size not including hdr */
 GLOBAL_EXTERN unsigned int cifs_min_rcv;    /* min size of big ntwrk buf pool */
index 81df2bf8e75a70d222f85757c5afdd1df9f20246..6df9dadba647035ad58f719a5e322bca1b9ac8de 100644 (file)
@@ -26,7 +26,8 @@
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 #define LANMAN_PROT 0
-#define CIFS_PROT   1
+#define LANMAN2_PROT 1
+#define CIFS_PROT   2
 #else
 #define CIFS_PROT   0
 #endif
@@ -408,6 +409,8 @@ typedef struct negotiate_req {
 
 /* Dialect index is 13 for LANMAN */
 
+#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
+
 typedef struct lanman_neg_rsp {
        struct smb_hdr hdr;     /* wct = 13 */
        __le16 DialectIndex;
@@ -417,7 +420,10 @@ typedef struct lanman_neg_rsp {
        __le16 MaxNumberVcs;
        __le16 RawMode;
        __le32 SessionKey;
-       __le32 ServerTime;
+       struct {
+               __le16 Time;
+               __le16 Date;
+       } __attribute__((packed)) SrvTime;
        __le16 ServerTimeZone;
        __le16 EncryptionKeyLength;
        __le16 Reserved;
@@ -674,7 +680,7 @@ typedef union smb_com_tree_disconnect {     /* as an altetnative can use flag on
 typedef struct smb_com_close_req {
        struct smb_hdr hdr;     /* wct = 3 */
        __u16 FileID;
-       __u32 LastWriteTime;    /* should be zero */
+       __u32 LastWriteTime;    /* should be zero or -1 */
        __u16 ByteCount;        /* 0 */
 } __attribute__((packed)) CLOSE_REQ;
 
index b35c55c3c8bb9d76b1afc8ae9e13189d2f3f6071..f1f8225102f0a6dead4670ef95c6fa42fe0917e3 100644 (file)
@@ -50,12 +50,12 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
 extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
                        struct kvec *, int /* nvec to send */, 
                        int * /* type of buf returned */ , const int long_op);
-extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *,
+extern int SendReceiveBlockingLock(const unsigned int /* xid */ , 
+                                       struct cifsTconInfo *,
                                struct smb_hdr * /* input */ ,
                                struct smb_hdr * /* out */ ,
                                int * /* bytes returned */);
-extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
-extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
+extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
 extern int is_valid_oplock_break(struct smb_hdr *smb, struct TCP_Server_Info *);
 extern int is_size_safe_to_change(struct cifsInodeInfo *);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
@@ -80,6 +80,9 @@ extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
 extern void DeleteOplockQEntry(struct oplock_q_entry *);
 extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
 extern u64 cifs_UnixTimeToNT(struct timespec);
+extern __le64 cnvrtDosCifsTm(__u16 date, __u16 time);
+extern struct timespec cnvrtDosUnixTm(__u16 date, __u16 time);
+
 extern int cifs_get_inode_info(struct inode **pinode,
                        const unsigned char *search_path, 
                        FILE_ALL_INFO * pfile_info,
@@ -116,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
 extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
                        FILE_ALL_INFO * findData,
+                       int legacy /* whether to use old info level */,
                        const struct nls_table *nls_codepage, int remap);
 extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
                         const unsigned char *searchName,
@@ -279,8 +283,6 @@ extern void sesInfoFree(struct cifsSesInfo *);
 extern struct cifsTconInfo *tconInfoAlloc(void);
 extern void tconInfoFree(struct cifsTconInfo *);
 
-extern int cifs_reconnect(struct TCP_Server_Info *server);
-
 extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *);
 extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
                          __u32 *);
index 075d8fb3d37608a96d0610c519794388351d1173..5dc5a966bd5ff1b191838346bc19f465402aea9f 100644 (file)
@@ -46,6 +46,7 @@ static struct {
 } protocols[] = {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        {LANMAN_PROT, "\2LM1.2X002"},
+       {LANMAN2_PROT, "\2LANMAN2.1"},
 #endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"}, 
        {POSIX_PROT, "\2POSIX 2"},
@@ -58,6 +59,7 @@ static struct {
 } protocols[] = {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
        {LANMAN_PROT, "\2LM1.2X002"},
+       {LANMAN2_PROT, "\2LANMAN2.1"},
 #endif /* weak password hashing for legacy clients */
        {CIFS_PROT, "\2NT LM 0.12"}, 
        {BAD_PROT, "\2"}
@@ -67,13 +69,13 @@ static struct {
 /* define the number of elements in the cifs dialect array */
 #ifdef CONFIG_CIFS_POSIX
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 3
+#define CIFS_NUM_PROT 4
 #else
 #define CIFS_NUM_PROT 2
 #endif /* CIFS_WEAK_PW_HASH */
 #else /* not posix */
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 2
+#define CIFS_NUM_PROT 3
 #else
 #define CIFS_NUM_PROT 1
 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
@@ -446,7 +448,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                goto neg_err_exit;
 #ifdef CONFIG_CIFS_WEAK_PW_HASH 
        } else if((pSMBr->hdr.WordCount == 13)
-                       && (pSMBr->DialectIndex == LANMAN_PROT)) {
+                       && ((pSMBr->DialectIndex == LANMAN_PROT)
+                               || (pSMBr->DialectIndex == LANMAN2_PROT))) {
+               __s16 tmp;
                struct lanman_neg_rsp * rsp = (struct lanman_neg_rsp *)pSMBr;
 
                if((secFlags & CIFSSEC_MAY_LANMAN) || 
@@ -472,12 +476,44 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                        server->maxRw = 0;/* we do not need to use raw anyway */
                        server->capabilities = CAP_MPX_MODE;
                }
-               server->timeZone = le16_to_cpu(rsp->ServerTimeZone);
+               tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
+               if (tmp == -1) {
+                       /* OS/2 often does not set timezone therefore
+                        * we must use server time to calc time zone.
+                        * Could deviate slightly from the right zone.
+                        * Smallest defined timezone difference is 15 minutes
+                        * (i.e. Nepal).  Rounding up/down is done to match
+                        * this requirement.
+                        */
+                       int val, seconds, remain, result;
+                       struct timespec ts, utc;
+                       utc = CURRENT_TIME;
+                       ts = cnvrtDosUnixTm(le16_to_cpu(rsp->SrvTime.Date),
+                                               le16_to_cpu(rsp->SrvTime.Time));
+                       cFYI(1,("SrvTime: %d sec since 1970 (utc: %d) diff: %d",
+                               (int)ts.tv_sec, (int)utc.tv_sec, 
+                               (int)(utc.tv_sec - ts.tv_sec)));
+                       val = (int)(utc.tv_sec - ts.tv_sec);
+                       seconds = val < 0 ? -val : val;
+                       result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
+                       remain = seconds % MIN_TZ_ADJ;
+                       if(remain >= (MIN_TZ_ADJ / 2))
+                               result += MIN_TZ_ADJ;
+                       if(val < 0)
+                               result = - result;
+                       server->timeAdj = result;
+               } else {
+                       server->timeAdj = (int)tmp;
+                       server->timeAdj *= 60; /* also in seconds */
+               }
+               cFYI(1,("server->timeAdj: %d seconds", server->timeAdj));
+
 
                /* BB get server time for time conversions and add
                code to use it and timezone since this is not UTC */    
 
-               if (rsp->EncryptionKeyLength == cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
+               if (rsp->EncryptionKeyLength == 
+                               cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
                        memcpy(server->cryptKey, rsp->EncryptionKey,
                                CIFS_CRYPTO_KEY_SIZE);
                } else if (server->secMode & SECMODE_PW_ENCRYPT) {
@@ -531,7 +567,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
        cFYI(0, ("Max buf = %d", ses->server->maxBuf));
        GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
        server->capabilities = le32_to_cpu(pSMBr->Capabilities);
-       server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);  
+       server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
+       server->timeAdj *= 60;
        if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
                memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
                       CIFS_CRYPTO_KEY_SIZE);
@@ -1617,7 +1654,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
        pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */
 
        pSMB->FileID = (__u16) smb_file_id;
-       pSMB->LastWriteTime = 0;
+       pSMB->LastWriteTime = 0xFFFFFFFF;
        pSMB->ByteCount = 0;
        rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -2773,9 +2810,11 @@ GetExtAttrOut:
 
 
 /* security id for everyone */
-const struct cifs_sid sid_everyone = {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
+const static struct cifs_sid sid_everyone = 
+               {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
 /* group users */
-const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
+const static struct cifs_sid sid_user = 
+               {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
 
 /* Convert CIFS ACL to POSIX form */
 static int parse_sec_desc(struct cifs_sid * psec_desc, int acl_len)
@@ -2856,7 +2895,6 @@ qsec_out:
        return rc;
 }
 
-
 /* Legacy Query Path Information call for lookup to old servers such
    as Win9x/WinME */
 int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
@@ -2898,7 +2936,16 @@ QInfRetry:
        if (rc) {
                cFYI(1, ("Send error in QueryInfo = %d", rc));
        } else if (pFinfo) {            /* decode response */
+               struct timespec ts;
+               __u32 time = le32_to_cpu(pSMBr->last_write_time);
+               /* BB FIXME - add time zone adjustment BB */
                memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
+               ts.tv_nsec = 0;
+               ts.tv_sec = time;
+               /* decode time fields */
+               pFinfo->ChangeTime = cifs_UnixTimeToNT(ts);
+               pFinfo->LastWriteTime = pFinfo->ChangeTime;
+               pFinfo->LastAccessTime = 0;
                pFinfo->AllocationSize =
                        cpu_to_le64(le32_to_cpu(pSMBr->size));
                pFinfo->EndOfFile = pFinfo->AllocationSize;
@@ -2922,6 +2969,7 @@ int
 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
                 const unsigned char *searchName,
                 FILE_ALL_INFO * pFindData,
+                int legacy /* old style infolevel */,
                 const struct nls_table *nls_codepage, int remap)
 {
 /* level 263 SMB_QUERY_FILE_ALL_INFO */
@@ -2970,7 +3018,10 @@ QPathInfoRetry:
        byte_count = params + 1 /* pad */ ;
        pSMB->TotalParameterCount = cpu_to_le16(params);
        pSMB->ParameterCount = pSMB->TotalParameterCount;
-       pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
+       if(legacy)
+               pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
+       else
+               pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
        pSMB->Reserved4 = 0;
        pSMB->hdr.smb_buf_length += byte_count;
        pSMB->ByteCount = cpu_to_le16(byte_count);
@@ -2982,13 +3033,24 @@ QPathInfoRetry:
        } else {                /* decode response */
                rc = validate_t2((struct smb_t2_rsp *)pSMBr);
 
-               if (rc || (pSMBr->ByteCount < 40)) 
+               if (rc) /* BB add auto retry on EOPNOTSUPP? */
+                       rc = -EIO;
+               else if (!legacy && (pSMBr->ByteCount < 40)) 
                        rc = -EIO;      /* bad smb */
+               else if(legacy && (pSMBr->ByteCount < 24))
+                       rc = -EIO;  /* 24 or 26 expected but we do not read last field */
                else if (pFindData){
+                       int size;
                        __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
+                       if(legacy) /* we do not read the last field, EAsize, fortunately
+                                          since it varies by subdialect and on Set vs. Get, is  
+                                          two bytes or 4 bytes depending but we don't care here */
+                               size = sizeof(FILE_INFO_STANDARD);
+                       else
+                               size = sizeof(FILE_ALL_INFO);
                        memcpy((char *) pFindData,
                               (char *) &pSMBr->hdr.Protocol +
-                              data_offset, sizeof (FILE_ALL_INFO));
+                              data_offset, size);
                } else
                    rc = -ENOMEM;
        }
@@ -3613,6 +3675,14 @@ getDFSRetry:
                strncpy(pSMB->RequestFileName, searchName, name_len);
        }
 
+       if(ses->server) {
+               if(ses->server->secMode &
+                  (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+                       pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
+       }
+
+        pSMB->hdr.Uid = ses->Suid;
+
        params = 2 /* level */  + name_len /*includes null */ ;
        pSMB->TotalDataCount = 0;
        pSMB->DataCount = 0;
index c78762051da4e5b15da45fa06b46b66d85e55d82..4093d53329306bfc74c0487e06c09d434d7043a6 100644 (file)
@@ -109,7 +109,7 @@ static int ipv6_connect(struct sockaddr_in6 *psin_server,
         * wake up waiters on reconnection? - (not needed currently)
         */
 
-int
+static int
 cifs_reconnect(struct TCP_Server_Info *server)
 {
        int rc = 0;
@@ -771,13 +771,18 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
        separator[0] = ',';
        separator[1] = 0; 
 
-       memset(vol->source_rfc1001_name,0x20,15);
-       for(i=0;i < strnlen(utsname()->nodename,15);i++) {
-               /* does not have to be a perfect mapping since the field is
-               informational, only used for servers that do not support
-               port 445 and it can be overridden at mount time */
-               vol->source_rfc1001_name[i] = 
-                       toupper(utsname()->nodename[i]);
+       if (Local_System_Name[0] != 0)
+               memcpy(vol->source_rfc1001_name, Local_System_Name,15);
+       else {
+               char *nodename = utsname()->nodename;
+               int n = strnlen(nodename,15);
+               memset(vol->source_rfc1001_name,0x20,15);
+               for(i=0 ; i < n ; i++) {
+                       /* does not have to be perfect mapping since field is
+                       informational, only used for servers that do not support
+                       port 445 and it can be overridden at mount time */
+                       vol->source_rfc1001_name[i] = toupper(nodename[i]);
+               }
        }
        vol->source_rfc1001_name[15] = 0;
        /* null target name indicates to use *SMBSERVR default called name
@@ -3215,7 +3220,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        }
                        /* else do not bother copying these informational fields */
                }
-               if(smb_buffer_response->WordCount == 3)
+               if((smb_buffer_response->WordCount == 3) ||
+                        (smb_buffer_response->WordCount == 7))
+                       /* field is in same location */
                        tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
                else
                        tcon->Flags = 0;
@@ -3312,19 +3319,21 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                first_time = 1;
        }
        if (!rc) {
+               pSesInfo->flags = 0;
                pSesInfo->capabilities = pSesInfo->server->capabilities;
                if(linuxExtEnabled == 0)
                        pSesInfo->capabilities &= (~CAP_UNIX);
        /*      pSesInfo->sequence_number = 0;*/
-               cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
+               cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
                        pSesInfo->server->secMode,
                        pSesInfo->server->capabilities,
-                       pSesInfo->server->timeZone));
+                       pSesInfo->server->timeAdj));
                if(experimEnabled < 2)
                        rc = CIFS_SessSetup(xid, pSesInfo,
                                            first_time, nls_info);
                else if (extended_security
-                               && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
+                               && (pSesInfo->capabilities 
+                                       & CAP_EXTENDED_SECURITY)
                                && (pSesInfo->server->secType == NTLMSSP)) {
                        rc = -EOPNOTSUPP;
                } else if (extended_security
@@ -3338,7 +3347,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                        if (!rc) {
                                if(ntlmv2_flag) {
                                        char * v2_response;
-                                       cFYI(1,("Can use more secure NTLM version 2 password hash"));
+                                       cFYI(1,("more secure NTLM ver2 hash"));
                                        if(CalcNTLMv2_partial_mac_key(pSesInfo, 
                                                nls_info)) {
                                                rc = -ENOMEM;
index 6b90ef98e4cfe9cdfcd224bdb0a2df202b66612f..35d54bb0869ab67510449f4a412aa0018c9fcfc8 100644 (file)
@@ -337,6 +337,7 @@ int cifs_get_inode_info(struct inode **pinode,
                pfindData = (FILE_ALL_INFO *)buf;
                /* could do find first instead but this returns more info */
                rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
+                             0 /* not legacy */,
                              cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
                                CIFS_MOUNT_MAP_SPECIAL_CHR);
                /* BB optimize code so we do not make the above call
@@ -384,8 +385,10 @@ int cifs_get_inode_info(struct inode **pinode,
                /* get new inode */
                if (*pinode == NULL) {
                        *pinode = new_inode(sb);
-                       if (*pinode == NULL)
+                       if (*pinode == NULL) {
+                               kfree(buf);
                                return -ENOMEM;
+                       }
                        /* Is an i_ino of zero legal? Can we use that to check
                           if the server supports returning inode numbers?  Are
                           there other sanity checks we can use to ensure that
@@ -431,8 +434,11 @@ int cifs_get_inode_info(struct inode **pinode,
                (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
 
                /* Linux can not store file creation time so ignore it */
-               inode->i_atime =
-                   cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
+               if(pfindData->LastAccessTime)
+                       inode->i_atime = cifs_NTtimeToUnix
+                               (le64_to_cpu(pfindData->LastAccessTime));
+               else /* do not need to use current_fs_time - time not stored */
+                       inode->i_atime = CURRENT_TIME;
                inode->i_mtime =
                    cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
                inode->i_ctime =
index a57f5d6e6213d6f23e693c88a98c3d539eb4ae6a..0bee8b7e521a2a153fa50e03bde68ec69865a364 100644 (file)
@@ -254,7 +254,11 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                tmpbuffer,
                                len - 1,
                                cifs_sb->local_nls);
-       else {
+       else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
+               cERROR(1,("SFU style symlinks not implemented yet"));
+               /* add open and read as in fs/cifs/inode.c */
+       
+       } else {
                rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
                                OPEN_REPARSE_POINT,&fid, &oplock, NULL, 
                                cifs_sb->local_nls, 
index 7aa23490541f9d68edee8c465e489ec79ab4b95f..ccebf9b7eb86e2293d0cd52ee15137b6dbdd4ad4 100644 (file)
@@ -252,10 +252,11 @@ MD5Transform(__u32 buf[4], __u32 const in[16])
        buf[3] += d;
 }
 
+#if 0   /* currently unused */
 /***********************************************************************
  the rfc 2104 version of hmac_md5 initialisation.
 ***********************************************************************/
-void
+static void
 hmac_md5_init_rfc2104(unsigned char *key, int key_len,
                      struct HMACMD5Context *ctx)
 {
@@ -289,6 +290,7 @@ hmac_md5_init_rfc2104(unsigned char *key, int key_len,
        MD5Init(&ctx->ctx);
        MD5Update(&ctx->ctx, ctx->k_ipad, 64);
 }
+#endif
 
 /***********************************************************************
  the microsoft version of hmac_md5 initialisation.
@@ -350,7 +352,8 @@ hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
  single function to calculate an HMAC MD5 digest from data.
  use the microsoft hmacmd5 init method because the key is 16 bytes.
 ************************************************************/
-void
+#if 0 /* currently unused */
+static void
 hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
         unsigned char *digest)
 {
@@ -361,3 +364,4 @@ hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
        }
        hmac_md5_final(digest, &ctx);
 }
+#endif
index 00e1c5394fe1e8977d031f08a3e74f92b9ae10cc..f7d4f4197bac3cc6973e8c1c5de2ddc9c8721493 100644 (file)
@@ -27,12 +27,12 @@ void MD5Final(unsigned char digest[16], struct MD5Context *context);
 
 /* The following definitions come from lib/hmacmd5.c  */
 
-void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-                       struct HMACMD5Context *ctx);
+/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
+                       struct HMACMD5Context *ctx);*/
 void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
                        struct HMACMD5Context *ctx);
 void hmac_md5_update(const unsigned char *text, int text_len,
                        struct HMACMD5Context *ctx);
 void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
-void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-                       unsigned char *digest);
+/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
+                       unsigned char *digest);*/
index 22c937e5884f36baf85e49cb9f3c3fc014de4522..bbc9cd34b6ea42f02d85e9e31c140824b4ab5dd8 100644 (file)
@@ -389,7 +389,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
        return;
 }
 
-int
+static int
 checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 {
        /* Make sure that this really is an SMB, that it is a response, 
@@ -418,26 +418,42 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
 }
 
 int
-checkSMB(struct smb_hdr *smb, __u16 mid, int length)
+checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
 {
        __u32 len = smb->smb_buf_length;
        __u32 clc_len;  /* calculated length */
        cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
-       if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
-           (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
-               if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
-                       if (((unsigned int)length >= 
-                               sizeof (struct smb_hdr) - 1)
+
+       if (length < 2 + sizeof (struct smb_hdr)) {
+               if ((length >= sizeof (struct smb_hdr) - 1)
                            && (smb->Status.CifsError != 0)) {
-                               smb->WordCount = 0;
-                               /* some error cases do not return wct and bcc */
+                       smb->WordCount = 0;
+                       /* some error cases do not return wct and bcc */
+                       return 0;
+               } else if ((length == sizeof(struct smb_hdr) + 1) && 
+                               (smb->WordCount == 0)) {
+                       char * tmp = (char *)smb;
+                       /* Need to work around a bug in two servers here */
+                       /* First, check if the part of bcc they sent was zero */
+                       if (tmp[sizeof(struct smb_hdr)] == 0) {
+                               /* some servers return only half of bcc
+                                * on simple responses (wct, bcc both zero)
+                                * in particular have seen this on
+                                * ulogoffX and FindClose. This leaves
+                                * one byte of bcc potentially unitialized
+                                */
+                               /* zero rest of bcc */
+                               tmp[sizeof(struct smb_hdr)+1] = 0;
                                return 0;
-                       } else {
-                               cERROR(1, ("Length less than smb header size"));
                        }
+                       cERROR(1,("rcvd invalid byte count (bcc)"));
+               } else {
+                       cERROR(1, ("Length less than smb header size"));
                }
-               if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
-                       cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
+               return 1;
+       }
+       if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+               cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
                                   smb->Mid));
                return 1;
        }
@@ -446,7 +462,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
                return 1;
        clc_len = smbCalcSize_LE(smb);
 
-       if(4 + len != (unsigned int)length) {
+       if(4 + len != length) {
                cERROR(1, ("Length read does not match RFC1001 length %d",len));
                return 1;
        }
index ce87550e918f8d33d87573677287e24d2da234e9..992e80edc720bb782cc13d5dcb1843691a240adf 100644 (file)
@@ -909,3 +909,61 @@ cifs_UnixTimeToNT(struct timespec t)
        /* Convert to 100ns intervals and then add the NTFS time offset. */
        return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
 }
+
+static int total_days_of_prev_months[] =
+{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+
+
+__le64 cnvrtDosCifsTm(__u16 date, __u16 time)
+{
+       return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time)));
+}
+
+struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
+{
+       struct timespec ts;
+       int sec, min, days, month, year;
+       SMB_TIME * st = (SMB_TIME *)&time;
+       SMB_DATE * sd = (SMB_DATE *)&date;
+
+       cFYI(1,("date %d time %d",date, time));
+
+       sec = 2 * st->TwoSeconds;
+       min = st->Minutes;
+       if((sec > 59) || (min > 59))
+               cERROR(1,("illegal time min %d sec %d", min, sec));
+       sec += (min * 60);
+       sec += 60 * 60 * st->Hours;
+       if(st->Hours > 24)
+               cERROR(1,("illegal hours %d",st->Hours));
+       days = sd->Day;
+       month = sd->Month;
+       if((days > 31) || (month > 12))
+               cERROR(1,("illegal date, month %d day: %d", month, days));
+       month -= 1;
+       days += total_days_of_prev_months[month];
+       days += 3652; /* account for difference in days between 1980 and 1970 */
+       year = sd->Year;
+       days += year * 365;
+       days += (year/4); /* leap year */
+       /* generalized leap year calculation is more complex, ie no leap year
+       for years/100 except for years/400, but since the maximum number for DOS
+        year is 2**7, the last year is 1980+127, which means we need only
+        consider 2 special case years, ie the years 2000 and 2100, and only
+        adjust for the lack of leap year for the year 2100, as 2000 was a 
+        leap year (divisable by 400) */
+       if(year >= 120)  /* the year 2100 */
+               days = days - 1;  /* do not count leap year for the year 2100 */
+
+       /* adjust for leap year where we are still before leap day */
+       if(year != 120)
+               days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
+       sec += 24 * 60 * 60 * days; 
+
+       ts.tv_sec = sec;
+
+       /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */
+
+       ts.tv_nsec = 0;
+       return ts;
+} 
index b27b34537bf23c2bf3bbc566c1155c3d331df7a1..b5b0a2a41befe85734ffc30dc47f68f76bf05790 100644 (file)
@@ -106,6 +106,17 @@ static int construct_dentry(struct qstr *qstring, struct file *file,
        return rc;
 }
 
+static void AdjustForTZ(struct cifsTconInfo * tcon, struct inode * inode)
+{
+       if((tcon) && (tcon->ses) && (tcon->ses->server)) {
+               inode->i_ctime.tv_sec += tcon->ses->server->timeAdj;
+               inode->i_mtime.tv_sec += tcon->ses->server->timeAdj;
+               inode->i_atime.tv_sec += tcon->ses->server->timeAdj;
+       }
+       return;
+}
+
+
 static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
                char * buf, int *pobject_type, int isNewInode)
 {
@@ -135,16 +146,23 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
                tmp_inode->i_ctime =
                      cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
        } else { /* legacy, OS2 and DOS style */
+/*             struct timespec ts;*/
                FIND_FILE_STANDARD_INFO * pfindData = 
                        (FIND_FILE_STANDARD_INFO *)buf;
 
+               tmp_inode->i_mtime = cnvrtDosUnixTm(
+                               le16_to_cpu(pfindData->LastWriteDate),
+                               le16_to_cpu(pfindData->LastWriteTime));
+               tmp_inode->i_atime = cnvrtDosUnixTm(
+                               le16_to_cpu(pfindData->LastAccessDate),
+                               le16_to_cpu(pfindData->LastAccessTime));
+                tmp_inode->i_ctime = cnvrtDosUnixTm(
+                                le16_to_cpu(pfindData->LastWriteDate),
+                                le16_to_cpu(pfindData->LastWriteTime));
+               AdjustForTZ(cifs_sb->tcon, tmp_inode);
                attr = le16_to_cpu(pfindData->Attributes);
                allocation_size = le32_to_cpu(pfindData->AllocationSize);
                end_of_file = le32_to_cpu(pfindData->DataSize);
-               tmp_inode->i_atime = CURRENT_TIME;
-               /* tmp_inode->i_mtime =  BB FIXME - add dos time handling
-               tmp_inode->i_ctime = 0;   BB FIXME */
-
        }
 
        /* Linux can not store file creation time unfortunately so ignore it */
@@ -938,6 +956,7 @@ static int cifs_save_resume_key(const char *current_entry,
                filename = &pFindData->FileName[0];
                /* one byte length, no name conversion */
                len = (unsigned int)pFindData->FileNameLength;
+               cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
        } else {
                cFYI(1,("Unknown findfirst level %d",level));
                return -EINVAL;
index 22b4c35dcfe3e4bfbc067b56880f5fb958df50ae..a8a083543ba050fa65cceee9a302c9b733f68311 100644 (file)
@@ -268,6 +268,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 +294,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,6 +365,8 @@ 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];
@@ -377,7 +378,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
                /* 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);
index efaa044523a7094ecbbddd1ead52f89fc424cc7e..7a1b2b961ec875b7f1a964d8f20f27b8fec58239 100644 (file)
@@ -364,20 +364,20 @@ E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
        smbhash(p24 + 16, c8, p21 + 14, 1);
 }
 
-void
+#if 0 /* currently unsued */
+static 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
+static void
 E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
 {
        smbhash(out, in, p14, 1);
        smbhash(out + 8, in + 8, p14 + 7, 1);
 }
-#if 0
 /* these routines are currently unneeded, but may be
        needed later */
 void
index f518c5e45035c50955b51c55d08ab86b66127842..4b25ba92180d649497b74f77a594b7ba7327ed5f 100644 (file)
 
 void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
 void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
 static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
                   unsigned char p24[24]);
-void NTLMSSPOWFencrypt(unsigned char passwd[8],
-                      unsigned char *ntlmchalresp, unsigned char p24[24]);
 void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
 
 /*
@@ -144,8 +141,9 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
        memset(wpwd,0,129 * 2);
 }
 
+#if 0 /* currently unused */
 /* Does both the NT and LM owfs of a user's password */
-void
+static void
 nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
 {
        char passwd[514];
@@ -171,6 +169,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
        /* clear out local copy of user's password (just being paranoid). */
        memset(passwd, '\0', sizeof (passwd));
 }
+#endif
 
 /* Does the NTLMv2 owfs of a user's password */
 #if 0  /* function not needed yet - but will be soon */
@@ -223,7 +222,8 @@ SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
 }
 
 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void
+#if 0 /* currently unused */
+static void
 NTLMSSPOWFencrypt(unsigned char passwd[8],
                  unsigned char *ntlmchalresp, unsigned char p24[24])
 {
@@ -235,6 +235,7 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
 
        E_P24(p21, ntlmchalresp, p24);
 }
+#endif
 
 /* Does the NT MD4 hash then des encryption. */