⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vpopmail.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 5 页
字号:
  if ( strlen(gecos) >= MAX_PW_GECOS )    return(VA_GECOS_TOO_LONG);  umask(VPOPMAIL_UMASK);  lowerit(username);  lowerit(domain);  if ( is_username_valid(username) != 0 ) return(VA_ILLEGAL_USERNAME);  if ( is_domain_valid(domain) != 0 ) return(VA_INVALID_DOMAIN_NAME);  if ( vauth_getpw( username, domain ) != NULL ) return(VA_USERNAME_EXISTS);  /* record the dir where the vadduser command was run from */  getcwd(calling_dir, sizeof(calling_dir));  /* lookup the home dir, uid and gid for the domain */  if ( vget_assign(domain, Dir, sizeof(Dir), &uid, &gid)==NULL) {    return(VA_DOMAIN_DOES_NOT_EXIST);  }  /* make sure we can load domain limits for default quota */  if (vget_limits(domain, &limits) != 0) {    return(VA_CANNOT_READ_LIMITS);  }  /* go to the domain's home dir (ie test it exists) */  /* would a stat be a better option here? */  if ( chdir(Dir) != 0 ) {    return(VA_BAD_D_DIR);  }  /* create dir for the the user */   if ( (user_hash=make_user_dir(username, domain, uid, gid)) == NULL ) {    chdir(calling_dir);    if (verrori != 0 ) return(verrori);    else return(VA_BAD_U_DIR);  }          /* add the user to the auth backend */  if (vauth_adduser(username, domain, password, gecos, user_hash, apop )!=0) {    fprintf(stderr, "Failed while attempting to add user to auth backend\n");    /* back out of changes made so far */    chdir(Dir); if (strlen(user_hash)>0) { chdir(user_hash);} vdelfiles(username);    chdir(calling_dir);    return(VA_NO_AUTH_CONNECTION);  }  if (limits.defaultquota > 0) {    if (limits.defaultmaxmsgcount > 0)      snprintf (quota, sizeof(quota), "%dS,%dC", limits.defaultquota,        limits.defaultmaxmsgcount);    else      snprintf (quota, sizeof(quota), "%dS", limits.defaultquota);  } else {    if (limits.defaultmaxmsgcount > 0)      snprintf (quota, sizeof(quota), "%dC", limits.defaultmaxmsgcount);    else      strcpy (quota, "NOQUOTA");  }  vsetuserquota (username, domain, quota);#ifdef SQWEBMAIL_PASS  {   /* create the sqwebmail-pass file in the user's maildir    * This file contains a copy of the user's crypted password    */    struct vqpasswd *mypw;    mypw = vauth_getpw( username, domain);    if ( mypw != NULL ) {       vsqwebmail_pass( mypw->pw_dir, mypw->pw_passwd, uid, gid);    }  }#endif#ifdef ENABLE_AUTH_LOGGING  if (vset_lastauth(username,domain,NULL_REMOTE_IP) !=0) {    /* should we back out of all the work we have done so far? */    chdir(calling_dir);    fprintf (stderr, "Failed to create create lastauth entry\n");    return (VA_NO_AUTH_CONNECTION);  }#endif  /* jump back into the dir from which the vadduser was run */  chdir(calling_dir);  return(VA_SUCCESS);}/************************************************************************/char randltr(void){  static const char saltchar[] =    "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";  return saltchar[(rand() % 64)];}/************************************************************************//* * encrypt a password  * Input * clearpass = pointer to clear text password * ssize     = size of the crypted pointer buffer *  * Output *  copies the encrypted password into the crypted  *      character pointer *  * Return code: *   VA_CRYPT_FAILED = encryption failed *   VA_SUCCESS = 0  = encryption success *  */int mkpasswd3( char *clearpass, char *crypted, int ssize ){ char *tmpstr; char salt[12]; static int seeded = 0; if (!seeded) {   seeded = 1;   srand (time(NULL)^(getpid()<<15)); }#ifdef MD5_PASSWORDS  salt[0] = '$';  salt[1] = '1';  salt[2] = '$';  salt[3] = randltr();  salt[4] = randltr();  salt[5] = randltr();  salt[6] = randltr();  salt[7] = randltr();  salt[8] = randltr();  salt[9] = randltr();  salt[10] = randltr();  salt[11] = 0;#else  salt[0] = randltr();  salt[1] = randltr();  salt[2] = 0;#endif  tmpstr = crypt(clearpass,salt);  if ( tmpstr == NULL ) return(VA_CRYPT_FAILED);  strncpy(crypted,tmpstr, ssize);  return(VA_SUCCESS);}/************************************************************************//*  * prompt the command line and get a password twice, that matches  */char *vgetpasswd(char *user) { static char pass1[128]; char pass2[128]; char prompt[128]; /* Michael Bowe 14th August 2003  * Is setting up a static pass1 and returning a pointer  * to it is the best way to run this function? Maybe there  * is a better way we can do this....  */  memset(pass1, 0, sizeof(pass1));  snprintf( prompt, sizeof(prompt), "Please enter password for %s: ", user);  while( 1 ) {    snprintf(pass1, sizeof(pass1), "%s", getpass(prompt));    snprintf(pass2, sizeof(pass2), "%s", getpass("enter password again: "));    if ( strcmp( pass1, pass2 ) != 0 ) {      printf("Passwords do not match, try again\n");    } else {      break;    }  }  return(pass1);}/************************************************************************//*  * vdelfiles : delete a directory tree * * input: directory to start the deletion * output:  *         0 on success *        -1 on failer */int vdelfiles(char *dir){ DIR *mydir; struct dirent *mydirent; struct stat statbuf;  /* Modified By David Wartell david@actionwebservices.com to work with    * Solaris. Unlike Linux, Solaris will NOT return error when unlink()    * is called on a directory.   A correct implementation to support    * Linux & Solaris is to test to see if the file is a directory.     * If it is not a directory unlink() it.    * If unlink() returns an error return error.   */  if (lstat(dir, &statbuf) == 0) {    /* if dir is not a directory unlink it */    if ( !( S_ISDIR(statbuf.st_mode) ) ) {      if ( unlink(dir) == 0 ) {        /* return success we deleted the file */        return(0);      } else {        /* error, return error to calling function,          * we couldn't unlink the file          */        return(-1);      }    }  } else {    /* error, return error to calling function,      * we couldn't lstat the file      */    return(-1);  }  /* go to the directory, and check for error */   if (chdir(dir) == -1) {    /* error, return error to calling function */    return(-1);  }  /* open the directory and check for an error */  if ( (mydir = opendir(".")) == NULL ) {    /* error, return error */    fprintf(stderr, "Failed to opendir()");    return(-1);  }  while((mydirent=readdir(mydir))!=NULL){    /* skip the current directory and the parent directory entries */    if ( strncmp(mydirent->d_name,".", 2) !=0 &&         strncmp(mydirent->d_name,"..", 3)!=0 ) {      /* stat the file to check it's type, I/O expensive */      stat( mydirent->d_name, &statbuf);      /* Is the entry a directory? */      if ( S_ISDIR(statbuf.st_mode) ) {        /* delete the sub tree, -1 means an error */        if ( vdelfiles ( mydirent->d_name) == -1 ) {          /* on error, close the directory stream */          closedir(mydir);          /* and return error */          return(-1);        }      /* the entry is not a directory, unlink it to delete */      } else {        /* unlink the file and check for error */        if (unlink(mydirent->d_name) == -1) {          /* print error message and return and error */          fprintf (stderr, "Failed to delete directory %s", mydirent->d_name);          return(-1);        }      }    }  }    /* close the directory stream, we don't need it anymore */  closedir(mydir);  /* go back to the parent directory and check for error */  if (chdir("..") == -1) {    /* print error message and return an error */    fprintf(stderr, "Failed to cd to parent");    return(-1);  }  /* delete the directory, I/O expensive */  rmdir(dir);  /* return success */  return(0);}/************************************************************************//*  * Add a domain to all the control files  * And signal qmail * domain is the domain name * dir is the full path to the domain directory * uid and gid are the uid/gid to store in the assign file */int add_domain_assign( char *alias_domain, char *real_domain,                       char *dir, uid_t uid, gid_t gid ){ FILE *fs1 = NULL; struct stat mystat; char tmpstr1[MAX_BUFF]; char tmpstr2[MAX_BUFF];  snprintf(tmpstr1, sizeof(tmpstr1), "%s/users/assign", QMAILDIR);  /* stat assign file, if it's not there create one */  if ( stat(tmpstr1,&mystat) != 0 ) {    /* put a . on one line by itself */    if ( (fs1 = fopen(tmpstr1, "w+"))==NULL ) {      fprintf(stderr, "could not open assign file\n");      return(-1);    }    fputs(".\n", fs1);    fclose(fs1);  }  snprintf(tmpstr2, sizeof(tmpstr2), "+%s-:%s:%lu:%lu:%s:-::",    alias_domain, real_domain, (long unsigned)uid, (long unsigned)gid, dir);  /* update the file and add the above line and remove duplicates */  if (update_file(tmpstr1, tmpstr2) !=0 ) {   fprintf (stderr, "Failed while attempting to update_file() the assign file\n");   return (-1);  }  /* set the mode in case we are running with a strange mask */  chmod(tmpstr1, VPOPMAIL_QMAIL_MODE );   /* compile the assign file */  /* as of the 5.4 builds, we always need an updated assign file since   * we call vget_assign to add the postmaster account.  The correct   * solution is to cache the information somewhere so vget_assign   * can pull from cache instead of having to read the assign file.   */  /* if ( OptimizeAddDomain == 0 ) */ update_newu();  /* If we have more than 50 domains in rcpthosts   * make a morercpthosts and compile it   */  if ( count_rcpthosts() >= 50 ) {    snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/morercpthosts", QMAILDIR);    if (update_file(tmpstr1, alias_domain) !=0) {      fprintf (stderr, "Failed while attempting to update_file() the morercpthosts file\n");      return (-1);    }    snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/morercpthosts", QMAILDIR);    chmod(tmpstr1, VPOPMAIL_QMAIL_MODE );     if ( OptimizeAddDomain == 0 ) compile_morercpthosts();  /* or just add to rcpthosts */  } else {    snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/rcpthosts", QMAILDIR);    if (update_file(tmpstr1, alias_domain) != 0) {      fprintf (stderr, "Failed while attempting to update_file() the rcpthosts file\n");      return (-1);    }    snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/rcpthosts", QMAILDIR);    chmod(tmpstr1, VPOPMAIL_QMAIL_MODE );   }      /* Add to virtualdomains file and remove duplicates  and set mode */  snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/virtualdomains", QMAILDIR );  snprintf(tmpstr2, sizeof(tmpstr2), "%s:%s", alias_domain, alias_domain );  if (update_file(tmpstr1, tmpstr2) !=0 ) {    fprintf (stderr, "Failed while attempting to update_file() the virtualdomains file\n");    return (-1);  };  chmod(tmpstr1, VPOPMAIL_QMAIL_MODE );   /* make sure it's not in locals and set mode */  snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/locals", QMAILDIR);  if (remove_line( alias_domain, tmpstr1) < 0) {    fprintf (stderr, "Failure while attempting to remove_line() the locals file\n");    return(-1);  }  chmod(tmpstr1, VPOPMAIL_QMAIL_MODE );   return(0);}/************************************************************************//* * delete a domain from the control files * the control files consist of : * - /var/qmail/control/rcpthosts * - /var/qmail/control/virtualdomains */int del_control(char *domain ) { char tmpbuf1[MAX_BUFF]; char tmpbuf2[MAX_BUFF]; struct stat statbuf; int problem_occurred = 0;  /* delete entry from control/rcpthosts (if it is found) */  snprintf(tmpbuf1, sizeof(tmpbuf1), "%s/control/rcpthosts", QMAILDIR);  switch ( remove_line( domain, tmpbuf1) ) {    case -1 :      /* error ocurred in remove line */      fprintf (stderr, "Failed while attempting to remove_line() the rcpthosts file\n");      problem_occurred = 1;      break;    case 0 :      /* not found in rcpthosts, so try morercpthosts */      snprintf(tmpbuf1, sizeof(tmpbuf1), "%s/control/morercpthosts", QMAILDIR);        switch (remove_line( domain, tmpbuf1) ) {        case -1 :          /* error ocurred in remove line           * but this is normal enough as on smaller servers, the morercpthosts           * file wont exist. So ignore this 'error' condition.           */          break;         case 0 :         /* not found in morercpthosts */          break;        case 1 :          /* was removed from morercpthosts */          /* now test to see if morercpthosts exists */          if ( stat( tmpbuf1, &statbuf) == 0 ) {            /* morercpthosts exists. Now check to see if its empty */            if ( statbuf.st_size == 0 ) {              /* is empty. So delete it */              unlink(tmpbuf1);              /* also delete the morercpthosts.cdb */              strncat(tmpbuf1, ".cdb", sizeof(tmpbuf1)-strlen(tmpbuf1)-1);              unlink(tmpbuf1);            } else {              /* morercpthosts is not empty, so compile it */              compile_morercpthosts();              /* make sure correct permissions are set on morercpthosts */              chmod(tmpbuf1, VPOPMAIL_QMAIL_MODE );             }          }          break; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -