(DEFINE-FILE-INFO PACKAGE "INTERLISP" READTABLE "INTERLISP" BASE 10)
(FILECREATED "25-Nov-87 14:41:19" {ERIS}<LISPCORE>LIBRARY>NSMAINTAIN.;12 34051  

      changes to%:  (FNS NSMAINTAIN)

      previous date%: "14-Aug-87 15:55:50" {ERIS}<LISPCORE>LIBRARY>NSMAINTAIN.;11)


(* "
Copyright (c) 1985, 1986, 1987 by Xerox Corporation.  All rights reserved.
")

(PRETTYCOMPRINT NSMAINTAINCOMS)

(RPAQQ NSMAINTAINCOMS ((COMS (* ; "Main entry and utility fns") (FNS NSMAINTAIN \NSMT.READFNAME \NSMT.COLLECT.NAMES \NSMT.GET.REMARK \NSMT.GET.PASSWORD \NSMT.LOGIN \NSMT.CHANGE.DOMAIN \NSMT.PRINT.LIST \NSMT.PROCESS.LIST \NSMT.SHOW.RESULT)) (COMS (* ; "Ordinary user commands") (FNS \NSMT.CHANGE.PASSWORD \NSMT.DESCRIBE.GROUP \NSMT.DESCRIBE.OBJECT \NSMT.DESCRIBE.PROPERTY \NSMT.LIST.OBJECTS \NSMT.LIST.CLEARINGHOUSES \NSMT.LIST.SERVERS \NSMT.SHOW.DETAILS \NSMT.GROUP.FILTER \NSMT.LIST.ADMINISTRATORS \NSMT.LIST.DOMAINS \NSMT.TYPE.ENTRY \NSMT.TYPE.MEMBERS)) (COMS (* ; "Administrator commands") (FNS \NSMT.ADD.ALIAS \NSMT.ADD.GROUP \NSMT.ADD.USER \NSMT.CHANGE.ADMINISTRATORS \NSMT.CHANGE.GROUP.COMPONENT \NSMT.CHANGE.REMARK \NSMT.REMOVE.ALIAS \NSMT.REMOVE.OBJECT \NSMT.REMOVE.USER)) (FILES (SYSLOAD) DES AUTHENTICATION) (VARS *NSMAINTAIN-COMMANDS* *NSMAINTAIN-ABORT-ITEM*) (ADDVARS (CH.PROPERTIES (ALIAS 1)) (*NSMAINTAIN-DESCRIPTIVE-PROPERTIES* 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10023 10024) (*NSMAINTAIN-IGNORE-PROPERTIES* 6 7 10027 20003 20002 20101) (*NSMAINTAIN-PROPERTY-FORMATS* (4 CLEARINGHOUSE . NETWORK.ADDRESS.LIST) (8 RECORD (SIMPLE BOOLEAN) (STRONG BOOLEAN)) (30 . NSNAME) (31 CLEARINGHOUSE . MAILBOX.VALUES) (10000 . STRING) (10001 . STRING) (10002 . STRING) (10003 . STRING) (10004 . STRING) (10005 . STRING) (10006 . STRING) (10007 . STRING) (10008 . STRING) (10009 . STRING) (10010 . STRING) (10011 . STRING) (10012 . STRING) (10013 . STRING) (10014 . STRING) (10015 . STRING) (10016 . STRING) (10017 . STRING) (10018 . STRING) (10019 . STRING) (10020 . STRING) (10021 . STRING) (10022 . STRING) (10023 . STRING) (10024 . STRING) (10029 . STRING) (10030 . STRING) (10032 . STRING) (10034 . STRING) (10035 . STRING) (15002 . STRING) (20000 CLEARINGHOUSE . USERDATA.VALUE) (20001 GAP . RS232CData) (20007 . NSNAME) (20102 GAP . RS232CBack) (29965 . STRING) (30005 . NSNAME))) (DECLARE%: EVAL@COMPILE DONTCOPY (GLOBALVARS *NSMAINTAIN-COMMANDS* *NSMAINTAIN-ABORT-ITEM* *NSMAINTAIN-DESCRIPTIVE-PROPERTIES* *NSMAINTAIN-IGNORE-PROPERTIES* *NSMAINTAIN-PROPERTY-FORMATS*) (P (CL:PROCLAIM (QUOTE (CL:SPECIAL LASTDOMAIN LASTNAME LASTGROUP LASTSTRING SERVERTYPES ALLTYPES DEFAULTDOMAIN LASTLIST)))) (LOCALVARS . T)))
)



(* ; "Main entry and utility fns")

(DEFINEQ

(NSMAINTAIN
(LAMBDA NIL (* ; "Edited 25-Nov-87 14:36 by bvm:") (PROG ((*STANDARD-OUTPUT* (\GETSTREAM T (QUOTE OUTPUT))) (LASTNAME (PARSE.NSNAME (CAR (\INTERNAL/GETPASSWORD (QUOTE |NS::|))))) DEFAULTDOMAIN LASTDOMAIN LASTGROUP LASTSTRING LASTLIST SERVERTYPES ALLTYPES FULLNAME) (DECLARE (SPECVARS LASTNAME LASTDOMAIN LASTGROUP LASTSTRING LASTLIST SERVERTYPES ALLTYPES DEFAULTDOMAIN)) (* ; "*STANDARD-OUTPUT* setting is to make sure T for FORMAT and PRINTOUT are the same (yecch).") (SETQ FULLNAME (CH.LOOKUP.OBJECT LASTNAME)) (CL:FORMAT T "[Default login:  ~A~:[ (not a valid name)~;~];~%% Default domain: ~A]~%%" (NSNAME.TO.STRING (OR FULLNAME LASTNAME) T) FULLNAME (NSNAME.TO.STRING (SETQ LASTDOMAIN (SETQ DEFAULTDOMAIN (create NSNAME NSDOMAIN ← CH.DEFAULT.DOMAIN NSORGANIZATION ← CH.DEFAULT.ORGANIZATION))) T)) (if (AND FULLNAME (NOT (EQUAL.CH.NAMES LASTNAME FULLNAME))) then (* ; "Canonical name different from current login, so be helpful and canonize") (\INTERNAL/SETPASSWORD (QUOTE |NS::|) (CONS (NSNAME.TO.STRING (SETQ LASTNAME FULLNAME) T) (\DECRYPT.PWD (CONCAT (CDR (\INTERNAL/GETPASSWORD (QUOTE |NS::|)))))))) (do (TERPRI T) repeatwhile (NULL (ERSETQ (bind CMD while (SETQ CMD (ASKUSER NIL NIL "CH: " *NSMAINTAIN-COMMANDS* T NIL (QUOTE (AUTOCOMPLETEFLG T)))) do (if (LISTP CMD) then (APPLY (CAR CMD) (CDR CMD)) else (CL:FUNCALL CMD)) (TERPRI T)))))))
)

(\NSMT.READFNAME
(LAMBDA (PROMPT DEFAULT DOMAINFLG ...FLG CHECK *OK) (* ; "Edited 14-Aug-87 15:05 by bvm:") (PROG ((COLON ":") NAME COLPOS FULLNAME REALNAME) RETRY (COND ((NULL (SETQ NAME (PROMPTFORWORD PROMPT (if (AND DEFAULT (TYPENAMEP DEFAULT (QUOTE NSNAME))) then (* ; "Make it fully qualified") (NSNAME.TO.STRING DEFAULT T) else DEFAULT) NIL T NIL NIL (CHARCODE (EOL))))) (printout T " xxx" T) (* ; "aborted") (RETURN NIL))) (SETQ FULLNAME (COND ((AND (SETQ COLPOS (STRPOS COLON NAME)) (NEQ COLPOS (NCHARS NAME))) (SETQ COLPOS (STRPOS COLON NAME (ADD1 COLPOS))) (* ; "Find second colon") (if DOMAINFLG then (* ; "Wants domain name--a 2-part name") (if COLPOS then (* ; "too many colons") (PRINTOUT T " Invalid domain" T) (RETURN NIL) else (PARSE.NSNAME NAME 2 DEFAULTDOMAIN)) else (COND ((NOT COLPOS) (* ; "Org defaulted") (printout T COLON (fetch NSORGANIZATION of DEFAULTDOMAIN))) ((EQ COLPOS (NCHARS NAME)) (* ; "Trailing colon after domain") (printout T (fetch NSORGANIZATION of DEFAULTDOMAIN)))) (PARSE.NSNAME NAME 3 DEFAULTDOMAIN))) (T (* ; "Completely unqualified (or only a trailing colon)") (if COLPOS then (* ; "User typed, e.g., %"Fred:%"") (SETQ NAME (SUBSTRING NAME 1 -2)) else (PRIN1 COLON T)) (if DOMAINFLG then (printout T (fetch NSORGANIZATION of DEFAULTDOMAIN)) (create NSNAME using DEFAULTDOMAIN NSDOMAIN ← NAME) else (printout T (fetch NSDOMAIN of DEFAULTDOMAIN) COLON (fetch NSORGANIZATION of DEFAULTDOMAIN)) (create NSNAME using DEFAULTDOMAIN NSOBJECT ← NAME))))) (if (STRPOS "*" NAME) then (if (SELECTQ *OK (:ANY (* ; "Any old * is ok") NIL) (NIL (* ; "No * is ok") T) (PROGN (* ; "* permitted in first part only") (OR (STRPOS "*" (fetch NSORGANIZATION of FULLNAME)) (AND (NOT DOMAINFLG) (STRPOS "*" (fetch NSDOMAIN of FULLNAME)))))) then (PRINTOUT T " ... Invalid use of *" T) (SETQ DEFAULT FULLNAME) (GO RETRY)) elseif CHECK then (* ; "Canonicalize the name") (SETQ REALNAME (CH.LOOKUP.OBJECT FULLNAME)) (if (NULL REALNAME) then (if (EQ CHECK :OK) then (printout T " (non-existent name)") else (printout T " ... No such name.") (if (NOT (if (NEQ CHECK :CONFIRM) then (* ; "Must be valid name") (TERPRI T) NIL else (* ; "Accept non-names") (CL:Y-OR-N-P " Use it anyway? "))) then (SETQ DEFAULT FULLNAME) (GO RETRY))) elseif (NOT (EQUAL.CH.NAMES FULLNAME REALNAME)) then (* ; " show real name") (printout T " = " (NSNAME.TO.STRING (SETQ FULLNAME REALNAME) T)))) (if ...FLG then (PRIN1 " ... " T)) (RETURN FULLNAME)))
)

(\NSMT.COLLECT.NAMES
(LAMBDA (PROMPT CHECK *OK) (* ; "Edited 14-Aug-87 15:14 by bvm:") (* ;; "Prompt for an arbitrary number of names.  CHECK and *OK are the corresponding args to \nsmt.readfname.") (bind NAME while (SETQ NAME (PROGN (TERPRI T) (\NSMT.READFNAME PROMPT NIL NIL NIL CHECK *OK))) collect NAME))
)

(\NSMT.GET.REMARK
(LAMBDA (DEFAULT) (* ; "Edited 11-Aug-87 12:24 by bvm:") (* ;; "Prompt for a remark (an arbitrary string used to describe an object).  DEFAULT if any is usually the previous remark.") (PROMPTFORWORD "Remark (terminate with CR):" DEFAULT NIL T NIL NIL (CHARCODE (CR))))
)

(\NSMT.GET.PASSWORD
(LAMBDA (PROMPT) (* ; "Edited 11-Aug-87 13:39 by bvm:") (* ;; "Read a password, prompting with PROMPT.  Ask user to retry password to verify that it was typed correctly.  Loop if the retype mismatches the original.  Return NIL if user declines to enter a password in the first place.") (PROG (PASS) LP (if (NULL (SETQ PASS (PROMPTFORWORD PROMPT NIL NIL T (QUOTE *)))) then (RETURN NIL) elseif (STREQUAL PASS (PROMPTFORWORD " (retype password)" NIL NIL T (QUOTE *))) then (RETURN PASS) else (PRINTOUT T T "Mismatch.  Try again." T) (SETQ PROMPT "Password:") (GO LP))))
)

(\NSMT.LOGIN
(LAMBDA NIL (* ; "Edited 31-Jul-87 15:41 by bvm:") (bind LOGINFO FULLNAME NAME until (OR (NULL (SETQ LOGINFO (\INTERNAL/GETPASSWORD (QUOTE |NS::|) T))) (if (SETQ FULLNAME (CH.LOOKUP.OBJECT (SETQ NAME (PARSE.NSNAME (CAR LOGINFO) 3 DEFAULTDOMAIN)))) then (RPLACA LOGINFO (NSNAME.TO.STRING FULLNAME T)) (\NSMT.SHOW.RESULT (NS.AUTHENTICATE (NS.MAKE.SIMPLE.CREDENTIALS LOGINFO))) else (CL:FORMAT T "  Invalid name ~A~%%" (NSNAME.TO.STRING NAME T)) NIL))))
)

(\NSMT.CHANGE.DOMAIN
(LAMBDA NIL (* ; "Edited 27-Jul-87 13:00 by bvm:") (LET ((DOMAIN (\NSMT.READFNAME " (for name entry) to be:" DEFAULTDOMAIN T))) (if DOMAIN then (TERPRI T) (if (CL:Y-OR-N-P "Set this default globally as well (i.e. for use outside Maintain)? ") then (SETQ CH.DEFAULT.DOMAIN (fetch NSDOMAIN of DOMAIN)) (SETQ CH.DEFAULT.ORGANIZATION (fetch NSORGANIZATION of DOMAIN))) (SETQ LASTDOMAIN (SETQ DEFAULTDOMAIN DOMAIN)))))
)

(\NSMT.PRINT.LIST
(LAMBDA (LST PREFIX) (* ; "Edited 27-Jul-87 13:10 by bvm:") (if (EQ (CAR LST) (QUOTE ERROR)) then (\NSMT.SHOW.RESULT LST) else (if PREFIX then (PRINTOUT T .FONT BOLDFONT PREFIX .FONT DEFAULTFONT)) (if (NULL LST) then (PRINTOUT T "(none)") else (MAPRINT LST T NIL NIL ", ")) (TERPRI T)))
)

(\NSMT.PROCESS.LIST
(LAMBDA (ITEMS DOMAIN LISTFN) (* ; "Edited 14-Aug-87 14:25 by bvm:") (* ;; "Display a list of Clearinghouse objects.  OBJECTS is the result of some sort of listing call.  If the result is a list of strings, DOMAIN is supplied so that future %"Show Details%" commands can use it.  LISTFN is a function to call to print the list; it returns a possibly new list of objects to be saved for later.") (if (EQ (CAR ITEMS) (QUOTE ERROR)) then (\NSMT.SHOW.RESULT ITEMS) else (if LISTFN then (SETQ ITEMS (CL:FUNCALL LISTFN ITEMS)) else (\NSMT.PRINT.LIST ITEMS)) (if ITEMS then (* ; "Save list for Show Details command.") (SETQ LASTLIST (CONS (AND DOMAIN (SETQ LASTDOMAIN (create NSNAME using DOMAIN NSOBJECT ← NIL))) ITEMS)))))
)

(\NSMT.SHOW.RESULT
(LAMBDA (RESULT PART) (* ; "Edited 11-Aug-87 13:51 by bvm:") (* ;; "Used to show the outcome of a typical clearinghouse operation.  If RESULT is T or NIL, it succeeded, otherwise we print an error code") (if (OR (EQ RESULT T) (NULL RESULT)) then (printout T " done" T) (* ; "Return T for success") T else (if PART then (PRINTOUT T " " PART)) (PRINTOUT T " failed: " (if (EQ (CAR (LISTP RESULT)) (QUOTE ERROR)) then (CADDR RESULT) else RESULT) T) NIL))
)
)



(* ; "Ordinary user commands")

(DEFINEQ

(\NSMT.CHANGE.PASSWORD
(LAMBDA NIL (* ; "Edited 11-Aug-87 13:40 by bvm:") (PROG ((CURRENTUSER (CAR (\INTERNAL/GETPASSWORD (QUOTE |NS::|)))) NAME PASS) (DECLARE (USEDFREE LASTNAME LASTSTRING)) (COND ((NULL (SETQ NAME (\NSMT.READFNAME " for user:" CURRENTUSER)))) ((NULL (SETQ PASS (\NSMT.GET.PASSWORD " to be:"))) (printout T " xxx" T)) (T (PRIN1 "..." T) (if (NULL (SETQ NAME (CH.LOOKUP.OBJECT NAME))) then (PRINTOUT T " no such name." T) elseif (EQUAL.CH.NAMES (PARSE.NSNAME CURRENTUSER) (SETQ LASTNAME (SETQ LASTSTRING NAME))) then (* ; "Changing own password") (COND ((\NSMT.SHOW.RESULT (AS.CHANGE.OWN.PASSWORDS (\ENCRYPT.PWD (CONCAT PASS)))) (\INTERNAL/SETPASSWORD (QUOTE |NS::|) (CONS (NSNAME.TO.STRING NAME T) PASS)))) else (* ; "Changing someone else's password.  Only way to do this is to delete the old keys and create new ones.") (\NSMT.SHOW.RESULT (AS.REPLACE.PASSWORDS NAME (\ENCRYPT.PWD (CONCAT PASS)))))))))
)

(\NSMT.DESCRIBE.GROUP
(LAMBDA (NAME PROPS EXTRA BRIEFLY) (* ; "Edited 31-Jul-87 11:36 by bvm:") (if EXTRA then (PRINTOUT T T T NAME " is also a ") else (PRINTOUT T " is a ")) (LET ((P (CONSTANT (CH.PROPERTY (QUOTE USERGROUP))))) (if (MEMB P PROPS) then (CL:FORMAT T "User Group (~A)" (CADR (CH.RETRIEVE.ITEM NAME P (QUOTE STRING)))) (SETQ PROPS (CL:DELETE P PROPS)) else (PRINTOUT T "group"))) (if (NOT BRIEFLY) then (TERPRI T) (\NSMT.PRINT.LIST (CH.RETRIEVE.PROPERTY.ACL NAME (QUOTE MEMBERS) (QUOTE Administrators)) "Owners: ") (\NSMT.PRINT.LIST (CH.RETRIEVE.PROPERTY.ACL NAME (QUOTE MEMBERS) (QUOTE selfControllers)) "Friends: ")) PROPS)
)

(\NSMT.DESCRIBE.OBJECT
(LAMBDA (NAME BRIEFLY) (* ; "Edited 14-Aug-87 15:40 by bvm:") (* ;; "Identify name by type and show its interesting properties.") (PROG ((NAME&PROPS (CH.LIST.PROPERTIES NAME)) MAINPROPS PROPS ALIASES DESCR FORWARD GROUPP) (if (EQ (CAR NAME&PROPS) (QUOTE ERROR)) then (RETURN (\NSMT.SHOW.RESULT NAME&PROPS)) else (SETQ NAME (CAR NAME&PROPS))) (FRESHLINE T) (printout T T .FONT BOLDFONT (NSNAME.TO.STRING NAME T) .FONT DEFAULTFONT) (SETQ PROPS (CL:NSET-DIFFERENCE (CADR NAME&PROPS) *NSMAINTAIN-IGNORE-PROPERTIES*)) (for P in (SETQ MAINPROPS (CL:INTERSECTION PROPS *NSMAINTAIN-DESCRIPTIVE-PROPERTIES*)) bind GOTSOME do (if GOTSOME then (printout T T NAME " is also") else (* ; "First prop") (printout T " is")) (printout T " a " (CL:STRING-CAPITALIZE (STRING (OR (CH.NUMBER.TO.PROPERTY P) P)))) (if (SETQ DESCR (CADR (CH.RETRIEVE.ITEM NAME P))) then (* ;; "Description of object is stored as string on this descriptive property.  Sometimes the value is null, which is why we didn't pass STRING to CH.RETRIEVE.ITEM.  CONCAT is so that we don't get an ugly line break after the open paren.") (printout T (CONCAT " (" (COURIER.READ.REP DESCR NIL (QUOTE STRING)) ")"))) (SETQ PROPS (CL:DELETE P PROPS))) (if (MEMB (CONSTANT (CH.PROPERTY (QUOTE MEMBERS))) PROPS) then (if (MEMB (CONSTANT (CH.PROPERTY (QUOTE USER))) MAINPROPS) then (* ; "Both USER and group?  This is kludge to get NS mail forwarding.") (SETQ PROPS (CL:DELETE (CONSTANT (CH.PROPERTY (QUOTE USERGROUP))) PROPS)) (* ; "describes the forwarding, but is pretty uninteresting") (SETQ FORWARD T) elseif (NULL MAINPROPS) then (SETQ PROPS (\NSMT.DESCRIBE.GROUP NAME PROPS NIL BRIEFLY)) (SETQ GROUPP 0) else (SETQ GROUPP T)) (SETQ PROPS (CL:DELETE (CONSTANT (CH.PROPERTY (QUOTE MEMBERS))) PROPS))) (if (NOT BRIEFLY) then (TERPRI T) (COND ((SETQ ALIASES (CH.LIST.ALIASES.OF NAME)) (\NSMT.PRINT.LIST ALIASES "Aliases: "))) (for P in PROPS do (\NSMT.DESCRIBE.PROPERTY NAME P)) (if FORWARD then (\NSMT.PRINT.LIST (CH.RETRIEVE.MEMBERS NAME) "Forwarding: "))) (if (EQ GROUPP T) then (\NSMT.DESCRIBE.GROUP NAME PROPS T BRIEFLY)) (RETURN (SETQ LASTSTRING (if GROUPP then (SETQ LASTGROUP NAME) else (SETQ LASTNAME NAME))))))
)

(\NSMT.DESCRIBE.PROPERTY
(LAMBDA (FNAME CHP) (* ; "Edited 23-Jul-87 17:35 by bvm:") (* ;; "Called by \NSMT.TYPE.ENTRY to show one particular property.") (LET ((PROPNAME (CH.NUMBER.TO.PROPERTY CHP)) (VAL (CADR (CH.RETRIEVE.ITEM FNAME CHP))) PGM HOW) (PRINTOUT T .FONT BOLDFONT (if PROPNAME then (CL:STRING-CAPITALIZE (STRING PROPNAME)) else (PRINTOUT T "Property ") CHP) ": " .FONT DEFAULTFONT) (if (AND (SETQ HOW (CDR (ASSOC CHP *NSMAINTAIN-PROPERTY-FORMATS*))) (NLSETQ (bind PGM while (AND (LISTP HOW) (LITATOM (CDR HOW)) (CDR HOW)) do (* ; "Reduce to a less qualified name") (SETQ HOW (\GET.COURIER.TYPE (SETQ PGM (CAR HOW)) (CDR HOW))) finally (SETQ VAL (COURIER.READ.REP VAL PGM HOW)) (if (EQ (CAR (LISTP HOW)) (QUOTE RECORD)) then (* ; "make records humanly intelligible") (for PAIR in (CDR HOW) as V in VAL bind (PREFIX ← "[") do (PRIN1 PREFIX T) (PRINTOUT T (CL:STRING-CAPITALIZE (STRING (CAR PAIR))) ": " (SELECTQ (CADR PAIR) (BOOLEAN (CL:IF V "true" "false")) (TIME (GDATE V)) V)) (SETQ PREFIX "; ") finally (PRIN1 "]" T)) else (PRINTOUT T VAL))))) else (* ; "if all else fails, print raw numbers") (PRINTOUT T VAL)) (TERPRI T)))
)

(\NSMT.LIST.OBJECTS
(LAMBDA (PROP LISTFN) (* ; "Edited 14-Aug-87 15:47 by bvm:") (* ;;; "given a clearinghouse property, lookup all objects with a user-specified pattern that have that property.  Default pattern is * in recent domain.") (LET (PATTERN) (COND ((AND (OR PROP (SETQ PROP (ASKUSER NIL NIL " having property " (OR ALLTYPES (SETQ ALLTYPES (CONS (QUOTE ("" "any" EXPLAINSTRING "<cr> - list ALL objects" RETURN (QUOTE ALL))) (CONS (QUOTE (* "" EXPLAINSTRING "* - list ALL objects" CONFIRMFLG T RETURN (QUOTE ALL))) (SORT (DREMOVE (QUOTE ALL) (MAPCAR CH.PROPERTIES (FUNCTION CAR)))))))) T))) (SETQ PATTERN (\NSMT.READFNAME " by pattern:" (AND LASTNAME (create NSNAME using LASTNAME NSOBJECT ← "*")) NIL T NIL T))) (\NSMT.PROCESS.LIST (CH.LIST.OBJECTS PATTERN PROP) PATTERN LISTFN)))))
)

(\NSMT.LIST.CLEARINGHOUSES
(LAMBDA NIL (* ; "Edited 14-Aug-87 14:10 by bvm:") (DECLARE (USEDFREE LASTDOMAIN)) (LET ((DOMAIN (\NSMT.READFNAME " serving domain:" LASTDOMAIN T)) (CHSPART "CHServers") SERVERS) (COND (DOMAIN (SETQ LASTDOMAIN DOMAIN) (TERPRI T) (SETQ SERVERS (LISTP (CH.RETRIEVE.MEMBERS (CONCAT (fetch NSDOMAIN of DOMAIN) ":" (fetch NSORGANIZATION of DOMAIN) ":" CHSPART)))) (if (EQ (CAR SERVERS) (QUOTE ERROR)) then (\NSMT.SHOW.RESULT (if (EQ (CADDR SERVERS) (QUOTE NoSuchObject)) then (* ; "translate this error") "No Such Domain" else SERVERS)) elseif (SETQ SERVERS (for S in SERVERS collect (if (AND (STRING-EQUAL (fetch NSDOMAIN of S) CHSPART) (STRING-EQUAL (fetch NSORGANIZATION of S) CHSPART)) then (* ;; "Clearinghouse names are usually of the form server:CHServers:CHServers.  The domain here is thus junk--print the name only.  Hope for not too much confusion if user tries to type name by hand, rather than using Show Details command.") (fetch NSOBJECT of S) else (* ; "An aberrant name--punt by printing all full names") (\NSMT.PROCESS.LIST SERVERS) (RETURN NIL)))) then (* ; "Show short names, preserve domain for Show Details") (\NSMT.PROCESS.LIST SERVERS (create NSNAME NSDOMAIN ← CHSPART NSORGANIZATION ← CHSPART)))))))
)

(\NSMT.LIST.SERVERS
(LAMBDA NIL (* ; "Edited 14-Aug-87 13:55 by bvm:") (* ;; "List Objects specialized to servers.  We offer as choices those properties with SERVICE in their name, plus the oddly generic %"SERVER%".  CLEARINGHOUSE.SERVICE is excluded because its name space doesn't work as you'd expect.") (LET (PROP) (AND (SETQ PROP (ASKUSER NIL NIL " of type " (OR SERVERTYPES (SETQ SERVERTYPES (CONS *NSMAINTAIN-ABORT-ITEM* (SORT (CONS (QUOTE ("Server" "" RETURN (QUOTE SERVER))) (for P in CH.PROPERTIES when (AND (STRPOS "SERVICE" (CAR P) -7) (NEQ (CAR P) (QUOTE CLEARINGHOUSE.SERVICE))) collect (BQUOTE ((\, (CL:STRING-CAPITALIZE (SUBSTRING (CAR P) 1 -9))) "" RETURN (QUOTE (\, (CAR P))))))) T)))) T)) (\NSMT.LIST.OBJECTS PROP))))
)

(\NSMT.SHOW.DETAILS
(LAMBDA NIL (* ; "Edited 14-Aug-87 14:24 by bvm:") (if (NULL LASTLIST) then (PRINTOUT T " (no previous list)" T) else (DESTRUCTURING-BIND (DOMAIN . OBJECTS) LASTLIST (IF (NULL (CDR OBJECTS)) THEN (* ; "only one, describe it straight away") (TERPRI T) (\NSMT.DESCRIBE.OBJECT (if DOMAIN then (create NSNAME using DOMAIN NSOBJECT ← (CAR OBJECTS)) else (CAR OBJECTS))) ELSE (IF (NOT (STRINGP (CAR OBJECTS))) THEN (* ; "Turn ns names into strings") (RPLACD LASTLIST (SETQ OBJECTS (FOR N IN OBJECTS COLLECT (NSNAME.TO.STRING N T))))) (bind (CMDS ← (CONS *NSMAINTAIN-ABORT-ITEM* OBJECTS)) NAME while (SETQ NAME (PROGN (TERPRI T) (ASKUSER NIL NIL "  name: " CMDS T))) do (\NSMT.DESCRIBE.OBJECT (if DOMAIN then (create NSNAME using DOMAIN NSOBJECT ← NAME) else NAME)))))))
)

(\NSMT.GROUP.FILTER
(LAMBDA (NAMES) (* ; "Edited 11-Aug-87 15:47 by bvm:") (* ;; "List function for List Objects -- NAMES is a list of objects that have a members prop.  Filter out those that also have a USER prop, assuming that these %"groups%" are merely for forwarding, and print the rest.") (COND ((for NAME in NAMES bind (PREFIX ← " ") unless (CH.RETRIEVE.ITEM NAME (QUOTE USER)) collect (PRINTOUT T PREFIX NAME) (SETQ PREFIX ", ") NAME)) (T (* ; "Print %"none%"") (\NSMT.PRINT.LIST) NIL)))
)

(\NSMT.LIST.ADMINISTRATORS
(LAMBDA NIL (* ; "Edited 14-Aug-87 14:34 by bvm:") (LET ((DOMAIN (\NSMT.READFNAME " of domain:" LASTDOMAIN T T))) (COND (DOMAIN (\NSMT.PROCESS.LIST (CH.RETRIEVE.DOMAIN.ACL (SETQ LASTDOMAIN DOMAIN) (QUOTE Administrators)))))))
)

(\NSMT.LIST.DOMAINS
(LAMBDA NIL (* ; "Edited 14-Aug-87 15:09 by bvm:") (LET ((DOMAIN (\NSMT.READFNAME " by pattern:" (create NSNAME using LASTDOMAIN NSDOMAIN ← "*") T T NIL T))) (COND (DOMAIN (\NSMT.PRINT.LIST (CH.LIST.DOMAINS DOMAIN))))))
)

(\NSMT.TYPE.ENTRY
(LAMBDA NIL (* ; "Edited 14-Aug-87 15:41 by bvm:") (LET (NAME) (COND ((SETQ NAME (\NSMT.READFNAME " name:" LASTSTRING NIL T NIL T)) (\NSMT.DESCRIBE.OBJECT NAME)))))
)

(\NSMT.TYPE.MEMBERS
(LAMBDA NIL (* ; "Edited 11-Aug-87 15:21 by bvm:") (LET (NAME ITEMS) (DECLARE (USEDFREE LASTGROUP LASTSTRING)) (COND ((SETQ NAME (\NSMT.READFNAME " of group:" LASTGROUP NIL T)) (SETQ LASTSTRING NAME) (SETQ ITEMS (LISTP (CH.RETRIEVE.MEMBERS NAME (QUOTE MEMBERS)))) (if (EQ (CAR ITEMS) (QUOTE ERROR)) then (* ; "Failure.  Translate the %"Missing%" error into English") (\NSMT.SHOW.RESULT (if (EQ (CADDR ITEMS) (QUOTE Missing)) then "Not A Group" else ITEMS)) else (SETQ LASTGROUP NAME) (\NSMT.PRINT.LIST ITEMS) (if ITEMS then (* ; "Save list for Show Details command.") (SETQ LASTLIST (CONS NIL ITEMS))))))))
)
)



(* ; "Administrator commands")

(DEFINEQ

(\NSMT.ADD.ALIAS
(LAMBDA NIL (* ; "Edited 31-Jul-87 12:09 by bvm:") (LET (OBJECT ALIAS) (if (AND (SETQ OBJECT (\NSMT.READFNAME " for object:" LASTSTRING)) (LET ((DEFAULTDOMAIN (create NSNAME using OBJECT NSOBJECT ← NIL))) (DECLARE (CL:SPECIAL DEFAULTDOMAIN)) (* ; "Read the alias by default in the same domain as object") (TERPRI T) (SETQ ALIAS (\NSMT.READFNAME " Alias:" NIL NIL T)))) then (OR (\NSMT.SHOW.RESULT (LISTP (SETQ LASTSTRING (CH.CREATE.ALIAS ALIAS OBJECT)))) (SETQ LASTSTRING OBJECT)))))
)

(\NSMT.ADD.GROUP
(LAMBDA NIL (* ; "Edited 14-Aug-87 15:14 by bvm:") (* ;; "Create a new group") (LET (GROUP REMARK RESULT MEMBERS OWNERS FRIENDS) (if (NOT (SETQ GROUP (\NSMT.READFNAME "  New group name:" NIL NIL T))) elseif (LISTP (SETQ RESULT (CH.CREATE.OBJECT (SETQ LASTSTRING (SETQ LASTGROUP GROUP))))) then (* ; "Failed to create object") (\NSMT.SHOW.RESULT RESULT) else (* ;; "Assume if user had access rights to create the object, then calls below don't fail.  Gather all the info before taking the time to call the Clearinghouse, since sometimes these update calls are very slow.") (TERPRI T) (SETQ REMARK (\NSMT.GET.REMARK)) (CL:FORMAT T "~%%~%%Enter names of members, owners and friends, one per line, terminated with a blank line.~%%") (SETQ MEMBERS (\NSMT.COLLECT.NAMES "Member:" :CONFIRM :ANY)) (CL:FORMAT T "~%%(If you enter no owners, the group will be owned by the administrators of ~A.)~%%" (create NSNAME using GROUP NSOBJECT ← NIL)) (SETQ OWNERS (\NSMT.COLLECT.NAMES "Owner:" T :ANY)) (SETQ FRIENDS (\NSMT.COLLECT.NAMES "Friend:" T :ANY)) (TERPRI T) (CH.ADD.ITEM.PROPERTY GROUP (QUOTE USERGROUP) REMARK (QUOTE STRING)) (if MEMBERS then (PRINTOUT T "Adding members...") (\NSMT.SHOW.RESULT (LISTP (CH.ADD.GROUP.PROPERTY GROUP (QUOTE MEMBERS) MEMBERS T)))) (if OWNERS then (PRINTOUT T "Adding owners...") (LET ((SELF (PARSE.NSNAME (CAR (\INTERNAL/GETPASSWORD (QUOTE |NS::|)))))) (* ;; "Have to make user be first owner, because as soon as we add one administrator, we override the default administrators, which means user is no longer empowered to add the rest of the owners! ") (for NAME in OWNERS when (EQUAL.CH.NAMES NAME SELF) do (if (NEQ NAME (CAR OWNERS)) then (* ; "make it first") (SETQ OWNERS (CONS NAME (REMOVE NAME OWNERS)))) (RETURN) finally (CL:FORMAT T " (including ~A)" (NSNAME.TO.STRING SELF T)) (push OWNERS SELF))) (\NSMT.SHOW.RESULT (for NAME in OWNERS thereis (SETQ $$VAL (LISTP (CH.ADD.MEMBER.TO.PROPERTY.ACL GROUP (QUOTE MEMBERS) (QUOTE Administrators) NAME T)))))) (if FRIENDS then (PRINTOUT T "Adding friends...") (\NSMT.SHOW.RESULT (for NAME in FRIENDS thereis (SETQ $$VAL (LISTP (CH.ADD.MEMBER.TO.PROPERTY.ACL GROUP (QUOTE MEMBERS) (QUOTE selfControllers) NAME T)))))))))
)

(\NSMT.ADD.USER
(LAMBDA NIL (* ; "Edited 11-Aug-87 13:55 by bvm:") (* ;; "Create new user") (LET (NAME PASS ERROR DESC ALIASES) (DECLARE (USEDFREE LASTNAME LASTSTRING)) (TERPRI T) (COND ((SETQ NAME (\NSMT.READFNAME "New user's name:" LASTNAME NIL T)) (SETQ LASTSTRING (SETQ LASTNAME NAME)) (COND ((LISTP (SETQ ERROR (CH.CREATE.OBJECT NAME))) (* ; "Error") (\NSMT.SHOW.RESULT ERROR)) (T (* ;; "Having created the object, get all the other parts.  We assume that if the creation succeeded, we'll be able to do the rest, so gather all the info first, then do the calls.") (TERPRI T) (SETQ DESC (\NSMT.GET.REMARK)) (SETQ ALIASES (LET ((DEFAULTDOMAIN (create NSNAME using NAME NSOBJECT ← NIL))) (DECLARE (CL:SPECIAL DEFAULTDOMAIN)) (* ; "Read the aliases by default in the same domain as user") (\NSMT.COLLECT.NAMES "Alias:"))) (COND ((NULL (SETQ PASS (\NSMT.GET.PASSWORD "Initial password:"))) (printout T " (no password stored; use Change Password to create one)" T))) (PRIN1 "... " T) (if (SETQ ERROR (LISTP (CH.ADD.ITEM.PROPERTY NAME (QUOTE USER) DESC (QUOTE STRING)))) then (\NSMT.SHOW.RESULT ERROR "remark")) (if (for A in ALIASES thereis (SETQ ERROR (LISTP (CH.CREATE.ALIAS A NAME)))) then (\NSMT.SHOW.RESULT ERROR "alias")) (\NSMT.SHOW.RESULT (AND PASS (AS.CREATE.PASSWORDS NAME (\ENCRYPT.PWD PASS))) "password creation")))))))
)

(\NSMT.CHANGE.ADMINISTRATORS
(LAMBDA (CHACCESSFN OPERATION) (* ; "Edited 27-Jul-87 12:11 by bvm:") (* ;; "Add/remove a domain administrator") (LET (DOMAIN INDIVIDUAL) (DECLARE (USEDFREE LASTNAME LASTDOMAIN LASTSTRING)) (COND ((AND (SETQ INDIVIDUAL (\NSMT.READFNAME " name:" LASTNAME)) (SETQ DOMAIN (\NSMT.READFNAME (SELECTQ OPERATION (ADD " to domain:") (REMOVE " from domain:") (SHOULDNT)) LASTDOMAIN T T))) (\NSMT.SHOW.RESULT (CL:FUNCALL CHACCESSFN DOMAIN (QUOTE Administrators) INDIVIDUAL)) (SETQ LASTSTRING (SETQ LASTNAME INDIVIDUAL)) (SETQ LASTDOMAIN DOMAIN)))))
)

(\NSMT.CHANGE.GROUP.COMPONENT
(LAMBDA (CHACCESSFN OPERATION SELF/LIST) (* ; "Edited 14-Aug-87 15:11 by bvm:") (* ;; "Add or remove a member from to/from a group") (PROG (GROUP INDIVIDUAL) (DECLARE (USEDFREE LASTNAME LASTGROUP LASTSTRING)) (COND ((AND (OR (EQ SELF/LIST T) (SETQ INDIVIDUAL (\NSMT.READFNAME " name:" LASTNAME NIL NIL (if (EQ OPERATION (QUOTE REMOVE)) then (* ; "Want to be able to remove bogus names if they got on there somehow") :OK elseif SELF/LIST then (* ; "must be valid ns name") T else (* ; "use canonical name, but foreign names ok") :CONFIRM) :ANY))) (SETQ GROUP (\NSMT.READFNAME (SELECTQ OPERATION (ADD " to group:") (REMOVE " from group:") (SHOULDNT)) LASTGROUP NIL T))) (if (NOT (\NSMT.SHOW.RESULT (LISTP (SETQ LASTGROUP (SELECTQ SELF/LIST (T (* ; "adding/removing self") (CL:FUNCALL CHACCESSFN GROUP (QUOTE MEMBERS))) (NIL (* ; "adding/removing member") (CL:FUNCALL CHACCESSFN GROUP (QUOTE MEMBERS) INDIVIDUAL T)) (PROGN (* ; "Adding/removing from access list") (CL:FUNCALL CHACCESSFN GROUP (QUOTE MEMBERS) SELF/LIST INDIVIDUAL T))))))) then (* ; "Call returned canonical name of group, unless it was error (in which case we must undo)") (SETQ LASTGROUP GROUP)) (SETQ LASTSTRING LASTGROUP) (SETQ LASTNAME INDIVIDUAL)))))
)

(\NSMT.CHANGE.REMARK
(LAMBDA NIL (* ; "Edited 11-Aug-87 14:03 by bvm:") (PROG (PROPS GOODPROPS MAINPROP NAME REALNAME RESULT REMARK) (DECLARE (USEDFREE LASTSTRING LASTNAME LASTGROUP)) (if (SETQ NAME (\NSMT.READFNAME " for object:" LASTSTRING)) then (SETQ PROPS (CH.LIST.PROPERTIES NAME)) (* ; "returns (realname props)") (if (EQ (SETQ REALNAME (CAR PROPS)) (QUOTE ERROR)) then (* ; "Object does not exist, probably") (\NSMT.SHOW.RESULT PROPS) elseif (NULL (SETQ GOODPROPS (if (for P in (SETQ PROPS (CADR PROPS)) collect (OR (CH.NUMBER.TO.PROPERTY P) P) when (MEMB P *NSMAINTAIN-DESCRIPTIVE-PROPERTIES*)) elseif (MEMB (CONSTANT (CH.PROPERTY (QUOTE USERGROUP))) PROPS) then (* ; "Treat USERGROUP specially, as it is the property conventionally holding a group remark, but we ignore it if object has other props (like USER).") (LIST (QUOTE USERGROUP))))) then (printout T T (SETQ LASTSTRING REALNAME) " has no remarkable properties." T) else (if (NULL (CDR GOODPROPS)) then (* ; "only one, the normal case") (PRINTOUT T (CONCAT " (" (if (EQUAL.CH.NAMES REALNAME NAME) then "" else (CONCAT (NSNAME.TO.STRING REALNAME) " -- ")) "a " (CL:STRING-CAPITALIZE (STRING (SETQ MAINPROP (CAR GOODPROPS)))) ")")) else (PRINTOUT T T (NSNAME.TO.STRING REALNAME) " has the descriptive properties ") (\NSMT.PRINT.LIST GOODPROPS) (if (NULL (SETQ MAINPROP (CAR (TTYIN "Specify property to modify: " GOODPROPS T (QUOTE (FIX RAISE)))))) then (RETURN))) (TERPRI T) (if (SETQ REMARK (CADR (CH.RETRIEVE.ITEM REALNAME MAINPROP))) then (* ; "Retrieve carefully in case the prop is null") (SETQ REMARK (COURIER.READ.REP REMARK NIL (QUOTE STRING)))) (if (SETQ REMARK (\NSMT.GET.REMARK REMARK)) then (PRIN1 "..." T) (\NSMT.SHOW.RESULT (LISTP (CH.CHANGE.ITEM REALNAME MAINPROP REMARK (QUOTE STRING)))) else (PRINTOUT T " xxx" T)) (SETQ LASTSTRING (if (EQ MAINPROP (QUOTE USERGROUP)) then (SETQ LASTGROUP REALNAME) else (SETQ LASTNAME REALNAME)))))))
)

(\NSMT.REMOVE.ALIAS
(LAMBDA NIL (* ; "Edited 31-Jul-87 15:51 by bvm:") (LET (ALIAS) (COND ((NULL (SETQ ALIAS (\NSMT.READFNAME " alias:" NIL NIL T)))) ((NLISTP (SETQ ALIAS (CH.DELETE.ALIAS ALIAS))) (* ; "Success, returned canonical name") (CL:FORMAT T "done, alias was removed from ~S~%%" (SETQ LASTSTRING ALIAS))) (T (\NSMT.SHOW.RESULT ALIAS)))))
)

(\NSMT.REMOVE.OBJECT
(LAMBDA (NAME) (* ; "Edited  6-Aug-87 14:06 by bvm:") (if (AND (OR NAME (SETQ NAME (\NSMT.READFNAME ":" LASTSTRING NIL T))) (SETQ NAME (\NSMT.DESCRIBE.OBJECT NAME T)) (CL:Y-OR-N-P " Confirm deletion (y or n): ")) then (\NSMT.SHOW.RESULT (LISTP (CH.DELETE.OBJECT NAME)))))
)

(\NSMT.REMOVE.USER
(LAMBDA NIL (* ; "Edited  6-Aug-87 14:06 by bvm:") (LET (USER INFO) (if (NULL (SETQ USER (\NSMT.READFNAME ":" LASTNAME NIL T))) elseif (NULL (SETQ INFO (CH.RETRIEVE.ITEM USER (QUOTE USER)))) then (PRINTOUT T " not a user." T) else (PRINTOUT T T (NSNAME.TO.STRING (CAR INFO) T)) (if (CADR INFO) then (CL:FORMAT T " (~A)" (COURIER.READ.REP (CADR INFO) NIL (QUOTE STRING)))) (if (CL:Y-OR-N-P " Confirm deletion (y or n): ") then (\NSMT.SHOW.RESULT (LISTP (CH.DELETE.OBJECT USER)))))))
)
)
(FILESLOAD (SYSLOAD) DES AUTHENTICATION)

(RPAQQ *NSMAINTAIN-COMMANDS* (("Add Alias" "" RETURN (FUNCTION \NSMT.ADD.ALIAS)) ("Add Domain Administrator" "" RETURN (QUOTE (\NSMT.CHANGE.ADMINISTRATORS CH.ADD.MEMBER.TO.DOMAIN.ACL ADD))) ("Add Friend" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.ADD.MEMBER.TO.PROPERTY.ACL ADD selfControllers))) ("Add Group" "" RETURN (FUNCTION \NSMT.ADD.GROUP)) ("Add Member" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.ADD.MEMBER ADD))) ("Add Owner" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.ADD.MEMBER.TO.PROPERTY.ACL ADD Administrators))) ("Add Self" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.ADD.SELF ADD T))) ("Add User" "" RETURN (FUNCTION \NSMT.ADD.USER)) ("Change Default Domain" "" RETURN (FUNCTION \NSMT.CHANGE.DOMAIN)) ("Change Login" "" RETURN (FUNCTION \NSMT.LOGIN)) ("Change Password" "" RETURN (FUNCTION \NSMT.CHANGE.PASSWORD)) ("Change Remark" "" RETURN (FUNCTION \NSMT.CHANGE.REMARK)) ("Describe" "" RETURN (FUNCTION \NSMT.TYPE.ENTRY)) ("List Administrators" "" RETURN (FUNCTION \NSMT.LIST.ADMINISTRATORS)) ("List Aliases" "" RETURN (QUOTE (\NSMT.LIST.OBJECTS ALIAS))) ("List Clearinghouses" "" RETURN (FUNCTION \NSMT.LIST.CLEARINGHOUSES)) ("List Domains" "" RETURN (FUNCTION \NSMT.LIST.DOMAINS)) ("List Groups" "" RETURN (QUOTE (\NSMT.LIST.OBJECTS MEMBERS))) ("List Members" "" RETURN (FUNCTION \NSMT.TYPE.MEMBERS)) ("List Objects" "" RETURN (FUNCTION \NSMT.LIST.OBJECTS)) ("List Servers" "" RETURN (FUNCTION \NSMT.LIST.SERVERS)) ("List True Groups" "" RETURN (QUOTE (\NSMT.LIST.OBJECTS MEMBERS \NSMT.GROUP.FILTER))) ("List Users" "" RETURN (QUOTE (\NSMT.LIST.OBJECTS USER))) ("Quit" " [confirm]" CONFIRMFLG T RETURN NIL) ("Remove Alias" "" RETURN (FUNCTION \NSMT.REMOVE.ALIAS)) ("Remove Domain Administrator" "" RETURN (QUOTE (\NSMT.CHANGE.ADMINISTRATORS CH.DELETE.MEMBER.FROM.DOMAIN.ACL REMOVE))) ("Remove Friend" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.DELETE.MEMBER.FROM.PROPERTY.ACL REMOVE selfControllers))) ("Remove Member" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.DELETE.MEMBER REMOVE))) ("Remove Owner" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.DELETE.MEMBER.FROM.PROPERTY.ACL REMOVE Administrators))) ("Remove Registered Object" "" RETURN (FUNCTION \NSMT.REMOVE.OBJECT)) ("Remove Self" "" RETURN (QUOTE (\NSMT.CHANGE.GROUP.COMPONENT CH.DELETE.SELF REMOVE T))) ("Remove User" "" RETURN (FUNCTION \NSMT.REMOVE.USER)) ("Show Details of previously listed names" "" RETURN (FUNCTION \NSMT.SHOW.DETAILS)) ("Type Entry" "" RETURN (FUNCTION \NSMT.TYPE.ENTRY)) ("Type Members" "" RETURN (FUNCTION \NSMT.TYPE.MEMBERS)))
)

