Example #1
0
static int getmailboxexists(void *sc, const char *extname)
{
    script_data_t *sd = (script_data_t *)sc;
    char *intname = mboxname_from_external(extname, sd->ns, mbname_userid(sd->mbname));
    int r = mboxlist_lookup(intname, NULL, NULL);
    free(intname);
    return r ? 0 : 1; /* 0 => exists */
}
Example #2
0
static int getmetadata(void *sc, const char *extname, const char *keyname, char **res)
{
    script_data_t *sd = (script_data_t *)sc;
    struct buf attrib = BUF_INITIALIZER;
    char *intname = extname ? mboxname_from_external(extname, sd->ns, mbname_userid(sd->mbname)) : xstrdup("");
    int r;
    if (!strncmp(keyname, "/private/", 9)) {
        r = annotatemore_lookup(intname, keyname+8, mbname_userid(sd->mbname), &attrib);
    }
    else if (!strncmp(keyname, "/shared/", 8)) {
        r = annotatemore_lookup(intname, keyname+7, "", &attrib);
    }
    else {
        r = IMAP_MAILBOX_NONEXISTENT;
    }
    *res = (r || !attrib.len) ? NULL : buf_release(&attrib);
    free(intname);
    buf_free(&attrib);
    return r ? 0 : 1;
}
Example #3
0
static void expand_mboxnames(strarray_t *sa, int nmboxnames,
                             const char **mboxnames, int user_mode)
{
    int i;

    if (!nmboxnames) {
        assert(!recursive_flag);
        mboxlist_allmbox(NULL, addmbox, sa, 0);
    }

    for (i = 0; i < nmboxnames; i++) {
        if (user_mode) {
            mboxlist_usermboxtree(mboxnames[i], addmbox, sa, 0);
        }
        else {
            /* Translate any separators in mailboxname */
            char *intname = mboxname_from_external(mboxnames[i], &squat_namespace, NULL);
            int flags = recursive_flag ? 0 : MBOXTREE_SKIP_CHILDREN;
            mboxlist_mboxtree(intname, addmbox, sa, flags);
            free(intname);
        }
    }
}
Example #4
0
int main(int argc, char *argv[])
{
    extern char *optarg;
    int opt, r = 0;
    char *alt_config = NULL, *intname = NULL, *extname = NULL;
    struct mailbox *mailbox = NULL;
    int mode = MODE_UNKNOWN;
    unsigned numrestored = 0;
    time_t time_since = time(NULL);
    int len, secs = 0;
    unsigned long *uids = NULL;
    unsigned nuids = 0;

    while ((opt = getopt(argc, argv, "C:laudt:f:v")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file */
            alt_config = optarg;
            break;

        case 'l':
            if (mode != MODE_UNKNOWN) usage();
            mode = MODE_LIST;
            break;

        case 'a':
            if (mode != MODE_UNKNOWN) usage();
            mode = MODE_ALL;
            break;

        case 't':
            if (mode != MODE_UNKNOWN) usage();

            mode = MODE_TIME;
            secs = atoi(optarg);
            len  = strlen(optarg);

            if ((secs > 0) && (len > 1)) {
                switch (optarg[len-1]) {
                case 'm':
                    secs *= 60;
                    break;
                case 'h':
                    secs *= (60*60);
                    break;
                case 'd':
                    secs *= (24*60*60);
                    break;
                case 'w':
                    secs *= (7*24*60*60);
                    break;
                }
            }
            time_since = time(NULL) - secs;
            break;

        case 'u':
            if (mode != MODE_UNKNOWN) usage();
            mode = MODE_UID;
            break;

        case 'd':
            unsetdeleted = 1;
            break;

        case 'f':
            addflag = optarg;
            break;

        case 'v':
            verbose = 1;
            break;

        default:
            usage();
            break;
        }
    }

    /* sanity check */
    if (mode == MODE_UNKNOWN ||
        (optind + (mode == MODE_UID ? 1 : 0)) >= argc) usage();


    cyrus_init(alt_config, "unexpunge", 0, 0);

    sync_log_init();

    if (addflag && addflag[0] == '\\') {
        syslog(LOG_ERR, "can't set a system flag");
        fatal("can't set a system flag", EX_SOFTWARE);
    }

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&unex_namespace, 1)) != 0) {
        syslog(LOG_ERR, "%s", error_message(r));
        fatal(error_message(r), EX_CONFIG);
    }

    /* Translate mailboxname */
    intname = mboxname_from_external(argv[optind], &unex_namespace, NULL);

    if (mode == MODE_LIST) {
        list_expunged(intname);
        goto done;
    }

    /* Open/lock header */
    r = mailbox_open_iwl(intname, &mailbox);
    if (r) {
        printf("Failed to open mailbox '%s'\n", intname);
        goto done;
    }

    if (mode == MODE_UID) {
        unsigned i;

        nuids = argc - ++optind;
        uids = (unsigned long *) xmalloc(nuids * sizeof(unsigned long));

        for (i = 0; i < nuids; i++)
            uids[i] = strtoul(argv[optind+i], NULL, 10);

        /* Sort the UIDs so we can binary search */
        qsort(uids, nuids, sizeof(unsigned long), compare_uid);
    }

    extname = mboxname_to_external(intname, &unex_namespace, NULL);

    printf("restoring %sexpunged messages in mailbox '%s'\n",
            mode == MODE_ALL ? "all " : "", extname);

    r = restore_expunged(mailbox, mode, uids, nuids, time_since, &numrestored, extname);

    if (!r) {
        printf("restored %u expunged messages\n",
                numrestored);
        syslog(LOG_NOTICE,
               "restored %u expunged messages in mailbox '%s'",
               numrestored, extname);
    }

    mailbox_close(&mailbox);

