📄 vpopmail.c
字号:
/* Michael Bowe 23rd August 2003 * should we do a vset_default_domain(domain) here? * This function is called by vdeluser.c which will ensure * domain is set. But what if this function is called from * somewhere else and is passed with a null domain? * Should we display en error (which is what will happen when * vget_assign runs below. */ umask(VPOPMAIL_UMASK); lowerit(user); lowerit(domain); /* see if the user exists in the authentication system */ if ((mypw = vauth_getpw(user, domain)) == NULL) { return(VA_USER_DOES_NOT_EXIST); } /* backup the dir where the vdeluser was run from */ getcwd(calling_dir, sizeof(calling_dir)); /* lookup the location of this domain's directory */ if ( vget_assign(domain, Dir, sizeof(Dir), &uid, &gid ) ==NULL ) { return(VA_DOMAIN_DOES_NOT_EXIST); } /* change into that directory */ if ( chdir(Dir) != 0 ) { chdir(calling_dir); return(VA_BAD_D_DIR); } /* del the user from the auth system */ if (vauth_deluser( user, domain ) !=0 ) { fprintf (stderr, "Failed to delete user from auth backend\n"); chdir(calling_dir); return (-1); } dec_dir_control(domain, uid, gid); /* remove the user's directory from the file system * and check for error */ if ( vdelfiles(mypw->pw_dir) != 0 ) { fprintf(stderr, "could not remove %s\n", mypw->pw_dir); chdir(calling_dir); return(VA_BAD_DIR); } /* go back to the callers directory */ chdir(calling_dir); return(VA_SUCCESS);}/************************************************************************//* * make all characters in a string be lower case */void lowerit(char *instr ){ int size; if (instr==NULL) return; for(size=0;*instr!=0;++instr,++size ) { if (isupper((int)*instr)) *instr = tolower(*instr); /* Michael Bowe 23rd August 2003 * this looks like a bit of a kludge... * how can we improve on it? */ /* add alittle size protection */ if ( size == 156 ) { *instr = 0; return; } } }/************************************************************************/int update_file(char *filename, char *update_line){ FILE *fs = NULL; FILE *fs1 = NULL;#ifdef FILE_LOCKING FILE *fs3 = NULL;#endif char tmpbuf1[MAX_BUFF]; char tmpbuf2[MAX_BUFF]; int user_assign = 0; int i;#ifdef FILE_LOCKING snprintf(tmpbuf1, sizeof(tmpbuf1), "%s.lock", filename); if ( (fs3 = fopen(tmpbuf1, "w+")) == NULL ) { fprintf(stderr, "could not open lock file %s\n", tmpbuf1); return(VA_COULD_NOT_UPDATE_FILE); } if ( get_write_lock(fs3) < 0 ) return(-1);#endif snprintf(tmpbuf1, sizeof(tmpbuf1), "%s.%lu", filename, (long unsigned)getpid()); fs1 = fopen(tmpbuf1, "w+"); if ( fs1 == NULL ) {#ifdef FILE_LOCKING unlock_lock(fileno(fs3), 0, SEEK_SET, 0); fclose(fs3); return(VA_COULD_NOT_UPDATE_FILE);#endif } snprintf(tmpbuf1, sizeof(tmpbuf1), "%s", filename); if ( (fs = fopen(tmpbuf1, "r+")) == NULL ) { if ( (fs = fopen(tmpbuf1, "w+")) == NULL ) { fclose(fs1);#ifdef FILE_LOCKING fclose(fs3); unlock_lock(fileno(fs3), 0, SEEK_SET, 0);#endif return(VA_COULD_NOT_UPDATE_FILE); } } while( fgets(tmpbuf1,sizeof(tmpbuf1),fs) != NULL ) { snprintf(tmpbuf2, sizeof(tmpbuf2), "%s", tmpbuf1); for(i=0;tmpbuf1[i]!=0;++i) { if (tmpbuf1[i]=='\n') { tmpbuf1[i]=0; } } /* special case for users/assign */ if ( strncmp(tmpbuf1, ".", sizeof(tmpbuf1)) == 0 ) { fprintf(fs1, "%s\n", update_line); user_assign = 1; } else if ( strncmp(tmpbuf1, update_line, sizeof(tmpbuf1)) != 0 ) { fputs(tmpbuf2, fs1); } } if ( user_assign == 1 ) fprintf(fs1, ".\n"); else fprintf(fs1, "%s\n", update_line); fclose(fs); fclose(fs1); snprintf(tmpbuf1, sizeof(tmpbuf1), "%s", filename); snprintf(tmpbuf2, sizeof(tmpbuf2), "%s.%lu", filename, (long unsigned)getpid()); rename(tmpbuf2, tmpbuf1);#ifdef FILE_LOCKING unlock_lock(fileno(fs3), 0, SEEK_SET, 0); fclose(fs3);#endif return(0);}/************************************************************************//* * Update a users quota */int vsetuserquota( char *username, char *domain, char *quota ){ struct vqpasswd *mypw; char *formattedquota; int ret; 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(quota) >= MAX_PW_QUOTA ) return(VA_QUOTA_TOO_LONG); lowerit(username); lowerit(domain); /* correctly format the quota string, * and then store the quota into the auth backend */ formattedquota = format_maildirquota(quota); ret = vauth_setquota( username, domain, formattedquota); if (ret != VA_SUCCESS ) return(ret); mypw = vauth_getpw( username, domain ); remove_maildirsize(mypw->pw_dir); if (strcmp (quota, "NOQUOTA") != 0) { uid_t uid; gid_t gid; char maildir[MAX_BUFF]; snprintf(maildir, sizeof(maildir), "%s/Maildir/", mypw->pw_dir); umask(VPOPMAIL_UMASK); (void)vmaildir_readquota(maildir, formattedquota); if ( vget_assign(domain, NULL, 0, &uid, &gid)!=NULL) { strcat(maildir, "maildirsize"); chown(maildir,uid,gid); } } return(0);}/************************************************************************//* * count the lines in /var/qmail/control/rcpthosts */int count_rcpthosts(){ char tmpstr1[MAX_BUFF]; FILE *fs; int count; snprintf(tmpstr1, sizeof(tmpstr1), "%s/control/rcpthosts", QMAILDIR); fs = fopen(tmpstr1, "r"); if ( fs == NULL ) return(0); count = 0; while( fgets(tmpstr1, sizeof(tmpstr1), fs) != NULL ) ++count; fclose(fs); return(count);}/************************************************************************//* * compile the morercpthosts file using qmail-newmrh program */int compile_morercpthosts(){ int pid; pid=vfork(); if ( pid==0){ execl(QMAILNEWMRH,"qmail-newmrh", NULL); exit(127); } else { wait(&pid); } return(0);}/************************************************************************//* * fill out a passwd structure from then next * line in a file */ struct vqpasswd *vgetent(FILE *pw){ static struct vqpasswd pwent; static char line[MAX_BUFF]; int i=0,j=0; char *tmpstr; char *tmpstr1; if (fgets(line,sizeof(line),pw) == NULL) return NULL; for (i=0; line[i] != 0; i++) if (line[i] == ':') j++; if (j < 6) return NULL; tmpstr = line; pwent.pw_name = line; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; *tmpstr = 0; ++tmpstr; pwent.pw_passwd = tmpstr; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; *tmpstr = 0; ++tmpstr; tmpstr1 = tmpstr; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; *tmpstr = 0; ++tmpstr; pwent.pw_uid = atoi(tmpstr1); tmpstr1 = tmpstr; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; *tmpstr = 0; ++tmpstr; pwent.pw_gid = atoi(tmpstr1); pwent.pw_gecos = tmpstr; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; *tmpstr = 0; ++tmpstr; pwent.pw_dir = tmpstr; while (*tmpstr!=0 && *tmpstr!=':') ++tmpstr; if (*tmpstr) { *tmpstr = 0; ++tmpstr; } pwent.pw_shell = tmpstr; while (*tmpstr!=0 && *tmpstr!=':' && *tmpstr!='\n') ++tmpstr; if (*tmpstr) { *tmpstr = 0; ++tmpstr; }#ifdef CLEAR_PASS pwent.pw_clear_passwd = tmpstr; while (*tmpstr!=0 && *tmpstr!='\n') ++tmpstr; if (*tmpstr) { *tmpstr = 0; ++tmpstr; }#endif return &pwent;}/************************************************************************//* * figure out where to put the user and * make the directories if needed * * if successfull, return a pointer to the user hash * on error return NULL */char *make_user_dir(char *username, char *domain, uid_t uid, gid_t gid){ char *user_hash; struct vqpasswd *mypw; char calling_dir[MAX_BUFF]; char domain_dir[MAX_BUFF]; const char *dirnames[] = {"Maildir", "Maildir/new", "Maildir/cur", "Maildir/tmp"}; int i; verrori = 0; /* record the dir where the command was run from */ getcwd(calling_dir, sizeof(calling_dir)); /* retrieve the dir that stores this domain */ if (vget_assign(domain, domain_dir, sizeof(domain_dir), NULL, NULL) == NULL) { fprintf(stderr, "Error. vget_assign() failed for domain : %s",domain); return(NULL); } /* go to the dir for our chosen domain */ chdir(domain_dir); user_hash="";#ifdef USERS_BIG_DIR /* go into a user hash dir if required */ open_big_dir(domain, uid, gid); user_hash = next_big_dir(uid, gid); close_big_dir(domain, uid, gid); chdir(user_hash);#endif /* check the length of the dir path to make sure it is not too long to save back to the auth backend */ if ((strlen(domain_dir)+strlen(user_hash)+strlen(username)) >= MAX_PW_DIR) { fprintf (stderr, "Error. Path exceeds maximum permitted length\n"); chdir(calling_dir); return (NULL); } /* create the users dir, including all the Maildir structure */ if ( mkdir(username, VPOPMAIL_DIR_MODE) != 0 ) { /* need to add some code to remove the hashed dirs we created above... */ verrori = VA_EXIST_U_DIR; chdir(calling_dir); return(NULL); } if ( chdir(username) != 0 ) { /* back out of changes made above */ chdir(domain_dir); chdir(user_hash); vdelfiles(username); chdir(calling_dir); fprintf(stderr, "make_user_dir: error 2\n"); return(NULL); } for (i = 0; i < sizeof(dirnames)/sizeof(dirnames[0]); i++) { if (mkdir(dirnames[i],VPOPMAIL_DIR_MODE) == -1){ fprintf(stderr, "make_user_dir: failed on %s\n", dirnames[i]); /* back out of changes made above */ chdir(".."); vdelfiles(username); chdir(calling_dir); return(NULL); } } /* set permissions on the user's dir */ r_chown(".", uid, gid); /* see if the user already exists in the auth backend */ mypw = vauth_getpw( username, domain); if ( mypw != NULL ) { /* user does exist in the auth backend, so fill in the dir field */ mypw->pw_dir = malloc(MAX_PW_DIR); if ( strlen(user_hash) > 0 ) { snprintf(mypw->pw_dir, MAX_PW_DIR, "%s/%s/%s", domain_dir, user_hash, username); } else { snprintf(mypw->pw_dir, MAX_PW_DIR, "%s/%s", domain_dir, username); } /* save these values to the auth backend */ vauth_setpw( mypw, domain );#ifdef SQWEBMAIL_PASS vsqwebmail_pass( mypw->pw_dir, mypw->pw_passwd, uid, gid);#endif free (mypw->pw_dir); } chdir(calling_dir); return(user_hash);}/************************************************************************/int r_mkdir(char *path, uid_t uid, gid_t gid ){ char tmpbuf[MAX_BUFF]; int i; for(i=0;path[i]!=0;++i){ if ( (i > 0) && (path[i] == '/') ) { tmpbuf[i] = 0; if (mkdir(tmpbuf,VPOPMAIL_DIR_MODE) == 0) chown(tmpbuf, uid, gid); } tmpbuf[i] = path[i]; } mkdir(path,VPOPMAIL_DIR_MODE); chown(path, uid, gid); return(0);}/************************************************************************/#ifdef APOPchar *dec2hex(unsigned char *digest){ static char ascii[33]; char *hex="0123456789abcdef"; int i,j,k; memset(ascii,0,sizeof(ascii)); for (i=0; i < 16; i++) { j = digest[i]/16; k = digest[i]%16; ascii[i*2] = hex[j]; ascii[(i*2)+1] = hex[k]; } return ascii;}#endif/************************************************************************//* Function used by qmailadmin to auth users */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -