]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: store data verification mode
authorJeffrey Altman <jaltman@your-file-system.com>
Sun, 22 Jan 2012 23:42:32 +0000 (18:42 -0500)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 23 Jan 2012 05:25:09 +0000 (21:25 -0800)
Over the lifetime of OpenAFS a number of bugs have been discovered
that can result in data corruption.  This new mode (Windows only)
will double check that the data received by the file server does
in fact match the data that was written by the cache manager.

After a successful StoreData and status merge but before the BIOD
is released, a fetchdata is issued to read the data written by the
cache manager.  If the data fails to match, the StoreData operation
is repeated.

Data verification mode can be queried with "fs getverify" and set
with "fs setverify {on, off}".  The default value can be set with
the TransarcAFSDaemon\Parameters DWORD "VerifyData" registry value.

By default verification is disabled.

Change-Id: Ic99c1692e6e78790e65ae600c3e428a79df59370
Reviewed-on: http://gerrit.openafs.org/6601
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@secure-endpoints.com>
Tested-by: Jeffrey Altman <jaltman@secure-endpoints.com>
12 files changed:
src/WINNT/afsd/afsd.h
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_dcache.c
src/WINNT/afsd/cm_dcache.h
src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_ioctl.h
src/WINNT/afsd/fs.c
src/WINNT/afsd/smb_iocons.h
src/WINNT/afsd/smb_ioctl.c
src/WINNT/afsd/smb_ioctl.h
src/WINNT/afsrdr/user/RDRIoctl.c
src/WINNT/afsrdr/user/RDRIoctl.h

index 516e22c8c2e95472c5e590b9012395535e1e9587..65f2d18117de5b7b3a455fc4060c51c051707d7f 100644 (file)
@@ -124,6 +124,8 @@ extern afs_uint32 smb_Enabled;
 
 extern int cm_virtualCache;
 
+extern afs_int32 cm_verifyData;
+
 #define DFS_SUPPORT 1
 #define LOG_PACKET 1
 #undef  NOTSERVICE
index 8d195bf4ca8cb9c4ee95cd69770e8db195fa449e..e6d9da2daed82e9931d5c2e37d84898f32d54909 100644 (file)
@@ -76,6 +76,7 @@ int cm_readonlyVolumeVersioning = 0;
 int cm_logChunkSize;
 int cm_chunkSize;
 int cm_virtualCache = 0;
+afs_int32 cm_verifyData = 0;
 
 int smb_UseV3 = 1;
 afs_uint32 smb_Enabled = 1;
@@ -1020,7 +1021,12 @@ afsd_InitCM(char **reasonP)
     else
        LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_CRYPT_OFF);
 
-    dummyLen = sizeof(cryptall);
+    dummyLen = sizeof(cm_verifyData);
+    code = RegQueryValueEx(parmKey, "VerifyData", NULL, NULL,
+                           (BYTE *) &cm_verifyData, &dummyLen);
+    afsi_log("VerifyData is %s", cm_verifyData?"on":"off");
+
+    dummyLen = sizeof(cm_anonvldb);
     code = RegQueryValueEx(parmKey, "ForceAnonVLDB", NULL, NULL,
                             (BYTE *) &cm_anonvldb, &dummyLen);
     afsi_log("CM ForceAnonVLDB is %s", cm_anonvldb ? "on" : "off");
index 79fe80b6aee44e402ac0b51d332ad4bbc9b4ecb4..96e5dd6acc80b3514d270448fcbf188d04701233 100644 (file)
@@ -54,6 +54,7 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
     cm_scache_t *scp = vscp;
     afs_int32 nbytes;
     afs_int32 save_nbytes;
+    cm_scache_t save_scache;
     long temp;
     AFSFetchStatus outStatus;
     AFSStoreStatus inStatus;
@@ -152,11 +153,14 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
         require_64bit_ops = 1;
     }
 
+    /* now we're ready to do the store operation */
+  retry_rpc:
     InterlockedIncrement(&scp->activeRPCs);
     lock_ReleaseWrite(&scp->rw);
 
