Intranet/Hosting Toolkit [table of contents]
[CFX_UserManager]
v2.3 December 2nd 2001
CFX_UserManager
OPEN-SOURCE
NT DLL for Cold Fusion 4.0.1 and up
Lewis A. Sellers
http://www.intrafoundation.com/ihtk.html
ihtk@intrafoundation.com

FOREWORD

This is an Allaire Cold Fusion Extension Tag (CFX). It is for use with Allaire Cold Fusion Servers 4.0.1 (and up) running on Microsoft NT. It was written by Lewis A. Sellers of Intrafoundation Software.

CFX_UserManager provides a functionality similar to NT's administrative tool "User Manager for Domains": With it you can create, delete, modify or copy any NT user account You also have control over the local and domain groups which the user may be a member of.

There are also additional "support" functions available which include, among other things, browsing the list of currently logged in users, listing domain controllers and servers, etc.

Please read the version history for current tag status before emailing questions.

C O N T E N T S

Foreword

General
Users
Local Groups
Groups

Version History

top

G E N E R A L

ABOUT

<CFX_UserManager ACTION="ABOUT">

The tag itself returns a couple variables back no matter what you do (UserManagerDescription, UserManagerVersion and UserManagerError). These are always available unless there is a catastrophic failure of the tag.

Additionally you can use the ABOUT function to return more detailed information on the tag. The fields returned are mostly only of interest for curiosity or in debugging a situation.

Note below that though the tag returns it's SerialNumber, it's not used currently, and hasn't been for a very long time, but probably will be again soon.

For the curious, it also proves the total number of lines of c/c++ that the current build was using. This includes the scant comments in the source code. For instance, this build of the tag has 3754 lines of code.

Description
The general product description.
Version
The version number of the software, ie 2.0.
Quality

The quality field will be one of the following four: "Alpha", "Beta", "Gamma" or "Omega". Quality relates the quality control status of the version of the tag you're currently using.

Alpha code is highly unstable and shouldn't be trusted for anything. Do not use on production machines.

Beta code is close to being finish and it is in a debugging phase. Do not use on production machines.

Gamma code is for use on production machines. As far as the beta testers have determined it works as it should.

When a product goes Omega that generally means it is long used Gamma code that is now no longer being maintained.

SubVersion
The subversion number of the software, ie 4 for "2.0beta4".
SerialNumber
Currently unused.
Lines
The total lines of c/c++ code in the software.
BuildDate
The ODBC DATETIME when the tag was last compiled (built).
Evaluation
Boolean field (0 or 1). 1 indicates the version of the tag you're using is a time-limited evaluation version. 0 is full commercial.
ExpirationDate
The ODBC DATETIME date when the tag will stop working.



THISSERVER

<CFX_UserManager ACTION="THISSERVER" [QUERY=""]>

New as of 2.0. Returns information about the server the cfx tag is installed on. For the most part these fields are of little practical use beyond curiosity. ComputerName and Username are exceptions however.

ComputerName relates the actual name given to the computer by netBIOS. This is also known as the server name if you prepend two-slashes to it. For instance, you're currently reading this on a machine that calls itself SASHA.

Username is the NT user name of the account that the ColdFusion application server is running under. It's installed by default to use SYSTEM. Some people will create an Administrator account specifically for ColdFusion to run under. You, btw, are using the account SYSTEM to run ColdFusion.

The fields returned are:

MaxUsernameLength, MaxPasswordLength and MaxPathLength are useful in that they give you the system's maximum character length for those three fields. This is information, which if you didn't already know of it, is useful in checking form fields for valid data.





SERVERS

<CFX_UserManager ACTION="SERVERS" [DOMAIN=""] [SERVERNAME=""] [SERVERTYPE=""] [QUERY=""]>

This function returns a list of all servers in a domain. If you don't specify a domain, it assumes the local one. Additionally, instead of having it return all the servers in said domain you can ask for only specific types (through SERVERTYPE) such as:

For instance, this allows you to quickly list all the workstations only. If you don't specify a server type, then it assumes you want all servers.

SERVERS returns a SQL query with the following six columns:

The name field is primarily all that is important. PlatformID, VersionMajor and VersionMinor, etc refer to LAN Manager specific information that you probably aren't interested in unless you're debugging your network.

LEGACY NOTE: In 1.x this function was called SERVERSENUM. To support legacy cfml code you may still use the action SERVERSENUM. It simply calls the current SERVERS function.




DOMAINS

<CFX_UserManager ACTION="DOMAINS" [QUERY=""]>

Returns a list of domains.

