Tuesday, November 18, 2003

ADSI_IsMemberOfGroup()

While working with Active Directory in IIS/ASP on another web project, we hit upon the problem that the ADSI function IsMember() won't tell you if a user is a member by virtue of indirect group membership. (Where user X is a member of group A and group A is a member of group B... IsMember() will say that X is not a member of B and there's no switch to make it traverse nested groups).

So I hacked up a function called ADSI_IsMemberOfGroup() which, given a NT4-style domain name (e.g. "DOMAINNAME"), the NT4-style username (e.g. "THOMAS") and the name of the group (e.g. "Network Administrators"), will make an attempt to determine if THOMAS is a member of Network Administrators either directly or through nested group membership. It then returns TRUE if it found membership, or FALSE if no membership or an error occured.

Now, the code is rather rough, it uses recursion but doesn't check for runaway conditions (however, the IIS script time-out will kill the page eventually). Also, it's unable to properly search AD for the domain so it makes the assumption that there is only one domain in the directory. If someone can find code to finish out support of multi-domain situations where a SAM name can appear multiple times I'd appreciate it.

See the source: ADSI_IsMemberOfGroup() (VBScript for IIS v5.x)

Sunday, November 16, 2003

MinGW (basic makefile)

First off, make sure you have the GNU Tools for Win32, MinGW, and MSYS installed and working.

Then, create the following makefile in your project folder (note, any indented lines must be done using the TAB character, not spaces):


############################################
# MAKEFILE FOR main.exe -- last rev 2003-11-14 TGH

# NOTES:
# - This makefile was designed for compilation using MinGW under Win32
# - Get GNU tools for Win32 (http://sourceforge.net/projects/unxutils/)
# - Get MinGW (http://www.mingw.org/)
# - Get MSYS (http://www.mingw.org/msys.shtml)
# - Make sure that the GNU tools and MinGW are in your PATH= statement
# - Start the MSYS shell, cd to your project file and type "make all" to compile

############################################
# MACRO DEFINITIONS
# (hint: "make -p" will spit out a default list for your environment)
# $@ - name of the file to be made (e.g. "main.o")
# $? - names of the changed dependents

CC=gcc
LINK=$(CC)

#COMPILE FLAGS - CFLAGS2 appears at the end of the command
CFLAGS1=
CFLAGS2=
#CFDEBUG= -Wp,-DDEBUG
CFDEBUG=

#LINK FLAGS - LFLAGS2 appears at the end of the command
LFLAGS1=
LFLAGS2=

#OBJS is the list of all object files created by the compiles
OBJS=module1.o module2.o main.o
PROGNAME=main.exe

############################################
# IMPLICIT RULES
# $< - name of the related file that caused the action (e.g. "main.c")
# $* - prefix shared by both the target and the dependent (e.g. "main")

.c.o:
$(CC) $(CFLAGS1) $(CFDEBUG) -c -o $@ $*.c $(CFLAGS2)

.o.exe:
$(LINK) $(LFLAGS1) -o $@ $? $(LFLAGS2)

############################################
# MAKE TARGETS (all, clean, install, etc)
# - all: should be the first link target within the make file

all: $(PROGNAME)

clean:
-rm $(OBJS)
-rm $(PROGNAME)

install:
@echo No action taken.

############################################
# MODULES TO BE COMPILED

module1.o: module1.c module1.h
module2.o: module2.c module2.h
main.o: main.c module1.h module2.h

############################################
# PROGRAM TO BE COMPILED (.EXE)

$(PROGNAME): $(OBJS)
$(LINK) $(LFLAGS1) -o $@ $(OBJS) $(LFLAGS2)

### END OF MAKEFILE ###


Once that's finished, and you've changed things like main.exe, module1.c to match your project, open up the MSYS window and type the following commands to compile:

UserName@MACHINENAME ~
$ pwd
/home/UserName

UserName@MACHINENAME ~
$ cd /c/dev/projects/test/src

UserName@MACHINENAME /c/dev/projects/test/src
$ make clean
rm module1.o module2.o main.o
rm main.exe

