RFC 2378

The CCSO Nameserver (Ph) Architecture

πŸ“… published September 1998, from ietf

RFC 2378: The CCSO Nameserver (Ph) Architecture πŸ’–

Okay bestie, let's get the basics out of the way first πŸŽ€

  • RFC number: 2378
  • Network Working Group: R. Hedberg (Umea University) and P. Pomes (QUALCOMM, Inc.)
  • Category: Informational πŸ¦‹
  • Date: September 1998
  • Obsoletes / Updates: the header doesn't list anything it obsoletes or updates 🌸

Status of This Memo ✨

So this memo is giving "here's some info for the Internet community" energy πŸ’… It is not a standard of any kind. It's just info, babe. Distribution is unlimited, so share it with everyone 🫢

Copyright (C) The Internet Society (1998). All Rights Reserved. The rights are reserved, so be respectful πŸ’œ

Abstract 🌈

Okay so the Ph Nameserver from the Computing and Communications Services Office (CCSO), University of Illinois at Urbana-Champaign, has been around for a while, and a bunch of organizations picked it as their go-to publicly available database for info about people (and other things too) πŸ‘‘ This doc gives a formal definition of the client-server protocol. The Ph service is built around three things: an information model, a client command language, and the server responses 🧚

1. Overview ✨

1.1. Basic Information Model πŸ“

Ph is basically a computer-resident "phone book" πŸ“ž But it's so much more than that, bestie. You can collect arbitrary info about people, and when someone asks about an object in the database, Ph returns info about that entity. It's a nameserver for people and objects, iykyk πŸ’…

It was designed to keep a relatively small amount of arbitrary info about a relatively large number of people or things, and to give access to that info over the Internet 🌸 To give the info some structure, the database manager has to decide which views to present of the real-world objects in the database. Each view is then made up of a bunch of fields and their values. So Ph has the concept of named information, which means sorting info into fields and giving those fields descriptive names πŸŽ€

Here's the lowkey important bit: even if the database lives on the Internet and can be reached from it, it's still local in the sense that no server is supposed to refer a client to another server that might hold the info they want πŸ™ˆ A server can, however, keep a list of other Nameservers that clients can use to query for info πŸ¦‹

1.1.1. Fields πŸ’–

Every field has a field descriptor πŸ’… It describes the type and behavior of the field, and it includes the fieldname, the maximum length of info the field can store before truncation, keywords for the field's properties, and some free text about what kind of info the field is meant to hold.

These are the keywords, and they're all so iconic:

  • Always: Forces the field's contents to always be printed, in addition to whatever fields the query asks for ✨
  • Any: This field is always searched by queries. To be most useful, a field marked as Any should also have the Indexed and Lookup keywords as well πŸ”
  • Change: Can be changed by the owner of the entry 🫢
  • Default: Printed if no return clause is given in the query 🌈
  • Encrypt: Must be encrypted before transmission πŸ”
  • ForcePub: Viewable/searchable regardless of the content of the suppress field πŸ‘‘
  • Indexed: Fields that are kept track of in the database's index for efficient lookups. At least one indexed field must be present in each query 🧚
  • LocalPub: May be viewed by anyone in the "local" domain or address space. Fields with this keyword are completely invisible outside of the "local" domain. They will not be shown with the fields command (section 3.3), and are disallowed in query commands or return clauses (section 3.8) πŸ™ˆ
  • Lookup: May be used in the selection part of a query. A Field without this keyword may not be used to select entries πŸ”Ž
  • NoMeta: Wildcard searches are disallowed 🚫
  • NoPeople: No entry of type "person" may include this field πŸ’€
  • Private: Field may be viewed by Heros (section 1.4) only πŸ‘‘
  • Public: May be viewed by anyone. Fields not marked with this keyword may only be viewed by the entry's owner or a Hero 🌸
  • Sacred: Changes to the field are prohibited except via non-network invocations of the server, i.e., from a tty, file, or pipe πŸ”’
  • Turn: Users may turn off visibility of a field to everyone except themselves and Heros by prefixing the field text with '*' πŸ™ˆ
  • Unique: Any change to the field will be rejected if the change causes the modified field to match the same field in any other entry πŸ’…

1.1.2. Character Sets 🌈

Historically, Ph was restricted to printable characters only, meaning characters with hexadecimal values between 0x20 and 0x7f πŸ“ Lately, though, 8-bit clean operating systems are everywhere, so there's no real reason to keep that limit πŸ’–

So this document proposes that ISO-8859-1 shall be regarded as an alternative character set for Ph, with the default still being US-ASCII ✨

Clients that use ISO-8859-1 should ask the server to return ISO-8859-1 by using the "set"-command πŸŽ€

If values are stored using ISO-8859-1 and need to be shown to a client that expects US-ASCII, then the characters with character codes outside the US-ASCII range should be displayed in the "Quoted-Printable" content-transfer-encoding form defined in RFC-2045 [MIME] πŸ¦‹

1.2. Standardization issues 🧚

Each Nameserver manager is essentially free to name new fields to suit their organization's special needs πŸ’… But if you want the directory service to be useful outside your organization, it is recommended that a core set of standard fields always should be present 🫢

So this document defines a couple of standard collections of fields (Appendix A) 🌸

Also, the architecture makes no assumption about the search and retrieval mechanisms used within individual servers. Operators are free to use any kind of dedicated databases, fast indexing software, or even gateways to other directory services to store and retrieve info, if they want πŸ”₯

Ph simply functions as a known front-end, offering a simple data model plus a well known port and simple query language πŸ‘‘

1.3. Conventions Used in this Document πŸ“

In examples, "C:" and "S:" indicate lines sent by the client and server respectively πŸ’œ

1.4. Heros 🌈

For Ph, a Hero is equivalent to a superuser or operator πŸ‘‘ Being in Hero mode means some or all artificial limits are removed. Full Heros may change any field in any entry in the database, and view as many entries as they wish. Heros can also be limited to one field of one other entry πŸ”’ Hero mode is mostly used for administrative purposes and for delegating group authority over selected fields, and it's controlled by the acl field πŸŽ€

2. Basic Operation πŸ’–

The server host starts the Ph service by listening on TCP port 105 🧚 When a client host wants to use the service, it establishes a TCP connection to the server host. The client and the Ph server then exchange commands and responses (respectively) until the connection is closed or aborted ✨

2.1. Command syntax πŸ’…

Commands in Ph consist of a keyword, optionally followed by zero or more keywords or values. They're separated by spaces, tabs, or newlines, and followed by a carriage return-linefeed (CRLF) pair πŸ¦‹ A more thorough description using BNF is given in Appendix C πŸ”

Values containing spaces, tabs, or newlines must be enclosed in double quotes ('"'). The sequences "\n", "\t", "\"", and "\\" may be used to mean newline, tab, double quote, and backslash, respectively 🫢

Keywords must be given in lower case. Case in the values of fields is preserved, although queries are not case-sensitive 🌸

2.2. Response syntax 🌈

Responses consist of a result code, followed by additional information possibly separated by entry index and/or field name, and terminated by a CRLF pair πŸ’œ

result code:[entry index:][field name:]text

Responses to some commands might be multi-lined. In these cases, each line in the response except the last has the appropriate result code negated (prefaced with "-"). The last line then starts with the appropriate result code without negation. Each line must be terminated by a CRLF pair πŸ“

If a particular command can apply to more than one entry, the multilined response must be organized so that all info pertaining to each entry is returned on consecutive lines. Each of those lines must have one and the same entry index directly following the resultcode. The first entry index should be 1, and it gets incremented each time a new entry is referred to 🧚

C: query hedberg return email name title
S: 102:There were 3 matches to your request.
S: -200:1:        email: canheg95@student.umu.se
S: -200:1:         name: Carl Johan Hedberg
S: -200:1:        title: Student
S: -200:2:        email: parheg95@student.umu.se
S: -200:2:         name: Par Hedberg
S: -200:2:        title: Student
S: -200:3:        email: Roland.Hedberg@umdac.umu.se
S: -200:3:         name: Roland Hedberg
S: -200:3:        title: Boss of the Network group
S: 200:Ok

Commands that can apply to more than one field must have the name of the field that the response applies to directly following the entry index πŸ”₯

The text of the response will be either an error message in human readable format, or data from the Nameserver. Whitespace (spaces or tabs) may appear anywhere in the response, but the field name and text columns, if present, must each begin with a whitespace character πŸ’…

