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

📄 vpopmail.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 5 页
字号:
      } /* switch for morercpthosts */       break;    case 1 : /* we removed the line successfully */      /* make sure correct permissions are set on rcpthosts */      chmod(tmpbuf1, VPOPMAIL_QMAIL_MODE );      break;   } /* switch for rcpthosts */  /* delete entry from control/virtualdomains (if it exists) */  snprintf(tmpbuf1, sizeof(tmpbuf1), "%s:%s", domain, domain);  snprintf(tmpbuf2, sizeof(tmpbuf2), "%s/control/virtualdomains", QMAILDIR);  if (remove_line( tmpbuf1, tmpbuf2) < 0 ) {    fprintf(stderr, "Failed while attempting to remove_line() the virtualdomains file\n");     problem_occurred = 1;   }  /* make sure correct permissions are set on virtualdomains */  chmod(tmpbuf2, VPOPMAIL_QMAIL_MODE );     if (problem_occurred == 1) {    return (-1);  } else {     return(0);  }}/************************************************************************//* * delete a domain from the users/assign file * input : lots ;) * output : 0 = success *          less than error = failure * */int del_domain_assign( char *alias_domain, char *real_domain,                        char *dir, gid_t uid, gid_t gid )  { char search_string[MAX_BUFF]; char assign_file[MAX_BUFF];  /* format the removal string */   snprintf(search_string, sizeof(search_string), "+%s-:%s:%lu:%lu:%s:-::",    alias_domain, real_domain, (long unsigned)uid, (long unsigned)gid, dir);  /* format the assign file name */  snprintf(assign_file, sizeof(assign_file), "%s/users/assign", QMAILDIR);  /* remove the formatted string from the file */  if (remove_line( search_string, assign_file) < 0) {    fprintf(stderr, "Failed while attempting to remove_line the assign file\n");    return (-1);  }  /* force the permission on the file */  chmod(assign_file, VPOPMAIL_QMAIL_MODE );   /* compile assign file */  update_newu();  return(0);}/************************************************************************//* * Generic remove a line from a file utility * input: template to search for *        file to search inside * * output: -1 on failure *          0 on success, no match found *          1 on success, match was found */int remove_line( char *template, char *filename ){ char tmpbuf1[MAX_BUFF]; struct stat statbuf; FILE *fs_orig; FILE *fs_bak;#ifdef FILE_LOCKING FILE *fs_lock;#endif int found; int i;  /* if we can't stat the file, return error */  if ( stat(filename,&statbuf) == -1 ) return(-1);#ifdef FILE_LOCKING  /* format the lock file name */  snprintf(tmpbuf1, sizeof(tmpbuf1), "%s.lock", filename);  /* open the file with write permissions and check for error */  if ( (fs_lock = fopen(tmpbuf1, "w+")) == NULL ) {    /* return error */    fprintf(stderr, "could not open lock file %s\n", tmpbuf1);    return(-1);  }  /* ask for a write lock on the file   * we don't want anyone writing to it now    */  if ( get_write_lock(fs_lock) < 0 ) {    /* remove lock */    unlock_lock(fileno(fs_lock), 0, SEEK_SET, 0);    fclose(fs_lock);    /* print error message */    fprintf(stderr, "could not get write lock on %s\n", tmpbuf1);    /* return error */    return(-1);  }#endif  /* format a backup file name */  snprintf(tmpbuf1, sizeof(tmpbuf1), "%s.bak", filename);  /* remove the file if it exists already */  unlink(tmpbuf1);  /* move the orignal file to the .bak file */  rename(filename, tmpbuf1);  /* open the file and check for error */  if ( (fs_orig = fopen(filename, "w+")) == NULL ) {#ifdef FILE_LOCKING    /* release resources */    fclose(fs_lock);#endif    fprintf(stderr, "%s file would not open w+\n", filename);    return(-1);  }  /* open the .bak file in read mode and check for error *//* Michael Bowe 23rd August 2003 * Isnt the w+ bit of this code wrong? * At this point our orignal file is known as .bak * so why would we want to try and w+ it? Wont this * del the contents of the file? Ouch! * I have remarked the original code out and left my version below * *  if ( (fs_bak = fopen(tmpbuf1, "r+")) == NULL ) { *   if ( (fs_bak = fopen(tmpbuf1, "w+")) == NULL ) { *     fprintf(stderr, "%s would not open r+ or w+\n", tmpbuf1); *     fclose(fs_orig); * #ifdef FILE_LOCKING *     unlock_lock(fileno(fs_lock), 0, SEEK_SET, 0); *     fclose(fs_lock); * #endif *      return(-1); *    } *  } */  if ( (fs_bak = fopen(tmpbuf1, "r+")) == NULL ) {     fprintf(stderr, "%s would not open r+ \n", tmpbuf1);     fclose(fs_orig);#ifdef FILE_LOCKING     unlock_lock(fileno(fs_lock), 0, SEEK_SET, 0);     fclose(fs_lock);#endif     return(-1);  }  /* Search the .bak file line by line.   * Copy across any lines that do not contain our search string   * back to the original filename.   */  found = 0;  /* suck in a line from the .bak file */  while (fgets(tmpbuf1,sizeof(tmpbuf1),fs_bak)!=NULL){    /* if a newline was sucked in (likely), change it to be a \0 */    for(i=0;tmpbuf1[i]!=0;++i) if (tmpbuf1[i]=='\n') tmpbuf1[i]=0;    /* look to see if this line contains our search string */     if ( strcmp(template, tmpbuf1) != 0) {      /* match not found, so copy this line from the .bak to the filename */      fputs(tmpbuf1, fs_orig);      fputs("\n", fs_orig);    } else {      found = 1;    }  }  /* we are done with these two, release the resources */  fclose(fs_orig);  fclose(fs_bak);  /* format the name of the backup file */  snprintf(tmpbuf1, sizeof(tmpbuf1), "%s.bak", filename);  /* remove the .bak file */  unlink(tmpbuf1);#ifdef FILE_LOCKING  /* unlock, we are done */  unlock_lock(fileno(fs_lock), 0, SEEK_SET, 0);  /* close the lock file to release resources */  fclose(fs_lock);#endif  /* return 0 = everything went okay, but we didn't find it   *        1 = everything went okay, and we found a match   */  return(found);}/************************************************************************//*  * Recursive change ownership utility  */int r_chown(char *path, uid_t owner, gid_t group ){ DIR *mydir; struct dirent *mydirent; struct stat statbuf;  chown(path,owner,group);  if (chdir(path) == -1) {    fprintf(stderr, "r_chown() : Failed to cd to directory %s", path);    return(-1);  }  mydir = opendir(".");  if ( mydir == NULL ) {     fprintf(stderr, "r_chown() : Failed to opendir()");    return(-1);  }  while((mydirent=readdir(mydir))!=NULL){    if ( strncmp(mydirent->d_name,".", 2)!=0 &&          strncmp(mydirent->d_name,"..", 3)!=0 ) {      stat( mydirent->d_name, &statbuf);      if ( S_ISDIR(statbuf.st_mode) ) {        r_chown( mydirent->d_name, owner, group);      } else {        chown(mydirent->d_name,owner,group);      }    }  }  closedir(mydir);  if (chdir("..") == -1) {    fprintf(stderr, "rchown() : Failed to cd to parent");    return(-1);  }  return(0);}/************************************************************************//*  * Send a signal to a process utility function * * name    = name of process * sig_num = signal number  */int signal_process(char *name, int sig_num){ FILE *ps; char *tmpstr; int  col; pid_t tmppid; pid_t mypid; int  pid_col=0; char pid[MAX_BUFF]; char tmpbuf1[MAX_BUFF];  mypid = getpid();  if ( (ps = popen(PS_COMMAND, "r")) == NULL ) {    perror("popen on ps command");    return(-1);  }  if (fgets(tmpbuf1, sizeof(tmpbuf1), ps)!= NULL ) {    col=0;    tmpstr = strtok(tmpbuf1, PS_TOKENS);    while (tmpstr != NULL ) {      if (strcmp(tmpstr, "PID") == 0 ) pid_col = col;      tmpstr = strtok(NULL, PS_TOKENS);      ++col;    }  }  while (fgets(tmpbuf1, sizeof(tmpbuf1), ps)!= NULL ) {    if ( strstr( tmpbuf1, name ) != NULL &&          strstr(tmpbuf1,"supervise")==NULL) {      tmpstr = strtok(tmpbuf1, PS_TOKENS);      col = 0;      do {        if( col == pid_col ) {          snprintf(pid, sizeof(pid), "%s", tmpstr);          break;        }         ++col;        tmpstr = strtok(NULL, PS_TOKENS);      } while ( tmpstr!=NULL );      tmppid = atoi(pid);      if ( tmppid != mypid ) {         kill(tmppid,sig_num);      }    }  }  pclose(ps);  return(0);}/************************************************************************//* * Compile the users/assign file using qmail-newu program */int update_newu(){ int pid;  pid=vfork();  if ( pid==0){    execl(QMAILNEWU,"qmail-newu", NULL);    exit(127);  } else {    wait(&pid);  }  return(0);}/************************************************************************//* * parse out user and domain from an email address utility function *  * email  = input email address * user   = parsed user * domain = parsed domain * buff_size = the size of the user and domain buffer.  *             These need to be the same size or potential buffer overflows *             could occur! *  * return 0 on success *       -1 on error */int parse_email(char *email, char *user, char *domain, int buff_size ) { int i; int n; int len; char *at = NULL;  lowerit(email);  len = strlen(ATCHARS);  for(i=0;i<len; ++i ) if ((at=strchr(email,ATCHARS[i]))) break;  /* did we find an "AT" char in the email address? */  if ( at!=NULL ) {    /* yep we found an AT char */    /* work out what pos it is in the email address array, store this in n */    n = at - email + 1;    if ( n > buff_size ) n = buff_size;    /* suck out the username */    snprintf(user, n, "%s", email);     /* now suck out the domain name */    snprintf(domain, buff_size, "%s", ++at);  } else {    /* No AT char found, so populate username, leave domain blank */    snprintf(user, buff_size, "%s", email);    domain[0] = 0;  }  /* check the username for any invalid chars */  if ( is_username_valid( user ) != 0 ) {    fprintf(stderr, "user invalid %s\n", user);    return(-1);  }  /* check the domain for any invalid chars */  if ( is_domain_valid( domain ) != 0 ) {    fprintf(stderr, "domain invalid %s\n", domain);    return(-1);  }  /* if we havent found a domain, try and set it to the the default domain */  vset_default_domain(domain);  return(0);} /************************************************************************//* * update a users virtual password file entry with a different password */int vpasswd( char *username, char *domain, char *password, int apop ){ struct vqpasswd *mypw; char Crypted[MAX_BUFF];#ifdef SQWEBMAIL_PASS uid_t uid; gid_t gid;#endif  if ( strlen(username) >= MAX_PW_NAME ) return(VA_USER_NAME_TOO_LONG);#ifdef USERS_BIG_DIR    if ( strlen(username) == 1 ) return(VA_ILLEGAL_USERNAME);#endif  if ( strlen(domain) >= MAX_PW_DOMAIN ) return(VA_DOMAIN_NAME_TOO_LONG);  if ( strlen(password) >= MAX_PW_CLEAR_PASSWD ) return(VA_PASSWD_TOO_LONG);  lowerit(username);  lowerit(domain);  /* get the password entry for this user */  mypw = vauth_getpw( username, domain);  if ( mypw == NULL ) return(-1);   /* dont update password, if password updates are disabled */  if ( mypw->pw_flags & NO_PASSWD_CHNG ) return(-1);  /* encrypt their supplied password, and save it */  mkpasswd3(password,Crypted, sizeof(Crypted));  mypw->pw_passwd = Crypted;#ifdef CLEAR_PASS  /* save the clear password too (if clear passwords are enabled) */  mypw->pw_clear_passwd = password;#endif#ifdef SQWEBMAIL_PASS  /* update the sqwebmail-pass file in the user's maildir (if required) */  vget_assign(domain, NULL, 0, &uid, &gid );  vsqwebmail_pass( mypw->pw_dir, Crypted, uid, gid);#endif  return (vauth_setpw( mypw, domain));}/************************************************************************//* * delete a user from a virtual domain password file */int vdeluser( char *user, char *domain ){ struct vqpasswd *mypw; char Dir[MAX_BUFF]; uid_t uid; gid_t gid; char calling_dir[MAX_BUFF];  if ( user == 0 || strlen(user)<=0) return(VA_ILLEGAL_USERNAME);

⌨️ 快捷键说明

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