(RPAQQ *NSMAINTAIN-ABORT-ITEM* ("" "" EXPLAINSTRING "<cr> - abort" RETURN NIL))

(ADDTOVAR CH.PROPERTIES (ALIAS 1))

(ADDTOVAR *NSMAINTAIN-DESCRIPTIVE-PROPERTIES* 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009
 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10023 10024)

(ADDTOVAR *NSMAINTAIN-IGNORE-PROPERTIES* 6 7 10027 20003 20002 20101)

(ADDTOVAR *NSMAINTAIN-PROPERTY-FORMATS* (4 CLEARINGHOUSE . NETWORK.ADDRESS.LIST) (8 RECORD (SIMPLE BOOLEAN) (STRONG BOOLEAN))
 (30 . NSNAME) (31 CLEARINGHOUSE . MAILBOX.VALUES) (10000 . STRING) (10001 . STRING) (10002 . STRING) (10003 . STRING)
 (10004 . STRING) (10005 . STRING) (10006 . STRING) (10007 . STRING) (10008 . STRING) (10009 . STRING)
 (10010 . STRING) (10011 . STRING) (10012 . STRING) (10013 . STRING) (10014 . STRING) (10015 . STRING)
 (10016 . STRING) (10017 . STRING) (10018 . STRING) (10019 . STRING) (10020 . STRING) (10021 . STRING)
 (10022 . STRING) (10023 . STRING) (10024 . STRING) (10029 . STRING) (10030 . STRING) (10032 . STRING)
 (10034 . STRING) (10035 . STRING) (15002 . STRING) (20000 CLEARINGHOUSE . USERDATA.VALUE) (20001 GAP . RS232CData)
 (20007 . NSNAME) (20102 GAP . RS232CBack) (29965 . STRING) (30005 . NSNAME))