Since more than one specific piece of info may be manipulated by a particular command, it's possible for parts of a command to succeed while other parts of the same command fail. This situation is handled as a single multi-line response, with the result code changing as appropriate πŸ™ˆ

As for FTP, the result codes are in the range 100-699 (or from -699 to -100 for multiline responses), where the leading digit has the following significance:

1: In progress
2: Success
3: More information needed
4: Temporary failure; it may be worthwhile to try again.
5: Permanent failure
6: Phquery specific codes

Many commands generate more than one line of response, so every client should be prepared to deal with such continued responses. Note that a command is finished when, and only when, the result code on a response line (treated as a signed integer) is greater than or equal to 200 πŸ‘‘

Clients should assume that any numeric response within the above mentioned ranges is valid. Also, the server is allowed to send one or more lines with result codes between -199 - -100 (the leading "-" indicates a continuation line) and 100 - 199, as status info, before the actual results are transmitted Part 1 of 3 done, bestie, more is coming! πŸŒˆπŸ’–

2.3. Format of a search string πŸŽ€

Okay so matching is totally not case sensitive πŸ™ˆ and it's usually done word by word. Your query and the entry info both get chopped into words, and then each word gets compared with exact matching. If the order of the words matters, wrap the query in " (double quotes) and the whole search string gets matched against the Nameserver database as one chunk πŸ’…

Word delimiters are <SPACE>, <TAB>, <NEW-LINE>, ,, ; and : πŸ¦‹ These characters aren't indexed, so they should not be part of your search string.

Now the wildcards, which are giving detective energy πŸ•΅οΈβ€β™€οΈ If you don't know the exact spelling, use * (asterisk, 0x2A) for zero or more characters, + (plus, 0x2B) for one or more unknown characters, and ? (question mark, 0x3F) when exactly one character is unknown. If the unknown character can only be one of a few options, put those options in brackets. For example, [ei] means that spot matches an e or an i ✨

3. Commands 🧚

3.1. status πŸ’œ

status

This one prints the message of the day and the current status of the nameserver. Iconic, simple, love it 🌸

C: status
S: 100:Qi server $Revision: 1.6 $
S: 100:Ph passwords may be obtained at CCSO Accounting,
S: 100:1420 Digital Computer Lab, between 8:30 and 5 Monday-Friday.
S: 100:Be sure to bring your U of I ID card.
S: 200:Database ready

3.2. siteinfo πŸ“

siteinfo

This returns info about the server's site. The possible fields are:

Version        Version information for the server.
Maildomain     The mail domain to use for phquery-type mail.
Mailfield      The field containing the specific email address.
Mailbox        Mandatory entry that names the field to use as
               maildrop.
Administrator  Guru in charge of service.
Passwords      Person in charge of ordinary password/change requests.
Authenticate   Authentication methods supported by the server,
               ordered in the site-preferred way.  Presently the
               following options are defined:

                 1   attempt auto login
                 2   allowed to be interactive if needed
                 4   use ANSI X9.9 challenge/response
                 8   use v4 Kerberos login
                 16  use v5 Kerberos [KRB5] login
                 32  use GSS-API [GSS-API] login
                 64  use email login
                 128 password encrypted response to challenge
                 256 use clear-text password
                 512 use HMAC [HMAC] with SHA-1 of challenge string

Here's an example of how it looks in action πŸ‘€

     C: siteinfo
     S: -200:1:version:3.1
     S: -200:2:maildomain:umu.se
     S: -200:3:mailfield:alias
     S: -200:4:mailbox:email
     S: -200:5:administrator:roland.hedberg@umdac.umu.se
     S: -200:6:passwords:roland.hedberg@umdac.umu.se
     S: -200:7:authenticate:64:32:128
     S: 200: Ok.

The mail fields in siteinfo decide how the address info stored in the Nameserver gets used for delivering mail πŸ“¬ The specific (username, host) pair where a user's mail should go for final delivery is stored in the field named by {mailbox}, and phquery and similar utilities use that field.

To build a usable email address from Nameserver info, follow this algorithm:

     if ({maildomain} is not null) then
          address = (contents of {mailfield})@{maildomain}
     else
          address = (contents of {mailfield})

Some existing client software won't format email addresses correctly if {mailbox} is set to anything other than "email" while {maildomain} is non-empty. Ugh, so annoying 😭

If {mailbox} is set to anything other than {email}, then {maildomain} must be reported empty by the siteinfo command. Also, the server must reformat each record's {mailfield} before reporting it to the client. Non-negotiable πŸ’…

3.3. fields 🌈

fields [field ...]

With no argument, you get a list of all available field descriptors. Any space-separated argument(s) limit the list to the named fields. Fields marked with the "LocalPub" keyword (section 1.1.1) should not be delivered outside of the local domain πŸ”’

The output has two lines for each field. The first line defines the field in technical terms (max length and field attributes), and the second line is a brief description of what the field is meant to hold. The second number in each response is the field id number πŸ”’

C: fields
S: -200:6:alias:max 32 Indexed Lookup Public Default
S: -200:6:alias:Unique name for user.
S: -200:3:name:max 64 Indexed Lookup Public Default
S: -200:3:name:Fullname
S: -200:2:email:max 128 Lookup Public Default
S: -200:2:email:Account to receive electronic mail.
S: -200:16:other:max 256 Lookup Public Default Change
S: -200:16:other:Other info the user finds important.
S: -200:33:home_phone:max 60 Lookup Public Change Turn
S: -200:33:home_phone:Home telephone number.
S: 200:Ok.

3.4. id πŸ¦‹

id information

This enters the given info into the Nameserver's log. The Ph client uses it to log the user id of the person running it 🫢

3.5. set πŸ’…

set [option[=value] ...]

This sets the named option for your nameserver session to a value. If no value is given, the default string "on" is used. Used with no arguments, it returns the settable options and their current values ⭐ Some common options are:

  • echo: If on, echo the client's commands back to the client.
  • limit: Changes that affect more than the specified number of entries result in an error.
  • charset: Return responses to the client in the character set specified.
  • verbose: If on, report interim progress messages to the client.
  • addonly: If on, change commands can only create fields in entries, not modify them.
  • nolog: If on, disable logging.
  • external: If on, make Fields marked as "LocalPub" invisible.

Example time πŸ“

   C: set verbose=off
   S: 200:Done.

   C: set
   S: -200:echo:off
   S: -200:limit:2
   S: -200:charset:iso-8859-1
   S: -200:verbose:off
   S: -200:addonly:off
   S: -200:nolog:off
   S: -200:external:on
   S: 200:Done.

3.6. login, logout, answer, clear, email, and xlogin πŸ”

3.6.1. login πŸ‘‘

login [alias]

The "login" command lets client users identify themselves to the Nameserver. More specifically, it ties a client user to a particular entry in the Nameserver, and lets them change fields in that entry and possibly other entries. You also need to be logged in to see certain sensitive fields in your own entry 🫣

To use "login", the client has to prompt the user for their ph alias and password. The client is then responsible for (optionally) encrypting the password and sending it to the server. This is covered in sections 3.6.3 (answer) and 3.6.4 (clear).

C: login foo
S: 301:,:P"_Y$ONU%"SDUQ6&^`ZZ'?*#Y`A_.Z/A>?@SH>*-

3.6.2. logout πŸŒ™

logout

The "logout" command lets a logged-in user log out of the Nameserver πŸ‘‹

C: logout S: 200:Ok.

3.6.3. answer 🧠

answer encrypted-response

After a login command, the Nameserver replies with a random challenge string. The Nameserver client encrypts the challenge with the password the user supplied, uuencodes the result into US-ASCII, and sends the printable result back in the "answer" command:

C: login ppomes
S: 301:.%$&.D^67$*1?<.2S@DR:Z@M*)AV-<:4QM>#R>M*HT
C: answer M5K'F:NI(a?M?O2+-a9`48RA#ZF=L9)G)/XRS7Q^0>0@-R7X$WGb`50B]
S: 200:ppomes:Hi how are you?

The encryption algorithm is based on a three rotor Enigma engine. There are known attacks on the security of this approach πŸ’€ Be careful out there.

The answer command is also used to return method-specific responses to the xlogin command (section 3.6.6).

3.6.4. clear πŸ™ˆ

clear cleartext-password

The "clear" command can be used instead of "answer" to finish a login sequence. Its argument is the user's cleartext password. This command is only there to support clients that haven't implemented one of the encryption engines used by "answer". Its use is strongly discouraged, so please don't πŸ™…β€β™€οΈ

