bbonev          Tue Jan 23 13:46:08 2001 EDT

  Modified files:              
    /php4/ext/vpopmail  CREDITS README config.m4 php_vpopmail.c 
                        php_vpopmail.h 
  Log:
  changed function names to be like vpopmail_add_user instead vpopmail_adduser
  added vpopmail_error to report error string (vpopmail_errno global var)
  put exec functions back in with _ex (vpopmail_add_domain_ex)
  rewritten README to help users keep secure
  fixed protos to state bool instead void return type
  
  
Index: php4/ext/vpopmail/CREDITS
diff -u php4/ext/vpopmail/CREDITS:1.2 php4/ext/vpopmail/CREDITS:1.3
--- php4/ext/vpopmail/CREDITS:1.2       Sun Jan 14 08:47:55 2001
+++ php4/ext/vpopmail/CREDITS   Tue Jan 23 13:46:03 2001
@@ -1,3 +1,2 @@
 Vpopmail
-David Croft
-Boian Bonev
+David Croft, Boian Bonev
Index: php4/ext/vpopmail/README
diff -u php4/ext/vpopmail/README:1.1 php4/ext/vpopmail/README:1.2
--- php4/ext/vpopmail/README:1.1        Sun Jan 14 09:38:29 2001
+++ php4/ext/vpopmail/README    Tue Jan 23 13:46:03 2001
@@ -1,63 +1,173 @@
 Minimum Survial Readme
 
-1) select a uid and gid apache to run under
-   or if this is already fixed take it into account
+VPOPMAIL SPECIFIC ISSUES
+-------------------------------------------------------------------------------
 
-2) install vpopmail with EXACTLY the same uid gid
-   in case you already have installed vpopmail
-   you have two choices - to change apache's 
-   uid/gid but be careful - this may break some 
-   existing scripts or worse your server's security
+assume
+       qmail is installed in /var/qmail
+       vpopmail in ~vpopmail
+       qmail-send runs as qmails
 
-   changing existing vpopmail uid/gid is possible
-   but not easy - take these into account:
 
-   #1 - backup your setup!
+different parts of vpopmail require certain user id (uid) and
+group id (gid) in order to operate normally.
 
-   stop qmail-send before doing any changes
-   else your mail in process may get bounced or 
-   deleted or delivered to a default destination or...
+brief list with requirements:
 
-   stop pop3/imap remote users - while changing uids
-   users cannot check their mail
+adddomain
+deldomain
+addaliasdomain
+       read/write permissions on
+       /var/qmail/users/ assing, assign.lock, cdb
 