(DECLARE%: EVAL@COMPILE DONTCOPY 
(DECLARE%: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS *NSMAINTAIN-COMMANDS* *NSMAINTAIN-ABORT-ITEM* *NSMAINTAIN-DESCRIPTIVE-PROPERTIES* *NSMAINTAIN-IGNORE-PROPERTIES* *NSMAINTAIN-PROPERTY-FORMATS*)
)

(CL:PROCLAIM (QUOTE (CL:SPECIAL LASTDOMAIN LASTNAME LASTGROUP LASTSTRING SERVERTYPES ALLTYPES DEFAULTDOMAIN LASTLIST)))

(DECLARE%: DOEVAL@COMPILE DONTCOPY

(LOCALVARS . T)
)
)
(PUTPROPS NSMAINTAIN COPYRIGHT ("Xerox Corporation" 1985 1986 1987))
(DECLARE%: DONTCOPY
  (FILEMAP (NIL (2765 10248 (NSMAINTAIN 2775 . 4141) (\NSMT.READFNAME 4143 . 6593) (\NSMT.COLLECT.NAMES 
6595 . 6909) (\NSMT.GET.REMARK 6911 . 7203) (\NSMT.GET.PASSWORD 7205 . 7798) (\NSMT.LOGIN 7800 . 8269)
 (\NSMT.CHANGE.DOMAIN 8271 . 8711) (\NSMT.PRINT.LIST 8713 . 9023) (\NSMT.PROCESS.LIST 9025 . 9768) (
\NSMT.SHOW.RESULT 9770 . 10246)) (10288 20637 (\NSMT.CHANGE.PASSWORD 10298 . 11225) (
\NSMT.DESCRIBE.GROUP 11227 . 11872) (\NSMT.DESCRIBE.OBJECT 11874 . 14068) (\NSMT.DESCRIBE.PROPERTY 
14070 . 15214) (\NSMT.LIST.OBJECTS 15216 . 16013) (\NSMT.LIST.CLEARINGHOUSES 16015 . 17267) (
\NSMT.LIST.SERVERS 17269 . 18010) (\NSMT.SHOW.DETAILS 18012 . 18801) (\NSMT.GROUP.FILTER 18803 . 19304
) (\NSMT.LIST.ADMINISTRATORS 19306 . 19564) (\NSMT.LIST.DOMAINS 19566 . 19811) (\NSMT.TYPE.ENTRY 19813
 . 20001) (\NSMT.TYPE.MEMBERS 20003 . 20635)) (20677 29672 (\NSMT.ADD.ALIAS 20687 . 21193) (
\NSMT.ADD.GROUP 21195 . 23413) (\NSMT.ADD.USER 23415 . 24751) (\NSMT.CHANGE.ADMINISTRATORS 24753 . 
25326) (\NSMT.CHANGE.GROUP.COMPONENT 25328 . 26583) (\NSMT.CHANGE.REMARK 26585 . 28508) (
\NSMT.REMOVE.ALIAS 28510 . 28862) (\NSMT.REMOVE.OBJECT 28864 . 29162) (\NSMT.REMOVE.USER 29164 . 29670
)))))
STOP