Exemple #1
0
int
temp_nfs(void)
{
	if (substdio_puts(subfdout, "ZNFS failure in qmail-verify.") == -1)
		die_write();
	if (substdio_putflush(subfdout, "", 1) == -1)
		die_write();
	return -1;
}
Exemple #2
0
void
die_nomem(void)
{
	cleanup();
	if (substdio_puts(subfdout, "ZOut of memory in qmail-verify.") == -1)
		die_write();
	if (substdio_putflush(subfdout, "", 1) == -1)
		die_write();
	_exit(111);
}
Exemple #3
0
void
die_cdb(void)
{
	if (substdio_puts(subfdout,
	    "ZTrouble reading users/cdb in qmail-verify.") == -1)
		die_write();
	if (substdio_putflush(subfdout, "", 1) == -1)
		die_write();
	_exit(111);
}
Exemple #4
0
/* Outputs all addresses in the table through subwrite. subwrite must be
 * a function returning >=0 on success, -1 on error, and taking
 * arguments (char* string, unsigned int length). It will be called once
 * per address and should take care of newline or whatever needed for
 * the output form. */
unsigned long sub_sql_putsubs(struct subdbinfo *info,
			      const char *table,
			      unsigned long hash_lo,
			      unsigned long hash_hi,
			      int subwrite()) /* write function. */
{
  void *result;
  unsigned long no = 0L;
  char strnum[FMT_ULONG];

  stralloc_copyb(&params[0],strnum,fmt_ulong(strnum,hash_lo));
  stralloc_copyb(&params[1],strnum,fmt_ulong(strnum,hash_hi));
  make_name(info,table?"_":0,table,0);

  /* main query */
  stralloc_copys(&query,"SELECT address FROM ");
  stralloc_cat(&query,&name);
  stralloc_cats(&query," WHERE ");
  stralloc_cats(&query,sql_putsubs_where_defn);

  result = sql_select(info,&query,2,params);

  no = 0;
  while (sql_fetch_row(info,result,1,&addr)) {
    if (subwrite(addr.s,addr.len) == -1) die_write();
    no++;					/* count for list-list fxn */
  }
  sql_free_result(info,result);
  return no;
}
Exemple #5
0
void
temp_fail(void)
{
	if (substdio_putflush(subfdout, "Z", 2) == -1)
		die_write();
	qldap_free_results(q);
}
Exemple #6
0
int
lookup_passwd(const char *local)
{
	char username[GETPW_USERLEN];
	struct stat st;
	const char *extension;
	struct passwd *pw;


	extension = local + str_len(local);
	for (; extension >= local; extension--) {
		if ((unsigned long)(extension - local) < sizeof(username))
			if (!*extension || (*extension == *auto_break)) {
				byte_copy(username, extension - local, local);
				username[extension - local] = 0;
				case_lowers(username);
				errno = 0;
				pw = getpwnam(username);
				if (errno == error_txtbsy)
					return temp_sys();
				if (pw && pw->pw_uid != 0) {
					if (stat(pw->pw_dir,&st) == 0 &&
					    st.st_uid == pw->pw_uid) {
						/* OK */
						if (substdio_putflush(subfdout,
						    "K", 1) == -1)
							die_write();
						return (1);
					} else if (error_temp(errno))
						return temp_nfs();
				}
			}
	}
	return (0);
}
Exemple #7
0
int main(int argc,char **argv)
{
  int fd;
  unsigned long loop;

  if (!*argv) _exit(0);
  if (!*++argv) _exit(0);
  scan_ulong(*argv,&loop);

  if (cdb_make_start(&c,1) == -1) die_write();

  while (loop) {
    uint32_pack(key,--loop);
    if (cdb_make_add(&c,key,4,data,sizeof data) == -1) die_write();
  }

  if (cdb_make_finish(&c) == -1) die_write();
  _exit(0);
}
Exemple #8
0
main(int argc,char **argv)
{
  char *key;
  int r;
  uint32 pos;
  uint32 len;
  unsigned long u = 0;

  if (!*argv) die_usage();

  if (!*++argv) die_usage();
  key = *argv;

  if (*++argv) {
    scan_ulong(*argv,&u);
  }

  cdb_init(&c,0);
  cdb_findstart(&c);

  for (;;) {
    r = cdb_findnext(&c,key,str_len(key));
    if (r == -1) die_read();
    if (!r) _exit(100);
    if (!u) break;
    --u;
  }

  pos = cdb_datapos(&c);
  len = cdb_datalen(&c);

  while (len > 0) {
    r = sizeof buf;
    if (r > len) r = len;
    if (cdb_read(&c,buf,r,pos) == -1) die_read();
    if (buffer_put(buffer_1small,buf,r) == -1) die_write();
    pos += r;
    len -= r;
  }
  if (buffer_flush(buffer_1small) == -1) die_write();
  _exit(0);
}
Exemple #9
0
int main(int argc,char **argv)
{
  const char *subdir;
  unsigned long n;
  int i;
  char strnum[FMT_ULONG];

  i = getconfopt(argc,argv,options,1,0);
  initsub(flagsubdb);
  subdir = argv[i];

  if (flagnumber) {
    n = putsubs(subdir,0L,52L,dummywrite);
    if (substdio_put(subfdout,strnum,fmt_ulong(strnum,n)) == -1) die_write();
    if (substdio_put(subfdout,"\n",1) == -1) die_write();
  } else
    (void) putsubs(subdir,0L,52L,subwrite);
  if (substdio_flush(subfdout) == -1) die_write();
  closesub();
  _exit(0);
}
Exemple #10
0
/* Searches the subscriber log and outputs via subwrite(s,len) any entry
 * that matches search. A '_' is search is a wildcard. Any other
 * non-alphanum/'.' char is replaced by a '_'. */
static void _searchlog(struct subdbinfo *info,
                       const char *table,
                       char *search,		/* search string */
                       int subwrite())		/* output fxn */
{
    sqlite3_stmt *stmt;
    int res;
    datetime_sec when;
    struct datetime dt;
    char date[DATE822FMT];

    /* SELECT (*) FROM list_slog WHERE fromline LIKE '%search%' OR address   */
    /* LIKE '%search%' ORDER BY tai; */
    /* The '*' is formatted to look like the output of the non-mysql version */
    /* This requires reading the entire table, since search fields are not   */
    /* indexed, but this is a rare query and time is not of the essence.     */

    if (!stralloc_copys(&line,"SELECT tai, edir||etype||' '||address||' '||fromline"
                        " FROM ")) die_nomem();
    if (!stralloc_cat_table(&line,info,table)) die_nomem();
    if (!stralloc_cats(&line,"_slog")) die_nomem();
    if (*search) {	/* We can afford to wait for LIKE '%xx%' */
        if (!stralloc_cats(&line," WHERE fromline LIKE '%")) die_nomem();
        if (!stralloc_cats(&line,search)) die_nomem();
        if (!stralloc_cats(&line,"%' OR address LIKE '%")) die_nomem();
        if (!stralloc_cats(&line,search)) die_nomem();
        if (!stralloc_cats(&line,"%'")) die_nomem();
    }	/* ordering by tai which is an index */
    if (!stralloc_cats(&line," ORDER by tai")) die_nomem();
    if (!stralloc_0(&line)) die_nomem();

    if ((stmt = _sqlquery(info, &line)) == NULL)
        strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn));

    while ((res = sqlite3_step(stmt)) != SQLITE_DONE) {
        if (res != SQLITE_ROW)
            strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn));

        (void)scan_ulong((const char*)sqlite3_column_text(stmt,0),&when);
        datetime_tai(&dt,when);
        if (!stralloc_copyb(&line,date,date822fmt(date,&dt)-1)) die_nomem();
        if (!stralloc_cats(&line,": ")) die_nomem();
        if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,when))) die_nomem();
        if (!stralloc_cats(&line," ")) die_nomem();
        if (!stralloc_catb(&line,
                           (const char*)sqlite3_column_text(stmt,1),
                           sqlite3_column_bytes(stmt,1)))
            die_nomem();
        if (subwrite(line.s,line.len) == -1) die_write();
    }

    sqlite3_finalize(stmt);
}
Exemple #11
0
/* Searches the subscriber log and outputs via subwrite(s,len) any entry
 * that matches search. A '_' is search is a wildcard. Any other
 * non-alphanum/'.' char is replaced by a '_'. */
