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

📄 vpopmail.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 5 页
字号:
struct vqpasswd *vauth_user(char *user, char *domain, char* password, char *apop) {  struct vqpasswd *mypw;  char *tmpstr;  uid_t uid;  gid_t gid;    if ( password == NULL ) return(NULL);   mypw = vauth_getpw(user, domain);   if ( mypw == NULL ) return(NULL);   if ( vauth_crypt(user, domain, password, mypw) != 0 ) return(NULL);    tmpstr = vget_assign(domain, NULL, 0, &uid, &gid );   mypw->pw_uid = uid;   mypw->pw_gid = gid;   return(mypw); }/************************************************************************//* * default_domain() *   returns a pointer to a string, containing *   the default domain (or blank if not set).  Loads from *   ~vpopmail/etc/defaultdomain.  Only loads once per program *   execution. */char *default_domain(){   static int init = 0;   static char d[MAX_PW_DOMAIN];   char path[MAX_BUFF];   int dlen;   FILE *fs;   if (!init) {     init++;     d[0] = '\0';  /* make sure d is empty in case file doesn't exist */     snprintf (path, sizeof(path), "%s/etc/defaultdomain", VPOPMAILDIR);     fs = fopen (path, "r");     if (fs != NULL) {       fgets (d, sizeof(d), fs);       fclose (fs);       dlen = strlen(d) - 1;       if (d[dlen] == '\n') { d[dlen] = '\0'; }     }   }   return d;} /************************************************************************//* * If domain is blank, set it to the VPOPMAIL_DOMAIN environment * variable, an ip alias domain, or the default domain. */void vset_default_domain( char *domain ) { char *tmpstr, *cp;#ifdef IP_ALIAS_DOMAINS char host[MAX_BUFF];#endif  if (domain != NULL) {    if (strlen(domain)>0) {      /* domain isnt blank, so dont try to set it */      return;    }  }  /* domain is blank, so now try various lookups to set it */  tmpstr = getenv("VPOPMAIL_DOMAIN");  if ( tmpstr != NULL) {    /* As a security precaution, remove all but good chars */    for (cp = tmpstr; *(cp += strspn(cp, ok_env_chars)); /* */) {*cp='_';}    /* Michael Bowe 14th August 2003     * How can we prevent possible buffer overflows here     * For the moment, stick with a conservative size of MAX_PW_DOMAIN     */    snprintf(domain, MAX_PW_DOMAIN, "%s", tmpstr);    return;  }#ifdef IP_ALIAS_DOMAINS  tmpstr = getenv("TCPLOCALIP");  /* courier-imap uses IPv6 */  if ( tmpstr != NULL ) {    /* As a security precaution, remove all but good chars */    for (cp = tmpstr; *(cp += strspn(cp, ok_env_chars)); ) {*cp='_';}    /* Michael Bowe 14th August 2003     * Mmmm Yuk below. What if TCPLOCALIP=":\0"     * Buffer overflow.     * Need to perhaps at least check strlen of tmpstr     */    if ( tmpstr[0] == ':') {      tmpstr +=2;      while(*tmpstr!=':') ++tmpstr;      ++tmpstr;    }  }  memset(host,0,sizeof(host));  /* take the ip address that the connection was made to   * and go and look this up in our vip map   * and then store the domain into the host var    */  if ( vget_ip_map(tmpstr,host,sizeof(host))==0 && !host_in_locals(host)){    if ( strlen(host) > 0 ) {      /* Michael Bowe 14th August 2003       * How can we prevent possible buffer overflows here       * For the moment, stick with a conservative size of MAX_PW_DOMAIN       */      snprintf(domain, MAX_PW_DOMAIN, "%s", host);    }    return;  }#endif /* IP_ALIAS_DOMAINS */  /* Michael Bowe 14th August 2003   * How can we prevent possible buffer overflows here   * For the moment, stick with a conservative size of MAX_PW_DOMAIN   */  snprintf(domain, MAX_PW_DOMAIN, "%s", DEFAULT_DOMAIN);}/************************************************************************/#ifdef IP_ALIAS_DOMAINS/* look to see if the nominated domain is is locals file * return 1 if there is a match * return 0 if there is no match */int host_in_locals(char *domain){ int i; char tmpbuf[MAX_BUFF]; FILE *fs;  snprintf(tmpbuf, sizeof(tmpbuf), "%s/control/locals", QMAILDIR);  if ((fs = fopen(tmpbuf,"r")) == NULL) {    return(0);  }  while( fgets(tmpbuf,sizeof(tmpbuf),fs) != NULL ) {    /* usually any newlines into nulls */    for(i=0;tmpbuf[i]!=0;++i) if (tmpbuf[i]=='\n') tmpbuf[i]=0;    /* Michael Bowe 14th August 2003     * What happens if domain isnt null terminated?     */    if (( strcmp( domain, tmpbuf)) == 0 ) {      /* we found a match */      fclose(fs);      return(1);    }    /* always match with localhost */    if ( strcmp(domain, "localhost") == 0 &&        strstr(domain,"localhost") != NULL ) {      fclose(fs);      return(1);    }  }  fclose(fs);  return(0);}#endif/************************************************************************//* Convert error flag to text */char *verror(int va_err ){  switch(va_err) {   case VA_SUCCESS:    return("Success");   case VA_ILLEGAL_USERNAME:    return("Illegal username");   case VA_USERNAME_EXISTS:    return("Username exists");   case VA_BAD_DIR:    return("Unable to chdir to vpopmail directory");   case VA_BAD_U_DIR:    return("Unable to chdir to vpopmail/users directory");   case VA_BAD_D_DIR:    return("Unable to chdir to vpopmail/" DOMAINS_DIR " directory");   case VA_BAD_V_DIR:    return("Unable to chdir to vpopmail/" DOMAINS_DIR "/domain directory");   case VA_EXIST_U_DIR:    return("User's directory already exists?");   case VA_BAD_U_DIR2:    return("Unable to chdir to user's directory");   case VA_SUBDIR_CREATION:    return("Creation of user's subdirectories failed?");   case VA_USER_DOES_NOT_EXIST:    return("User does not exist");   case VA_DOMAIN_DOES_NOT_EXIST:    return("Domain does not exist");   case VA_INVALID_DOMAIN_NAME:    return("Invalid domain name");   case VA_DOMAIN_ALREADY_EXISTS:    return("Domain already exists");   case VA_COULD_NOT_MAKE_DOMAIN_DIR:    return("Could not make domain dir");   case VA_COULD_NOT_OPEN_QMAIL_DEFAULT:    return("Could not open qmail default");   case VA_CAN_NOT_MAKE_DOMAINS_DIR:    return("Can not make " DOMAINS_DIR " directory");   case VA_COULD_NOT_UPDATE_FILE:    return("Could not update file");   case VA_CRYPT_FAILED:    return("Crypt failed");   case VA_COULD_NOT_OPEN_DOT_QMAIL:    return("Could not open dot qmail file");   case VA_BAD_CHAR:    return("bad character");   case VA_BAD_UID:    return("running as invalid uid");   case VA_NO_AUTH_CONNECTION:    return("no auth connection");   case VA_MEMORY_ALLOC_ERR:    return("memory allocation error");   case VA_USER_NAME_TOO_LONG:    return("user name too long");   case VA_DOMAIN_NAME_TOO_LONG:    return("domain name too long");   case VA_PASSWD_TOO_LONG:    return("password too long");   case VA_GECOS_TOO_LONG:    return("gecos too long");   case VA_QUOTA_TOO_LONG:    return("quota too long");   case VA_DIR_TOO_LONG:    return("dir too long");   case VA_CLEAR_PASSWD_TOO_LONG:    return("clear password too long");   case VA_ALIAS_LINE_TOO_LONG:    return("alias line too long");   case VA_NULL_POINTER:    return("null pointer");   case VA_INVALID_EMAIL_CHAR:    return("invalid email character");   case VA_PARSE_ERROR:    return("error parsing data");   case VA_CANNOT_READ_LIMITS:    return("can't read domain limits");   default:    return("Unknown error");  }}/************************************************************************//* Michael Bowe 21st Aug 2003 * This function doesnt appear to be used by vpopmail or qmailadmin  * Consider it for removal perhaps *//* Add an entry to a domain/.qmail-alias file */int vadddotqmail( char *alias, char *domain,... ) { struct vqpasswd *mypw = NULL;  FILE *fs; va_list args; char *email; char Dir[MAX_BUFF]; uid_t uid; gid_t gid; char tmpbuf[MAX_BUFF];  /* extract the details for the domain (Dir, uid, gid) */  if ( vget_assign(domain, Dir, sizeof(Dir), &uid, &gid ) == NULL) {    return(VA_DOMAIN_DOES_NOT_EXIST);  }  /* open the .qmail-alias file for writing */  snprintf(tmpbuf, sizeof(tmpbuf), "%s/.qmail-%s", Dir, alias);  if ((fs=fopen(tmpbuf, "w")) == NULL) return(VA_COULD_NOT_OPEN_DOT_QMAIL);  va_start(args,domain);  while ( (email=va_arg(args, char *)) != NULL ) {    /* are we dealing with an email address? */    if ( strstr(email, "@") == NULL ) {      /* not an email address */      /* get passwd entry for this user */      mypw = vauth_getpw( email, domain );      if ( mypw == NULL ) return(VA_USER_DOES_NOT_EXIST);      /* write out the appropriate maildir entry for this user */      fprintf(fs, "%s/Maildir/\n", mypw->pw_dir);    } else {      /* yes, we have an email address, so write it out */      fprintf(fs, "%s\n", email);    }  }  fclose(fs);  /* setup the permission of the .qmail-alias file */  snprintf(tmpbuf, sizeof(tmpbuf), "%s/.qmail-%s", Dir, alias);  chown(tmpbuf,uid,gid);  va_end(args);  return(VA_SUCCESS);}/************************************************************************//* Michael Bowe 21st Aug 2003 * This function doesnt appear to be used by vpopmail or qmailadmin  * Consider it for removal perhaps */ /* delete a domain/qmail-alias file */int vdeldotqmail( char *alias, char *domain ){ char Dir[MAX_BUFF]; uid_t uid; gid_t gid; char tmpbuf[MAX_BUFF];  if ( vget_assign(domain, Dir, sizeof(Dir), &uid, &gid ) == NULL) {    return(VA_DOMAIN_DOES_NOT_EXIST);  }  snprintf(tmpbuf, sizeof(tmpbuf), "%s/.qmail-%s", Dir, alias);  if ( unlink(tmpbuf) < 0 ) return(VA_COULD_NOT_OPEN_DOT_QMAIL);  return(VA_SUCCESS);}/************************************************************************//* * Given the domain name: *  *   get dir, uid, gid from the users/cdb file (if they are not passed as NULL) * *   If domain is an alias domain, then domain gets updated to be the real domain *    * Function will return the domain directory on success * or return NULL if the domain does not exist. *  * This function caches last lookup in memory to increase speed */char *vget_assign(char *domain, char *dir, int dir_len, uid_t *uid, gid_t *gid){ FILE *fs; int dlen; int i; char *ptr; static char *in_domain = NULL; static int in_domain_size = 0; static char *in_dir = NULL; static int in_dir_size = 0; static uid_t in_uid = -1; static gid_t in_gid = -1; char cdb_key[MAX_BUFF];  char cdb_file[MAX_BUFF]; char *cdb_buf;  /* cant lookup a null domain! */  if ( domain == NULL || *domain == 0) return(NULL);  /* if domain matches last lookup, use cached values */  lowerit(domain);  if ( in_domain_size != 0 && in_domain != NULL     && in_dir != NULL && strcmp( in_domain, domain )==0 ) {    /* return the vars, if the user has asked for them */    if ( uid!=NULL ) *uid = in_uid;    if ( gid!=NULL ) *gid = in_gid;    if ( dir!=NULL ) snprintf(dir, dir_len, "%s", in_dir);    /* cached lookup complete, exit out now */    return(in_dir);  }  /* this is a new lookup, free memory from last lookup if necc. */  if ( in_domain != NULL ) {    free(in_domain);    in_domain = NULL;  }  if ( in_dir != NULL ) {    free(in_dir);    in_dir = NULL;  }  /* build up a search string so we can search the cdb file */  snprintf(cdb_key, sizeof(cdb_key), "!%s-", domain);    /* work out the location of the cdb file */  snprintf(cdb_file, sizeof(cdb_file), "%s/users/cdb", QMAILDIR);  /* try to open the cdb file */  if ( (fs = fopen(cdb_file, "r")) == 0 ) {    return(NULL);  }  /* search the cdb file for our requested domain */  i = cdb_seek(fileno(fs), cdb_key, strlen(cdb_key), &dlen);  in_uid = -1;  in_gid = -1;  if ( i == 1 ) {     /* we found a matching record in the cdb file     * so next create a storage buffer, and then read it in     */    cdb_buf = malloc(dlen);    i = fread(cdb_buf, sizeof(char), dlen, fs);    /* format of cdb_buf is :     * realdomain.com\0uid\0gid\0path\0     */    /* get the real domain */    ptr = cdb_buf;                      /* point to start of cdb_buf (ie realdomain) */    in_domain_size = strlen(ptr)+1;     /* how long is the domain name? cache the length */    in_domain = malloc(in_domain_size); /* create storage space for domain cache */    snprintf(in_domain, in_domain_size, "%s", ptr); /* suck out the domain, store into cache */    /* get the uid */    while( *ptr != 0 ) ++ptr;           /* advance pointer past the realdomain */    ++ptr;                              /* skip over the null */    in_uid = atoi(ptr);                 /* suck out the uid */    if ( uid!=NULL) *uid = in_uid;      /* if the user requested the uid, give it to them */    /* get the gid */    while( *ptr != 0 ) ++ptr;           /* skip over the uid */    ++ptr;                              /* skip over the null */    in_gid = atoi(ptr);                 /* suck out the gid */    if ( gid!=NULL) *gid = in_gid;      /* if the user requested the gid, give it to them */    /* get the domain directory */    while( *ptr != 0 ) ++ptr;           /* skip over the gid */    ++ptr;                              /* skip over the null */    if ( dir!=NULL ) strncpy( dir, ptr, dir_len); /* if user requested dir, give it */    in_dir_size = strlen(ptr)+1;        /* how long is dir? cache the length */    in_dir = malloc(in_dir_size);       /* create storage space for dir cache */    snprintf(in_dir, in_dir_size, "%s", ptr); /* suck out the dir, and store it in cache */    free(cdb_buf);    /* when vget_assign is called with the domain parameter set as an alias domain,     * it is meant to replace this alias domain with the real domain     *     * in_domain contains the real domain, so do this replacement now.     *     * Michael Bowe 21st Aug 2003. Need to watch out for buffer overflows here.     * We

⌨️ 快捷键说明

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