Common subdirectories: vpopmail-4.10.35/cdb and vpopmail-patched/cdb
Common subdirectories: vpopmail-4.10.35/contrib and vpopmail-patched/contrib
Common subdirectories: vpopmail-4.10.35/convert and vpopmail-patched/convert
Common subdirectories: vpopmail-4.10.35/doc and vpopmail-patched/doc
Common subdirectories: vpopmail-4.10.35/oracle and vpopmail-patched/oracle
diff -u vpopmail-4.10.35/vaddaliasdomain.c vpopmail-patched/vaddaliasdomain.c
--- vpopmail-4.10.35/vaddaliasdomain.c	Tue Jun 26 12:11:23 2001
+++ vpopmail-patched/vaddaliasdomain.c	Thu Aug 30 17:47:54 2001
@@ -4,6 +4,9 @@
  * 
  * Copyright (C) 1999,2001 Inter7 Internet Technologies, Inc.
  *
+ * Rewritten by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> to reflect
+ * the addition of vaddaliasdomain()
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -47,37 +50,43 @@
  int argc;
  char *argv[];
 {
- char Dir[156];
- char *tmpstr;
- uid_t uid;
- gid_t gid;
+ int result;
 
 	get_options(argc,argv);
 
 	lowerit(Domain_old);
 	lowerit(Domain_new);
 
-	tmpstr = vget_assign(Domain_old, Dir, 156, &uid, &gid);
-	if ( tmpstr == NULL ) {
-		printf("existing domain %s not found\n", Domain_old);
-		usage();
-		vexit(0);
-	}
-	strncpy(TmpBuf3, Dir, MAX_BUFF);
-
-	tmpstr = strstr(Dir, "/domains");
-	*tmpstr = 0;
-
-	snprintf(TmpBuf1, MAX_BUFF, "%s/domains/%s", Dir, Domain_new);
-	snprintf(TmpBuf2, MAX_BUFF, "%s/domains/%s", Dir, Domain_old);
-	if ( symlink(TmpBuf2, TmpBuf1) != 0 ) {
-		fprintf(stderr, "Could not make link\n");
-		perror("making link");
-	}
-	add_domain_assign( Domain_new, TmpBuf3, uid, gid );
-	signal_process("qmail-send", SIGHUP);
+  result=vaddaliasdomain(Domain_new,Domain_old);
+
+  if(result==VA_INVALID_DOMAIN_NAME)
+  {
+    printf("Error: The aliasdomain %s is invalid.\n", Domain_new);
+    usage();
+    return(1);
+  }
+ 
+  else if(result==VA_DOMAIN_ALREADY_EXISTS)
+  {
+    printf("Error: The domain %s already exists.\n", Domain_new);
+    usage();
+    return(1);
+  }
+
+  else if(result==VA_OLD_DOMAIN_DOES_NOT_EXIST)
+  {
+    printf("Error: The domain %s doesn't exist.\n", Domain_old);
+    usage();
+    return(1);
+  }
+
+  if(result==0)
+  {
+    printf("Successfully added domain %s as an alias to %s\n", Domain_new, Domain_old);
+    return(0);
+  }
+  
 
-	return(vexit(0));
 }
 
 void usage()
diff -u vpopmail-4.10.35/vpopmail.c vpopmail-patched/vpopmail.c
--- vpopmail-4.10.35/vpopmail.c	Thu Aug 23 18:05:54 2001
+++ vpopmail-patched/vpopmail.c	Thu Aug 30 17:55:20 2001
@@ -4,6 +4,13 @@
  * 
  * Copyright (C) 2000,2001 Inter7 Internet Technologies, Inc.
  *
+ * vaddaliasdomain() and is_alias_domain() and the changes needed to vdeldomain()
+ * to reflect the new aliasdomain scheme were added by Gabriel Ambuehl
+ * <gabriel_ambuehl@buz.ch> who hereby places them under the GNU GPL.
+ * I hereby explicitely agree to put the code I contributed under any less 
+ * restrictive license if Inter7 Internet Technologies, Inc. should decide 
+ * to do so and declare that my employer allowed me to do so.
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -73,6 +80,58 @@
 int host_in_locals(char *domain);
 #endif
 
+/*
+ *
+ * written by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> 
+ * Add an alias domain to the control files
+ * new_domain: name of the alias domain
+ * old_domain: name of the domain the mail should be routed to
+ *
+ */
+int vaddaliasdomain( char *new_domain, char *old_domain)
+{
+ int i;
+ char tmpbuf[156];
+ char * tmpstr;
+ uid_t uid;
+ gid_t gid;
+ char dir[156];
+
+    /* we only do lower case */
+    lowerit(new_domain);
+    lowerit(old_domain);
+ 
+    /* check invalid email domain characters */
+    for(i=0; new_domain[i]!=0;++i) {
+        if (i == 0 && new_domain[i] == '-' ) return(VA_INVALID_DOMAIN_NAME);
+        if (isalnum((int) new_domain[i])==0 && new_domain[i]!='-' && new_domain[i]!='.')
+            return(VA_INVALID_DOMAIN_NAME);
+    }
+    if ( new_domain[i-1] == '-' ) return(VA_INVALID_DOMAIN_NAME);
+
+    /* after the name is okay, check if it already exists */
+    if ( vget_assign(new_domain, NULL, 156, NULL, NULL ) != NULL ) {
+        return(VA_DOMAIN_ALREADY_EXISTS);
+    }
+
+   /*old domain must exist too, of course and we need it's data! */
+	tmpstr = vget_assign(old_domain, dir , 156, &uid, &gid);
+	if ( tmpstr == NULL ) {
+		return(VA_OLD_DOMAIN_DOES_NOT_EXIST);
+	}
+	/*add the  domain to all the control files */
+	add_domain_assign(new_domain, dir, uid, gid);
+
+  /*add the domain to the dir/aliasdomains file*/
+
+  snprintf(tmpbuf, 156, "%s/aliasdomains", dir);
+  update_file(tmpbuf, new_domain);
+  
+	signal_process("qmail-send", SIGHUP);
+	return NULL;
+}
+ 
+
 /* 
  * Add a domain to the entire email system
  *
@@ -159,7 +218,7 @@
         chdir(TmpBuf1);
         return(VA_COULD_NOT_MAKE_DOMAIN_DIR);
     }
-    
+      
     if ( chdir(DomainSubDir) != 0 ) {
         chdir(TmpBuf1);
         return(VA_BAD_D_DIR);
@@ -193,68 +252,92 @@
 
     /* return back to the callers directory and return success */
     chdir(TmpBuf1);
-
     return(VA_SUCCESS);
 }
 