void sub_sql_searchlog(struct subdbinfo *info,
		       const char *table,
		       char *search,		/* search string */
		       int subwrite())		/* output fxn */
{
  void *result;
  datetime_sec when;
  struct datetime dt;
  char date[DATE822FMT];
  int nparams;
  char strnum[FMT_ULONG];

  make_name(info,table?"_":0,table,0);
/* SELECT (*) FROM list_slog WHERE fromline LIKE '%search%' OR address   */
/* LIKE '%search%' ORDER BY tai; */
/* The '*' is formatted to look like the output of the non-mysql version */
/* This requires reading the entire table, since search fields are not   */
/* indexed, but this is a rare query and time is not of the essence.     */

  stralloc_copys(&query,"SELECT ");
  stralloc_cats(&query,sql_searchlog_select_defn);
  stralloc_cats(&query," FROM ");
  stralloc_cat(&query,&name);
  stralloc_cats(&query,"_slog");
  if (*search) {	/* We can afford to wait for LIKE '%xx%' */
    stralloc_copys(&params[0],search);
    stralloc_copys(&params[1],search);
    nparams = 2;
    stralloc_cats(&query," WHERE ");
    stralloc_cats(&query,sql_searchlog_where_defn);
  }
  else
    nparams = 0;
  /* ordering by tai which is an index */
  stralloc_cats(&query," ORDER by tai");

  result = sql_select(info,&query,nparams,params);
  while (sql_fetch_row(info,result,2,params)) {
    stralloc_0(&params[0]);
    (void)scan_ulong(params[0].s,&when);
    datetime_tai(&dt,when);
    stralloc_copyb(&params[0],date,date822fmt(date,&dt)-1);
    stralloc_cats(&params[0],": ");
    stralloc_catb(&params[0],strnum,fmt_ulong(strnum,when));
    stralloc_cats(&params[0]," ");
    stralloc_cat(&params[0],&params[1]);
    if (subwrite(params[0].s,params[0].len) == -1) die_write();
  }
  sql_free_result(info,result);
}
Exemple #12
0
void doanddie(char *user, unsigned int userlen /* including 0 byte */,
    char *pass)
{
  int child;
  int wstat;
  int pi[2];
 
  close(3);
  if (pipe(pi) == -1) die_pipe();
  if (pi[0] != 3) die_pipe();
  switch(child = fork()) {
    case -1:
      die_fork();
    case 0:
      close(pi[1]);
      sig_pipedefault();
      execvp(*childargs,childargs);
      _exit(1);
  }
  close(pi[0]);
  substdio_fdbuf(&ssup,subwrite,pi[1],upbuf,sizeof upbuf);
  if (substdio_put(&ssup,user,userlen) == -1) die_write();
  if (substdio_put(&ssup,pass,str_len(pass) + 1) == -1) die_write();
  if (substdio_puts(&ssup,"<") == -1) die_write();
  if (substdio_puts(&ssup,unique) == -1) die_write();
  if (substdio_puts(&ssup,hostname) == -1) die_write();
  if (substdio_put(&ssup,">",2) == -1) die_write();
  if (substdio_flush(&ssup) == -1) die_write();
  close(pi[1]);
  byte_zero(pass,str_len(pass));
  byte_zero(upbuf,sizeof upbuf);
  if (wait_pid(&wstat,child) == -1) die();
  if (wait_crashed(wstat)) die_childcrashed();
  switch (wait_exitcode(wstat)) {
    case 0: die();
    case 1: die_1();
    case 2: die_2();
    case 25: die_25();
    case 3: die_3();
    case 4: die_4();
    case 5: die_5();
    case 6: die_6();
    case 61: die_61();
    case 62: die_62();
    case 7: die_7();
    case 8: die_nomem();
    default: die_unknown();
  }
  die();
}
Exemple #13
0
static inline int32_t get_len(char end) {
  char ch;
  int32_t len = 0;
  
  for (;;) {
    ch = get_ch();
    if (ch == end)
      break;
    if ((ch < '0') || (ch > '9'))
      die_format();
    if (len > 429496720) {
      errno = ENOMEM;
      die_write();
    }
    len = len * 10 + (ch - '0');
  }
  
  return len;
}
Exemple #14
0
/* Outputs all addresses in the table through subwrite. subwrite must be
 * a function returning >=0 on success, -1 on error, and taking
 * arguments (char* string, unsigned int length). It will be called once
 * per address and should take care of newline or whatever needed for
 * the output form. */
