📄 vpopmail.c
字号:
} /* 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 + -