UserName@MACHINENAME /c/dev/projects/test/src
$ make all
gcc -c -o module1.o module1.c
gcc -c -o module2.o module2.c
gcc -c -o main.o main.c
gcc -o main.exe module1.o module2.o main.o

UserName@MACHINENAME /c/dev/projects/test/src
$ ls *.exe
main.exe

RenByDate v2003.11a (a.k.a. QRen)

Finished up the first (re-)release of RenByDate which is a tool that will rename a file and allow you to insert things like the current year, or the day of the week into the filename. This is actually a re-write of QREN that I wrote back in 1991-1992 and uploaded to the CompuServe forums under the userID of 71750,3724 (and was also part of a larger package called QUTIL1). Back then, I charged $5/seat or $20/server for the package but now I'm re-releasing it under the BSD open-source license.

The old version of QREN was written for the MS-DOS platform (using the MIX C compiler) and used some MIX C specific call as well as not being able to handle longer filenames. During the re-write, I used MinGW and tried to re-structure the code to make for easy porting to other platforms.

Installation is as easy as copying the "renbydate.exe" file to a directory in your Windows PATH. None of the other files are required.

Using RenByDate is pretty simple: renbydate log.txt log_%Y%m%d_%H%M.txt will rename "log.txt" to "log_19921021_1455.txt" (if the date/time is currently Oct-21-1992 at 2:55pm). Or you can specify that it should use the timestamp of the file by putting the "-f" switch in. If you're using it inside of a batch file, you'll probably need to double-up the '%' signs (e.g. %%Y%%m%%d) because MS-DOS/Windows likes to interpret '%' signs differently then when you're using the command at the command prompt. As with the original version, it only handles single filenames and will choke on wildcards.

Download:
renbydate-2003.11a.zip - 10KB, Win32 (README.TXT and LICENSE.TXT)
renbydate-2003.11a-source.zip

renbydate 2003.11a - Rename files based on the current or file timestamp value.
Copyright 1991-1992,2003, Thomas G. Harold, All Rights Reserved.
For updates visit http://www.tgharold.com/ or e-mail tgh@tgharold.com.

Usage: renbydate [-f] filename newname
-f - Rename using filename time stamp
filename - This is the original filename, wildcards are not allowed.
newname - This is the new filename, with optional time/date codes

The following is a list of codes to use in the string. (case sensitive)
%a - Abbr. weekday name %A - Full weekday name
%b - Abbr. month name %B - Full month name
%d - Day of month (01..31)
%H - hour (00..23) %I - hour (01..12)
%j - day of year (001..366) %m - month (01..12)
%M - minute (00..59) %p - AM/PM indicator
%S - second (00.59) %U - week of year (Sun first, 00..52)
%w - day of week (0..7) %W - week of year (Mon first, 00..52)
%y - year (00..99) %Y - year (0000..9999)
%Z - timezone name %% - '%' (percent) sign

Note: In a windows batch file, you must double up '%' signs.


For the historically curious folks, they may wish to download the original QRen v1.0 zip file from 1992. Or you can see the contents of the old QRen Documentation, Site License, or Product List files.

Source files:

dbg.c
dbg.h
file.c
file.h
jdate.c
jdate.h
LICENSE.TXT
makefile
renbydate.c
usage.c
usage.h

Tuesday, November 11, 2003

Getting Started with MinGW

Getting started with MinGW


So I'm trying to dust off my very rusty (and crusty) C and C++ skills and I've downloaded the MinGW compiler and the MSYS package. On the plus side, compiling with MinGW means that you don't need the Cygwin stuff in order to distribute windows-only binaries - but on the down side, MinGW has very little documentation (I have yet to find a central site). I guess you could try the GCC home pages since MinGW is a port of the GCC compiler collection.

Anyway, it took me a bit to figure out how to compile and link a C application where I have (1) module (usage.c and usage.h) and (1) program (main.c). To compile this into a working .exe file requires the following steps if you're doing it by hand:

gcc -c -o usage.o usage.c
gcc -c -o main.o main.c
gcc -o main.exe main.o usage.o

Now that I know those basics, I need to remember how to use makefiles...