+
+/*
+ * rewritten by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> to support deletion of the
+ * new non-symlink domain style including all the aliasdomains
+ */
+ 
 int vdeldomain( char *domain )
 {
- struct stat statbuf;
- char Dir[156];
- char *tmpstr;
- uid_t uid;
- gid_t gid;
-
-    getcwd(TmpBuf1, MAX_BUFF);
-
-    lowerit(domain);
-    tmpstr = vget_assign(domain, Dir, 156, &uid, &gid );
-    if ( tmpstr == NULL ) {
-	return(VA_DOMAIN_DOES_NOT_EXIST);
-    }
-
-    if ( chdir(Dir) != 0 ) {
-        return(VA_BAD_V_DIR);
-    }
-
-    if ( chdir("..") != 0 ) {
-	return(VA_BAD_D_DIR);
-    }
-
-    if ( stat(domain, &statbuf) != 0 ) {
-        chdir(TmpBuf1);
-        return(VA_DOMAIN_DOES_NOT_EXIST);
-    }
-
-	/* delete the domain from the filesystem */ 
-    if ( vdelfiles(domain) != 0 ) {
-		printf("could not delete directory %s\n", domain);
-		return(VA_BAD_DIR);
-	}
-
-	/* delete the assign file line */
+   char Dir[156];
+   char tmpbuf1[156];
+   char tmpbuf2[156];
+   char tmpbuf3[156];
+   
+   char TmpBuf1[MAX_BUFF];
+   char *tmpstr;
+   uid_t uid;
+   gid_t gid;
+   struct stat stat_result;
+
+  getcwd(TmpBuf1, MAX_BUFF);
+
+  lowerit(domain);
+  tmpstr = vget_assign(domain, Dir, 156, &uid, &gid);
+  if ( tmpstr == NULL ) {
+      return(VA_DOMAIN_DOES_NOT_EXIST);
+  }
+
+  if ( chdir(Dir) != 0 ) {
+      return(VA_BAD_V_DIR);
+  }
+  
+  if ( chdir("..") != 0 ) {
+      return(VA_BAD_D_DIR);
+  }
+
+  //what is is this good for? If we can chdir(Dir) then the domain dir has to exist
+  //the existence of the domain itself was checked above already
+  /*if ( stat(domain, &statbuf) != 0 ) {
+      chdir(TmpBuf1);
+      return(VA_DOMAIN_DOES_NOT_EXIST);
+  }*/
+
+  
+  if (is_alias_domain(domain)!=0) {
+	// delete the domain from the filesystem 
+      FILE * fs;
+      snprintf(tmpbuf1, 156, "%s/aliasdomains", Dir);
+      if(stat(tmpbuf1, &stat_result)==0) {
+          while((int) stat_result.st_size > 2) {
+              fs=fopen(tmpbuf1, (const char *) "r");
+              fgets(tmpbuf2, sizeof(tmpbuf2), fs);
+              strlcpy(tmpbuf3, tmpbuf2, strlen(tmpbuf2));
+              fclose(fs);
+              vdeldomain(tmpbuf3);
+              stat(tmpbuf1, &stat_result);
+          }
+      }
+  
+      if ( vdelfiles(domain) != 0 ) {
+          //libs shouldn't print error messages but simply return the error code
+          //printf("could not delete directory %s\n", domain);
+          return(VA_BAD_DIR);
+      }
+      vauth_deldomain(domain);
+      vdel_dir_control(domain);
+      snprintf(tmpbuf1, 156, "dom_%lu", (long unsigned)uid);
+      dec_dir_control(domain, uid, gid);
+
+  }
+  else {
+      //remove alias domain from aliasdomains file
+      snprintf(tmpbuf1, 156, "%s/aliasdomains", Dir);
+      remove_line(domain, tmpbuf1);
+  }
+  
 	del_domain_assign(domain, Dir, uid, gid);
-
-	/* call the auth module to delete the domain from the storage */
-    vauth_deldomain(domain);
-
-    /* delete the email domain from the qmail control files */
-    del_control(domain);
-
-    /* delete the dir control info for this domain */
-    vdel_dir_control(domain);
-
-    /* decrement the master domain control info */
-    snprintf(Dir, 156, "dom_%lu", (long unsigned)uid);
-    dec_dir_control(Dir, uid, gid);
-
-    /* send a HUP signal to qmail-send process to reread control files */
-    signal_process("qmail-send", SIGHUP);
+  del_control(domain);
+  signal_process("qmail-send", SIGHUP);
 
     /* return back to the callers directory */
-    chdir(TmpBuf1);
+  chdir(TmpBuf1);
 
-    return(VA_SUCCESS);
+  return(VA_SUCCESS);
 
 }
 
@@ -656,6 +739,7 @@
  int len1, len2;
  char *tmpstr1, *tmpstr2;
 
+  
 	/* get some memory for string1 */
 	len1 = (2*strlen(domain)) + strlen(domain) + strlen(dir) + 40;
 	if ( (tmpstr1 = calloc(1, len1)) == NULL ) {
@@ -673,6 +757,8 @@
     snprintf(tmpstr1, MAX_BUFF, "+%s-:%s:%lu:%lu:%s:-::", domain, domain,
         (long unsigned)uid, (long unsigned)gid, dir);
 
+    
+
 	/* format the file name */
     snprintf(tmpstr2, MAX_BUFF, "%s/users/assign", QMAILDIR);
 
@@ -1137,6 +1223,10 @@
         return(VA_USER_DOES_NOT_EXIST);
     }
 
+    if (strcmp((const char *) "postmaster", (const char *) user)!=NULL) {
+        return(VA_MAY_NOT_DELETE_POSTMASTER);
+    }
+    
     getcwd(TmpBuf1, MAX_BUFF);
 
     if ( domain == NULL || domain[0] == 0 ) {
@@ -1698,6 +1788,12 @@
           return("no auth connection");
       case VA_MEMORY_ALLOC_ERR:
           return("memory allocation error");
+      /*next two case added by Gabriel Ambuehl <gabriel_ambuehl@buz.ch>*/
+      case VA_OLD_DOMAIN_DOES_NOT_EXIST:
+          return("The old domain you want me to create an alias to doesn't exist.");
+      case VA_MAY_NOT_DELETE_POSTMASTER:
+          return("Sorry, but postmaster accounts may not be deleted as RFC 821 requires that there's a postmaster.");
+
       default:
           return("Unknown error");
     }
@@ -2111,4 +2207,36 @@
 {
     vclose();
     exit(err);
+}
+
+
+int is_alias_domain(char * domain)
+{
+  FILE * fs;
+  char dir[156];
+  char tmpbuf1[156];
+  char tmpbuf2[156];
+  char tmpbuf3[MAX_BUFF];
+  struct stat stat_result;
+  uid_t uid;
+  gid_t gid;
+   
+
+  if(vget_assign(domain, dir, 156, &uid, &gid )==0) {
+      return(VA_DOMAIN_DOES_NOT_EXIST);
+  }
+  snprintf(tmpbuf1, 156, "%s/aliasdomains", dir);
+  snprintf(tmpbuf2, 156, "%s\n", domain);
+  if(stat(tmpbuf1, &stat_result)==0) {
+    fs=fopen((const char *) tmpbuf1, (const char *) "r");
+    while(feof(fs)==0) {
+        fgets(tmpbuf3, MAX_BUFF,  fs);
+        if (strcmp(tmpbuf2, tmpbuf3)==0) {
+            fclose(fs);
+            return 0;
+        }
+    }
+    fclose(fs);
+  }
+  return 1;
 }
Only in vpopmail-patched/: vpopmail.c~
diff -u vpopmail-4.10.35/vpopmail.h vpopmail-patched/vpopmail.h
--- vpopmail-4.10.35/vpopmail.h	Thu Aug 23 18:06:40 2001
+++ vpopmail-patched/vpopmail.h	Thu Aug 30 17:47:54 2001
@@ -63,6 +63,10 @@
 #define VA_BAD_UID                      -22
 #define VA_NO_AUTH_CONNECTION           -23
 #define VA_MEMORY_ALLOC_ERR             -24
+/*added by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> */
+#define VA_OLD_DOMAIN_DOES_NOT_EXIST    -25
+/*added by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> */
+#define VA_MAY_NOT_DELETE_POSTMASTER -26
 
 
 /* gid flags */
@@ -89,8 +93,11 @@
 int vdeluser( char *, char *);
 int vpasswd( char *, char *, char *, int);
 int vsetuserquota( char *, char *, char * );
+/*added by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> */
+int vaddaliasdomain( char *new_domain, char *old_domain);
 int vexit(int err);
 
+
 char randltr(void);
 int mkpasswd3( char *, char *, int);
 char *vgetpasswd( char *);
@@ -132,6 +139,8 @@
 int vfd_move(int,int);
 void update_rules();
 char *vversion(char *);
+/*added by Gabriel Ambuehl <gabriel_ambuehl@buz.ch> */
+int is_alias_domain(char * domain);
 
 #ifdef APOP
 char *dec2hex(unsigned char *);
