예제 #1
0
def proc_sympa_remove(request):
    """Execute the request for removing a sympa mailing list.

    @type request: ??
    @param request:
      A dict-like object containing all the parameters for sympa list
      removal.
    """

    try:
        state = pickle.loads(str(request["state_data"]))
    except:
        logger.exception("Corrupt request state for sympa request %s: %s",
                         request["request_id"], request["state_data"])
        return True

    try:
        listname = state["listname"]
        host = state["run_host"]
    except KeyError:
        logger.error("No listname/runhost specified for request %s",
                     request["request_id"])
        return True

    cmd = [cereconf.SYMPA_SCRIPT, host, 'rmlist', listname]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #2
0
def delete_user(uname, old_host, old_home, operator, mail_server):
    account = get_account(name=uname)
    generation = account.get_trait(const.trait_account_generation)
    if generation:
        generation = generation['numval'] + 1
    else:
        generation = 1

    args = [
        SUDO_CMD, cereconf.RMUSER_SCRIPT,
        '--username', account.account_name,
        '--deleted-by', operator,
        '--homedir', old_home,
        '--generation', str(generation)
    ]
    if DEBUG:
        args.append('--debug')
    cmd = SSH_CEREBELLUM + [" ".join(args), ]

    if Utils.spawn_and_log_output(cmd, connect_to=[old_host]) == EXIT_SUCCESS:
        account.populate_trait(const.trait_account_generation,
                               numval=generation)
        account.write_db()
        return True
    return False
예제 #3
0
def archive_cyrus_data(uname, mail_server, generation):
    args = [
        SUDO_CMD, cereconf.ARCHIVE_MAIL_SCRIPT,
        '--server', mail_server,
        '--user', uname,
        '--gen', str(generation)
    ]
    if DEBUG:
        args.append('--debug')
    cmd = SSH_CEREBELLUM + [" ".join(args), ]
    return (
        Utils.spawn_and_log_output(cmd, connect_to=[mail_server]) ==
        EXIT_SUCCESS)
예제 #4
0
def move_user(uname, uid, gid, old_host, old_disk, new_host, new_disk,
              operator):
    args = [SUDO_CMD, cereconf.MVUSER_SCRIPT,
            '--user', uname,
            '--uid', str(uid),
            '--gid', str(gid),
            '--old-disk', old_disk,
            '--new-disk', new_disk,
            '--operator', operator]
    if DEBUG:
        args.append('--debug')
    cmd = SSH_CEREBELLUM + [" ".join(args), ]
    return (Utils.spawn_and_log_output(cmd, connect_to=[old_host, new_host]) ==
            EXIT_SUCCESS)
예제 #5
0
def proc_sympa_create(request):
    """Execute the request for creating a sympa mailing list.

    :type request: db_row
    :param request:
      A dict-like object describing the sympa list creation request.
    """

    try:
        listname = get_address(request["entity_id"])
    except Errors.NotFoundError:
        logger.info("Sympa list address id:%s is deleted! No need to create",
                    request["entity_id"])
        return True

    try:
        state = json.loads(request["state_data"])
    except ValueError:
        state = None

    # Remove this when there's no chance of pickled data
    if state is None:
        try:
            state = pickle.loads(request["state_data"])
        except Exception:
            pass

    if state is None:
        logger.error("Cannot parse request state for sympa list=%s: %s",
                     listname, request["state_data"])
        return True

    try:
        host = state["runhost"]
        profile = state["profile"]
        description = state["description"]
        admins = state["admins"]
        admins = ",".join(admins)
    except KeyError:
        logger.error("No host/profile/description specified for sympa list %s",
                     listname)
        return True

    # 2008-08-01 IVR FIXME: Safe quote everything fished out from state.
    cmd = [
        cereconf.SYMPA_SCRIPT, host, 'newlist', listname, admins, profile,
        description
    ]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #6
0
def proc_sympa_create(request):
    """Execute the request for creating a sympa mailing list.

    :type request: db_row
    :param request:
      A dict-like object describing the sympa list creation request.
    """

    try:
        listname = get_address(request["entity_id"])
    except Errors.NotFoundError:
        logger.info("Sympa list address id:%s is deleted! No need to create",
                    request["entity_id"])
        return True

    try:
        state = json.loads(request["state_data"])
    except ValueError:
        state = None

    # Remove this when there's no chance of pickled data
    if state is None:
        try:
            state = pickle.loads(request["state_data"])
        except Exception:
            pass

    if state is None:
        logger.error("Cannot parse request state for sympa list=%s: %s",
                     listname, request["state_data"])
        return True

    try:
        host = state["runhost"]
        profile = state["profile"]
        description = state["description"]
        admins = state["admins"]
        admins = ",".join(admins)
    except KeyError:
        logger.error("No host/profile/description specified for sympa list %s",
                     listname)
        return True

    # 2008-08-01 IVR FIXME: Safe quote everything fished out from state.
    cmd = [cereconf.SYMPA_SCRIPT, host, 'newlist',
           listname, admins, profile, description]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #7
0
def proc_sympa_create(request):
    """Execute the request for creating a sympa mailing list.

    @type request: ??
    @param request:
      An object describing the sympa list creation request.
    """

    try:
        listname = get_address(request["entity_id"])
    except Errors.NotFoundError:
        logger.warn("Sympa list address id:%s is deleted! No need to create",
                    request["entity_id"])
        return True

    try:
        state = pickle.loads(str(request["state_data"]))
    except:
        logger.exception("Corrupt request state for sympa list=%s: %s",
                         listname, request["state_data"])
        return True

    try:
        host = state["runhost"]
        profile = state["profile"]
        description = state["description"]
        admins = state["admins"]
        admins = ",".join(admins)
    except KeyError:
        logger.error("No host/profile/description specified for sympa list %s",
                     listname)
        return True

    # 2008-08-01 IVR FIXME: Safe quote everything fished out from state.
    cmd = [cereconf.SYMPA_SCRIPT, host, 'newlist',
           listname, admins, profile, description]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #8
0
def proc_sympa_remove(request):
    """Execute the request for removing a sympa mailing list.

    :type request: db_row
    :param request:
      A dict-like object containing all the parameters for sympa list
      removal.
    """

    try:
        state = json.loads(request["state_data"])
    except ValueError:
        state = None

    # Remove this when there's no chance of pickled data
    if state is None:
        try:
            state = pickle.loads(request["state_data"])
        except Exception:
            pass

    if state is None:
        logger.error("Cannot parse request state for sympa request %s: %s",
                     request["request_id"], request["state_data"])
        return True

    try:
        listname = state["listname"]
        host = state["run_host"]
    except KeyError:
        logger.error("No listname/runhost specified for request %s",
                     request["request_id"])
        return True

    cmd = [cereconf.SYMPA_SCRIPT, host, 'rmlist', listname]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #9
0
def proc_sympa_remove(request):
    """Execute the request for removing a sympa mailing list.

    :type request: db_row
    :param request:
      A dict-like object containing all the parameters for sympa list
      removal.
    """

    try:
        state = json.loads(request["state_data"])
    except ValueError:
        state = None

    # Remove this when there's no chance of pickled data
    if state is None:
        try:
            state = pickle.loads(request["state_data"])
        except Exception:
            pass

    if state is None:
        logger.error("Cannot parse request state for sympa request %s: %s",
                     request["request_id"], request["state_data"])
        return True

    try:
        listname = state["listname"]
        host = state["run_host"]
    except KeyError:
        logger.error("No listname/runhost specified for request %s",
                     request["request_id"])
        return True

    cmd = [cereconf.SYMPA_SCRIPT, host, 'rmlist', listname]
    return Utils.spawn_and_log_output(cmd) == EXIT_SUCCESS
예제 #10
0
def email_move_child(host, r):
    local_db = Utils.Factory.get('Database')()
    local_co = Utils.Factory.get('Constants')(local_db)
    r_id = r['request_id']
    if not is_valid_request(r_id, local_db=local_db, local_co=local_co):
        return
    if dependency_pending(r['state_data'], local_db=local_db,
                          local_co=local_co):
        logger.debug("Request '%d' still has deps: '%s'.",  r_id,
                     r['state_data'])
        return
    try:
        acc = get_account(r['entity_id'], local_db=local_db)
    except Errors.NotFoundError:
        logger.error("email_move: user %d not found",
                     r['entity_id'])
        return
    old_server = get_email_server(r['entity_id'], local_db=local_db)
    new_server = Email.EmailServer(local_db)
    new_server.find(r['destination_id'])
    if old_server.entity_id == new_server.entity_id:
        logger.error("Trying to move %s from " % acc.account_name +
                     "and to the same server! Deleting request")
        br = BofhdRequests(local_db, local_co)
        br.delete_request(request_id=r_id)
        local_db.commit()
        return
    if not email_delivery_stopped(acc.account_name):
        logger.debug("E-mail delivery not stopped for %s",
                     acc.account_name)
        return
    logger.debug("User being moved: '%s'.",  acc.account_name)
    reqlock = RequestLockHandler()
    if not reqlock.grab(r_id):
        return
    # Disable quota while copying so the move doesn't fail
    cyrus_set_quota(acc.entity_id, 0, host=new_server, local_db=local_db)
    # Call the script
    cmd = [SSH_CMD, "cerebrum@%s" % host, cereconf.IMAPSYNC_SCRIPT,
           '--user1', acc.account_name, '--host1', old_server.name,
           '--user2', acc.account_name, '--host2', new_server.name,
           '--authusing', cereconf.CYRUS_ADMIN,
           '--passfile1', '/etc/cyrus.pw',
           '--useheader', 'Message-ID',
           '--regexmess', 's/\\0/ /g',
           '--ssl', '--subscribe', '--nofoldersizes']
    proc = subprocess.Popen(cmd, capturestderr=True, bufsize=10240,
                            close_fds=True, stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    pid = proc.pid
    logger.debug("Called cmd(%d): '%s'", pid, cmd)
    proc.stdin.close()
    # Stolen from Utils.py:spawn_and_log_output()
    descriptor = {proc.stdout: logger.debug,
                  proc.stderr: logger.info}
    while descriptor:
        # select() is called for _every_ line, since we can't inspect
        # the buffering in Python's file object.  This works OK since
        # select() will return "readable" for an unread EOF, and
        # Python won't read the EOF until the buffers are exhausted.
        ready, x, x = select(descriptor.keys(), [], [])
        for fd in ready:
            line = fd.readline()
            if line == '':
                fd.close()
                del descriptor[fd]
            else:
                descriptor[fd]("[%d] %s" % (pid, line.rstrip()))
    status = proc.wait()
    if status == EXIT_SUCCESS:
        logger.debug("[%d] Completed successfully", pid)
    elif os.WIFSIGNALED(status):
        # The process was killed by a signal.
        sig = os.WTERMSIG(status)
        logger.warning('[%d] Command "%r" was killed by signal %d',
                       pid, cmd, sig)
        return
    else:
        # The process exited with an exit status
        sig = os.WSTOPSIG(status)
        logger.warning("[%d] Return value was %d from command %r",
                       pid, sig, cmd)
        return
    # Need move SIEVE filters as well
    cmd = [cereconf.MANAGESIEVE_SCRIPT,
           '-v', '-a', cereconf.CYRUS_ADMIN, '-p', pwfile,
           acc.account_name, old_server.name, new_server.name]
    if Utils.spawn_and_log_output(
            cmd,
            connect_to=[old_server.name, new_server.name]) != 0:
        logger.warning('%s: managesieve_sync failed!', acc.account_name)
        return
    logger.info('%s: managesieve_sync completed successfully',
                acc.account_name)
    # The move was successful, update the user's server
    # Now set the correct quota.
    hq = get_email_hardquota(acc.entity_id, local_db=local_db)
    cyrus_set_quota(acc.entity_id, hq, host=new_server, local_db=local_db)
    et = Email.EmailTarget(local_db)
    et.find_by_target_entity(acc.entity_id)
    et.email_server_id = new_server.entity_id
    et.write_db()
    # We need to delete this request before adding the
    # delete to avoid triggering the conflicting request
    # test.
    br = BofhdRequests(local_db, local_co)
    br.delete_request(request_id=r_id)
    local_db.commit()
    br.add_request(r['requestee_id'], r['run_at'],
                   local_co.bofh_email_delete,
                   r['entity_id'], old_server.entity_id)
    local_db.commit()
    logger.info("%s: move_email success.", acc.account_name)
    reqlock.release()