static unsigned long _putsubs(struct subdbinfo *info,
                              const char *table,
                              unsigned long hash_lo,
                              unsigned long hash_hi,
                              int subwrite())		/* write function. */
{
    unsigned long no = 0L;
    sqlite3_stmt *stmt;
    int res;
    int length;
    const char *row;

    /* main query */
    if (!stralloc_copys(&line,"SELECT address FROM "))
        die_nomem();
    if (!stralloc_cat_table(&line,info,table)) die_nomem();
    if (!stralloc_cats(&line," WHERE hash BETWEEN ")) die_nomem();
    if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_lo)))
        die_nomem();
    if (!stralloc_cats(&line," AND ")) die_nomem();
    if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,hash_hi)))
        die_nomem();
    if (!stralloc_0(&line)) die_nomem();

    if ((stmt = _sqlquery(info, &line)) == NULL)
        strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn));

    no = 0;
    while ((res = sqlite3_step(stmt)) != SQLITE_DONE) {
        if (res != SQLITE_ROW)
            strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn));
        /* this is safe even if someone messes with the address field def */
        length = sqlite3_column_bytes(stmt, 0);
        row = (const char*)sqlite3_column_text(stmt, 0);
        if (subwrite(row,length) == -1) die_write();
        no++;					/* count for list-list fxn */
    }

    sqlite3_finalize(stmt);
    return no;
}
Exemple #15
0
int main()
{
  umask(033);
  if (chdir(auto_qmail) == -1)
    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");

  fd = open_read("control/morercpthosts");
  if (fd == -1) die_read();

  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf);

  fdtemp = open_trunc("control/morercpthosts.tmp");
  if (fdtemp == -1) die_write();

  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_write();

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdbmss_add(&cdbmss,line.s,line.len,"",0) == -1)
	  die_write();
      break;
    }
    if (!match) break;
  }

  if (cdbmss_finish(&cdbmss) == -1) die_write();
  if (fsync(fdtemp) == -1) die_write();
  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
  if (rename("control/morercpthosts.tmp","control/morercpthosts.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move control/morercpthosts.tmp to control/morercpthosts.cdb");

  _exit(0);
}
Exemple #16
0
int main(int argc, char **argv)
{
  umask(033);

  if (argc != 3)
    strerr_die1sys(111,"qmail-cdb: usage: qmail-cdb rules.cdb rules.tmp");

  substdio_fdbuf(&ssin,subread,0,inbuf,sizeof inbuf);

  fdtemp = open_trunc(argv[2]);
  if (fdtemp == -1) die_write(argv[2]);

  if (cdb_make_start(&cdbm,fdtemp) == -1) die_write(argv[2]);

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdb_make_add(&cdbm,line.s,line.len,"",0) == -1)
	  die_write(argv[2]);
      break;
    }
    if (!match) break;
  }

  if (cdb_make_finish(&cdbm) == -1) die_write(argv[2]);
  if (fsync(fdtemp) == -1) die_write(argv[2]);
  if (close(fdtemp) == -1) die_write(argv[2]); /* NFS stupidity */
  if (rename(argv[2],argv[1]) == -1)
    strerr_die5sys(111, FATAL, "unable to move ", argv[2], " to ", argv[1]);

  return 0;
}
Exemple #17
0
int std_subscribe(const char *dir,
		  const char *subdir,
		  const char *userhost,
		  int flagadd,
		  const char *comment,
		  const char *event,
		  int forcehash)
