Windows: Improve SMB detection of Local System account
[openafs.git] / src / WINNT / afsd / smb_ioctl.c
index c2750a5..d441fe9 100644 (file)
@@ -11,6 +11,7 @@
 #include <afs/stds.h>
 
 #include <windows.h>
+#include <sddl.h>
 #include <stdlib.h>
 #include <malloc.h>
 #include <string.h>
@@ -122,7 +123,7 @@ smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
  * call to the ioctl code.
  */
 afs_int32
-smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     afs_int32 opcode;
     smb_ioctlProc_t *procp = NULL;
@@ -155,7 +156,7 @@ smb_IoctlPrepareRead(struct smb_fid *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp
         }
         /* otherwise, make the call */
         ioctlp->ioctl.outDatap += sizeof(afs_int32); /* reserve room for return code */
-        code = (*procp)(ioctlp, userp);
+        code = (*procp)(ioctlp, userp, pflags);
         osi_Log1(afsd_logp, "smb_IoctlPrepareRead operation returns code 0x%x", code);
 
         /* copy in return code */
@@ -205,21 +206,48 @@ smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *o
     afs_int32 leftToCopy;
     char *op;
     afs_int32 code;
-    cm_user_t *userp;
+    smb_user_t *uidp;
+    cm_user_t *userp = NULL;
+    smb_t *smbp;
+    int isSystem = 0;
 
     iop = fidp->ioctlp;
     count = smb_GetSMBParm(inp, 1);
