no-more-ini-files-20040713
[openafs.git] / src / WINNT / afsd / fs.c
index 5c4c384..ac32533 100644 (file)
 #include <osi.h>
 #include <afsint.h>
 
-typedef long afs_int32;
-typedef unsigned long afs_uint32;
-typedef short afs_int16;
-typedef unsigned short afs_uint16;
-
 #include "fs.h"
 #include "fs_utils.h"
 #include "cmd.h"
@@ -49,6 +44,7 @@ static struct ubik_client *uclient;
 #endif /* not WIN32 */
 
 static MemDumpCmd(struct cmd_syndesc *asp);
+static CSCPolicyCmd(struct cmd_syndesc *asp);
 
 extern afs_int32 VL_GetEntryByNameO();
 
@@ -520,25 +516,25 @@ char *name; {
     double QuotaUsed =0.0;
     double PartUsed =0.0;
     int WARN = 0;
-    printf("%-20s",name);
+    printf("%-25.25s",name);
 
     if (status->MaxQuota != 0) {
-       printf("%8d%8d", status->MaxQuota, status->BlocksInUse);
+       printf("%10d%10d", status->MaxQuota, status->BlocksInUse);
        QuotaUsed = ((((double)status->BlocksInUse)/status->MaxQuota) * 100.0);
     } else {
-       printf("no limit%8d", status->BlocksInUse);
+       printf("no limit%10d", status->BlocksInUse);
     }
     if (QuotaUsed > 90.0){
-       printf(" %8.0f%%<<", QuotaUsed);
+       printf(" %5.0f%%<<", QuotaUsed);
        WARN = 1;
     }
-    else printf(" %8.0f%%  ", QuotaUsed);
+    else printf(" %5.0f%%  ", QuotaUsed);
     PartUsed = (100.0 - ((((double)status->PartBlocksAvail)/status->PartMaxBlocks) * 100.0));
     if (PartUsed > 97.0){
-       printf(" %8.0f%%<<", PartUsed);
+       printf(" %9.0f%%<<", PartUsed);
        WARN = 1;
     }
-    else printf(" %8.0f%%  ", PartUsed);
+    else printf(" %9.0f%%  ", PartUsed);
     if (WARN){
        printf("\t<<WARNING\n");
     }
@@ -550,16 +546,16 @@ VolumeStatus *status;
 char *name; {
     double PartUsed =0.0;
     int WARN = 0;
-    printf("%-20s",name);
+    printf("%-25.25s",name);
 
-    printf("%8d%8d%8d", status->PartMaxBlocks, status->PartMaxBlocks - status->PartBlocksAvail, status->PartBlocksAvail);
+    printf("%10d%10d%10d", status->PartMaxBlocks, status->PartMaxBlocks - status->PartBlocksAvail, status->PartBlocksAvail);
        
     PartUsed = (100.0 - ((((double)status->PartBlocksAvail)/status->PartMaxBlocks) * 100.0));
     if (PartUsed > 90.0){
-       printf(" %8.0f%%<<", PartUsed);
+       printf(" %4.0f%%<<", PartUsed);
        WARN = 1;
     }
-    else printf(" %8.0f%%  ", PartUsed);
+    else printf(" %4.0f%%  ", PartUsed);
     if (WARN){
        printf("\t<<WARNING\n");
     }
@@ -587,6 +583,69 @@ char *AclToString(acl)
     return mydata;
 }
 
+BOOL IsAdmin (void)
+{
+    static BOOL fAdmin = FALSE;
+    static BOOL fTested = FALSE;
+
+    if (!fTested)
+    {
+        /* Obtain the SID for BUILTIN\Administrators. If this is Windows NT,
+         * expect this call to succeed; if it does not, we can presume that
+         * it's not NT and therefore the user always has administrative
+         * privileges.
+         */
+        PSID psidAdmin = NULL;
+        SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY;
+
+        fTested = TRUE;
+
+        if (!AllocateAndInitializeSid (&auth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin))
+            fAdmin = TRUE;
+        else
+        {
+            /* Then open our current ProcessToken */
+            HANDLE hToken;
+
+            if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
+            {
+                /* We'll have to allocate a chunk of memory to store the list of
+                 * groups to which this user belongs; find out how much memory
+                 * we'll need.
+                 */
+                DWORD dwSize = 0;
+                PTOKEN_GROUPS pGroups;
+                
+                GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize);
+            
+                pGroups = (PTOKEN_GROUPS)malloc(dwSize);
+                
+                /* Allocate that buffer, and read in the list of groups. */
+                if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize))
+                {
+                    /* Look through the list of group SIDs and see if any of them
+                     * matches the Administrator group SID.
+                     */
+                    size_t iGroup = 0;
+                    for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup)
+                    {
+                        if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid))
+                            fAdmin = TRUE;
+                    }
+                }
+
+                if (pGroups)
+                    free(pGroups);
+            }
+        }
+
+        if (psidAdmin)
+            FreeSid (psidAdmin);
+    }
+
+    return fAdmin;
+}
+
 static SetACLCmd(as)
 struct cmd_syndesc *as; {
     register afs_int32 code;
@@ -1115,8 +1174,8 @@ register struct cmd_syndesc *as; {
     struct VolumeStatus *status;
     char *name;
     
-    printf("%-20s%-9s%-8s%-11s%-11s\n",
-           "Volume Name","   Quota", "   Used", "   % Used", " Partition");
+    printf("%-25s%-10s%-10s%-7s%-13s\n", 
+           "Volume Name", "     Quota", "      Used", "  %Used", "    Partition");
     SetDotDefault(&as->parms[0].items);
     for(ti=as->parms[0].items; ti; ti=ti->next) {
        /* once per file */
@@ -1177,8 +1236,8 @@ register struct cmd_syndesc *as; {
     char *name;
     struct VolumeStatus *status;
     
-    printf("%-20s%-9s%-8s%-11s%-11s\n",
-           "Volume Name","  kbytes ", " used", "  avail ", " %used");
+    printf("%-25s%-10s%-10s%-10s%-6s\n", "Volume Name", "    kbytes",
+          "      used", "     avail", " %used");
     SetDotDefault(&as->parms[0].items);
     for(ti=as->parms[0].items; ti; ti=ti->next) {
        /* once per file */
@@ -1589,12 +1648,26 @@ register struct cmd_syndesc *as; {
                } else if(checkserv.tinterval> 600) {
                    printf("Warning: The maximum -interval value is 10 mins (600 secs)\n");
                    checkserv.tinterval=600;    /* 10 min max interval */
-              }
+        }
        }
        else {
-         checkserv.tinterval = -1;     /* don't change current interval */
+        checkserv.tinterval = -1;      /* don't change current interval */
        }
 
+    if ( checkserv.tinterval != 0 ) {
+#ifdef WIN32
+        if ( !IsAdmin() ) {
+            fprintf (stderr,"Permission denied: requires Administrator access.\n");
+            return EACCES;
+        }
+#else /* WIN32 */
+        if (geteuid()) {
+            fprintf (stderr,"Permission denied: requires root access.\n");
+            return EACCES;
+        }
+#endif /* WIN32 */
+    }
+
     code = pioctl(0, VIOCCKSERV, &blob, 1);
     if (code) {
        if ((errno == EACCES) && (checkserv.tinterval > 0)) {
@@ -1694,6 +1767,18 @@ register struct cmd_syndesc *as; {
     struct ViceIoctl blob;
     afs_int32 temp;
     
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     if (!as->parms[0].items && !as->parms[1].items) {
        fprintf(stderr,"%s: syntax error in set cache size cmd.\n", pn);
        return 1;
@@ -1796,6 +1881,18 @@ register struct cmd_syndesc *as; {
     register struct hostent *thp;
     afs_int32 fsport = 0, vlport = 0;
 
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     memset(space, 0, MAXHOSTS * sizeof(afs_int32));
     tp = space;
     lp = (afs_int32 *)tp;
@@ -1999,42 +2096,68 @@ static SysNameCmd(as)
 register struct cmd_syndesc *as; {
     register afs_int32 code;
     struct ViceIoctl blob;
-    register struct cmd_item *ti;
+    struct cmd_item *ti;
     char *input = space;
-    afs_int32 setp = 1;
+    afs_int32 setp = 0;
     
     ti = as->parms[0].items;
-    if (!ti) setp = 0;
+    if (ti) {
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+    }
+
     blob.in = space;
     blob.out = space;
     blob.out_size = MAXSIZE;
     blob.in_size = sizeof(afs_int32);
     memcpy(input, &setp, sizeof(afs_int32));
     input += sizeof(afs_int32);
-    if (ti) {
-       strcpy(input, ti->data);
-       blob.in_size += strlen(ti->data) + 1;
-       input += strlen(ti->data);
-       *(input++) = '\0';
+    for (; ti; ti = ti->next) {
+        setp++;
+        blob.in_size += strlen(ti->data) + 1;
+        if (blob.in_size > MAXSIZE) {
+            fprintf(stderr, "%s: sysname%s too long.\n", pn,
+                     setp > 1 ? "s" : "");
+            return 1;
+        }
+        strcpy(input, ti->data);
+        input += strlen(ti->data);
+        *(input++) = '\0';
     }
+    memcpy(space, &setp, sizeof(afs_int32));
     code = pioctl(0, VIOC_AFS_SYSNAME, &blob, 1);
     if (code) {
-       Die(errno, 0);
-       exit(1);
+        Die(errno, 0);
+        return 1;
     }    
     if (setp) {
-       printf("%s: new sysname set.\n", pn);
+        printf("%s: new sysname%s set.\n", pn, setp > 1 ? "s" : "");
+        return 0;
     }
-    else {
+
        input = space;
        memcpy(&setp, input, sizeof(afs_int32));
        input += sizeof(afs_int32);
        if (!setp) {
            fprintf(stderr,"No sysname name value was found\n");
-       } else {
-           printf("Current sysname is '%s'\n", input);
+        return 1;
+       } 
+    
+    printf("Current sysname%s", setp > 1 ? "s are" : " is");
+    for (; setp > 0; --setp ) {
+        printf(" \'%s\'", input);
+        input += strlen(input) + 1;
        }
-    }
+    printf("\n");
     return 0;
 }
 
@@ -2046,6 +2169,18 @@ register struct cmd_syndesc *as; {
     register struct cmd_item *ti;
     int export=0, type=0, mode = 0, exp = 0, gstat = 0, exportcall, pwsync=0, smounts=0;
     
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     ti = as->parms[0].items;
     if (strcmp(ti->data, "nfs")        == 0) type = 0x71; /* NFS */
     else {
@@ -2113,6 +2248,7 @@ register struct cmd_syndesc *as; {
            }
        }
     }
+    return(0);
 }
 
 
@@ -2173,6 +2309,18 @@ register struct cmd_syndesc *as; {
     args.stat = 0;
     args.junk = 0;
 
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     if (! as->parms[1].items) args.stat |= CM_SETCELLFLAG_SUID; /* default to -nosuid */
 
     /* set stat for all listed cells */
@@ -2296,6 +2444,8 @@ struct afsconf_cell *info;
                                          info->hostAddr[i].sin_port, USER_SERVICE_ID,
                                          sc, scIndex);
 
+    if (sc)
+        rxs_Release(sc);    /* Decrement the initial refCount */
     code = ubik_ClientInit(serverconns, &uclient);
 
     if (code) {
@@ -2374,6 +2524,29 @@ static addServer(name, rank)
        return code;
 }
 
+static BOOL IsWindowsNT (void)
+{
+    static BOOL fChecked = FALSE;
+    static BOOL fIsWinNT = FALSE;
+
+    if (!fChecked)
+    {
+        OSVERSIONINFO Version;
+
+        fChecked = TRUE;
+
+        memset (&Version, 0x00, sizeof(Version));
+        Version.dwOSVersionInfoSize = sizeof(Version);
+
+        if (GetVersionEx (&Version))
+        {
+            if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
+                fIsWinNT = TRUE;
+        }
+    }
+    return fIsWinNT;
+}
+
 
 static SetPrefCmd(as)
 register struct cmd_syndesc *as; {
@@ -2392,12 +2565,16 @@ register struct cmd_syndesc *as; {
   gblob.out = space;
   gblob.out_size = MAXSIZE;
 
-
-#ifndef WIN32
-  if (geteuid()) {
-    fprintf (stderr,"Permission denied: requires root access.\n");
-    return EACCES;
-  }
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
 #endif /* WIN32 */
 
   code = 0;
@@ -2535,33 +2712,45 @@ register struct cmd_syndesc *as; {
     }
   } while (!code && out->next_offset > 0);
 
-return code;
+    return code;
 }
 
 static TraceCmd(struct cmd_syndesc *asp)
 {
        long code;
-        struct ViceIoctl blob;
-        long inValue;
-        long outValue;
-        
-        if ((asp->parms[0].items && asp->parms[1].items)) {
-               fprintf(stderr, "fs trace: must use at most one of '-off' or '-on'\n");
-                return EINVAL;
+    struct ViceIoctl blob;
+    long inValue;
+    long outValue;
+    
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+        if (geteuid()) {
+            fprintf (stderr,"Permission denied: requires root access.\n");
+            return EACCES;
         }
+#endif /* WIN32 */
+
+    if ((asp->parms[0].items && asp->parms[1].items)) {
+               fprintf(stderr, "fs trace: must use at most one of '-off' or '-on'\n");
+        return EINVAL;
+    }
         
        /* determine if we're turning this tracing on or off */
        inValue = 0;
-        if (asp->parms[0].items)
-               inValue = 3;            /* enable */
+    if (asp->parms[0].items)
+        inValue = 3;           /* enable */
        else if (asp->parms[1].items) inValue = 2;      /* disable */
-        if (asp->parms[2].items) inValue |= 4;         /* do reset */
+    if (asp->parms[2].items) inValue |= 4;             /* do reset */
        if (asp->parms[3].items) inValue |= 8;          /* dump */
         
-        blob.in_size = sizeof(long);
-        blob.in = (char *) &inValue;
-        blob.out_size = sizeof(long);
-        blob.out = (char *) &outValue;
+    blob.in_size = sizeof(long);
+    blob.in = (char *) &inValue;
+    blob.out_size = sizeof(long);
+    blob.out = (char *) &outValue;
         
        code = pioctl(NULL, VIOC_TRACECTL, &blob, 1);
        if (code) {
@@ -2569,10 +2758,10 @@ static TraceCmd(struct cmd_syndesc *asp)
                return code;
        }
         
-        if (outValue) printf("AFS tracing enabled.\n");
-        else printf("AFS tracing disabled.\n");
+    if (outValue) printf("AFS tracing enabled.\n");
+    else printf("AFS tracing disabled.\n");
 
-        return 0;
+    return 0;
 }
 
 static void sbusage()
@@ -2589,6 +2778,18 @@ struct cmd_syndesc *as; {
     struct sbstruct tsb;
     int kb;
     
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     if ((as->parms[0].items && as->parms[1].items) ||   
         (!as->parms[0].items && !as->parms[1].items)) /* same as logical xor */
       ;
@@ -2642,6 +2843,18 @@ static afs_int32 SetCryptCmd(as)
     struct ViceIoctl blob;
     char *tp;
  
+#ifdef WIN32
+    if ( !IsAdmin() ) {
+        fprintf (stderr,"Permission denied: requires Administrator access.\n");
+        return EACCES;
+    }
+#else /* WIN32 */
+    if (geteuid()) {
+        fprintf (stderr,"Permission denied: requires root access.\n");
+        return EACCES;
+    }
+#endif /* WIN32 */
+
     tp = as->parms[0].items->data;
     if (strcmp(tp, "on") == 0)
       flag = 1;
@@ -2924,6 +3137,13 @@ char **argv; {
     cmd_AddParm(ts, "-begin", CMD_FLAG, CMD_OPTIONAL, "set a memory checkpoint");
     cmd_AddParm(ts, "-end", CMD_FLAG, CMD_OPTIONAL, "dump memory allocs");
     
+    ts = cmd_CreateSyntax("cscpolicy", CSCPolicyCmd, 0, "change client side caching policy for AFS shares");
+    cmd_AddParm(ts, "-share", CMD_SINGLE, CMD_OPTIONAL, "AFS share");
+    cmd_AddParm(ts, "-manual", CMD_FLAG, CMD_OPTIONAL, "manual caching of documents");
+    cmd_AddParm(ts, "-programs", CMD_FLAG, CMD_OPTIONAL, "automatic caching of programs and documents");
+    cmd_AddParm(ts, "-documents", CMD_FLAG, CMD_OPTIONAL, "automatic caching of documents");
+    cmd_AddParm(ts, "-disable", CMD_FLAG, CMD_OPTIONAL, "disable caching");
+
     code = cmd_Dispatch(argc, argv);
 
 #ifndef WIN32
@@ -3017,3 +3237,104 @@ static MemDumpCmd(struct cmd_syndesc *asp)
     return 0;
 }
 
+static CSCPolicyCmd(struct cmd_syndesc *asp)
+{
+       struct cmd_item *ti;
+       char *share = NULL;
+    HKEY hkCSCPolicy;
+
+       for(ti=asp->parms[0].items; ti;ti=ti->next) {
+               share = ti->data;
+               if (share)
+               {
+                       break;
+               }
+       }
+
+       if (share)
+       {
+        char *policy;
+
+        RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                        "SOFTWARE\\OpenAFS\\Client\\CSCPolicy",
+                        0, 
+                        "AFS", 
+                        REG_OPTION_NON_VOLATILE,
+                        KEY_WRITE,
+                        NULL, 
+                        &hkCSCPolicy,
+                        NULL );
+
+        if ( !IsAdmin() || hkCSCPolicy == NULL ) {
+            fprintf (stderr,"Permission denied: requires Administrator access.\n");
+            if ( hkCSCPolicy )
+                RegCloseKey(hkCSCPolicy);
+            return EACCES;
+        }
+
+        policy = "manual";
+               
+               if (asp->parms[1].items)
+                       policy = "manual";
+               if (asp->parms[2].items)
+                       policy = "programs";
+               if (asp->parms[3].items)
+                       policy = "documents";
+               if (asp->parms[4].items)
+                       policy = "disable";
+               
+        RegSetValueEx( hkCSCPolicy, share, 0, REG_SZ, policy, strlen(policy)+1);
+               
+               printf("CSC policy on share \"%s\" changed to \"%s\".\n\n", share, policy);
+               printf("Close all applications that accessed files on this share or restart AFS Client for the change to take effect.\n"); 
+       }
+       else
+       {
+        DWORD dwIndex, dwPolicies;
+               char policyName[256];
+               DWORD policyNameLen;
+        char policy[256];
+        DWORD policyLen;
+        DWORD dwType;
+
+               /* list current csc policies */
+               
+        RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
+                        "SOFTWARE\\OpenAFS\\Client\\CSCPolicy",
+                        0, 
+                        "AFS", 
+                        REG_OPTION_NON_VOLATILE,
+                        KEY_READ|KEY_QUERY_VALUE,
+                        NULL, 
+                        &hkCSCPolicy,
+                        NULL );
+
+        RegQueryInfoKey( hkCSCPolicy,
+                         NULL,  /* lpClass */
+                         NULL,  /* lpcClass */
+                         NULL,  /* lpReserved */
+                         NULL,  /* lpcSubKeys */
+                         NULL,  /* lpcMaxSubKeyLen */
+                         NULL,  /* lpcMaxClassLen */
+                         &dwPolicies, /* lpcValues */
+                         NULL,  /* lpcMaxValueNameLen */
+                         NULL,  /* lpcMaxValueLen */
+                         NULL,  /* lpcbSecurityDescriptor */
+                         NULL   /* lpftLastWriteTime */
+                         );
+               
+               printf("Current CSC policies:\n");
+        for ( dwIndex = 0; dwIndex < dwPolicies; dwIndex ++ ) {
+
+            policyNameLen = sizeof(policyName);
+            policyLen = sizeof(policy);
+            RegEnumValue( hkCSCPolicy, dwIndex, policyName, &policyNameLen, NULL,
+                          &dwType, policy, &policyLen);
+
+                       printf("  %s = %s\n", policyName, policy);
+               }
+       }
+
+    RegCloseKey(hkCSCPolicy);
+       return (0);
+}