-   you may leave smtp - qmail-inject will take care
-   no matter vpopmail setup is broken (if and only
-   if you have stopped qmail-send)
+       read/write permissions on
+       /var/qmail/control/*
 
-   rc.d scrips tcpserver uid/gid may need to be changed
+       singnal qmail-send with SIGHUP (uid==qmails or root)
 
-   remember to
-       ./configure ....opts....
-       make clean all install
-   in vpopmail src tree
+       read/write permissions on
+       ~vpopmail/domains
 
-   after these steps change the uid/gid in
-   /var/qmail/users/assign
-   compile the assign file. the dummies way is to
-   vadddomain mydummy.domain aaaa
-   vdeldomain mydummy.domain
+       optionally read/write to cdb vpopmail databases
 
-   suid root vadddomain, vdeldomain and vaddaliasdomain
-       cd ~vpopmail/bin
-       chown 0.0 vadddomain vdeldomain vaddaliasdomain
-       chmod +s vadddomain vdeldomain vaddaliasdomain
-   beware these programs may be exploitable and if
-   neccessary chmod 700 ~vpopmail/bin
+adduser
+deluser
+       read/write permissions on
+       ~vpopmail/domains/<givendomain> (or the default domain)
 
-   run qmail-send (/bin/csh -cf '/var/qmail/rc &')
-   run pop3 tcpserver or what you are using
+       optionally read/write to cdb vpopmail databases
 
-   verify your setup
+passwd
+       optionally read/write on
+       ~vpopmail/domains/<givendomain>/<givenuser>
+       (only when sqwebmail is configured)
 
-3) check that vpopmail support is compiled into apache
-   throug a simple phpinfo. there some more info helpful
-   for debugging will appear
+setuserquota
+       optionally read/write to cdb vpopmail databases
 
-4) happy vpopmail-ing :-)
+auth_user
+       optionally read from cdb vpopmail databases
 
+POSSIBLE SCENARIOS
+-------------------------------------------------------------------------------
+
+php is in cgi mode
+
+       command line invocation
+
+       web server cgi invocation
+
+php is web server module
+
+
+in command line mode the php interpreter may be run from vpopmail uid to
+administer users, etc. or as root to add/del domains - this is the easiest case
+
+in cgi mode proper uid may be provided eighter by suid php interpreter or
+using cgi exec wrapper. the same restrictions as in command line mode apply
+
+the web server module mode is the most powerful and works much faster that cgi.
+in this mode more restrictions apply because web server's uid at least must
+be able to read/write the directories of the manages domains.
+
+first scenario only allows web scripts to manage certain domains.  security 
+may be compromised if there are user webs under the same web server
+with allowed script execution.
+
+second scenario is to setup web server and vpopmail under the same uid/gid.
+thus allowing only user management in all domains.
+
+third scenario extends second with the ability to manage domains. generally
+from security reasons it is not a good idea to run such a system on a server
+with shell users - vpopmail's domain admin tools must be suid root to work
+properly and most users will be able to add/delete domains.
+
+it is not considered a good idea to run web servers as root. hence the need
+to suid vpopmail domain management tools and exec them insted using native api.
+native api for domains is only suitable for cgi/command line mode, when php is
+run through suid root wrapper or suid itself.
+
+almost all scenarios lack secutiry in different ways - eighter powerful tools
+get suid root or parts of vpopmail setup become useable by any system user
+or web users with cgi/php access may utilize vpopmail api for mail management.
+
+perhapse the most secure solution is to run a separate apache server under
+the vpopmail user and chmod 700 ~vpopmail/bin.
+
+FREQUENTLY USED CONFIGURATION STEPS
+-------------------------------------------------------------------------------
+
+changing existing vpopmail uid/gid is possible but not easy - 
+take these into account:
+
+#1 - backup your setup, mail and configuration!
+
+       stop qmail-send before doing any changes
+       else your mail in process may get bounced or 
+       deleted or delivered to a default destination or...
+
+       stop pop3/imap remote/local users - while changing uids
+       users cannot check their mail
+
+       you may leave smtp - qmail-inject will take care
+       no matter vpopmail setup is broken (if and only
+       if you have stopped qmail-send)
+
+       in rc.d scripts tcpserver uid/gid may need to be changed
+
+       reconfiguring vpopmail:
+               ./configure ....your opts plus new uid/gid....
+
+       remember to
+               make clean all install
+       in vpopmail src tree; clean is needed if vpopmail has already been
+       configured with another uid/gid - vpopmail's dependencies are not
+       intact after reconfigure
+
+       after these steps change the uid/gid in
+               /var/qmail/users/assign
+       compile the assign file. the dummies way is to
+               vadddomain mydummy.domain aaaa
+               vdeldomain mydummy.domain
+
+       suid root vadddomain, vdeldomain and vaddaliasdomain
+       (this is only needed for domain management in web server module)
+               cd ~vpopmail/bin
+               chown 0.0 vadddomain vdeldomain vaddaliasdomain
+               chmod +s vadddomain vdeldomain vaddaliasdomain
+
+       optionally secure ~vpopmail/bin
+       (beware these programs may be exploitable or at least used)
+               chmod 700 ~vpopmail/bin
+
+       run qmail-send
+               /bin/csh -cf '/var/qmail/rc &'
+               
+       run pop3 tcpserver or what you are using
+
+       verify your setup
+
+#2 verify php vpopmail module and configuration
+
+       for web server module and cgi setups create a phpinfo page:
+
+       <?php phpinfo() ?>
+
+       for command line mode run
+               php -i
+
+       check for vpopmail section in result
+
+       verify that php euid/egid match vpopmail's
+
+       in setups where only certain domain users will be administrated
+       verify that php euid/egid can access their respective directories
+
+CONTACT INFO
+-------------------------------------------------------------------------------
+
 your comments, fixes and stuff are welcome
 Boian Bonev <[EMAIL PROTECTED]>
 
-$Id: README,v 1.1 2001/01/14 17:38:29 bbonev Exp $
+$Id: README,v 1.2 2001/01/23 21:46:03 bbonev Exp $
 
Index: php4/ext/vpopmail/config.m4
diff -u php4/ext/vpopmail/config.m4:1.3 php4/ext/vpopmail/config.m4:1.4
--- php4/ext/vpopmail/config.m4:1.3     Sun Jan 14 14:21:15 2001
+++ php4/ext/vpopmail/config.m4 Tue Jan 23 13:46:03 2001
@@ -1,45 +1,50 @@
-dnl $Id: config.m4,v 1.3 2001/01/14 22:21:15 david Exp $
+dnl $Id: config.m4,v 1.4 2001/01/23 21:46:03 bbonev Exp $
 dnl config.m4 for extension vpopmail
 
-PHP_ARG_WITH(vpopmail, whether to include vpopmail support,
-[  --with-vpopmail[=DIR]      Include vpopmail support])
+PHP_ARG_WITH(vpopmail, for vpopmail support,
+[  --with-vpopmail[=DIR]   Include vpopmail support.])
 
 if test "$PHP_VPOPMAIL" != "no"; then
+       AC_MSG_CHECKING(for vpopmail install directory)
+       for i in ~vpopmail /home/vpopmail /home/popmail /var/qmail/vpopmail 
+/var/qmail/popmail $PHP_VPOPMAIL; do
+               if test -r $i/vpopmail.h; then
+                       VPOPMAIL_INC_DIR=$i
+                       VPOPMAIL_DIR=$i
+               elif test -r $i/include/vpopmail.h; then
+                       VPOPMAIL_INC_DIR=$i/include
+                       VPOPMAIL_DIR=$i
+               fi
+
+               if test -r $i/libvpopmail.a; then
+                       VPOPMAIL_LIB_DIR=$i
+               elif test -r $i/lib/libvpopmail.a; then
+                       VPOPMAIL_LIB_DIR=$i/lib
+               fi
+
+               if test -r $i/vadddomain; then
+                       VPOPMAIL_BIN_DIR=$i
+               elif test -r $i/bin/vadddomain; then
+                       VPOPMAIL_BIN_DIR=$i/bin
+               fi
+       done
+
+       for i in "$VPOPMAIL_INC_DIR/vpopmail.h" "$VPOPMAIL_INC_DIR/vpopmail_config.h" 
+"$VPOPMAIL_LIB_DIR/libvpopmail.a" "$VPOPMAIL_BIN_DIR/vadddomain" 
+"$VPOPMAIL_BIN_DIR/vaddaliasdomain" "$VPOPMAIL_BIN_DIR/vdeldomain" ; do
+               if test ! -r "$i"; then
+                       AC_MSG_ERROR(Could not find '$i'. Please make sure you have
+                               vpopmail installed. Use
+                               ./configure --with-vpopmail=<vpopmail-home-dir> if 
+necessary)
+               fi
+       done
+
+       AC_MSG_RESULT($VPOPMAIL_DIR)
+
+       AC_ADD_INCLUDE($VPOPMAIL_INC_DIR)
 
-  for i in /home/vpopmail /home/popmail /var/qmail/vpopmail /var/qmail/popmail 
$PHP_VPOPMAIL; do
-    if test -r $i/vpopmail.h; then
-      VPOPMAIL_INC_DIR=$i
-    elif test -r $i/include/vpopmail.h; then
-      VPOPMAIL_INC_DIR=$i/include
-    fi
-
-    if test -r $i/libvpopmail.a; then
-      VPOPMAIL_LIB_DIR=$i
-    elif test -r $i/lib/libvpopmail.a; then
-      VPOPMAIL_LIB_DIR=$i/lib
-    fi
-  done
-
-  if test -z "$VPOPMAIL_INC_DIR"; then
-    AC_MSG_ERROR(Could not find vpopmail.h. Please make sure you have
-                 vpopmail installed. Use
-                 ./configure --with-vpopmail=<vpopmail-home-dir> if necessary)
-  fi
-
-  if test -z "$VPOPMAIL_LIB_DIR"; then
-    AC_MSG_ERROR(Could not find libvpopmail.a. Please make sure you have
-                 vpopmail installed. Use
-                 ./configure --with-vpopmail=<vpopmail-home-dir> if necessary)
-  fi
-
-  AC_MSG_RESULT(found in $VPOPMAIL_LIB_DIR)
+       PHP_SUBST(VPOPMAIL_SHARED_LIBADD)
+       AC_ADD_LIBRARY_WITH_PATH(vpopmail, $VPOPMAIL_LIB_DIR, VPOPMAIL_SHARED_LIBADD)
 
-  AC_ADD_INCLUDE($VPOPMAIL_INC_DIR)
+       AC_DEFINE(HAVE_VPOPMAIL,1,[Whether you have vpopmail])
+       AC_DEFINE_UNQUOTED(VPOPMAIL_BIN_DIR,"$VPOPMAIL_BIN_DIR",[vpopmail bin path])
 
-  PHP_SUBST(VPOPMAIL_SHARED_LIBADD)
-  AC_ADD_LIBRARY_WITH_PATH(vpopmail, $VPOPMAIL_LIB_DIR, VPOPMAIL_SHARED_LIBADD)
-
-  AC_DEFINE(HAVE_VPOPMAIL, 1, [ ])
-
-  PHP_EXTENSION(vpopmail, $ext_shared)
+       PHP_EXTENSION(vpopmail, $ext_shared)
 fi
Index: php4/ext/vpopmail/php_vpopmail.c
diff -u php4/ext/vpopmail/php_vpopmail.c:1.4 php4/ext/vpopmail/php_vpopmail.c:1.5
--- php4/ext/vpopmail/php_vpopmail.c:1.4        Sun Jan 14 18:14:12 2001
+++ php4/ext/vpopmail/php_vpopmail.c    Tue Jan 23 13:46:03 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_vpopmail.c,v 1.4 2001/01/15 02:14:12 david Exp $ */
+/* $Id: php_vpopmail.c,v 1.5 2001/01/23 21:46:03 bbonev Exp $ */
 
 /* TODO: move to config.m4 when support for old versions is ready or just
  * don't support rather old vpopmail. current version must bail out if
@@ -32,8 +32,11 @@
 #include "php_ini.h"
 #include "php_vpopmail.h"
 
+#if HAVE_VPOPMAIL
+
 #include "vpopmail.h"
 
+#include "ext/standard/exec.h"
 #include "ext/standard/php_string.h"
 
 ZEND_DECLARE_MODULE_GLOBALS(vpopmail)
@@ -46,18 +49,28 @@
 #undef PACKAGE
 #include "vpopmail.h"
 
+/* vpopmail does not export this, argh! */
+#define MAX_BUFF 500
+
 /* Function table */
 
 function_entry vpopmail_functions[] = {
-       /* domain management */
-       PHP_FE(vpopmail_adddomain, NULL)
-       PHP_FE(vpopmail_deldomain, NULL)
+       /* domain management - lib call */
+       PHP_FE(vpopmail_add_domain, NULL)
+       PHP_FE(vpopmail_del_domain, NULL)
+       PHP_FE(vpopmail_add_alias_domain, NULL)
+       /* domain management - exec */
+       PHP_FE(vpopmail_add_domain_ex, NULL)
+       PHP_FE(vpopmail_del_domain_ex, NULL)
+       PHP_FE(vpopmail_add_alias_domain_ex, NULL)
        /* user management */
-       PHP_FE(vpopmail_adduser, NULL)
-       PHP_FE(vpopmail_deluser, NULL)
+       PHP_FE(vpopmail_add_user, NULL)
+       PHP_FE(vpopmail_del_user, NULL)
        PHP_FE(vpopmail_passwd, NULL)
-       PHP_FE(vpopmail_setuserquota, NULL)
+       PHP_FE(vpopmail_set_user_quota, NULL)
        PHP_FE(vpopmail_auth_user, NULL)
+       /* error handling */
+       PHP_FE(vpopmail_error, NULL)
        {NULL, NULL, NULL}
 };
 