DOMAINS returns a SQL query with one field:





GETPRIMARYDOMAINCONTROLLER

<CFX_UserManager ACTION="GETPRIMARYDOMAINCONTROLLER" [SERVERNAME=""] [DOMAINNAME=""] [QUERY=""]>

Retrieves the Primary (PDC) Domain Controller name. Of use mainly for NT4.

The function returns a SQL query with the following column:





top

U S E R S

Managing users is what this software is all about. What that in mind it should probably be mentioned that, if you didn't know already the NT User Account name consists of up to 20 printable ANSI characters (case sensitive) except: " / \ [ ] : ; | = . + ? <>

USERSQUICK

<CFX_UserManager ACTION="USERSQUICK" [SERVERNAME=""] [QUERY=""]>

So, you want a list of all the users in the domain and you want it quickly. You've come to the right function. USERSQUICK returns SQL query with the single field called Username. This field of course an NT user account name.

This function is quicker than USERS (below). It's generally of more use when doing autonomous book-keeping type work where you don't need to know anything other than the usernames.

If servername is not supplied then the local machine is assumed.





USERS

<CFX_UserManager ACTION="USERS" [SERVERNAME=""] [QUERY=""]>

This is similiar to USERSQUICK, but it provides a little more information. The additional fields that are available are the users' full human-readable name, any comments the administrators may have regarding the users, comments or a description by the users about themselves and their SIDs.

A SID? What's that? It's a Security Descriptor. It's the way NT makes sure all user accounts across domains are unique. Each time a user account is created a new SID assigned to it.

If you were wondering (and you know you were), the SID for the Administrator account of this machine is S-1-5-21-1177238915-688789844-1343024091-500. The Guest account has a SID of S-1-5-21-1177238915-688789844-1343024091-501.

The field names for the returned query are:

If servername is not supplied then the local machine is assumed.

LEGACY NOTE: In 1.x this function was called ENUM. To support legacy cfml code you may still use the action ENUM. It simply calls the current USERS function.




ADD

< CFX_UserManager ACTION="ADD"
USERNAME=""
PASSWORD=""
[BLANKPASSWORD="YES"] [LOCALGROUPS=""]
[SERVERNAME=""]
[FULLNAME=""]
[COMMENT=""]
[HOMEDIR=""]
[HOMEDIRDRIVE=""]
[SCRIPTPATH=""]
[SCRIPT="YES|NO"]
[ACCOUNTDISABLE="YES|NO"]
[HOMEDIRREQUIRED="YES|NO"]
[LOCKOUT="YES|NO"]
[PASSWORDCANTCHANGE="YES|NO"]
[DONTEXPIREPASSWORD="YES|NO"]
[ACCOUNTTYPE="NORMAL|TEMPDUPLICATE|WORKSTATIONTRUST|SERVERTRUST|INTERDOMAINTRUST"]
[FLAGS="n"]
>


Adds a new user account by username. You can specify a minimum number of attributes of the account when initially creating it. To access or modify the more detailed attributes use the SETINFO function.

You must specify a password of no greater than 14 characters. If your network requires it you may also allow users to be added with no passwords by using the argument BLANKPASSWORD="Yes".

In 1.x days the FLAGS parameter was used to set several boolean flags that specified attributes of this account. Don't bother with it anymore. You can explicitly toggle these options now with the parms: SCRIPT, ACCOUNTDISABLE, HOMEDIRREQUIRED, LOCKOUT, PASSWORDCANTCHANGE, and DONTEXPIREPASSWORD. You can also directly set the account type with ACCOUNTTYPE. The last can take a value of NORMAL, TEMPDUPLICATE, WORKSTATIONTRUST, SERVERTRUST or INTERDOMAINTRUST. NT won't accept all combinations of these as valid. In that case no change will be made.

If servername is not supplied then the local machine is assumed.

As stated above, FLAGS does not need to be used anymore. But if you're maintaining legacy code this is how it works. "Flags" is a number containing the following boolean switches. Add up the numbers in parentheses to compute the magic number you wish to use. 66409 is the Administrator default. 66115 is the Guest default.

  1. Script (1)
  2. AccountDisable (2)
  3. HomeDirRequired (8)
  4. PasswdNotReqd (32)
  5. PasswdCantChange (64)
  6. Lockout (16)
  7. DontExpirePasswd (65536)
  8. NormalAccount (512)
  9. TempDuplicateAccount (256)
  10. WorkstationTrustAccount (4096)
  11. ServerTrustAccount (8192)
  12. InterdomainTrustAccount (2048)




DEL

