2006-10Oct-27
Checking for privileges
Windows maintains two different security related information: permissions and privileges
Permissions apply to particular objects. They control if a user can read, write, delete, etc.
a particular file, manage a certain printer, or access a specifc registry key. Permissions never apply to
some abstract group, but always to a very specifc object. To manage permissions, Windows uses ACLs.
Privileges, on the other hand, are enforced system wide. They define if a user or group has the
right to perform some kind of operation independed of the object. For example, a user might have the
right to install any driver, debug any program, shutdown the entire system. You can't limit a user
to only install a particular driver, debug a specific program, etc.
A user (called Token in Microsoft security speak) has a certain set of privileges. However, this
doesn't mean that a privilege is enabled. A privilege that is assigned to a user can be enabled, disabled
or removed. Disabled privileges can be enabled. Privileges that have been removed or never have been assigned
cannot be added to the list of privileges for that user. If your application depends on a partiular privilege,
such as installing a printer (SeLoadDriverPrivilege), you have to check if the privilege is available and
enabled.
There are only a limited number of privileges defined in Windows. You cannot add your own ones:
SeCreateTokenPrivilege
SeAssignPrimaryTokenPrivilege
SeLockMemoryPrivilege
SeIncreaseQuotaPrivilege
SeUnsolicitedInputPrivilege
eMachineAccountPrivilege
SeTcbPrivilege
SeSecurityPrivilege
SeTakeOwnershipPrivilege
SeLoadDriverPrivilege
SeSystemProfilePrivilege
SeSystemtimePrivilege
SeProfileSingleProcessPrivilege
SeIncreaseBasePriorityPrivilege
SeCreatePagefilePrivilege
SeCreatePermanentPrivilege
SeBackupPrivilege
SeRestorePrivilege
SeShutdownPrivilege
SeDebugPrivilege
SeAuditPrivilege
SeSystemEnvironmentPrivilege
SeChangeNotifyPrivilege
SeRemoteShutdownPrivilege
SeUndockPrivilege
SeSyncAgentPrivilege
SeEnableDelegationPrivilege
SeManageVolumePrivilege
SeImpersonatePrivilege
SeCreateGlobalPrivilege
To check whether a user has got a particular privilege, I wrote a little utility
called HasPrivilege.prg.
2006-10Oct-24
Convert ANSI to char in .NET
Sometimes you have a byte array that is an ANSI string. To convert it to a char array or a string in C#,
you need to apply a conversion. It appears that many folks are using:
char val = Encoding.ASCII.GetChars(byteArray);
This is plain and simple wrong. The ASCII encoder is a 7-bit encoder that can only be used for ASCII data.
Unless you are interfacing with a CP/M machine or a 9-dot IBM matrix printer, you are unlikely dealing with ASCII.
Most likely you are talking about ANSI, or more precisely, about a Windows code page such as 1252 for Western
countries, 1251 for many East European countries, and so on. Hence, if you created some so called "ASCII" data on
a European or US Windows computer, what you actually want to use is:
char val = Encoding.GetEncoding(1252).GetChars(byteValue);
Change the codepage if your Windows system codepage is not 1252. If data is always stored in
the current code page, you can also use:
char val = Encoding.Default.GetChars(byteValue);
2006-10Oct-23
Maximum number of procedures in PRG files
Visual FoxPro stores procedures and methods of a PRG file in a rather unusal
way. Instead of keeping methods with their classes, Visual FoxPro compiles one
huge list of all procedures in a PRG file. Each procedure is assigned a 16-bit
ID value. For this reason, the total number of procedures that can be stored in
a PRG file is 65,535. It doesn't matter how many of them are methods or procedures.
It's the total number of PROCEDURE and FUNCTION statements that counts. Here's a
code sample that demonstrates this:
lc = "define Class test as custom" + Chr(13)+Chr(10)
lc = lc + ;
"Procedure proc"+Chr(13)+Chr(10)+"ENDPROC"+Chr(13)+Chr(10)
For t=1 to 65535
lc = lc + ;
"Procedure method"+Transform(t)+Chr(13)+Chr(10)+;
"ENDPROC"+Chr(13)+Chr(10)
EndFor
lc = m.lc + "ENDDEFINE"
StrToFile(lc,"testcode.prg")
Compile testcode.prg