@@ -78,7 +91,7 @@
 
 
 PHP_INI_BEGIN()
-       /*      STD_PHP_INI_ENTRY("vpopmail.directory",         "",                    
         PHP_INI_ALL, OnUpdateString,    directory,                      
php_vpopmail_globals,   vpopmail_globals) */
+       /*STD_PHP_INI_ENTRY("vpopmail.directory",               "",                    
+         PHP_INI_ALL, OnUpdateString,    directory,                      
+php_vpopmail_globals,   vpopmail_globals)*/
 PHP_INI_END()
 
 
@@ -99,6 +112,7 @@
        VPOPMAILLS_FETCH();
 
        VPOPMAILG(vpopmail_open) = 0;
+       VPOPMAILG(vpopmail_errno) = 0;
 
        return SUCCESS;
 }
@@ -118,23 +132,28 @@
 {
        char ids[64];
 
-       sprintf(ids, "%d/%d", VPOPMAILUID, VPOPMAILGID);
+       sprintf(ids, "%d/%d %d/%d/%d/%d", VPOPMAILUID, VPOPMAILGID, getuid(), 
+getgid(), geteuid(), getegid());
 
        php_info_print_table_start();
        php_info_print_table_header(2, "vpopmail support", "enabled");
        php_info_print_table_row(2, "vpopmail version", VERSION);
-       php_info_print_table_row(2, "vpopmail uid/gid", ids);
+       php_info_print_table_row(2, "vpopmail uid/gid php uid/gid/euid/egid", ids);
        php_info_print_table_row(2, "vpopmail dir", VPOPMAILDIR);
+       php_info_print_table_row(2, "vpopmail vadddomain", VPOPMAIL_BIN_DIR 
+VPOPMAIL_ADDD);
+       php_info_print_table_row(2, "vpopmail vdeldomain", VPOPMAIL_BIN_DIR 
+VPOPMAIL_DELD);
+       php_info_print_table_row(2, "vpopmail vaddaliasdomain", VPOPMAIL_BIN_DIR 
+VPOPMAIL_ADAD);
        php_info_print_table_end();
 
        DISPLAY_INI_ENTRIES();
 }