C: login ppomes
S: 301:E=@Y&VW^_9YVI;D5.[EB0:B)9Z#_&X$:2)/eL$VJC87
C: clear MySecret
S: 200:ppomes:Hi how are you?

3.6.5. email πŸ“§

email local-userid

The "email" command can also be used instead of "answer" to finish a login sequence. The value of local-userid is the user's login name on the local machine. If all of the following conditions are true, the server will accept the email command:

  1. The connection to the server originates on port 1023 or less on the client. Note: This is a system port. Port 1023 is not allocated to this use.
  2. The canonical name of the client's host matches the right-hand side of the email address of the requested alias specified in the "login" command.
  3. The "local-userid" matches the left-hand side of the email address belonging to the requested alias.

This is a weak but convenient form of authentication πŸ₯Ί Depending on the info users are allowed to change about themselves and the threat environment the server runs in, this method might be appropriate. Servers should take care to avoid DNS spoofing 🚨

3.6.6. xlogin πŸ”‘

xlogin option alias

This is the extended login command for GSS, Kerberos v4 and v5, ANSI X9.9 token devices (e.g., SNK/4), and so on. The option is one of the values returned in the Authenticate field of the "siteinfo" command (section 3.2). Alias is the user's alias.

C: xlogin 16 ppomes
S: 301:DoKrbLogin started; send Kerberos mutual authenticator.
C: answer MJa8QO1cJHYz2IdWyg7uhAnixVqgCZQBWr64ciXYku1ktdu....
S: 200:ppomes:Hi how are you?

C: xlogin 4 ppomes
S: 302:SNK Challenge "024142":
C: answer 82344338
S: 200:ppomes:Hi how are you?

The answer command returns the requested quantity: a Kerberos authenticator, an X9.9 device response, and so on. Binary quantities are first uuencoded into US-ASCII 🧚

3.7. add βž•

add field=value...

This command adds new entries to the database. You must be logged in and have full Hero privileges (section 1.4) to use "add" πŸ‘‘

C: add name="doe john" id="123456789" alias="j-doe"
S: 200:Ok.

3.8. query πŸ”

query [field=]value [field=value] . . . [return field1 [field2]]

If no field is given with a value, the field is assumed to be "name" and/or "nickname". When a query has more than one field-value specification, entries matching all of them are returned (implicit AND) ✨

You can define which fields get returned by adding a "return" clause. If there's no return clause, the Ph server returns a default list of fields. Typical default fields are "alias", "name", "title", "email", "phone", "address", "department", "www", and "other". A return clause is the word "return" followed by a list of fields, or the word "all". If you use "all", every viewable field gets returned 🌷

C: query name=doe name=john
S: 102:There was 1 match to your request.
S: -200:1:            alias: j-doe
S: -200:1:             name: doe john
S: 200:Ok.

3.9. delete

delete [field=]value...

okay so delete is the nuclear option πŸ’€ it wipes entire entries out of the database. You must be logged in and have full Hero (section 1.4) privileges to use "delete" πŸ”₯

The arguments are the same as the selection part of a "query" command, so whatever you'd search for, delete goes hunting for matches and removes every single one it finds 🧹

"delete" obeys the Nameserver "limit" option, which can stop it from deleting more entries than you meant to 🫢

C: delete name="doe john" id="123456789" alias="j-doe"
S: 200:1 entries deleted.

3.10. change

change [field=]value    [make|force] field="value"...

bestie, "change" updates one or more fields across one or more entries πŸ¦‹ it's split into two clauses: the "change" clause and the "make" or "force" clause ✨

The "change" clause decides which entries get touched. It takes the same arguments as the selection clause of a "query" command. The "make" or "force" clause says which field(s) get changed and what the new value(s) are πŸ’– The "force" clause is only used to make non-encrypted changes to fields marked "Encrypt" πŸ”

You must be logged in to use "change" πŸ’…

"change" obeys the Nameserver "limit" option too, so it can't change the field contents of more entries than intended 🌸

C: change alias=j-doe force password=NewSecret
S: 200:1 entry changed.

C: set limit=500
S: 200:Done.
C: change fax="(619) 555-1212" make fax="(760) 555-1212"
S: 200: 113 entries changed.

3.11. help

help    [{native|client} [topic ...]]