/* add (flagadd=1) or remove (flagadd=0) userhost from the subscr. database  */
/* dbname. Comment is e.g. the subscriber from line or name. It is added to  */
/* the log. Event is the action type, e.g. "probe", "manual", etc. The       */
/* direction (sub/unsub) is inferred from flagadd. Returns 1 on success, 0   */
/* on failure. If flagmysql is set and the file "sql" is found in the        */
/* directory dbname, it is parsed and a mysql db is assumed. if forcehash is */
/* >=0 it is used in place of the calculated hash. This makes it possible to */
/* add addresses with a hash that does not exist. forcehash has to be 0..99. */
/* for unsubscribes, the address is only removed if forcehash matches the    */
/* actual hash. This way, ezmlm-manage can be prevented from touching certain*/
/* addresses that can only be removed by ezmlm-unsub. Usually, this would be */
/* used for sublist addresses (to avoid removal) and sublist aliases (to     */
/* prevent users from subscribing them (although the cookie mechanism would  */
/* prevent the resulting duplicate message from being distributed. */
{
  int fdlock;

  unsigned int j;
  unsigned char ch,lcch;
  int match;
  int flagwasthere;

  if (userhost[str_chr(userhost,'\n')])
    strerr_die2x(100,FATAL,ERR_ADDR_NL);

    if (!stralloc_copys(&addr,"T")) die_nomem();
    if (!stralloc_cats(&addr,userhost)) die_nomem();
    if (addr.len > 401)
      strerr_die2x(100,FATAL,ERR_ADDR_LONG);

    j = byte_rchr(addr.s,addr.len,'@');
    if (j == addr.len)
      strerr_die2x(100,FATAL,ERR_ADDR_AT);
    case_lowerb(addr.s + j + 1,addr.len - j - 1);
    if (!stralloc_copy(&lcaddr,&addr)) die_nomem();
    case_lowerb(lcaddr.s + 1,j - 1);	/* make all-lc version of address */

    if (forcehash >= 0 && forcehash <= 52) {
      ch = lcch = 64 + (unsigned char) forcehash;
    } else {
      ch = 64 + subhashsa(&addr);
      lcch = 64 + subhashsa(&lcaddr);
    }

    if (!stralloc_0(&addr)) die_nomem();
    if (!stralloc_0(&lcaddr)) die_nomem();
    std_makepath(&fn,dir,subdir,"/subscribers/",lcch);
    std_makepath(&fnlock,dir,subdir,"/lock",0);

    if (!stralloc_copyb(&fnnew,fn.s,fn.len-1)) die_nomem();
	/* code later depends on fnnew = fn + 'n' */
    if (!stralloc_cats(&fnnew,"n")) die_nomem();
    if (!stralloc_0(&fnnew)) die_nomem();

    fdlock = lockfile(fnlock.s);

				/* do lower case hashed version first */
    fdnew = open_trunc(fnnew.s);
    if (fdnew == -1) die_write();
    substdio_fdbuf(&ssnew,write,fdnew,ssnewbuf,sizeof(ssnewbuf));

    flagwasthere = 0;

    fd = open_read(fn.s);
    if (fd == -1) {
      if (errno != error_noent) { close(fdnew); die_read(); }
    }
    else {
      substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));

      for (;;) {
        if (getln(&ss,&line,&match,'\0') == -1) {
	  close(fd); close(fdnew); die_read();
        }
        if (!match) break;
        if (line.len == addr.len)
          if (!case_diffb(line.s,line.len,addr.s)) {
	    flagwasthere = 1;
	    if (!flagadd)
	      continue;
	  }
        if (substdio_bput(&ssnew,line.s,line.len) == -1) {
	  close(fd); close(fdnew); die_write();
        }
      }

      close(fd);
    }

    if (flagadd && !flagwasthere)
      if (substdio_bput(&ssnew,addr.s,addr.len) == -1) {
        close(fdnew); die_write();
      }

    if (substdio_flush(&ssnew) == -1) { close(fdnew); die_write(); }
    if (fsync(fdnew) == -1) { close(fdnew); die_write(); }
    close(fdnew);

    if (rename(fnnew.s,fn.s) == -1)
      strerr_die6sys(111,FATAL,ERR_MOVE,fnnew.s," to ",fn.s,": ");

    if ((ch == lcch) || flagwasthere) {
      close(fdlock);
      if (flagadd ^ flagwasthere) {
        if (!stralloc_0(&addr)) die_nomem();
        logaddr(dir,subdir,event,addr.s+1,comment);
        return 1;
      }
      return 0;
    }

			/* If unsub and not found and hashed differ, OR */
			/* sub and not found (so added with new hash) */
			/* do the 'case-dependent' hash */

    fn.s[fn.len - 2] = ch;
    fnnew.s[fnnew.len - 3] = ch;
    fdnew = open_trunc(fnnew.s);
    if (fdnew == -1) die_write();
    substdio_fdbuf(&ssnew,write,fdnew,ssnewbuf,sizeof(ssnewbuf));

    fd = open_read(fn.s);
    if (fd == -1) {
      if (errno != error_noent) { close(fdnew); die_read(); }
    } else {
      substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));

      for (;;) {
        if (getln(&ss,&line,&match,'\0') == -1)
          { close(fd); close(fdnew); die_read(); }
        if (!match) break;
        if (line.len == addr.len)
          if (!case_diffb(line.s,line.len,addr.s)) {
            flagwasthere = 1;
            continue;	/* always want to remove from case-sensitive hash */
          }
        if (substdio_bput(&ssnew,line.s,line.len) == -1)
          { close(fd); close(fdnew); die_write(); }
      }

      close(fd);
    }

    if (substdio_flush(&ssnew) == -1) { close(fdnew); die_write(); }
    if (fsync(fdnew) == -1) { close(fdnew); die_write(); }
    close(fdnew);

    if (rename(fnnew.s,fn.s) == -1)
      strerr_die6sys(111,FATAL,ERR_MOVE,fnnew.s," to ",fn.s,": ");

    close(fdlock);
    if (flagadd ^ flagwasthere) {
      if (!stralloc_0(&addr)) die_nomem();
      logaddr(dir,subdir,event,addr.s+1,comment);
      return 1;
    }
    return 0;

}
Exemple #18
0
int
main(int argc, char **argv)
{
	int match;
	unsigned int at;

	log_init(STDERR, ~256, 0);

	if (read_controls(ctrls) == -1)
		die_control();
	
	q = 0;
	do {
		if (getln(&ssin, &line, &match, '\0') != 0) {
			if (errno != error_timeout)
				die_read();
			cleanup();
			continue;
		}
		if (!match) {
			cleanup(); /* other side closed pipe */
			break;
		}

		logit(32, "qmail-verfiy: verifying %S\n", &line);

		at = byte_rchr(line.s,line.len,'@');
		if (at >= line.len) {
			if (substdio_puts(subfdout, "DSorry, address must "
			    "include host name. (#5.1.3)") == -1)
				die_write();
			if (substdio_putflush(subfdout, "", 1) == -1)
				die_write();
			continue;
		}

		switch (lookup(&line)) {
		case 0:
			if (localdelivery()) {
				/*
				 * Do the local address lookup.
				 */
				line.s[at] = '\0';
				if (lookup_cdb(line.s) == 1)
					break;
				if (lookup_passwd(line.s) == 1)
					break;
			}
			/* Sorry, no mailbox here by that name. */
			if (substdio_puts(subfdout,
			    "DSorry, no mailbox here by that name. "
			    "(#5.1.1)") == -1)
				die_write();
			if (substdio_putflush(subfdout, "", 1) == -1)
				die_write();
			break;
		case 1:
		default:
			break;
		}
	} while (1);

	return 0;
}
Exemple #19
0
void putflush(void)
{
  if (buffer_flush(buffer_1) == -1) die_write();
}
Exemple #20
0
void put(char *buf,off_t len)
{
  if (buffer_put(buffer_1,buf,len) == -1) die_write();
}
Exemple #21
0
int
lookup(stralloc *mail)
{
	const char *attrs[] = {  LDAP_ISACTIVE, 0 };
	char *f;
	int done;
	int status;
	int rv;

	if (q == 0) {
		q = qldap_new();
		if (q == 0)
			die_nomem();

		rv = qldap_open(q);
		if (rv != OK) die_temp();
		rv = qldap_bind(q, 0, 0);
		if (rv != OK) die_temp();
	}
	
	/*
	 * this handles the "catch all" and "-default" extension 
	 * but also the normal eMail address.
	 * Code handels also mail addresses with multiple '@' safely.
	 * at = index to last @ sign in mail address
	 * escaped = ldap escaped mailaddress
	 * len = length of escaped mailaddress
	 * i = position of current '-' or '@'
	 */
	done = 0;
	do {
		f = filter_mail(mail->s, &done);
		if (f == (char *)0) die_nomem();

		logit(16, "ldapfilter: '%s'\n", f);

		/* do the search for the email address */
		rv = qldap_lookup(q, f, attrs);
		switch (rv) {
		case OK:
			break; /* something found */
		case TIMEOUT:
			/* temporary error but give up so that the
			 * ldap server can recover */
			die_timeout();
		case TOOMANY:
#ifdef DUPEALIAS
			if (substdio_putflush(subfdout, "K", 1) == -1)
				die_write();
			qldap_free_results(q);
#else
			/* admin error, also temporary */
			temp_fail();
#endif
			return (-1);
		case FAILED:
			/* ... again temporary */
			temp_fail();
			return (-1);
		case NOSUCH:
			break;
		}
	} while (rv != OK && !done);
	/* reset filter_mail */
	filter_mail(0, 0);

	/* nothing found, try a local lookup or a alias delivery */
	if (rv == NOSUCH) {
		qldap_free_results(q);
		return (0);
	}

	/* check if the ldap entry is active */
	rv = qldap_get_status(q, &status);
	if (rv != OK) {
		temp_fail();
		return (-1);
	}
	if (status == STATUS_BOUNCE) {
		/* Mailaddress is administratively disabled. (#5.2.1) */
		if (substdio_puts(subfdout,
			    "DMailaddress is administratively disabled. "
			    "(#5.2.1)") == -1)
			die_write();
		if (substdio_putflush(subfdout, "", 1) == -1)
			die_write();
		qldap_free_results(q);
		return (1);
	} else if (status == STATUS_DELETE) {
		/* Sorry, no mailbox here by that name. (#5.1.1) */
		if (substdio_puts(subfdout,
			    "DSorry, no mailbox here by that name. "
			    "(#5.1.1)") == -1)
			die_write();
		if (substdio_putflush(subfdout, "", 1) == -1)
			die_write();
		qldap_free_results(q);
		return (1);
	}

	/* OK */
	if (substdio_putflush(subfdout, "K", 1) == -1)
		die_write();
	qldap_free_results(q);
	return (1);
}
Exemple #22
0
int main(int argc,char **argv)
{
  unsigned long ttl;
  struct stat st;
  int i;
  int j;
  int k;
  char ch;

  if (!*argv) die_usage();

  if (!*++argv) die_usage();
  fn = *argv;

  if (!*++argv) die_usage();
  fnnew = *argv;

  if (!*++argv) die_usage();
  if (str_diff(*argv,"add")) die_usage();

  if (!*++argv) die_usage();
  if (str_equal(*argv,"ns")) mode = '.';
  else if (str_equal(*argv,"childns")) mode = '&';
  else if (str_equal(*argv,"host")) mode = '=';
  else if (str_equal(*argv,"host6")) mode = '6';
  else if (str_equal(*argv,"alias")) mode = '+';
  else if (str_equal(*argv,"alias6")) mode = '3';
  else if (str_equal(*argv,"mx")) mode = '@';
  else die_usage();

  if (!*++argv) die_usage();
  if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem();

  if (!*++argv) die_usage();
  if (mode == '6' || mode == '3') {
    if (!ip6_scan(*argv,targetip6)) die_usage();
  } else {
    if (!ip4_scan(*argv,targetip)) die_usage();
  }

  umask(077);

  fd = open_read(fn);
  if (fd == -1) die_read();
  if (fstat(fd,&st) == -1) die_read();
  buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);

  fdnew = open_trunc(fnnew);
  if (fdnew == -1) die_write();
  if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write();
  buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace);

  switch(mode) {
    case '.': case '&':
      ttl = TTL_NS;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".ns.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
    case '+': case '=': case '6': case '3':
      ttl = TTL_POSITIVE;
      break;
    case '@':
      ttl = TTL_POSITIVE;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".mx.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
  }

  while (match) {
    if (getln(&b,&line,&match,'\n') == -1) die_read();

    put(line.s,line.len);
    if (line.len && !match) put("\n",1);

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(mode) {
      case '.': case '&':
	if (line.s[0] == mode) {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".ns.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[3])) nomem();
	    if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;

      case '=':
	if (line.s[0] == '=') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip4_scan(f[1].s,ip))
	    if (byte_equal(ip,4,targetip))
	      strerr_die2x(100,FATAL,"IP address already used");
	}
	break;

      case '6':
	if (line.s[0] == '6') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip6_scan(f[1].s,ip6))
	    if (byte_equal(ip,16,targetip6))
	      strerr_die2x(100,FATAL,"IPv6 address already used");
	}
	break;

      case '@':
	if (line.s[0] == '@') {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".mx.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[4])) nomem();
	    if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;
    }
  }

  if (!stralloc_copyb(&f[0],&mode,1)) nomem();
  if (!dns_domain_todot_cat(&f[0],target)) nomem();
  if (!stralloc_cats(&f[0],":")) nomem();
  if (mode == '6' || mode == '3') {
    if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem();
  } else {
    if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem();
  }
  switch(mode) {
    case '.': case '&': case '@':
      for (i = 0;i < 26;++i)
	if (!used[i])
	  break;
      if (i >= 26)
	strerr_die2x(100,FATAL,"too many records for that domain");
      ch = 'a' + i;
      if (!stralloc_cats(&f[0],":")) nomem();
      if (!stralloc_catb(&f[0],&ch,1)) nomem();
      if (mode == '@')
        if (!stralloc_cats(&f[0],":")) nomem();
      break;
  }
  if (!stralloc_cats(&f[0],":")) nomem();
  if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem();
  if (!stralloc_cats(&f[0],"\n")) nomem();
  put(f[0].s,f[0].len);

  if (buffer_flush(&bnew) == -1) die_write();
  if (fsync(fdnew) == -1) die_write();
  if (close(fdnew) == -1) die_write(); /* NFS dorks */
  if (rename(fnnew,fn) == -1)
    strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": ");
  _exit(0);
}
Exemple #23
0
void put(const char *buf,unsigned int len)
{
  if (buffer_putalign(&bnew,buf,len) == -1) die_write();
}
Exemple #24
0
void put(char *buf,unsigned int len)
{
  if (buffer_put(buffer_1small,buf,len) == -1) die_write();
}
Exemple #25
0
int main(int argc, char **argv, char **envp) {
  char ch;
  struct cdbmake cm;
  array_t data = ARRAY_INIT(1);
  int32_t dlen;
  int fd;
  uint32_t i;
  array_t key = ARRAY_INIT(1);
  int32_t klen;
  char *path;
  char *tmp;
  
  if (!*argv || !*++argv)
    usage();
  path = *argv;
  
  if (!*++argv)
    usage();
  tmp = *argv;
  
  /* Create the temporary file and start the cdb creation process with it. */
  fd = open("test.cdb", O_CREAT | O_TRUNC | O_WRONLY, 0644);
  if (fd == -1)
    strerr_die4sys(111, FATAL, "unable to create ", tmp, ": ");
  if (cdbmake_start(&cm, fd) == -1)
    strerr_die2sys(111, FATAL, "cdbmake initialization failed: ");
    
  for (;;) {
    /* Skip over new lines and require the first character to be '+'. */
    ch = get_ch();
    if (ch == '\n')
      break;
    if (ch != '+')
      die_format();
      
    /* Read the key length. */
    klen = get_len(',');
    if (klen == -1)
      die_format();
      
    /* Read the data length. */
    dlen = get_len(':');
    if (dlen == -1)
      die_format();
      
    /* Truncate the key array and load it with the key from the cdb record. */
    array_trunc(&key);
    for (i = 0; i < klen; i++) {
      ch = get_ch();
      array_append(&key, &ch, 1);
    }
    
    /* Verify the separator is ->. */
    if ((get_ch() != '-') || (get_ch() != '>'))
      die_format();
      
    /* Truncate the data array and load it with the data from the cdb record. */
    array_trunc(&data);
    for (i = 0; i < dlen; i++) {
      ch = get_ch();
      array_append(&data, &ch, 1);
    }
    
    /* The line is valid, so add it to the cdb file and check that it ends with
     * a new line. */
    if (cdbmake_add(&cm, array_start(&key), klen, array_start(&data), dlen) == -1)
      die_write();
    if (get_ch() != '\n')
      die_format();
  }
  
  /* Finish the cdb file, sync it to disk, close it, and finally rename it to
   * the target path. */
  if (cdbmake_finish(&cm) == -1)
    die_write();
  if (fsync(fd) == -1)
    die_write();
  if (close(fd) == -1)
    die_write();
  if (rename(tmp, path) == -1)
    strerr_die6sys(111, FATAL, "unable to rename ", tmp, " to ", path, ": ");
    
  _exit(0);
}
Exemple #26
0
int
lookup_cdb(const char *mail)
{
	int	fd;
	int	flagwild;
	int	r;

	if (!stralloc_copys(&lower, "!")) die_nomem();
	if (!stralloc_cats(&lower, mail)) die_nomem();
	if (!stralloc_0(&lower)) die_nomem();
	case_lowerb(lower.s, lower.len);

	fd = open_read("users/cdb");
	if (fd == -1)
		if (errno != error_noent)
			die_cdb();

	if (fd != -1) {
		uint32 dlen;
		unsigned int i;

		cdb_init(&cdb, fd);
		r = cdb_seek(&cdb, "", 0, &dlen);
		if (r != 1)
			die_cdb();

		if (!stralloc_ready(&wildchars, (unsigned int) dlen))
			die_nomem();
		wildchars.len = dlen;
		if (cdb_bread(&cdb, wildchars.s, wildchars.len) == -1)
			die_cdb();

		i = lower.len;
		flagwild = 0;

		do {
			/* i > 0 */
			if (!flagwild || i == 1 || byte_chr(wildchars.s,
			    wildchars.len, lower.s[i - 1]) < wildchars.len) {
				r = cdb_seek(&cdb,lower.s,i,&dlen);
				if (r == -1)
					die_cdb();
				if (r == 1) {
					/* OK */
					if (substdio_putflush(subfdout, "K",
					    1) == -1)
						die_write();
					
					cdb_free(&cdb);
					close(fd);
					return (1);
				}
			}
			--i;
			flagwild = 1;
		} while (i);

		close(fd);
	}
	return (0);
}