-
 
+/*
+ * Domain management functions - library call
+ */
 
-/* {{{ proto void vpopmail_adddomain(string domain, string dir, int uid, int gid)
+/* {{{ proto bool vpopmail_add_domain(string domain, string dir, int uid, int gid)
    Add a new virtual domain */
-PHP_FUNCTION(vpopmail_adddomain)
+PHP_FUNCTION(vpopmail_add_domain)
 {
        zval **domain;
        zval **dir;
@@ -163,20 +182,21 @@
                                                Z_LVAL_PP(gid)
 #endif
                                                );
+       VPOPMAILG(vpopmail_errno)=retval;
 
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_deldomain(string domain)
+/* {{{ proto bool vpopmail_del_domain(string domain)
    Delete a virtual domain */
-PHP_FUNCTION(vpopmail_deldomain)
+PHP_FUNCTION(vpopmail_del_domain)
 {
        zval **domain;
        int retval;
@@ -190,20 +210,22 @@
        VPOPMAILG(vpopmail_open) = 1;
 
        retval = vdeldomain(Z_STRVAL_PP(domain));
+       
+       VPOPMAILG(vpopmail_errno)=retval;
 
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_addaliasdomain(string domain, string aliasdomain)
+/* {{{ proto bool vpopmail_add_alias_domain(string domain, string aliasdomain)
    Add an alias for a virtual domain */
-PHP_FUNCTION(vpopmail_addaliasdomain)
+PHP_FUNCTION(vpopmail_add_alias_domain)
 {
        zval **domain;
        zval **aliasdomain;
@@ -229,7 +251,8 @@
        tmpstr = vget_assign(Z_STRVAL_PP(domain), Dir, 156, &uid, &gid);
 
        if (tmpstr == NULL) {
-        php_error(E_WARNING, "existing domain %s was not found", Z_STRVAL_PP(domain));
+               php_error(E_WARNING, "vpopmail_add_alias_domain error: existing domain 
+%s was not found", Z_STRVAL_PP(domain));
+               VPOPMAILG(vpopmail_errno) = 1;
                RETURN_FALSE;
        }
 
@@ -240,24 +263,259 @@
        sprintf(TmpBuf2, "%s/domains/%s", Dir, Z_STRVAL_PP(domain));
 
        if (symlink(TmpBuf2, TmpBuf1) != 0) {
-        php_error(E_WARNING, "vpopmail_addaliasdomain could not symlink domains: %s", 
strerror(errno));
+               php_error(E_WARNING, "vpopmail_add_alias_domain error: could not 
+symlink domains: %s", strerror(errno));
+               VPOPMAILG(vpopmail_errno) = 1;
                RETURN_FALSE;
        }
 
        if (add_domain_assign(Z_STRVAL_PP(aliasdomain), Dir, uid, gid) != 0) {
                php_error(E_WARNING, "vpopmail_addaliasdomain could not add domain to 
control files");
+               VPOPMAILG(vpopmail_errno) = 1;
                RETURN_FALSE;
        }
 
        signal_process("qmail-send", SIGHUP);
 
+       VPOPMAILG(vpopmail_errno) = 0;
        RETURN_TRUE;
 }
 /* }}} */
+
+/*
+ * Domain management functions - exec
+ */
+
+/* {{{ proto int vpopmail_add_domain_ex(string domain, string passwd [, string quota 
+[, string bounce [, bool apop]]])
+   Add a new virtual domain */
+PHP_FUNCTION(vpopmail_add_domain_ex) {
+       zval **domain, **passwd, **quota, **bounce, **apop;
+       int 
+retval,len=0,argc=ZEND_NUM_ARGS(),Uid=VPOPMAILUID,Gid=VPOPMAILGID,is_bounce_email;
+       int fr_bounce=0,fr_quota=0;
+       char 
+*q,*bo,*cmd,*escdomain="",*escpasswd="",*escquota="",*escbounce="",*escapop="";
+
+       if (argc < 2 || argc > 5 || zend_get_parameters_ex(argc, &domain, &passwd, 
+&quota, &bounce, &apop) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+       
+       VPOPMAILLS_FETCH();
+
+       switch (argc) {
+               case 5:
+                       convert_to_long_ex(apop);
+                       escapop=Z_BVAL_PP(apop)?"1":"0";
+                       /* Fall-through. */
+               case 4:
+                       fr_bounce=1;
+                       convert_to_string_ex(bounce);
+                       escbounce=php_escape_shell_cmd(Z_STRVAL_PP(bounce));
+                       if (!escbounce) {
+                               php_error(E_WARNING,"vpopmail_adddomain error: cannot 
+alloc");
+                               VPOPMAILG(vpopmail_errno)=1;
+                               RETURN_FALSE;
+                       }
+                       /* Fall-through. */
+               case 3:
+                       fr_quota=1;
+                       convert_to_string_ex(quota);
+                       escquota=php_escape_shell_cmd(Z_STRVAL_PP(quota));
+                       if (!escquota) {
+                               php_error(E_WARNING,"vpopmail_adddomain error: cannot 
+alloc");
+                               VPOPMAILG(vpopmail_errno)=1;
+                               RETURN_FALSE;
+                       }
+                       /* Fall-through. */
+               case 2:
+                       convert_to_string_ex(passwd);
+                       convert_to_string_ex(domain);
+                       break;
+       }
+
+       escdomain=php_escape_shell_cmd(Z_STRVAL_PP(domain));
+       escpasswd=php_escape_shell_cmd(Z_STRVAL_PP(passwd));
+       if (!escdomain||!escpasswd) {
+               if (fr_quota)
+                       efree(escquota);
+               if (fr_bounce)
+                       efree(escbounce);
+               php_error(E_WARNING,"vpopmail_adddomain error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       len+=strlen(VPOPMAIL_BIN_DIR);
+       len+=strlen(VPOPMAIL_ADDD);
+       if (*escquota)
+               len+=strlen("-q ")+strlen(escquota)+strlen(" ");
+       if (*escbounce) {
+               if (strchr(Z_STRVAL_PP(bounce),'@')) {
+                       is_bounce_email=1;
+                       len+=strlen("-e ")+strlen(escbounce)+strlen(" ");
+               } else {
+                       is_bounce_email=0;
+                       len+=strlen("-b ");
+               }
+       }
+       if (*escapop)
+               len+=strlen("-a ");
+       len+=strlen(escdomain)+strlen(" ");
+       len+=strlen(escpasswd)+strlen(" ");
+       len++;
+       cmd=emalloc(len);
+       if (!cmd) {
+               if (fr_quota)
+                       efree(escquota);
+               if (fr_bounce)
+                       efree(escbounce);
+               efree(escdomain);
+               efree(escpasswd);
+               php_error(E_WARNING,"vpopmail_adddomain error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       strcpy(cmd,VPOPMAIL_BIN_DIR VPOPMAIL_ADDD);
+       if (*escquota) {
+               strcat(cmd,"-q ");
+               strcat(cmd,escquota);
+               strcat(cmd," ");
+       }
+       if (*escbounce) {
+               if (is_bounce_email) {
+                       strcat(cmd,"-e ");
+                       strcat(cmd,escbounce);
+                       strcat(cmd," ");
+               } else {
+                       strcat(cmd,"-b ");
+               }
+       }
+       if (*escapop)
+               strcat(cmd,"-a ");
+       strcat(cmd,escdomain);
+       strcat(cmd," ");
+       strcat(cmd,escpasswd);
+       retval=php_Exec(0,cmd,NULL,return_value);
+       efree(cmd);
+       efree(escdomain);
+       efree(escpasswd);
+       if (fr_quota)
+               efree(escquota);
+       if (fr_bounce)
+               efree(escbounce);
+
+       if (retval!=VA_SUCCESS) {
+               php_error(E_WARNING,"vpopmail_add_domain_ex error: %d", retval);
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       } else {
+               VPOPMAILG(vpopmail_errno)=0;
+               RETURN_TRUE;
+       }
+}
+/* }}} */
+
+/* {{{ proto int vpopmail_del_domain_ex(string domain)
+   Delete a virtual domain */
+PHP_FUNCTION(vpopmail_del_domain_ex) {
+       zval **domain;
+       int retval=-1;
+       char *cmd,*escdomain;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &domain) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+
+       VPOPMAILLS_FETCH();
 
-/* {{{ proto void vpopmail_adduser(string user, string domain, string password[, 
string gecos[, bool apop]])
+       convert_to_string_ex(domain);
+
+       escdomain=php_escape_shell_cmd(Z_STRVAL_PP(domain));
+       if (!escdomain) {
+               php_error(E_WARNING,"vpopmail_del_domain_ex error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       
+cmd=emalloc(strlen(VPOPMAIL_BIN_DIR)+strlen(VPOPMAIL_DELD)+strlen(escdomain)+1);
+       if (!cmd) {
+               efree(escdomain);
+               php_error(E_WARNING,"vpopmail_del_domain_ex error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       sprintf(cmd,VPOPMAIL_BIN_DIR VPOPMAIL_DELD"%s",escdomain);
+       retval=php_Exec(0,cmd,NULL,return_value);
+       efree(escdomain);
+       efree(cmd);
+
+       if (retval!=VA_SUCCESS) {
+               php_error(E_WARNING,"vpopmail_del_domain_ex error: %d", retval);
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       } else {
+               VPOPMAILG(vpopmail_errno)=0;
+               RETURN_TRUE;
+       }
+}
+/* }}} */
+
+/* {{{ proto int vpopmail_add_alias_domain_ex(string olddomain, string newdomain)
+   Add alias to an existing virtual domain */
+PHP_FUNCTION(vpopmail_add_alias_domain_ex) {
+       zval **olddomain, **newdomain;
+       int retval;
+       char *cmd,*escolddomain,*escnewdomain;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &olddomain, &newdomain) 
+== FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+
+       VPOPMAILLS_FETCH();
+
+       convert_to_string_ex(olddomain);
+       convert_to_string_ex(newdomain);
+       escnewdomain=php_escape_shell_cmd(Z_STRVAL_PP(newdomain));
+       if (!escnewdomain) {
+               php_error(E_WARNING,"vpopmail_addaliasdomain error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       escolddomain=php_escape_shell_cmd(Z_STRVAL_PP(olddomain));
+       if (!escolddomain) {
+               efree(escnewdomain);
+               php_error(E_WARNING,"vpopmail_addaliasdomain error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+
+       cmd=emalloc(strlen(VPOPMAIL_BIN_DIR 
+VPOPMAIL_ADAD)+strlen(escolddomain)+strlen(" ")+strlen(escnewdomain)+1);
+       if (!cmd) {
+               efree(escnewdomain);
+               efree(escolddomain);
+               php_error(E_WARNING,"vpopmail_addaliasdomain error: cannot alloc");
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       }
+       sprintf(cmd,"%s%s %s",VPOPMAIL_BIN_DIR 
+VPOPMAIL_ADAD,escolddomain,escnewdomain);
+       retval=php_Exec(0,cmd,NULL,return_value);
+       efree(cmd);
+       efree(escnewdomain);
+       efree(escolddomain);
+
+       if (retval!=VA_SUCCESS) {
+               php_error(E_WARNING,"vpopmail_addaliasdomain error: %d", retval);
+               VPOPMAILG(vpopmail_errno)=1;
+               RETURN_FALSE;
+       } else {
+               VPOPMAILG(vpopmail_errno)=0;
+               RETURN_TRUE;
+       }
+}
+/* }}} */
+
+/*
+ * User management functions
+ */
+
+/* {{{ proto bool vpopmail_add_user(string user, string domain, string password[, 
+string gecos[, bool apop]])
    Add a new user to the specified virtual domain */
-PHP_FUNCTION(vpopmail_adduser)
+PHP_FUNCTION(vpopmail_add_user)
 {
        zval **user;
        zval **domain;
@@ -297,20 +555,22 @@
                                          Z_STRVAL_PP(password),
                                          the_gecos,
                                          is_apop);
+       
+       VPOPMAILG(vpopmail_errno)=retval;
 
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_deluser(string user, string domain)
+/* {{{ proto bool vpopmail_del_user(string user, string domain)
    Delete a user from a virtual domain */
-PHP_FUNCTION(vpopmail_deluser)
+PHP_FUNCTION(vpopmail_del_user)
 {
        zval **user;
        zval **domain;
@@ -329,17 +589,19 @@
        retval = vdeluser(Z_STRVAL_PP(user),
                                          Z_STRVAL_PP(domain));
 
+       VPOPMAILG(vpopmail_errno)=retval;
+
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_passwd(string user, string domain, string password)
+/* {{{ proto bool vpopmail_passwd(string user, string domain, string password)
    Change a virtual user's password */
 PHP_FUNCTION(vpopmail_passwd)
 {
@@ -370,20 +632,22 @@
                                         Z_STRVAL_PP(domain),
                                         Z_STRVAL_PP(password),
                                         is_apop);
+       
+       VPOPMAILG(vpopmail_errno)=retval;
 
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_setuserquota(string user, string domain, string quota)
+/* {{{ proto bool vpopmail_set_user_quota(string user, string domain, string quota)
    Sets a virtual user's quota */
-PHP_FUNCTION(vpopmail_setuserquota)
+PHP_FUNCTION(vpopmail_set_user_quota)
 {
        zval **user;
        zval **domain;
@@ -404,18 +668,20 @@
        retval = vsetuserquota(Z_STRVAL_PP(user),
                                                   Z_STRVAL_PP(domain),
                                                   Z_STRVAL_PP(quota));
+       
+       VPOPMAILG(vpopmail_errno)=retval;
 
        if (retval == VA_SUCCESS) {
                RETURN_TRUE;
        }
        else {
-        php_error(E_WARNING, "vpopmail error: %s", verror(retval));
+               php_error(E_WARNING, "vpopmail error: %s", verror(retval));
                RETURN_FALSE;
        }
 }
 /* }}} */
 
-/* {{{ proto void vpopmail_auth_user(string user, string domain, string password[, 
bool apop])
+/* {{{ proto bool vpopmail_auth_user(string user, string domain, string password[, 
+string apop])
    Attempt to validate a username/domain/password. Returns true/false */
 PHP_FUNCTION(vpopmail_auth_user)
 {
@@ -423,17 +689,14 @@
        zval **domain;
        zval **password;
        zval **apop;
-       int is_apop = 0;
        struct passwd *retval;
 
        if (ZEND_NUM_ARGS() < 3 || ZEND_NUM_ARGS() > 4
                        || zend_get_parameters_ex(ZEND_NUM_ARGS(), &user, &domain, 
&password, &apop) == FAILURE)
                WRONG_PARAM_COUNT;
 
-       if (ZEND_NUM_ARGS() > 3) {
-               convert_to_boolean_ex(apop);
-               is_apop = (Z_BVAL_PP(apop) ? 1 : 0);
-       }
+       if (ZEND_NUM_ARGS() > 3)
+               convert_to_string_ex(apop);
 
        convert_to_string_ex(user);
        convert_to_string_ex(domain);
@@ -441,12 +704,18 @@
 
        VPOPMAILLS_FETCH();
        VPOPMAILG(vpopmail_open) = 1;
+       VPOPMAILG(vpopmail_errno) = 0;
 
        retval = vauth_user(Z_STRVAL_PP(user),
                                                Z_STRVAL_PP(domain),
                                                Z_STRVAL_PP(password),
-                                               is_apop);
+                                               Z_STRVAL_PP(apop));
 
+       /* 
+        * we do not set vpopmail_errno here - it is considered auth_user cannot fail; 
+insted it does not auth
+        * this is a vpopmail's api limitation - there is no error return form 
+vauth_user
+        */
+
        if (retval == NULL) {
                RETURN_FALSE;
        }
@@ -456,6 +725,20 @@
 }
 /* }}} */
 
+/* {{{ proto string vpopmail_error(void)
+   Attempt to validate a username/domain/password. Returns true/false */
+PHP_FUNCTION(vpopmail_error)
+{
+       if (ZEND_NUM_ARGS() != 0)
+               WRONG_PARAM_COUNT;
+       
+       VPOPMAILLS_FETCH();
+
+       RETURN_STRING(verror(VPOPMAILG(vpopmail_errno)),1);
+}
+/* }}} */
+
+#endif HAVE_VPOPMAIL
 
 /*
  * Local variables:
Index: php4/ext/vpopmail/php_vpopmail.h
diff -u php4/ext/vpopmail/php_vpopmail.h:1.3 php4/ext/vpopmail/php_vpopmail.h:1.4
--- php4/ext/vpopmail/php_vpopmail.h:1.3        Sun Jan 14 18:14:12 2001
+++ php4/ext/vpopmail/php_vpopmail.h    Tue Jan 23 13:46:03 2001
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: php_vpopmail.h,v 1.3 2001/01/15 02:14:12 david Exp $ */
+/* $Id: php_vpopmail.h,v 1.4 2001/01/23 21:46:03 bbonev Exp $ */
 
 #ifndef PHP_VPOPMAIL_H
 #define PHP_VPOPMAIL_H
@@ -39,19 +39,31 @@
 PHP_RSHUTDOWN_FUNCTION(vpopmail);
 PHP_MINFO_FUNCTION(vpopmail);
 
-/* domain management */
-PHP_FUNCTION(vpopmail_adddomain);
-PHP_FUNCTION(vpopmail_deldomain);
-PHP_FUNCTION(vpopmail_addaliasdomain);
+/* domain management - lib call */
+PHP_FUNCTION(vpopmail_add_domain);
+PHP_FUNCTION(vpopmail_del_domain);
+PHP_FUNCTION(vpopmail_add_alias_domain);
+/* domain management - exec */
+PHP_FUNCTION(vpopmail_add_domain_ex);
+PHP_FUNCTION(vpopmail_del_domain_ex);
+PHP_FUNCTION(vpopmail_add_alias_domain_ex);
 /* user management */
-PHP_FUNCTION(vpopmail_adduser);
-PHP_FUNCTION(vpopmail_deluser);
+PHP_FUNCTION(vpopmail_add_user);
+PHP_FUNCTION(vpopmail_del_user);
 PHP_FUNCTION(vpopmail_passwd);
-PHP_FUNCTION(vpopmail_setuserquota);
+PHP_FUNCTION(vpopmail_set_user_quota);
 PHP_FUNCTION(vpopmail_auth_user);
+/* error handling */
+PHP_FUNCTION(vpopmail_error);
 
+/* defines for vpopmail command line tool names */
+#define VPOPMAIL_ADDD "/vadddomain "
+#define VPOPMAIL_DELD "/vdeldomain "
+#define VPOPMAIL_ADAD "/vaddaliasdomain "
+
 ZEND_BEGIN_MODULE_GLOBALS(vpopmail)
        int vpopmail_open;
+       int vpopmail_errno;
 ZEND_END_MODULE_GLOBALS(vpopmail)
 
 #ifdef ZTS

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to