"help" prints help on the Nameserver or on specific clients πŸ“š If client is specified, it should be a valid Nameserver client identifier, such as "ph" 🧚 The client-specific help gets searched for the topic first, and then the native help gets searched. If topic is omitted, you get a list of all available help texts. If "native" or client are also omitted, you get a list of clients instead 🌈

C: help native 101
-200:1:101:
-200:1: The Nameserver echo option is set.  The text of this response is
-200:1: the command you just gave, which has not (yet) been executed.
200:Ok.

3.12. quit/exit/stop

quit

"quit" terminates the session with the Nameserver and makes the client exit πŸ‘‹ bye bye πŸŽ€

C: quit
S: 200:Bye!

4. Security

4.1. Transport Layer

okay this one is SO important 🚨 If there's no encryption between client and server, all Nameserver traffic is unsecure 😭 Kerberos v4, v5, and the GSS-API all provide encryption mechanisms, but the Nameserver protocol doesn't support any way to negotiate encryption between client and server πŸ’€ That means anybody on the network linking the client and server can see all the traffic. And cleartext traffic can be modified in transit too πŸ™ˆ Possible ways to fix this would be to use something like TLS [TLS] or IPSec [IPSEC] πŸ”’

4.2. Server Authentication

Unless one of the mutual authentication mechanisms is used, e.g., Kerberos 4/5 or GSS-API, there is no way to prove the identity of a server 🫣 Also, there's no mechanism to prove a given server is authoritative for a set of information 🧐

4.3. Secure User Authentication

The Ph protocol lets client and server negotiate several authentication protocols, some weak and some strong πŸ’ͺ It does not prohibit cleartext passwords, which should be depreciated πŸ“‰ but they're still useful when dealing with some clients πŸ₯²

4.4. Privacy and Access Lists

Directory services like the CCSO white pages server, which hold information on people, have to think about privacy πŸ™ˆ This document describes one way to partition specific attributes away from unwanted access by marking them visible only to the "local" community, visible only to the person connected with the information, or visible only to the database administrator πŸ”πŸ‘‘

4.5. References

[GSS-API] Linn, J., "Generic Security Service Application Program
          Interface, Version 2", RFC 2078, January 1997.

[HMAC]    Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
          Hashing for Message Authentication", RFC 2104, February
          1997.

[IPSEC]   Atkinson, R., "Security Architecture for the Internet
          Protocol", RFC 1825, August 1995.

[KRB5]    Kohl, J., and C. Neuman, "The Kerberos Network
          Authentication Service (V5)", RFC 1510, September 1993.

[TLS]     Dierks, T., and C. Allen, "The TLS Protocol,
          Version 1.0", Work in Progress.

[MIME]    Freed, N., and N. Borenstein, "Multipurpose Internet Mail
          Extensions, (MIME) Part One: Format of Internet Message
          Bodies", RFC 2045, November 1996.

5. Miscellaneous

5.1. Authors' Addresses

Roland Hedberg
Umdac
Umea University
901 87 Umea
Sweden

EMail: Roland.Hedberg@umdac.umu.se


Paul Pomes
Qualcomm Inc
6455 Lusk Blvd
San Diego, CA
USA

EMail: ppomes@qualcomm.com

Appendix A

Default fields and suggested lengths connected to different object types πŸ“‹βœ¨

   All entries:  Information common to all entries
   type              64
   name              256
   address           128
   proxy             32
   password          32

   type=phone:   Information found in a phonebook
   phone             64
   fax               64

   type=person:  Information about a human being
   alias             32
   forename          64
   surname           64
   group             32
   email             128
   public_key        4096
   nickname          128
   www               256
   acl               128

   type=staff:   Information about an employee
   empno             16
   department        64
   supervisor        64
   secretary         64
   office_location   128
   office_address    128
   office_phone      64
   title             64
   pager             64
   hours             128

   type=unit:   Information about an organizational unit
   email             128
   www               256
   public_key        4096

Appendix B