-    userp = smb_GetUserFromVCP(vcp, inp);
+
+    /* Get the user and determine if it is the local machine account */
+    smbp = (smb_t *) inp;
+    uidp = smb_FindUID(vcp, smbp->uid, 0);
+    if (uidp) {
+        isSystem = smb_userIsLocalSystem(uidp);
+        userp = smb_GetUserFromUID(uidp);
+        if (uidp->unp) {
+            osi_Log3(afsd_logp, "smb_IoctlRead uid %d user %x name %s",
+                      uidp->userID, userp,
+                      osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+        } else {
+            osi_Log2(afsd_logp, "smb_IoctlRead uid %d user %x no name",
+                      uidp->userID, userp);
+        }
+        smb_ReleaseUID(uidp);
+    } else {
+        osi_Log1(afsd_logp, "smb_IoctlRead no uid user %x no name", userp);
+        return CM_ERROR_BADSMB;
+    }
+
+    if (!userp) {
+        userp = cm_rootUserp;
+        cm_HoldUser(userp);
+    }
 
     /* Identify tree */
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
-    if(code) {
+    if (code) {
         cm_ReleaseUser(userp);
         return CM_ERROR_NOSUCHPATH;
     }
 
     /* turn the connection around, if required */
-    code = smb_IoctlPrepareRead(fidp, iop, userp);
+    code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
 
     if (code) {
         cm_ReleaseUser(userp);
@@ -359,29 +387,37 @@ smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
     char *op;
     cm_user_t *userp;
     smb_user_t *uidp;
+    int isSystem = 0;
 
     iop = fidp->ioctlp;
     count = smb_GetSMBParm(inp, 5);
-       
+
+    /* Get the user and determine if it is the local machine account */
     uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
-    if (!uidp)
-        return CM_ERROR_BADSMB;
-    userp = smb_GetUserFromUID(uidp);
-    osi_assertx(userp != NULL, "null cm_user_t");
-    iop->uidp = uidp;
-    if (uidp && uidp->unp) {
-        osi_Log3(afsd_logp, "Ioctl uid %d user %x name %S",
-                  uidp->userID, userp,
-                  osi_LogSaveClientString(afsd_logp, uidp->unp->name));
-    } else {
-        if (uidp)
-           osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
-                     uidp->userID, userp);
-        else
-           osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
-                    userp);
+    if (uidp) {
+        isSystem = smb_userIsLocalSystem(uidp);
+        userp = smb_GetUserFromUID(uidp);
+        if (uidp->unp) {
+            osi_Log3(afsd_logp, "smb_IoctlV3Read uid %d user %x name %s",
+                      uidp->userID, userp,
+                      osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+        } else {
+            osi_Log2(afsd_logp, "smb_IoctlV3Read uid %d user %x no name",
+                      uidp->userID, userp);
+        }
+     } else {
+         osi_Log0(afsd_logp, "smb_IoctlV3Read no uid");
+         return CM_ERROR_BADSMB;
+     }
+
+    if (!userp) {
+        userp = cm_rootUserp;
+        cm_HoldUser(userp);
     }
 
+    iop->uidp = uidp;
+
+
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
     if (code) {
        if (uidp)
@@ -390,7 +426,7 @@ smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
         return CM_ERROR_NOSUCHPATH;
     }
 
-    code = smb_IoctlPrepareRead(fidp, iop, userp);
+    code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
     if (uidp) {
         iop->uidp = 0;
         smb_ReleaseUID(uidp);
@@ -457,26 +493,32 @@ smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
     afs_int32 code;
     cm_user_t *userp;
     smb_user_t *uidp;
+    int isSystem = 0;
 
     iop = fidp->ioctlp;
 
-    userp = smb_GetUserFromVCP(vcp, inp);
-
-    /* Log the user */
+    /* Get the user and determine if it is the local machine account */
     uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
-    if (uidp && uidp->unp) {
-        osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
-                 uidp->userID, userp,
-                 osi_LogSaveClientString(afsd_logp, uidp->unp->name));
-    } else if (uidp) {
-        osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
-                 uidp->userID, userp);
+    if (uidp) {
+        isSystem = smb_userIsLocalSystem(uidp);
+        userp = smb_GetUserFromUID(uidp);
+        if (uidp->unp) {
+            osi_Log3(afsd_logp, "smb_IoctlRawRead uid %d user %x name %s",
+                      uidp->userID, userp,
+                      osi_LogSaveClientString(afsd_logp, uidp->unp->name));
+        } else {
+            osi_Log2(afsd_logp, "smb_IoctlRawRead uid %d user %x no name",
+                      uidp->userID, userp);
+        }
+        smb_ReleaseUID(uidp);
     } else {
-        osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
-                  userp);
+        osi_Log0(afsd_logp, "smb_IoctlRawRead no uid");
+    }
+
+    if (!userp) {
+        userp = cm_rootUserp;
+        cm_HoldUser(userp);
     }
-    if (uidp) 
-        smb_ReleaseUID(uidp);
 
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
     if (code) {
@@ -484,7 +526,7 @@ smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
         goto done;
     }
 
-    code = smb_IoctlPrepareRead(fidp, iop, userp);
+    code = smb_IoctlPrepareRead(fidp, iop, userp, isSystem ? AFSCALL_FLAG_LOCAL_SYSTEM : 0);
     if (code) {
         goto done;
     }
@@ -941,7 +983,7 @@ smb_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
 }
 
 afs_int32 
-smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     char *saveDataPtr;
     char *tp;
@@ -958,6 +1000,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     clientchar_t *uname = NULL;
     clientchar_t *smbname = NULL;
     clientchar_t *wdir = NULL;
+    clientchar_t *rpc_sid = NULL;
     afs_int32 code = 0;
 
     saveDataPtr = ioctlp->ioctl.inDatap;
@@ -1019,37 +1062,113 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
         if (flags & PIOCTL_LOGON) {
             /* SMB user name with which to associate tokens */
             smbname = cm_ParseIoctlStringAlloc(&ioctlp->ioctl, tp);
-            osi_Log2(smb_logp,"cm_IoctlSetToken for user [%S] smbname [%S]",
+            osi_Log2(smb_logp,"smb_IoctlSetToken for user [%S] smbname [%S]",
                      osi_LogSaveClientString(smb_logp,uname),
                      osi_LogSaveClientString(smb_logp,smbname));
             fprintf(stderr, "SMB name = %S\n", smbname);
             tp += strlen(tp) + 1;
         } else {
-            osi_Log1(smb_logp,"cm_IoctlSetToken for user [%S]",
+            osi_Log1(smb_logp,"smb_IoctlSetToken for user [%S]",
                      osi_LogSaveClientString(smb_logp, uname));
         }
 
         /* uuid */
         memcpy(&uuid, tp, sizeof(uuid));
-        if (!cm_FindTokenEvent(uuid, sessionKey)) {
+        if (!cm_FindTokenEvent(uuid, sessionKey, &rpc_sid)) {
             code = CM_ERROR_INVAL;
             goto done;
         }
+
+        if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && rpc_sid) {
+            osi_Log1(smb_logp,"smb_IoctlSetToken Rpc Sid [%S]",
+                     osi_LogSaveClientString(smb_logp, rpc_sid));
+            if (!cm_ClientStrCmp(NTSID_LOCAL_SYSTEM, rpc_sid))
+                pflags |= AFSCALL_FLAG_LOCAL_SYSTEM;
+        }
+
+        if (!(pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
+            code = CM_ERROR_NOACCESS;
+            goto done;
+        }
     } else {
         cellp = cm_data.rootCellp;
-        osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
+        osi_Log0(smb_logp,"smb_IoctlSetToken - no name specified");
     }
 
-    if (flags & PIOCTL_LOGON) {
-        userp = smb_FindCMUserByName(smbname, ioctlp->fidp->vcp->rname,
-                                    SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
-       release_userp = 1;
+    if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
+        PSID pSid = NULL;
+        DWORD dwSize1 = 0, dwSize2 = 0;
+        wchar_t *pszRefDomain = NULL;
+        SID_NAME_USE snu = SidTypeGroup;
+        clientchar_t * secSidString = NULL;
+        DWORD gle;
+
+        /*
+         * The specified smbname is may not be a SID for the user.
+         * See if we can obtain the SID for the specified name.
+         * If we can, use that instead of the name provided.
+         */
+
+        LookupAccountNameW( NULL /* System Name to begin Search */,
+                            smbname,
+                            NULL, &dwSize1,
+                            NULL, &dwSize2,
+                            &snu);
+        gle = GetLastError();
+        if (gle == ERROR_INSUFFICIENT_BUFFER) {
+            pSid = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, dwSize1);
+            /*
+             * Although dwSize2 is supposed to include the terminating
+             * NUL character, on Win7 it does not.
+             */
+            pszRefDomain = malloc((dwSize2 + 1) * sizeof(wchar_t));
+        }
+
+        if ( pSid && pszRefDomain ) {
+            if (LookupAccountNameW( NULL /* System Name to begin Search */,
+                                    smbname,
+                                    pSid, &dwSize1,
+                                    pszRefDomain, &dwSize2,
+                                    &snu))
+                ConvertSidToStringSidW(pSid, &secSidString);
+        }
+
+        if (secSidString) {
+            userp = smb_FindCMUserBySID( secSidString, ioctlp->fidp->vcp->rname,
+                                         SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+            LocalFree(secSidString);
+        } else {
+            /* Free the SID so we can reuse the variable */
+            if (pSid) {
+                LocalFree(pSid);
+                pSid = NULL;
+            }
+
+            /*
+             * If the SID for the name could not be found,
+             * perhaps it already is a SID
+             */
+            if (!ConvertStringSidToSidW( smbname, &pSid)) {
+                userp = smb_FindCMUserBySID( smbname, ioctlp->fidp->vcp->rname,
+                                             SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+            } else {
+                userp = smb_FindCMUserByName( smbname, ioctlp->fidp->vcp->rname,
+                                              SMB_FLAG_CREATE|SMB_FLAG_AFSLOGON);
+            }
+        }
+
+        if (pSid)
+            LocalFree(pSid);
+        if (pszRefDomain)
+            free(pszRefDomain);
+
+        release_userp = 1;
     }
 
     /* store the token */
     lock_ObtainMutex(&userp->mx);
     ucellp = cm_GetUCell(userp, cellp);
-    osi_Log1(smb_logp,"cm_IoctlSetToken ucellp %lx", ucellp);
+    osi_Log1(smb_logp,"smb_IoctlSetToken ucellp %lx", ucellp);
     ucellp->ticketLen = ticketLen;
     if (ucellp->ticketp)
         free(ucellp->ticketp); /* Discard old token if any */
@@ -1077,13 +1196,15 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     ucellp->flags |= CM_UCELLFLAG_RXKAD;
     lock_ReleaseMutex(&userp->mx);
 
-    if (flags & PIOCTL_LOGON) {
+    if ((pflags & AFSCALL_FLAG_LOCAL_SYSTEM) && (flags & PIOCTL_LOGON)) {
         ioctlp->ioctl.flags |= CM_IOCTLFLAG_LOGON;
     }
 
     cm_ResetACLCache(cellp, userp);
 
   done:
+    SecureZeroMemory(sessionKey, sizeof(sessionKey));
+
     if (release_userp)
        cm_ReleaseUser(userp);
 
@@ -1099,7 +1220,7 @@ smb_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     smb_user_t *uidp = ioctlp->uidp;
 
@@ -1120,7 +1241,7 @@ smb_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
 }
 
 afs_int32 
-smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     cm_scache_t *scp;
     afs_int32 code;
@@ -1154,7 +1275,7 @@ smb_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
 }
 
 afs_int32 
-smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     cm_scache_t *scp;
     afs_int32 code;
@@ -1174,7 +1295,7 @@ smb_IoctlSetACL(smb_ioctl_t *ioctlp, cm_user_t *userp)
 }
 
 afs_int32
-smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1208,7 +1329,7 @@ smb_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_req_t req;
 
@@ -1220,7 +1341,7 @@ smb_IoctlFlushAllVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1254,7 +1375,7 @@ smb_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1287,7 +1408,7 @@ smb_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1305,7 +1426,7 @@ smb_IoctlSetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1339,7 +1460,7 @@ smb_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1365,7 +1486,7 @@ smb_IoctlGetFid(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1399,7 +1520,7 @@ smb_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1433,7 +1554,7 @@ smb_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1468,7 +1589,7 @@ smb_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32 
-smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1488,7 +1609,7 @@ smb_IoctlStatMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1508,7 +1629,7 @@ smb_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);  /* we don't care about the path */
 
@@ -1516,21 +1637,21 @@ smb_IoctlCheckServers(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGag(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     /* we don't print anything superfluous, so we don't support the gag call */
     return CM_ERROR_INVAL;
 }
 
 afs_int32 
-smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlCheckVolumes(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
     return cm_IoctlCheckVolumes(&ioctlp->ioctl, userp);
 }
 
-afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
+afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1539,7 +1660,7 @@ afs_int32 smb_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32 
-smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
        
@@ -1547,7 +1668,7 @@ smb_IoctlTraceControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
        
@@ -1555,7 +1676,7 @@ smb_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1563,7 +1684,7 @@ smb_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1571,7 +1692,7 @@ smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1579,7 +1700,7 @@ smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
+smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1587,7 +1708,7 @@ smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
 }
 
 afs_int32 
-smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1595,7 +1716,7 @@ smb_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1603,7 +1724,7 @@ smb_IoctlGetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1611,7 +1732,7 @@ smb_IoctlSetCellStatus(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1619,7 +1740,7 @@ smb_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1627,7 +1748,7 @@ smb_IoctlGetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     /* we ignore default asynchrony since we only have one way
      * of doing this today.
@@ -1636,7 +1757,7 @@ smb_IoctlStoreBehind(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }       
 
 afs_int32
-smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1656,7 +1777,7 @@ smb_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1676,7 +1797,7 @@ smb_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1694,7 +1815,7 @@ smb_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {/*CHECK FOR VALID SYMLINK*/
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1713,7 +1834,7 @@ smb_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *dscp;
@@ -1732,7 +1853,7 @@ smb_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32 
-smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1740,7 +1861,7 @@ smb_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1749,7 +1870,7 @@ smb_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1758,7 +1879,7 @@ smb_IoctlDelToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1767,7 +1888,7 @@ smb_IoctlDelAllToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1775,7 +1896,7 @@ smb_IoctlMakeSubmount(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1783,7 +1904,7 @@ smb_IoctlGetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1791,7 +1912,7 @@ smb_IoctlSetRxkcrypt(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1800,7 +1921,7 @@ smb_IoctlRxStatProcess(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1808,7 +1929,7 @@ smb_IoctlRxStatPeer(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1816,7 +1937,7 @@ smb_IoctlUnicodeControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1825,7 +1946,7 @@ smb_IoctlUUIDControl(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 
 afs_int32
-smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_SkipIoctlPath(&ioctlp->ioctl);
 
@@ -1833,7 +1954,7 @@ smb_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1865,7 +1986,7 @@ smb_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 afs_int32
-smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     cm_req_t req;
 
@@ -1883,7 +2004,7 @@ smb_IoctlVolStatTest(struct smb_ioctl *ioctlp, struct cm_user *userp)
  *
  */
 afs_int32 
-smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;
@@ -1921,13 +2042,13 @@ smb_IoctlSetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp)
 }
 
 /* 
- * VIOC_GETOWNER
+ * VIOC_SETGROUP
  * 
  * This pioctl requires the use of the cm_ioctlQueryOptions_t structure.
  *
  */
 afs_int32 
-smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp)
+smb_IoctlSetGroup(struct smb_ioctl *ioctlp, struct cm_user *userp, afs_uint32 pflags)
 {
     afs_int32 code;
     cm_scache_t *scp;