-    /* now we're ready to do the store operation */
     save_nbytes = nbytes;
+    save_scache = *scp;
+
     do {
         code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
         if (code)
@@ -423,6 +427,15 @@ long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
             _InterlockedOr(&scp->flags, CM_SCACHEFLAG_OVERQUOTA);
     }
 
+    if ( cm_verifyData )
+    {
+        if (!cm_VerifyStoreData(&biod, &save_scache)) {
+            /* file server content doesn't match what we sent. */
+            nbytes = save_nbytes;
+            goto retry_rpc;
+        }
+    }
+
     cm_ReleaseBIOD(&biod, 1, code, 1);
 
   exit_storedata_excl:
@@ -1009,6 +1022,7 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
     /* clear things out */
     biop->scp = scp;                   /* do not hold; held by caller */
     biop->userp = userp;                /* do not hold; held by caller */
+    biop->reqp = reqp;
     biop->offset = *inOffsetp;
     biop->length = 0;
     biop->bufListp = NULL;
@@ -1080,6 +1094,10 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
     /* put this element in the list */
     qdp = osi_QDAlloc();
     osi_SetQData(qdp, bufp);
+
+    if ( cm_verifyData )
+        buf_ComputeCheckSum(bufp);
+
     /* don't have to hold bufp, since held by buf_Find above */
     osi_QAddH((osi_queue_t **) &biop->bufListp,
               (osi_queue_t **) &biop->bufListEndp,
@@ -1145,6 +1163,10 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
          */
         qdp = osi_QDAlloc();
         osi_SetQData(qdp, bufp);
+
+        if ( cm_verifyData )
+            buf_ComputeCheckSum(bufp);
+
         /* no buf_hold necessary, since we have it held from buf_Find */
         osi_QAddT((osi_queue_t **) &biop->bufListp,
                   (osi_queue_t **) &biop->bufListEndp,
@@ -1205,6 +1227,10 @@ long cm_SetupStoreBIOD(cm_scache_t *scp, osi_hyper_t *inOffsetp, long inSize,
          */
         qdp = osi_QDAlloc();
         osi_SetQData(qdp, bufp);
+
+        if ( cm_verifyData )
+            buf_ComputeCheckSum(bufp);
+
         /* no buf_hold necessary, since we have it held from buf_Find */
         osi_QAddH((osi_queue_t **) &biop->bufListp,
                   (osi_queue_t **) &biop->bufListEndp,
@@ -2509,3 +2535,269 @@ long cm_GetData(cm_scache_t *scp, osi_hyper_t *offsetp, char *datap, int data_le
 
     return code;
 }
+
+/*
+ * cm_VerifyStoreData.   Function passed a rw locked cm_scache_t and a store data biod.
+ *
+ * Return 1 if the data verifies; 0 if not.
+ */
+
+long
+cm_VerifyStoreData(cm_bulkIO_t *biod, cm_scache_t *savedScp)
+{
+    long code=0, code1=0;
+    afs_uint32 nbytes;                 /* bytes in transfer */
+    afs_uint32 nbytes_hi = 0;           /* high-order 32 bits of bytes in transfer */
+    afs_uint64 length_found = 0;
+    long rbytes;                       /* bytes in rx_Read call */
+    long temp;
+    AFSFetchStatus afsStatus;
+    AFSCallBack callback;
+    AFSVolSync volSync;
+    AFSFid tfid;
+    struct rx_call *rxcallp;
+    struct rx_connection *rxconnp;
+    cm_conn_t *connp;
+    int require_64bit_ops = 0;
+    int call_was_64bit = 0;
+    int fs_fetchdata_offset_bug = 0;
+    int first_read = 1;
+    int scp_locked = 1;
+    char * bufferp = malloc(biod->length);
+    long verified = 0;
+    cm_scache_t *scp = biod->scp;
+    cm_user_t *userp = biod->userp;
+    cm_req_t *reqp = biod->reqp;
+    afs_uint64 dataVersion = scp->dataVersion;
+
+    memset(&volSync, 0, sizeof(volSync));
+    memset(bufferp, 0, biod->length);
+
+    cm_AFSFidFromFid(&tfid, &scp->fid);
+
+    if (LargeIntegerGreaterThan(LargeIntegerAdd(biod->offset,
+                                                ConvertLongToLargeInteger(biod->length)),
+                                ConvertLongToLargeInteger(LONG_MAX))) {
+        require_64bit_ops = 1;
+    }
+
+    InterlockedIncrement(&scp->activeRPCs);
+    osi_Log2(afsd_logp, "cm_VerifyStoreData: fetching data scp %p DV 0x%x", scp, scp->dataVersion);
+
+    if (scp_locked) {
+        lock_ReleaseWrite(&scp->rw);
+        scp_locked = 0;
+    }
+
+    /* now make the call */
+    do {
+        code = cm_ConnFromFID(&scp->fid, userp, reqp, &connp);
+        if (code)
+            continue;
+
+        rxconnp = cm_GetRxConn(connp);
+        rxcallp = rx_NewCall(rxconnp);
+        rx_PutConnection(rxconnp);
+
+        nbytes = nbytes_hi = 0;
+
+        if (SERVERHAS64BIT(connp)) {
+            call_was_64bit = 1;
+
+            osi_Log4(afsd_logp, "CALL FetchData64 scp 0x%p, off 0x%x:%08x, size 0x%x",
+                     scp, biod->offset.HighPart, biod->offset.LowPart, biod->length);
+
+            code = StartRXAFS_FetchData64(rxcallp, &tfid, biod->offset.QuadPart, biod->length);
+
+            if (code == 0) {
+                temp = rx_Read32(rxcallp, &nbytes_hi);
+                if (temp == sizeof(afs_int32)) {
+                    nbytes_hi = ntohl(nbytes_hi);
+                } else {
+                    nbytes_hi = 0;
+                   code = rx_Error(rxcallp);
+                    code1 = rx_EndCall(rxcallp, code);
+                    rxcallp = NULL;
+                }
+            }
+        } else {
+            call_was_64bit = 0;
+        }
+
+        if (code == RXGEN_OPCODE || !SERVERHAS64BIT(connp)) {
+            if (require_64bit_ops) {
+                osi_Log0(afsd_logp, "Skipping FetchData.  Operation requires FetchData64");
+                code = CM_ERROR_TOOBIG;
+            } else {
+                if (!rxcallp) {
+                    rxconnp = cm_GetRxConn(connp);
+                    rxcallp = rx_NewCall(rxconnp);
+                    rx_PutConnection(rxconnp);
+                }
+
+                osi_Log3(afsd_logp, "CALL FetchData scp 0x%p, off 0x%x, size 0x%x",
+                         scp, biod->offset.LowPart, biod->length);
+
+                code = StartRXAFS_FetchData(rxcallp, &tfid, biod->offset.LowPart, biod->length);
+
+                SET_SERVERHASNO64BIT(connp);
+            }
+        }
+
+        if (code == 0) {
+            temp  = rx_Read32(rxcallp, &nbytes);
+            if (temp == sizeof(afs_int32)) {
+                nbytes = ntohl(nbytes);
+                FillInt64(length_found, nbytes_hi, nbytes);
+                if (length_found > biod->length) {
+                    /*
+                     * prior to 1.4.12 and 1.5.65 the file server would return
+                     * (filesize - offset) if the requested offset was greater than
+                     * the filesize.  The correct return value would have been zero.
+                     * Force a retry by returning an RX_PROTOCOL_ERROR.  If the cause
+                     * is a race between two RPCs issues by this cache manager, the
+                     * correct thing will happen the second time.
+                     */
+                    osi_Log0(afsd_logp, "cm_GetData length_found > biod.length");
+                    fs_fetchdata_offset_bug = 1;
+                }
+            } else {
+                osi_Log1(afsd_logp, "cm_GetData rx_Read32 returns %d != 4", temp);
+                code = (rx_Error(rxcallp) < 0) ? rx_Error(rxcallp) : RX_PROTOCOL_ERROR;
+            }
+        }
+        /* for the moment, nbytes_hi will always be 0 if code == 0
+           because data_length is a 32-bit quantity. */
+
+        if (code == 0) {
+            /* fill length_found of data from the pipe into the pages.
+             * When we stop, qdp will point at the last page we're
+             * dealing with, and bufferp will tell us where we
+             * stopped.  We'll need this info below when we clear
+             * the remainder of the last page out (and potentially
+             * clear later pages out, if we fetch past EOF).
+             */
+            while (length_found > 0) {
+                /* assert that there are still more buffers;
+                 * our check above for length_found being less than
+                 * data_length should ensure this.
+                 */
+                osi_assertx(bufferp != NULL, "null cm_buf_t");
+
+                /* read rbytes of data */
+                rbytes = (afs_uint32)(length_found > biod->length ? biod->length : length_found);
+                temp = rx_Read(rxcallp, bufferp, rbytes);
+                if (temp < rbytes) {
+                    /*
+                     * If the file server returned (filesize - offset),
+                     * then the first rx_Read will return zero octets of data.
+                     * If it does, do not treat it as an error.  Correct the
+                     * length_found and continue as if the file server said
+                     * it was sending us zero octets of data.
+                     */
+                    if (fs_fetchdata_offset_bug && first_read)
+                        length_found = 0;
+                    else
+                        code = (rx_Error(rxcallp) < 0) ? rx_Error(rxcallp) : RX_PROTOCOL_ERROR;
+                    break;
+                }
+                first_read = 0;
+
+                /* and adjust counters */
+                length_found -= temp;
+            }
+        }
+
+        if (code == 0) {
+            if (call_was_64bit)
+                code = EndRXAFS_FetchData64(rxcallp, &afsStatus, &callback, &volSync);
+            else
+                code = EndRXAFS_FetchData(rxcallp, &afsStatus, &callback, &volSync);
+        } else {
+            if (call_was_64bit)
+                osi_Log1(afsd_logp, "CALL EndRXAFS_FetchData64 skipped due to error %d", code);
+            else
+                osi_Log1(afsd_logp, "CALL EndRXAFS_FetchData skipped due to error %d", code);
+        }
+
+        if (rxcallp)
+            code1 = rx_EndCall(rxcallp, code);
+
+        if (code1 == RXKADUNKNOWNKEY)
+            osi_Log0(afsd_logp, "CALL EndCall returns RXKADUNKNOWNKEY");
+
+        /* If we are avoiding a file server bug, ignore the error state */
+        if (fs_fetchdata_offset_bug && first_read && length_found == 0 && code == -451) {
+            /* Clone the current status info and clear the error state */
+            scp_locked = cm_CloneStatus(scp, userp, scp_locked, &afsStatus, &volSync);
+            if (scp_locked) {
+                lock_ReleaseWrite(&scp->rw);
+                scp_locked = 0;
+            }
+            code = 0;
+        /* Prefer the error value from FetchData over rx_EndCall */
+        } else if (code == 0 && code1 != 0)
+            code = code1;
+        osi_Log0(afsd_logp, "CALL FetchData DONE");
+
+    } while (cm_Analyze(connp, userp, reqp, &scp->fid, 0, &volSync, NULL, NULL, code));
+
+  fetchingcompleted:
+    code = cm_MapRPCError(code, reqp);
+
+    if (!scp_locked)
+        lock_ObtainWrite(&scp->rw);
+
+    if (code == 0)
+        cm_MergeStatus(NULL, scp, &afsStatus, &volSync, userp, reqp, CM_MERGEFLAG_FETCHDATA);
+    else
+        InterlockedDecrement(&scp->activeRPCs);
+
+    if (code == 0)
+    {
+        if (dataVersion == scp->dataVersion)
+        {
+            osi_queueData_t *qdp = NULL;
+            cm_buf_t *bufp;
+            afs_uint32 buf_offset;
+            afs_uint32 bytes_compared = 0;
+            afs_uint32 cmp_length;
+            int md5_match = 1;
+
+            verified = 1;
+
+            while ( bytes_compared < biod->length )
+            {
+                if (qdp == NULL) {
+                    qdp = biod->bufListEndp;
+                    buf_offset = biod->offset.LowPart % cm_data.buf_blockSize;
+                } else {
+                    qdp = (osi_queueData_t *) osi_QPrev(&qdp->q);
+                    buf_offset = 0;
+                }
+                cmp_length =  cm_data.buf_blockSize - buf_offset;
+
+                osi_assertx(qdp != NULL, "null osi_queueData_t");
+                bufp = osi_GetQData(qdp);
+
+                if (memcmp(bufferp+bytes_compared, bufp->datap+buf_offset, cmp_length) != 0)
+                {
+                    verified = 0;
+                    md5_match = buf_ValidateCheckSum(bufp);
+
+                    osi_Log5(afsd_logp, "cm_VerifyDataStore verification failed scp 0x%p bufp 0x%p offset 0x%x:%08x md5 %s",
+                             scp, bufp, bufp->offset.HighPart, bufp->offset.LowPart, md5_match ? "match" : "no-match");
+                }
+                bytes_compared += cmp_length;
+            }
+        } else {
+            osi_Log4(afsd_logp, "cm_VerifyStoreData unable to verify due to data version change scp 0x%p, off 0x%x:%08x, size 0x%x",
+                     scp, biod->offset.HighPart, biod->offset.LowPart, biod->length);
+        }
+    }
+
+    if (bufferp)
+        free(bufferp);
+
+    return verified;
+}
index dbe75399032b3ae94817c9d20bfc55fcab65420c..5fea18374b6a91670d4de6cb70f3b7c2324195aa 100644 (file)
@@ -65,4 +65,6 @@ extern long cm_ShutdownDCache(void);
 extern long cm_BufWrite(void *vscp, osi_hyper_t *offsetp, long length, long flags,
                  cm_user_t *userp, cm_req_t *reqp);
 
+extern long cm_VerifyStoreData(cm_bulkIO_t *biod, cm_scache_t *scp);
+
 #endif /*  OPENAFS_WINNT_AFSD_CM_DCACHE_H */
index c5ea701132ac60876f0bf41827d18b725db4fb5a..078ef6aeecbf7decfc012fce6d0e08a4d1da2cb9 100644 (file)
@@ -3564,3 +3564,31 @@ cm_IoctlSetUnixMode(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t
     }
     return code;
 }
+
+/*
+ * VIOC_GETVERIFYDATA internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlGetVerifyData(cm_ioctl_t *ioctlp)
+{
+    memcpy(ioctlp->outDatap, &cm_verifyData, sizeof(cm_verifyData));
+    ioctlp->outDatap += sizeof(cm_verifyData);
+
+    return 0;
+}
+
+/*
+ * VIOC_SETVERIFYDATA internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ */
+afs_int32
+cm_IoctlSetVerifyData(cm_ioctl_t *ioctlp)
+{
+    memcpy(&cm_verifyData, ioctlp->inDatap, sizeof(cm_verifyData));
+
+    return 0;
+}
+
index 605f5e7f57e5a5abebf984b211300c8402db9118..3ddbc1d28745180658605e579c39862f31408988 100644 (file)
@@ -286,6 +286,10 @@ extern afs_int32 cm_IoctlGetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_sc
 
 extern afs_int32 cm_IoctlSetUnixMode(cm_ioctl_t *ioctlp, cm_user_t *userp, cm_scache_t *scp, cm_req_t *reqp);
 
+extern afs_int32 cm_IoctlGetVerifyData(cm_ioctl_t *ioctlp);
+
+extern afs_int32 cm_IoctlSetVerifyData(cm_ioctl_t *ioctlp);
+
 #endif /* __CM_IOCTL_INTERFACES_ONLY__ */
 
 #endif /*  OPENAFS_WINNT_AFSD_CM_IOCTL_H */
index e3a17cf000653606d4381879f5f1d7884539c6f9..be1e3c49232aed69109b0611881dc57cfecd6088 100644 (file)
@@ -5007,6 +5007,77 @@ ChModCmd(struct cmd_syndesc *as, void *arock)
     return error;
 }
 
+static afs_int32
+SetDataVerifyCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code = 0, flag;
+    struct ViceIoctl blob;
+    char *tp;
+
+#ifdef WIN32
+    if ( !fs_IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
+    tp = as->parms[0].items->data;
+    if (strcmp(tp, "on") == 0)
+      flag = 1;
+    else if (strcmp(tp, "off") == 0)
+      flag = 0;
+    else {
+      fprintf (stderr, "%s: %s must be \"on\" or \"off\".\n", pn, tp);
+      return EINVAL;
+    }
+
+    blob.in = (char *) &flag;
+    blob.in_size = sizeof(flag);
+    blob.out_size = 0;
+    code = pioctl_utf8(0, VIOC_SETVERIFYDATA, &blob, 1);
+    if (code)
+        fs_Die(code, NULL);
+    return 0;
+}
+
+static afs_int32
+GetDataVerifyCmd(struct cmd_syndesc *as, void *arock)
+{
+    afs_int32 code = 0, flag;
+    struct ViceIoctl blob;
+    char *tp;
+    errno_t err;
+
+    blob.in = NULL;
+    blob.in_size = 0;
+    blob.out_size = sizeof(flag);
+    blob.out = space;
+
+    code = pioctl_utf8(0, VIOC_GETVERIFYDATA, &blob, 1);
+
+    if (code || blob.out_size != sizeof(flag))
+        fs_Die(code, NULL);
+    else {
+        tp = space;
+#if _MSC_VER < 1400
+        memcpy(&flag, tp, sizeof(afs_int32));
+#else
+        err = memcpy_s(&flag, sizeof(flag), tp, sizeof(afs_int32));
+        if ( err ) {
+            fprintf (stderr, "memcpy_s failure on flag");
+            exit(1);
+        }
+#endif
+
+      printf("Data verify mode is currently ");
+      if (flag == 1)
+        printf("on.\n");
+      else
+        printf("off.\n");
+    }
+    return 0;
+}
+
 #ifndef WIN32
 #include "AFS_component_version_number.c"
 #endif
@@ -5341,6 +5412,11 @@ int wmain(int argc, wchar_t **wargv)
     cmd_AddParm(ts, "-path", CMD_LIST, CMD_OPTIONAL, "dir/file path");
     cmd_AddParm(ts, "-literal", CMD_FLAG, CMD_OPTIONAL, "literal evaluation of mountpoints and symlinks");
 
+    ts = cmd_CreateSyntax("setverify", SetDataVerifyCmd, NULL, "set cache manager data verify mode");
+    cmd_AddParm(ts, "-verify", CMD_SINGLE, 0, "on or off");
+
+    ts = cmd_CreateSyntax("getverify", GetDataVerifyCmd, NULL, "get cache manager data verify mode");
+
     code = cmd_Dispatch(argc, argv);
 
     if (rxInitDone)
index 3015aa695208744326e518bc4e59aeaccd6e7c87..b8b2c3c7feeb0efd890951bd859d5e02911402c2 100644 (file)
@@ -101,6 +101,8 @@ struct sbstruct {
 #define VIOCNEWCELL2                    0x37
 #define VIOC_GETUNIXMODE                0x38
 #define VIOC_SETUNIXMODE                0x39
+#define VIOC_GETVERIFYDATA              0x3A
+#define VIOC_SETVERIFYDATA              0x3B
 
 #define VIOC_VOLSTAT_TEST               0x3F
 
index e4a72f364184f1ff5556e2aaff084b5f2376e9bf..aa692ade11cd7b1a6a63ec92e07e80f96bddc6d6 100644 (file)
@@ -96,6 +96,8 @@ smb_InitIoctl(void)
     smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2;
     smb_ioctlProcsp[VIOC_SETUNIXMODE] = smb_IoctlSetUnixMode;
     smb_ioctlProcsp[VIOC_GETUNIXMODE] = smb_IoctlGetUnixMode;
+    smb_ioctlProcsp[VIOC_SETVERIFYDATA] = smb_IoctlSetVerifyData;
+    smb_ioctlProcsp[VIOC_GETVERIFYDATA] = smb_IoctlGetVerifyData;
 }
 
 /* called to make a fid structure into an IOCTL fid structure */
@@ -2179,3 +2181,19 @@ smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32
     return code;
 }
 
+afs_int32
+smb_IoctlGetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+    cm_SkipIoctlPath(&ioctlp->ioctl);
+
+    return cm_IoctlGetVerifyData(&ioctlp->ioctl);
+}
+
+afs_int32
+smb_IoctlSetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+    cm_SkipIoctlPath(&ioctlp->ioctl);
+
+    return cm_IoctlSetVerifyData(&ioctlp->ioctl);
+}
+
index 9defd83b6fb7a641b60a4326868c44f7e33342ec..4ba8f4b3df55f6febfb79ba78eec633ea8d77219 100644 (file)
@@ -211,4 +211,8 @@ extern afs_int32 smb_IoctlGetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *
 
 extern afs_int32 smb_IoctlSetUnixMode(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
 
+extern afs_int32 smb_IoctlGetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
+
+extern afs_int32 smb_IoctlSetVerifyData(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 flags);
+
 #endif /*  OPENAFS_WINNT_AFSD_SMB_IOCTL_H */
index 09c895bfd8a8f3943abe54d84af8bc986ebbef68..89c3e67a57295fbbbb0414bf3e78dddc10fbbb42 100644 (file)
@@ -139,6 +139,8 @@ RDR_InitIoctl(void)
     RDR_ioctlProcsp[VIOCNEWCELL2] = RDR_IoctlNewCell2;
     RDR_ioctlProcsp[VIOC_GETUNIXMODE] = RDR_IoctlGetUnixMode;
     RDR_ioctlProcsp[VIOC_SETUNIXMODE] = RDR_IoctlSetUnixMode;
+    RDR_ioctlProcsp[VIOC_GETVERIFYDATA] = RDR_IoctlGetVerifyData;
+    RDR_ioctlProcsp[VIOC_SETVERIFYDATA] = RDR_IoctlSetVerifyData;
 }
 
 /* called to make a fid structure into an IOCTL fid structure */
@@ -1969,3 +1971,19 @@ RDR_IoctlSetUnixMode(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32
 
     return code;
 }
+
+afs_int32
+RDR_IoctlGetVerifyData(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+    cm_SkipIoctlPath(&ioctlp->ioctl);
+
+    return cm_IoctlGetVerifyData(&ioctlp->ioctl);
+}
+
+afs_int32
+RDR_IoctlSetVerifyData(struct RDR_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
+{
+    cm_SkipIoctlPath(&ioctlp->ioctl);
+
+    return cm_IoctlSetVerifyData(&ioctlp->ioctl);
+}
index 9944627e78c1ae8789051f189986c0c832ee2450..821431e91952cae20c4749f2acffea92ab936e78 100644 (file)
@@ -191,5 +191,9 @@ extern afs_int32 RDR_IoctlGetUnixMode(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs
 
 extern afs_int32 RDR_IoctlSetUnixMode(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
 
+extern afs_int32 RDR_IoctlGetVerifyData(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
+
+extern afs_int32 RDR_IoctlSetVerifyData(RDR_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags);
+
 #endif