Result codes 🎯 this is basically the Nameserver's way of talking back to you πŸ’¬

   100 In progress (general).
   101 Echo of current command.
   102 Count of number of matches to query.
   103 No hostname found for IP address.
   200 Success (general).
   201 Database ready, but read-only.
   300 More information (general).
   301 Encrypt this string.
   302 Print this prompt.
   400 Temporary error (general).
   401 Internal database error.
   402 Lock not obtained within timeout period.
   403 Login would have been OK, but database read-only
   475 Database unavailable; try later.
   500 Permanent error (general).
   501 No matches to query.
   502 Too many matches to query.
   503 Not authorized for requested information.
   504 Not authorized for requested search criteria.
   505 Not authorized to change requested field.
   506 Request refused; must be logged in to execute.
   507 Field does not exist.
   508 Field is not present in requested entry.
   509 Alias already in use.
   510 Not authorized to change this entry.
   511 Not authorized to add entries.
   512 Illegal value.
   513 Unknown option.
   514 Unknown command.
   515 No indexed field in query.
   516 No authorization for request.
   517 Operation failed because database is read-only.
   518 To many entries selected by change command.
   520 CPU usage limit exceeded.
   521 Change command would have overridden existing field,
   and the "addonly" option is on.
   522 Attempt to view "Encrypted" field.
   523 Expecting "answer" or "clear".
   524 Names of help topics may not contain "/".
   525 Email authentication failed
   526 Host name address not found in DNS
   527 Reverse DNS lookup does not match forward DNS lookup
   528 General Kerberos database error.
   529 Selected authentication method not available
   590 Remote queries not allowed.
   598 Command unknown.
   599 Syntax error.
   600 Ambiguous or multiple match

Appendix C

Description of the client command language using the augmented Backus-Naur Form (RFC822) 🧩

   response = code [index] [field] text CRLF

   code     = [-] LDIG 2DIGIT ":"
   index    = number ":"
   field    = 1*SPACE attribute ":" 1*SPACE
   text     = 1*( CHAR / LWSP-char )


   command     = ph-command CRLF

   ph-command  =  "status" / a-command / oa-command
   ph-command  =/ av-command / answer-command / query-command
   ph-command  =/ delete-command / change-command / "help" / quit-command

   a-command       = ("siteinfo"/"fields"/"id"/"login"/"help"/"email"/
              "clear") [attribute]
   oa-command      = ("xlogin") number attribute
   av-command      = ("set"/"add"/"make") 1*attribute-value
   answer-command  = ("answer") 1*printable
   query-command   = ("query"/"ph") 1*selection ["return" 1*attribute]
   quit-command    = "quit" / "exit" / "stop"
   change-command  = "change" 1*selection make 1*attribute-value
   delete-command  = "delete" selection

   selection       = value / attribute-value

   attribute-value = attribute "=" value

   value           = 1*(cstring / quoted-string / set)

   cstring         = 1*( ALPHA / DIGIT / S_SPEC / set / quoted-pair )
   attribute       = 1*( ALPHA / DIGIT / "_" / "-" )
   number          = 1*(DIGIT)

   quoted-string   = <"> 1*(qtext/quoted-pair) <">

   quoted-pair  =  "\" CHAR
   qtext        = 1*( CHAR / CR / SPEC1 / DELIMIT1 / DELIMIT2 / LWS )
   set          = '[' 1*(ALPHA/DIGIT) ']'

   LWSP-char    = SPACE / HTAB
   LWS          = 1*([CRLF] (LWSP-char))
   CRLF         = CR LF
   S_SPEC       = '*'/'+'/'?'
   SPEC1        = "=" / "*" / "?" / "+" / "[" / "]"
   SPEC2        = "\" / """
   DELIMIT1     = SPACE / HTAB / LF
   DELIMIT2     = "," / ";" / ":"
   PRINTABLE    = %d32..%d126
   CTL          = %d0..%d31 / %d127..%d160
   ALPHA        = %d65..%d90 / %d97..%d122
   DIGIT        = %d48..%d57
   LDIG         = %d49..%d54
   SPACE        = %d32
   SEP          = (CR LF) / LF
   CR           = %d13
   LF           = %d10
   HTAB         = %d9
   CHAR         = %d33..%d126 / %d160..%d255
   OTHER        = "(" / ")" / "-" / "." / "/"
          "@" / "$" / "_" / "!" / "~" /
          "'" / "#" / "&" / "<" / ">" /
          "^" / "`" / "{" / "|" / "}"

Copyright (C) The Internet Society (1998). All Rights Reserved. πŸ’œ

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ✨

πŸ“¦ where this page comes from