Windows: Improve SMB detection of Local System account
[openafs.git] / src / WINNT / afsd / cm_ioctl.c
index e4cbb84..b25cc0c 100644 (file)
@@ -10,6 +10,7 @@
 #include <afs/param.h>
 #include <afs/stds.h>
 #include <afs/cellconfig.h>
+#include <afs/afs_consts.h>
 #include <afs/ptserver.h>
 #include <ubik.h>
 
@@ -74,7 +75,7 @@ cm_CleanFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 {
     long code;
 
-    code = buf_CleanVnode(scp, userp, reqp);
+    code = cm_FSync(scp, userp, reqp, FALSE);
     if (!code) {
         lock_ObtainWrite(&scp->rw);
         cm_DiscardSCache(scp);
@@ -95,7 +96,7 @@ cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
 
 #ifdef AFS_FREELANCE_CLIENT
     if ( scp->fid.cell == AFS_FAKE_ROOT_CELL_ID && scp->fid.volume == AFS_FAKE_ROOT_VOL_ID ) {
-       cm_noteLocalMountPointChange();
+       cm_noteLocalMountPointChange(FALSE);
        return 0;
     }
 #endif
@@ -144,11 +145,11 @@ cm_FlushVolume(cm_user_t *userp, cm_req_t *reqp, afs_uint32 cell, afs_uint32 vol
 {
     afs_int32 code = 0;
     cm_scache_t *scp;
-    int i;
+    unsigned int i;
 
 #ifdef AFS_FREELANCE_CLIENT
     if ( cell == AFS_FAKE_ROOT_CELL_ID && volume == AFS_FAKE_ROOT_VOL_ID ) {
-       cm_noteLocalMountPointChange();
+       cm_noteLocalMountPointChange(FALSE);
        return 0;
     }
 #endif
@@ -253,17 +254,17 @@ int cm_UnparseIoctlString(cm_ioctl_t *ioctlp,
 
     if ((ioctlp->flags & CM_IOCTLFLAG_USEUTF8) == CM_IOCTLFLAG_USEUTF8) {
         cchout = cm_ClientStringToUtf8(cstr, cchlen, outp,
-                                       SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp));
+                                       (int)(SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp)));
     } else {
         if (smb_StoreAnsiFilenames) {
             cchout = WideCharToMultiByte(CP_ACP, 0, cstr, cchlen,
                                          outp,
-                                         SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp),
+                                         (int)(SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp)),
                                          NULL, NULL);
         } else {
             cchout = WideCharToMultiByte(CP_OEMCP, 0, cstr, cchlen,
                                          outp,
-                                         SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp),
+                                         (int)(SMB_IOCTL_MAXDATA - (outp - ioctlp->outAllocp)),
                                          NULL, NULL);
         }
     }