done:
    free(intname);
    free(extname);
    sync_log_done();

    cyrus_done();

    exit(r);
}
Example #5
0
/* This handles piping of the LSUB command, because we have to figure out
 * what mailboxes actually exist before passing them to the end user.
 *
 * It is also needed if we are doing a FIND MAILBOXES, for that we do an
 * LSUB on the backend anyway, because the semantics of FIND do not allow
 * it to return nonexistant mailboxes (RFC1176), but we need to really dumb
 * down the response when this is the case.
 */
int pipe_lsub(struct backend *s, const char *userid, const char *tag,
              int force_notfatal, const char *resp)
{
    int taglen = strlen(tag);
    int c;
    int r = PROXY_OK;
    int exist_r;
    static struct buf tagb, cmd, sep, name;
    struct buf flags = BUF_INITIALIZER;

    const char *end_strip_flags[] = { " \\NonExistent)", "\\NonExistent)",
                                      " \\Noselect)", "\\Noselect)",
                                      NULL };
    const char *mid_strip_flags[] = { "\\NonExistent ",
                                      "\\Noselect ",
                                      NULL
                                    };

    assert(s);
    assert(s->timeout);

    s->timeout->mark = time(NULL) + IDLE_TIMEOUT;

    while(1) {
        c = getword(s->in, &tagb);

        if(c == EOF) {
            if(s == backend_current && !force_notfatal)
                fatal("Lost connection to selected backend", EC_UNAVAILABLE);
            proxy_downserver(s);
            r = PROXY_NOCONNECTION;
            goto out;
        }

        if(!strncmp(tag, tagb.s, taglen)) {
            char buf[2048];
            if(!prot_fgets(buf, sizeof(buf), s->in)) {
                if(s == backend_current && !force_notfatal)
                    fatal("Lost connection to selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }
            /* Got the end of the response */
            buf_appendcstr(&s->last_result, buf);
            buf_cstring(&s->last_result);

            switch (buf[0]) {
            case 'O': case 'o':
                r = PROXY_OK;
                break;
            case 'N': case 'n':
                r = PROXY_NO;
                break;
            case 'B': case 'b':
                r = PROXY_BAD;
                break;
            default: /* huh? no result? */
                if(s == backend_current && !force_notfatal)
                    fatal("Lost connection to selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                break;
            }
            break; /* we're done */
        }

        c = getword(s->in, &cmd);

        if(c == EOF) {
            if(s == backend_current && !force_notfatal)
                fatal("Lost connection to selected backend", EC_UNAVAILABLE);
            proxy_downserver(s);
            r = PROXY_NOCONNECTION;
            goto out;
        }

        if(strncasecmp("LSUB", cmd.s, 4) && strncasecmp("LIST", cmd.s, 4)) {
            prot_printf(imapd_out, "%s %s ", tagb.s, cmd.s);
            r = pipe_to_end_of_response(s, force_notfatal);
            if (r != PROXY_OK)
                goto out;
        } else {
            /* build up the response bit by bit */
            int i;

            buf_reset(&flags);
            c = prot_getc(s->in);
            while(c != ')' && c != EOF) {
                buf_putc(&flags, c);
                c = prot_getc(s->in);
            }

            if(c != EOF) {
                /* terminate string */
                buf_putc(&flags, ')');
                buf_cstring(&flags);

                /* get the next character */
                c = prot_getc(s->in);
            }

            if(c != ' ') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* Check for flags that we should remove
             * (e.g. Noselect, NonExistent) */
            for(i=0; end_strip_flags[i]; i++)
                buf_replace_all(&flags, end_strip_flags[i], ")");

            for (i=0; mid_strip_flags[i]; i++)
                buf_replace_all(&flags, mid_strip_flags[i], NULL);

            /* Get separator */
            c = getastring(s->in, s->out, &sep);

            if(c != ' ') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* Get name */
            c = getastring(s->in, s->out, &name);

            if(c == '\r') c = prot_getc(s->in);
            if(c != '\n') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* lookup name */
            exist_r = 1;
            char *intname = mboxname_from_external(name.s, &imapd_namespace, userid);
            mbentry_t *mbentry = NULL;
            exist_r = mboxlist_lookup(intname, &mbentry, NULL);
            free(intname);
            if(!exist_r && (mbentry->mbtype & MBTYPE_RESERVE))
                exist_r = IMAP_MAILBOX_RESERVED;
            mboxlist_entry_free(&mbentry);

            /* send our response */
            /* we need to set \Noselect if it's not in our mailboxes.db */
            if (resp[0] == 'L') {
                if(!exist_r) {
                    prot_printf(imapd_out, "* %s %s \"%s\" ",
                                resp, flags.s, sep.s);
                } else {
                    prot_printf(imapd_out, "* %s (\\Noselect) \"%s\" ",
                                resp, sep.s);
                }

                prot_printstring(imapd_out, name.s);
                prot_printf(imapd_out, "\r\n");

            } else if(resp[0] == 'M' && !exist_r) {
                /* Note that it has to exist for a find response */
                prot_printf(imapd_out, "* %s ", resp);
                prot_printastring(imapd_out, name.s);
                prot_printf(imapd_out, "\r\n");
            }
        }
    } /* while(1) */

out:
    buf_free(&flags);
    return r;
}
Example #6
0
int main(int argc, char **argv)
{
    int opt, i, r;
    char buf[MAX_MAILBOX_PATH+1];
    char *alt_config = NULL;
    int quotachk = 0;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
        fatal("must run as the Cyrus user", EC_USAGE);
    }

    while ((opt = getopt(argc, argv, "C:u:s:q")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file */
            alt_config = optarg;
            break;

        case 'u':
            if(wantvalue) usage();
            wantuid = 1;
            wantvalue = atoi(optarg);
            break;

        case 's':
            if(wantvalue) usage();
            wantvalue = atoi(optarg);
            break;

        case 'q':
            quotachk = 1;
            break;

        default:
            usage();
        }
    }

    cyrus_init(alt_config, "mbexamine", 0, 0);

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&recon_namespace, 1)) != 0) {
        syslog(LOG_ERR, "%s", error_message(r));
        fatal(error_message(r), EC_CONFIG);
    }

    mboxlist_init(0);
    mboxlist_open(NULL);

    signals_set_shutdown(&shut_down);
    signals_add_handlers(0);

    if (optind == argc) {
        strlcpy(buf, "*", sizeof(buf));
        mboxlist_findall(&recon_namespace, buf, 1, 0, 0,
                         quotachk ? do_quota : do_examine,
                         NULL);
    }

    for (i = optind; i < argc; i++) {
        /* Handle virtdomains and separators in mailboxname */
        char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL);
        mboxlist_findall(&recon_namespace, intname, 1, 0, 0,
                         quotachk ? do_quota : do_examine,
                         NULL);
        free(intname);
    }

    mboxlist_close();
    mboxlist_done();

    exit(0);
}
Example #7
0
int main(int argc, char **argv)
{
    int opt, i, r;
    int dousers = 0;
    int rflag = 0;
    int mflag = 0;
    int fflag = 0;
    int xflag = 0;
    char buf[MAX_MAILBOX_PATH+1];
    strarray_t discovered = STRARRAY_INITIALIZER;
    char *alt_config = NULL;
    char *start_part = NULL;

    if ((geteuid()) == 0 && (become_cyrus(/*is_master*/0) != 0)) {
        fatal("must run as the Cyrus user", EC_USAGE);
    }

    construct_hash_table(&unqid_table, 2047, 1);

    while ((opt = getopt(argc, argv, "C:kp:rmfsxgGqRUMoOnV:u")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file */
            alt_config = optarg;
            break;

        case 'p':
            start_part = optarg;
            break;

        case 'r':
            rflag = 1;
            break;

        case 'u':
            dousers = 1;
            break;

        case 'm':
            mflag = 1;
            break;

        case 'n':
            reconstruct_flags &= ~RECONSTRUCT_MAKE_CHANGES;
            break;

        case 'g':
            fprintf(stderr, "reconstruct: deprecated option -g ignored\n");
            break;

        case 'G':
            reconstruct_flags |= RECONSTRUCT_ALWAYS_PARSE;
            break;

        case 'f':
            fflag = 1;
            break;

        case 'x':
            xflag = 1;
            break;

        case 'k':
            fprintf(stderr, "reconstruct: deprecated option -k ignored\n");
            break;

        case 's':
            reconstruct_flags &= ~RECONSTRUCT_DO_STAT;
            break;

        case 'q':
            reconstruct_flags |= RECONSTRUCT_QUIET;
            break;

        case 'R':
            reconstruct_flags |= RECONSTRUCT_GUID_REWRITE;
            break;

        case 'U':
            reconstruct_flags |= RECONSTRUCT_GUID_UNLINK;
            break;

        case 'o':
            reconstruct_flags |= RECONSTRUCT_IGNORE_ODDFILES;
            break;

        case 'O':
            reconstruct_flags |= RECONSTRUCT_REMOVE_ODDFILES;
            break;

        case 'M':
            reconstruct_flags |= RECONSTRUCT_PREFER_MBOXLIST;
            break;

        case 'V':
            if (!strcasecmp(optarg, "max"))
                setversion = MAILBOX_MINOR_VERSION;
            else
                setversion = atoi(optarg);
            break;

        default:
            usage();
        }
    }

    cyrus_init(alt_config, "reconstruct", 0, CONFIG_NEED_PARTITION_DATA);
    global_sasl_init(1,0,NULL);

    /* Set namespace -- force standard (internal) */
    if ((r = mboxname_init_namespace(&recon_namespace, 1)) != 0) {
        syslog(LOG_ERR, "%s", error_message(r));
        fatal(error_message(r), EC_CONFIG);
    }

    sync_log_init();

    if (mflag) {
        if (rflag || fflag || optind != argc) {
            cyrus_done();
            usage();
        }
        do_mboxlist();
    }

    mboxlist_init(0);
    mboxlist_open(NULL);

    quotadb_init(0);
    quotadb_open(NULL);

#ifdef WITH_DAV
    caldav_init();
    carddav_init();
    webdav_init();
#endif

    /* Deal with nonexistent mailboxes */
    if (start_part) {
        /* We were handed a mailbox that does not exist currently */
        if(optind == argc) {
            fprintf(stderr,
                    "When using -p, you must specify a mailbox to attempt to reconstruct.");
            exit(EC_USAGE);
        }

        /* do any of the mailboxes exist in mboxlist already? */
        /* Do they look like mailboxes? */
        for (i = optind; i < argc; i++) {
            if (strchr(argv[i],'%') || strchr(argv[i],'*')) {
                fprintf(stderr, "Using wildcards with -p is not supported.\n");
                exit(EC_USAGE);
            }

            /* Translate mailboxname */
            char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL);

            /* Does it exist */
            do {
                r = mboxlist_lookup(intname, NULL, NULL);
            } while (r == IMAP_AGAIN);

            if (r != IMAP_MAILBOX_NONEXISTENT) {
                fprintf(stderr,
                        "Mailbox %s already exists.  Cannot specify -p.\n",
                        argv[i]);
                exit(EC_USAGE);
            }
            free(intname);
        }

        /* None of them exist.  Create them. */
        for (i = optind; i < argc; i++) {
            /* Translate mailboxname */
            char *intname = mboxname_from_external(argv[i], &recon_namespace, NULL);

            /* don't notify mailbox creation here */
            r = mboxlist_createmailbox(intname, 0, start_part, 1,
                                       "cyrus", NULL, 0, 0, !xflag, 0, NULL);
            if (r) {
                fprintf(stderr, "could not create %s\n", argv[i]);
            }

            free(intname);
        }
    }

    /* Normal Operation */
    if (optind == argc) {
        if (rflag || dousers) {
            fprintf(stderr, "please specify a mailbox to recurse from\n");
            cyrus_done();
            exit(EC_USAGE);
        }
        assert(!rflag);
        strlcpy(buf, "*", sizeof(buf));
        mboxlist_findall(&recon_namespace, buf, 1, 0, 0,
                         do_reconstruct, NULL);
    }

    for (i = optind; i < argc; i++) {
        if (dousers) {
            mboxlist_usermboxtree(argv[i], do_reconstruct_p, NULL, MBOXTREE_TOMBSTONES|MBOXTREE_DELETED);
            continue;
        }
        char *domain = NULL;

        /* save domain */
        if (config_virtdomains) domain = strchr(argv[i], '@');

        strlcpy(buf, argv[i], sizeof(buf));

        /* reconstruct the first mailbox/pattern */
        mboxlist_findall(&recon_namespace, buf, 1, 0,
                         0, do_reconstruct,
                         fflag ? &discovered : NULL);
        if (rflag) {
            /* build a pattern for submailboxes */
            char *p = strchr(buf, '@');
            if (p) *p = '\0';
            strlcat(buf, ".*", sizeof(buf));

            /* append the domain */
            if (domain) strlcat(buf, domain, sizeof(buf));

            /* reconstruct the submailboxes */
            mboxlist_findall(&recon_namespace, buf, 1, 0,
                             0, do_reconstruct,
                             fflag ? &discovered : NULL);
        }
    }

    /* examine our list to see if we discovered anything */
    while (discovered.count) {
        char *name = strarray_shift(&discovered);
        int r = 0;

        /* create p (database only) and reconstruct it */
        /* partition is defined by the parent mailbox */
        /* don't notify mailbox creation here */
        r = mboxlist_createmailbox(name, 0, NULL, 1,
                                   "cyrus", NULL, 0, 0, !xflag, 0, NULL);
        if (r) {
            fprintf(stderr, "createmailbox %s: %s\n",
                    name, error_message(r));
        } else {
            mboxlist_findone(&recon_namespace, name, 1, 0,
                             0, do_reconstruct,
                             &discovered);
        }
        /* may have added more things into our list */

        free(name);
    }

    free_hash_table(&unqid_table, free);

    sync_log_done();

    mboxlist_close();
    mboxlist_done();

    quotadb_close();
    quotadb_done();

    partlist_local_done();
#ifdef WITH_DAV
    webdav_done();
    carddav_done();
    caldav_done();
#endif

    cyrus_done();

    strarray_fini(&discovered);

    return 0;
}