API
上传用户:pycemail
上传日期:2007-01-04
资源大小:329k
文件大小:11k
源码类别:

Ftp客户端

开发平台:

Unix_Linux

  1. ProFTPD Application Programmer Interface
  2. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  3. NOTE: This API documentation ONLY applies to proftpd versions 1.1.5 and
  4. greater, wherein the module interface was significantly enhanced.
  5. ProFTPD modules are designed to handle and respond to configuration
  6. directives (at startup), FTP commands sent over the control connection by
  7. FTP clients, and authentication requests.
  8. Module are prioritized in the *inverse* order of which they were loaded.
  9. In other words, the last loaded module is the FIRST to receive calls for a
  10. particular configuration directive, ftp command or authentication request.
  11. This can be used to allow later loaded modules (higher priority) to
  12. (optionally) "override" lower priority modules.  Thus, load order of the
  13. modules can be VERY important.
  14. Module handler functions are _always_ declared as:
  15. MODRET my_handler_func(cmd_rec *cmd);
  16. In include/modules.h, MODRET is defined as 'static modret_t *'.  cmd_rec
  17. is a structure created by the engine and passed to the handler which
  18. contains all information regarding the command, etc.  modret_t is a
  19. special structure that is created by the handler and returned to the
  20. engine in order to tell the engine how to proceed.  There are a few macros
  21. in include/modules.h which allow the module programmer to easily create
  22. return structures.  The `cmd' argument to each macro is a pointer to
  23. the current module function's cmd_rec structure.
  24. HANDLED(cmd)
  25.  - indicates that the handler properly handled the command, and that the
  26. engine should consider the command completed and continue processing.
  27. Note that if a module handler returns HANDLED, POST_CMD handlers
  28. will be called for the command (see below for handler types).
  29. DECLINED(cmd)
  30.  - indicates that the engine should act as though the handler was never
  31. called and continue processing.  POST_CMD type handlers will NOT
  32. be called in this case.
  33. ERROR(cmd)
  34.  - A protocol error occured.  POST_CMD type handlers are NOT
  35. called.
  36. ERROR_MSG(cmd,numeric,message)
  37.  - Same as above, however the string composed of "numeric message" is sent
  38. to the client.  In the case of directive configuration handlers, the
  39. "numeric" argument is ignored, "message" is displayed to the user (or
  40. logged via syslog), and proftpd terminates.
  41. ERROR_INT(cmd,n)
  42.  - Same as above, however this indicates a single integer numeric error.
  43. (Used only in authentication/mapping handlers [see mod_unixpw.c])
  44. Handler Tables
  45. --------------
  46. Each module can define up to three different handler tables (which are
  47. registered via the module structure).  These need not all be supplied.
  48. They are grouped by handler class:
  49.   conftable[]: For configuration directive handlers.
  50.   cmdtable[]: For command handlers, including POST_CMD and PRE_CMD
  51.                 (see below)
  52.   authtable[]: For authentication handlers.
  53. The "conftable" is a structure which lists all configuration directive
  54. handlers for the module.
  55. The "cmdtable" is a structure which lists all FTP command handlers for the
  56. module.  Each entry in this table contains a special "command type" field
  57. which determines the general 'type' of handler.  There are currently four
  58. types: CMD, PRE_CMD, and POST_CMD and LOG_CMD.  When proftpd receives a
  59. command for a client, it enters a five (eight?) step command->module
  60. cascading delivery process: 
  61.   1. Call any PRE_CMD type handlers which match the special "*"
  62.       command wildcard
  63.   1a. Call any PRE_CMD type handlers which match the command.
  64.   2. Call any CMD type handlers which match the special "*"
  65.       command wildcard
  66.   2a. Call any CMD type handlers which match the command.
  67.   3. Call any POST_CMD type handlers which match the special "*"
  68.       command wildcard
  69.   3a. Call any POST_CMD type handlers which match the command.
  70.   4. Call any LOG_CMD type handlers which match the special "*" wildcard.
  71.   5. Call any LOG_CMD type handlers which match the command.
  72. Further more, the return type of a particular command can allow or
  73. disallow further dispatching.  Rules:
  74.   PRE_CMD:
  75.     1. If DECLINED is returned, all other PRE_CMD handlers are called.
  76.     2. If ERROR is returned, command handler dispatching stops completely.
  77.   CMD:
  78.     1. If DECLINED is returned, all other CMD handlers are called.
  79.     2. If ERROR is returned, command handler dispatching stops completely.
  80.   POST_CMD:
  81.     1. If ERROR is returned, the message (if any) is sent to syslog,
  82.        however because the CMD handler already executed, nothing further
  83.        can be done.
  84.     
  85. As you can no doubt see, this allows a higher priority module to
  86. "overload" a PRE_CMD handler for a particular command and allow/disallow
  87. the command as desired.
  88. As a general rule of thumb, PRE_CMD handlers should check syntax/basic
  89. applicability of the command, while CMD type handlers should actually
  90. do the 'work'.  POST_CMD handlers generally handle any kind of cleanup,
  91. while LOG_CMD handlers handle logging successful completion of the
  92. command.
  93. Responding to client requests in command handlers
  94. =================================================
  95. There are two main ways to respond to a client command inside a command
  96. handler.  The first way is incompatible with other other handlers, and
  97. should only be used if the handler is about to terminate the current
  98. connection (and thus kill the child, usually with end_login()).  This
  99. first method, using one of the core functions outlined below, must be used
  100. because in the event that a handler is about to terminate proftpd, the
  101. internal response lists will never be processed by the proftpd engine.
  102.   Method 1 (Use only in conjunction with end_login() or similar
  103.             termination)
  104.     send_response(char *numeric, char *format, ...);
  105.       -- immediately sends the given response with the indicated numeric
  106.          to the client
  107.     send_response_ml_start(char *numeric, char *format, ...);
  108.       -- starts a multiline ftp protocol with the given numeric
  109.     send_response_ml(char *format, ...);
  110.       -- continues a multiline response using the numeric specified
  111.          in send_response_ml_start();
  112.     send_response_ml_end(char *format, ...);
  113.       -- completes a multiline response
  114.     send_response_async(char *numeric, char *format, ...);
  115.       -- send an asyncronous message to the client, this function is
  116.          suitable for use inside signal handlers
  117. The second, and prefered, method of transmitting numeric + text message
  118. responses to clients is via the internal response chain.  Using this
  119. allows all handlers to add their own individual responses which will all
  120. be sent en masse after the command successfully completes (or fails).
  121. Proftpd maintains two such chains, one response chain for success
  122. messages, and one for error messages.  However, when all handlers for a
  123. given command have been called, proftpd evaluates the final condition of
  124. the command.  If it has failed (caused by a handler returning one of the
  125. available ERROR* macros), all responses pending in the error response
  126. chain are sent.  If the command has successfully completed, the normal
  127. (success) response chain is sent.  If a command has neither completed
  128. successfully nor resulted in an error, proftpd assumes the command is
  129. invalid and informs the client appropriately.  Either way, once the
  130. "lifetime" of the command is over, and one (or none) of the response
  131. chains has been sent, BOTH chains are destroyed.
  132.   Method 2 (using response chains)
  133.     add_response(char *numeric, char *format, ...);
  134.       -- adds the given numeric + message to the end of the _success_
  135.          chain, to be sent if the command successfully completes.
  136.     add_response_err(char *numeric, char *format, ...);
  137.       -- adds the given numeric + message to the end of the _error_
  138.          chain, to be sent if the command results in a final error.
  139. As you can see, with method 2, there is no corresponding _ml* functions
  140. for multiline replies.  This is because proftpd automatically generates a
  141. multiline format reply if it detects that there are two or more responses
  142. with the same numeric waiting to be sent to the client.  In many cases,
  143. you may be writing a handler (post_cmd, for example) that neither cares
  144. nor specifically knows what numerics other handlers are using during their
  145. responses.  In this case, you can use the special R_DUP response numeric,
  146. which tells proftpd that your response should be _assumed_ to be part of a
  147. multiline response started by another handler.  For example, if the
  148. following add_response() calls were made from different modules:
  149. module a:
  150.   add_response(R_200,"Command successfully completed.");
  151. module b:
  152.   add_response(R_DUP,"Statistics for command '%s': none.",cmd->argv[0]);
  153. module c:
  154.   add_response(R_DUP,"XFOO post_cmd handler ran.");
  155. The final output sent to the client (assuming the command was successfully
  156. handled) would be (assuming your command is named 'XFOO'):
  157. 200-Command successfully completed.
  158.  Statistics for command 'XFOO': none.
  159. 200 XFOO post_cmd handler ran.
  160. Authentication Handlers
  161. =======================
  162. Authentication handlers allow a module to provide (or overload)
  163. authentication, uid/gid to name and name to uid/gid mappings.
  164. In order for a module to provide this functionality, it must export an
  165. authtable (via the module structure), and define one or more of the
  166. following handler "names" (authtable.name).
  167. Each handler accepts data in the cmd structure and should return it's
  168. data in the modret->data field.  The core function mod_create_data()
  169. can create this data structure properly for return to the caller.
  170. Defined 'names' are:
  171. "setpwent" : low-level emulation of setpwent libc function
  172. "setgrent" : low-level emulation of setgrent libc function
  173. "endpwent" : low-level emulation of endpwent libc function
  174. "endgrent" : low-level emulation of endgrent libc function
  175. "getpwent" : low-level emulation of getpwent libc function
  176. "getgrent" : low-level emulation of getgrent libc function
  177. "getpwnam" : low-level emulation of getpwnam libc function
  178. "getgrnam" : low-level emulation of getgrnam libc function
  179. "getpwuid" : low-level emulation of getpwuid libc function
  180. "getgrgid" : low-level emulation of getgrgid libc function
  181. "auth" : authenticate user
  182.                   (cmd->argv[0] = user,
  183.                    cmd->argv[1] = cleartext password)
  184. "check" : compare supplied passwords
  185.   (cmd->argv[0] = hashed password,
  186.                    cmd->argv[1] = user,
  187.    cmd->argv[2] = cleartext password)
  188. "uid_name" : map uid to name
  189.   (cmd->argv[0] = (char*)uid)
  190. "gid_name" : map gid to group
  191.                   (cmd->argv[0] = (char*)gid)
  192. "name_uid"      : map name to uid
  193.                   (cmd->argv[0] = name)
  194. "name_gid"      : map group to gid
  195.                   (cmd->argv[0] = name)
  196. The cascaded order of authentication handlers is similar to command
  197. handlers, but slightly different.  Rules:
  198.   1. If an authentication handler returns DECLINED, handlers in other
  199.      modules are called (in priority load order, just as with command
  200.      handlers).  If ALL handlers for a particular function return
  201.      DECLINED, proftpd will assume that the operation failed.
  202.   2. If an authentication handler returns HANDLED, proftpd assumes
  203.      that the operation completed successfully, and will stop calling
  204.      auth handlers.  Most auth handlers MUST return data if they complete
  205.      successfully (note that some void-style handlers do not have this
  206.      requirement; i.e. "setpwent" and friends).
  207.   3. If an authentication handler returns ERROR, proftpd assumes an
  208.      error has occured and discontinues calling other handlers.  Some
  209.      functions ("auth", for example), should use the ERROR_INT macro
  210.      to return a numeric error code (one of the AUTH_* macros in
  211.      include/modules.h) indicating the reason for failure.