<CFX_UserManager ACTION="DEL" USERNAME="" [SERVERNAME=""]>

Deletes a user by username. Note that even if you add a user account later on that has the same username their SID will be different. This means file permissions granted to the deleted user can not simply be given back by recreating an account with the same name. You must re-permission all files with the new account.

If servername is not supplied then the local machine is assumed.





GETINFO

<CFX_UserManager ACTION="GETINFO" USERNAME="" [SERVERNAME=""] [QUERY=""]>

Gets detailed information on the specified user account. This function returns a SQL query with a large number of fields. Some of them are... of little use beyond technical curiosity. Let us first list them all before we go further:

Username of course is the name of the NT account you requested information on.

PasswordAge is the number of seconds that have passed since the password has last changed.

Priv will be either "Guest", "User or "Administrator". It is a read-only field.

HomeDir is the home directory of the account.

ScriptPath. The full path to a bat, cmd or exe that runs everytime the users logs in. (And no, it can't be a cfm as far as I know.)

Parms is an interesting little field. It is used by MS applications to store null-terminated (ie, c-style) text strings. MS warns against modifying this information.

Workstations. This restricts the user to be able to log in to only the comma-seperated workstations named in this field. If no workstations are named, then they may use any station in the domain.

LastLogon and LastLogoff should be fairly obvious. The field will be 0 if they never logged in or have yet to log off.

AcctExpires. Yes, it's the date when the account automatically expires. In um1.x this field returned 1970-01-01 00:00:00 if the account never expired. This date is zero hour for NT's Y2K unfriendly date system. That's a bit cryptic though isn't? So for um2.x it was changed to report "-1" if the account never expires. (Sorry if that breaks some legacy code.)

Logonhours is a 168 character string indicating all the hours in a week (7 days times 24 hours equals 168 hours). Each character is a boolean. If it's "0" the user can't log in during that time. If it's "1" they can. Using SETINFO you can effectively make it so a user can only log in during their scheduled work hours. Very handy for anti-hacking puposes.

BadPWCount (Bad Password Count) is the number of times an incorrect password has been entered for that account. If it's above 2 or 3 (or 5000) that might tend to suggest indicate someone's tying to hack into the account.

LogonServer is exactly what it sounds like. The server the acount last logged in on. For NT Servers \\* is returned.

UserID is your account RID. It's similiar to a SID but of use within the domain only.

When PasswordExpired is not 0, then the password has expired.

Script. If this boolean value is 1, then the script in ScriptPath is executed when the user logs in.

AccountDisable. The user account is disabled.

HomeDirRequired. Not actually used in NT4.

PasswordNotRequired. No password is required to log in.

PasswordCantChange. The user can't change the password. Only an administrator.

AccountType. NORMAL, TEMPDUPLICATE, WORKSTATIONTRUST, SERVERTRUST and INTERDOMAINTRUST. TEMPDUPLICATES are users visiting from other domains. WORKSTATIONTRUST is the account for an actual NT Workstation or NT Server computer in this domain. SERVERTRUST is the account for BDC. INTERDOMAINTRUST allows for trust betwen two domains.

The Flags field is the raw bit-encoded boolean flags for various attributs of an account. Since 2.x decodes them for you this may or may not be of much use.

If servername is not supplied then the local machine is assumed.

LEGACY NOTE: There have been a few changes since 1.x. AcctExpires now returns -1 instead of 1970-01-01 00:00:00 if the account does not expire. Several spelling formats have been deprecated rom hte NT default to something human-readable.




SETINFO

<CFX_UserManager ACTION="USERS"
USERNAME=""
[HOMEDIR=""]
[COMMENT=""]
[FLAGS=""]
[SCRIPTHPATH=""]
[FULLNAME=""]
[USRCOMMENT=""]
[PARMS=""]
[WORKSTATIONS=""]
[ACCTEXPIRES=""]
[LOGONHOURS=""]
[COUNTRYCODE=""]
[CODEPAGE=""]
[PRIMARYGROUPID=""]
[PROFILE=""]
[HOMEDIRDRIVE=""]
[PASSWORDEXPIRED=""]
[SCRIPT="YES|NO"]
[ACCOUNTDISABLE="YES|NO"]
[HOMEDIRREQUIRED="YES|NO"]
[PASSWORDNOTREQUIRED="YES|NO"]
[PASSWORDCANTCHANGE="YES|NO"]
[LOCKOUT="YES|NO"]
[DONTEXPIREPASSWORD="YES|NO"]
[SERVERNAME=""]
>

Sets or changes information relatingto the NT user account.

Most of these fields have been discussed along with the GETINFO function above, so you should refer to that if you haven't already.

Here's a hint if you're trying to set your "Primary Group". See where it says PrimaryGroupID here and in GETINFO? Now, when you list (domain) GROUPS, see where it says GroupID? Yes, those are the same thing. If you set your PrimaryGroupID to the GroupID of a domain group then you've just set that as your Primary Group. FYI.

If servername is not supplied then the local machine is assumed.

Again, flags is left over from 1.x. It allows you to directly modify certain properties of the user account via boolean flags. 66409 is the Administrator default. 66115 is the Guest default.

  1. Script (1)
  2. AccountDisable (2)
  3. HomeDirRequired (8)
  4. PasswdNotReqd (32)
  5. PasswdCantChange (64)
  6. Lockout (16)
  7. DontExpirePasswd (65536)




CHANGEPASSWORD

<CFX_UserManager ACTION="CHANGEPASSWORD" USERNAME="" OLDPASSWORD="" NEWPASSWORD="" [DOMAINNAME="" or SERVERNAME=""] >

Changes a user account password from OLDPASSWORD to NEWPASSWORD. If you do not specify the domainname or the servername then the local domain is assumed.

This function may take several seconds to complete.





ISLOGGEDIN

<CFX_UserManager ACTION="ISLOGGEDIN" USERNAME="" [SERVERNAME=""]>

Checks if specified user is currently logged into the system. Return boolean values in UserManager variable. "0" means user is not logged in. "1" means user is logged in.

New as of 2.0.




USEREXISTS

<CFX_UserManager ACTION="USEREXISTS" USERNAME="" [SERVERNAME=""]>

Checks if specified user exists. Return boolean values, ie "0" or "1". "0" means user account does exist. "1" means user account does not exist.

New as of 2.0beta5.




LOGGEDUSERS

<CFX_UserManager ACTION="LOGGEDUSERS" [SERVERNAME=""] [QUERY=""]>

Returns a query containing a list of all users currently logged onto a server. Note that there are some instances involving SAMBA, NT3.51 and certain NT service patches where the user list is known to be sticky. That is, once a user logs in they may listed as still logged in for a time after they have actually logged out.

The Domains field is a coma-separated list of all domains/servers visited by the user. The other columns are self-evident: Domain is the domain of the user, the LoginServer is the machine they logged in from, etc.

LEGACY NOTE: In 1.x this function was called LOGGEDUSERSENUM. To support legacy cfml code you may still use the action LOGGEDUSERSENUM. It simply calls the current LOGGEDUSERS function.




VALIDATE

<CFX_UserManager ACTION="VALIDATE" USERNAME="" PASSWORD="" [SERVERNAME=""]>

New as of 1.12, you can validate user acounts. That is, you can give this function a username and password, and it will tell you if that is a validate account or not.

Btw, this function may seem innocent enough at first, but do not let access to it be easily exposed on your site. Hackers simply running nothing other than ColdFusion like you could easily set up a script with CFHTTP, etc to toss a dictionary at your site in order to brute force figure out what your Administrator password is. And so on. As with all functions here, no matter how trival they may sem at first, guard them well.

Anyway, results of VALIDATE are returned in boolean numbers. "0" (aka FALSE) if the username/password pair do not match. "1" (aka TRUE) if they do. If any error occurs or the account does not exist or the password is incorrect then "0" will be returned.

Note that if an account is "DISABLED", or some other limitations are enabled then this function may tell you their username/password are invalid (as well as producing a lengthy bit of text in the UserManagerError variable.) This is normal. Technically the VALIDATE function is actually determining whether or not the account is able to be logged into, not whether it simply exists. Thus, if the account is disabled, it can not be logged in to and the VALIDATE will fail.

You might also get the A required privilege is not held by the client error message if you do not have the Cold Fusion Server logging is as SystemAccount. You'll need to add the advanced right to the group "Act as part of the operating system" to the account that the Cold Fusion server runs under.

LEGACY NOTE: This function superceeds the old VERIFY function. Externally the only difference is VALIDATE returns boolean values, while VERIFY returned the text values "TRUE" or "FALSE". For legacy purposes VERIFY is still maintained in the code, but is otherwise undocumented.




COPY

<CFX_UserManager ACTION="COPY"
USERNAME=""
PASSWORD=""
COMMENT=""
TEMPLATEUSERNAME=""
[SERVERNAME=""]
>

[CAUTION: This function was a last minute user-request the night before 2.0 release.
It's not been tested. Wait for ums2.1.]

Have you every used User Manager for Domains' copy feature? Well then you know what this function does. It uses another account as a template in the create of a new user account. This is similiar to an ADD function in that it creates new acounts.





SETPRIMARYGROUP

<CFX_UserManager ACTION="SETPRIMARYGROUP"
USERNAME=""
GROUP=""
[SERVERNAME=""]
>

You can do this without a special function using GROUPS and SETINFO, but this is simplier to use. SETPRIMARYGROUP will change the global group which is a users' primary group. For this function to work the user must already be a member of said group (GROUPADDUSER).





GETPRIMARYGROUP

<CFX_UserManager ACTION="SETPRIMARYGROUP"
USERNAME=""
[SERVERNAME=""]
>

You can use GETINFO and GROUPS to derive the name of an accounts' primary group, but this is faster. It returns the name of the primary (global) group the user is a member of in UserManager.

Blank if the group or username is unknown.

New for 2.1




top

L O C A L G R O U P S

LOCALGROUPS

<CFX_UserManager ACTION="LOCALGROUPS" [SERVERNAME=""] [QUERY=""]>

Lists all localgroups. Data is returned in an SQL query with the fields Name and Comment. If servername is not supplied then the local machine is assumed.

LEGACY NOTE: In 1.x this function was called LOCALGROUPSENUM. To support legacy cfml code you may still use the action LOCALGROUPSENUM. It simply calls the current LOCALGROUPS function.




LOCALGROUPADD

<CFX_UserManager ACTION="LOCALGROUPADD" LOCALGROUP="" COMMENT="" [SERVERNAME=""]>

Adds to the local groups.





LOCALGROUPDEL

<CFX_UserManager ACTION="LOCALGROUPDEL" LOCALGROUP="" [SERVERNAME=""]>

Deletes a local group.





LOCALGROUPADDMEMBERS

<CFX_UserManager ACTION="LOCALGROUPADDMEMBERS" LOCALGROUP="" [MEMBERS=""] [SERVERNAME=""]>

Adds members to the specified local group. Members may be a comma separated list.





LOCALGROUPDELMEMBERS

<CFX_UserManager ACTION="LOCALGROUPADD" LOCALGROUP="" [MEMBERS=""] [SERVERNAME=""]>

Deletes members from the specified local group. Members may be a comma separated list.





LOCALGROUPGETMEMBERS

<CFX_UserManager ACTION="LOCALGROUPGETMEMBERS" LOCALGROUP="" [SERVERNAME=""] [QUERY=""]>

Lists all members of a local group.





GETLOCALGROUPS

<CFX_UserManager ACTION="GETLOCALGROUPS" USERNAME="" [SERVERNAME=""] [QUERY=""]>

Gets list of local groups user is in. If servername is not supplied then the local machine is assumed.





top

G R O U P S

GROUPS

<CFX_UserManager ACTION="GROUPS" [SERVERNAME=""] [QUERY=""]>

Lists all groups. If servername is not supplied then the local machine is assumed.

LEGACY NOTE: In 1.x this function was called GROUPSENUM. To support legacy cfml code you may still use the action GROUPSENUM. It simply calls the current GROUPS function.




GROUPADD

<CFX_UserManager ACTION="GROUPADD" GROUP="" COMMENT="" [SERVERNAME=""]>

Adds to the global groups.





GROUPDEL

<CFX_UserManager ACTION="GROUPDEL" GROUP="" [SERVERNAME=""]>

Deletes a global group.





GROUPADDUSER

<CFX_UserManager ACTION="GROUPADDUSER" GROUP="" USERNAME="" [SERVERNAME=""]>

Adds a user to a global group.





GROUPDELUSER

<CFX_UserManager ACTION="GROUPDELUSER" GROUP="" USERNAME="" [SERVERNAME=""]>

Deletes a user from a global group.





GROUPGETUSERS

<CFX_UserManager ACTION="GROUPGETUSERS" GROUP="" [SERVERNAME=""] [QUERY=""]>

Lists all users of a global group.





GETGROUPS

<CFX_UserManager ACTION="GETGROUPS" USERNAME="" [SERVERNAME=""] [QUERY=""]>

Gets list of global groups user is in.





SETGROUPS

<CFX_UserManager ACTION="SETGROUPS" GROUP="" USERNAME="" [SERVERNAME=""]>

Sets user info. If servername is not supplied then the local machine is assumed.





top

VERSION HISTORY

[The grassy field]





top
f i n i
-{ts '2001-12-03 03:35:35'} /ihtkdocs/UserManager/index.cfm-