@@ -281,7 +282,7 @@ int cm_UnparseIoctlString(cm_ioctl_t *ioctlp,
 cm_ioctlQueryOptions_t * 
 cm_IoctlGetQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp)
 {
-    afs_uint32 pathlen = strlen(ioctlp->inDatap) + 1;
+    afs_uint32 pathlen = (afs_uint32) strlen(ioctlp->inDatap) + 1;
     char *p = ioctlp->inDatap + pathlen;
     cm_ioctlQueryOptions_t * optionsp = NULL;
 
@@ -304,6 +305,7 @@ cm_IoctlSkipQueryOptions(struct cm_ioctl *ioctlp, struct cm_user *userp)
 {
     cm_ioctlQueryOptions_t * optionsp = (cm_ioctlQueryOptions_t *)ioctlp->inDatap;
     ioctlp->inDatap += optionsp->size;
+    ioctlp->inCopied -= optionsp->size;
 }
 
 /* format the specified path to look like "/afs/<cellname>/usr", by
@@ -325,7 +327,7 @@ cm_NormalizeAfsPath(clientchar_t *outpathp, long cchlen, clientchar_t *inpathp)
     if (!cm_ClientStrCmpNI(inpathp, cm_mountRootC, cm_mountRootCLen))
         cm_ClientStrCpy(outpathp, cchlen, inpathp);
     else if (!cm_ClientStrCmpNI(inpathp, bslash_mountRoot,
-                                cm_ClientStrLen(bslash_mountRoot)))
+                                (int)cm_ClientStrLen(bslash_mountRoot)))
         cm_ClientStrCpy(outpathp, cchlen, inpathp);
     else if ((inpathp[0] == '/') || (inpathp[0] == '\\'))
         cm_ClientStrPrintfN(outpathp, cchlen, _C("%s%s"), cm_mountRootC, inpathp);
@@ -540,7 +542,7 @@ cm_IoctlFlushAllVolumes(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_req_t
 {
     afs_int32 code;
     cm_scache_t *scp;
-    int i;
+    unsigned int i;
 
     lock_ObtainWrite(&cm_scacheLock);
     for (i=0; i<cm_data.scacheHashTableSize; i++) {
@@ -1133,7 +1135,8 @@ cm_IoctlDeleteMountPoint(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scac
     lock_ReleaseWrite(&scp->rw);
 
 #ifdef USE_BPLUS
-    code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop);
+    code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ,
+                         CM_DIROP_FLAG_NONE, &dirop);
     if (code == 0) {
         code = cm_BPlusDirLookupOriginalName(&dirop, cp, &originalName);
         /* The cm_Dir* functions can't be used to lookup the
@@ -1485,7 +1488,6 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
         /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
         cm_FreeServerList(&cp->vlServersp, CM_FREESERVERLIST_DELETE);
-        cp->vlServersp = NULL;
         lock_ReleaseWrite(&cm_cellLock);
 
         rock.cellp = cp;
@@ -1493,7 +1495,6 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
         code = cm_SearchCellRegistry(1, cp->name, cp->name, cp->linkedName, cm_AddCellProc, &rock);
         if (code && code != CM_ERROR_FORCE_DNS_LOOKUP)
             code = cm_SearchCellFileEx(cp->name, cp->name, cp->linkedName, cm_AddCellProc, &rock);
-#ifdef AFS_AFSDB_ENV
         if (code) {
             if (cm_dnsEnabled) {
                 int ttl;
@@ -1512,7 +1513,6 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
             cp->flags &= ~CM_CELLFLAG_DNS;
             lock_ReleaseMutex(&cp->mx);
         }
-#endif /* AFS_AFSDB_ENV */
         if (code) {
             lock_ObtainMutex(&cp->mx);
             cp->flags |= CM_CELLFLAG_VLSERVER_INVALID;
@@ -1532,6 +1532,90 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp)
 }
 
 /* 
+ * VIOCNEWCELL2 internals.
+ *
+ * Assumes that pioctl path has been parsed or skipped.
+ *
+ * The pioctl data buffer consists of the following structure:
+ *
+ *  afs_uint32 flags
+ *  afs_uint32 alternative fs port
+ *  afs_uint32 alternative vl port
+ *  afs_uint32 count of vldb servers
+ *  char[]     cellname
+ *  char[]     linkedcell
+ *  n * char[] hostnames
+ */
+afs_int32
+cm_IoctlNewCell2(struct cm_ioctl *ioctlp, struct cm_user *userp)
+{
+    afs_uint32  code = 0;
+    afs_uint32  flags = 0;
+    afs_uint32  fsport = 0;
+    afs_uint32  vlport = 0;
+    afs_uint32  i, host_count = 0;
+    char *      cellname = NULL;
+    char *      linked_cellname = NULL;
+    char *tp;
+    size_t tplen;
+    afs_uint32 *lp;
+    char * hostname[AFS_MAXHOSTS];
+    size_t len;
+
+    memset(hostname, 0, sizeof(hostname));
+
+    tp = ioctlp->inDatap;
+    tplen = ioctlp->inCopied;
+    lp = (afs_uint32 *)tp;
+
+    if (tplen >= 4 * sizeof(afs_uint32)) {
+        flags = *lp++;
+        fsport = *lp++;
+        vlport = *lp++;
+        host_count = *lp++;
+        tp = (char *)lp;
+        tplen -= 4 * sizeof(afs_uint32);
+    }
+
+    if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+         len + 1 > CELL_MAXNAMELEN)
+        return CM_ERROR_INVAL;
+    cellname = tp;
+    tp += len + 1;
+    tplen -= (len + 1);
+
+    if ( FAILED(StringCbLength(tp, tplen, &len)) ||
+         len + 1 > CELL_MAXNAMELEN)
+        return CM_ERROR_INVAL;
+    linked_cellname = tp;
+    tp += len + 1;
+    tplen -= (len + 1);
+
+    if (!(flags & VIOC_NEWCELL2_FLAG_USEDNS)) {
+        for ( i=0; i<host_count; i++) {
+            if ( FAILED(StringCbLength(tp, tplen, &len)) )
+                return CM_ERROR_INVAL;
+            hostname[i] = tp;
+            tp += len + 1;
+            tplen -= (len + 1);
+        }
+    }
+
+    code = cm_CreateCellWithInfo( cellname, linked_cellname,
+                                  vlport, host_count,
+                                  hostname,
+                                  (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+
+    if (code == 0 && (flags & VIOC_NEWCELL2_FLAG_USEREG)) {
+        cm_AddCellToRegistry( cellname, linked_cellname,
+                              vlport, host_count,
+                              hostname,
+                              (flags & VIOC_NEWCELL2_FLAG_USEDNS) ? CM_CELLFLAG_DNS : 0);
+    }
+    return code;
+}
+
+/*
  * VIOC_GET_WS_CELL internals.
  * 
  * Assumes that pioctl path has been parsed or skipped.
@@ -1573,7 +1657,8 @@ cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
     afs_uint32 setSysName;
     char *cp, *cp2;
     clientchar_t *inname = NULL;
-    int t, count;
+    int t;
+    unsigned int count;
 
     memcpy(&setSysName, ioctlp->inDatap, sizeof(afs_uint32));
     ioctlp->inDatap += sizeof(afs_uint32);
@@ -1629,7 +1714,7 @@ cm_IoctlSysName(struct cm_ioctl *ioctlp, struct cm_user *userp)
         }
         cm_sysNameCount = setSysName;
     } else {
-        afs_int32 i32;
+        afs_uint32 i32;
 
         /* return the sysname to the caller */
         i32 = cm_sysNameCount;
@@ -2181,7 +2266,8 @@ cm_IoctlDeletelink(struct cm_ioctl *ioctlp, struct cm_user *userp, cm_scache_t *
     lock_ReleaseWrite(&scp->rw);
         
 #ifdef USE_BPLUS
-    code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ, &dirop);
+    code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_READ,
+                         CM_DIROP_FLAG_NONE, &dirop);
     if (code == 0) {
         code = cm_BPlusDirLookupOriginalName(&dirop, clientp, &originalName);
         /* cm_Dir*() functions can't be used to lookup the original
@@ -2632,7 +2718,7 @@ cm_IoctlGetToken(struct cm_ioctl *ioctlp, struct cm_user *userp)
 
     lock_ReleaseMutex(&userp->mx);
 
-    cm_RegisterNewTokenEvent(uuid, ucellp->sessionKey.data);
+    cm_RegisterNewTokenEvent(uuid, ucellp->sessionKey.data, NULL);
 
     return 0;
 }