Post visibility option to theme front-end for author to select?

Wherever you want to provide this functionality, put the following:

<?php
    if (is_user_logged_in() && current_user_can('publish_posts')) {
        $ID = get_the_ID();
        $status = get_post_status($ID);
?>
        Visibility:
        <form id="update_post_visibility" name="update_post_visibility" method="post" action="/update-post-visibility">
            <input id="visibility-radio-public" type="radio" <?php if (('publish' === $status) && ! post_password_required($ID)) echo 'checked="checked" '; ?>value="public" name="visibility" />
            <label for="visibility-radio-public">Public</label>
            <br />
            <input id="visibility-radio-password" type="radio" <?php if (('publish' === $status) && post_password_required($ID)) echo 'checked="checked" '; ?>value="password" name="visibility">
            <label for="visibility-radio-password">Password:</label>
            <br />
            <input id="post_password" type="text" value="" name="post_password">
            <br />
            <input id="visibility-radio-private" type="radio" <?php if ('private' === $status) echo 'checked="checked" '; ?>value="private" name="visibility">
            <label for="visibility-radio-private">Private</label>
            <br />
            <input type="hidden" name="post_id" value="<?php echo $ID; ?>" />
            <input type="hidden" name="action" value="update_post_visibility" />
            <input id="submit" type="submit" value="Update" name="submit" />
        </form>
<?php
    }
?>

If you want, for instance, to provide this for single posts only, put the code right after the_post in your single.php file.

Note: You have to be in the Loop to use this.

Then create a (private) page (in your WordPress admin) having update-post-visibility as slug (or choose whatever you want, but adjust the action= of the above form).
The content of that page is as follows:

<?php
    if ('POST' === $_SERVER['REQUEST_METHOD']
        && ! empty($_POST['action'])
        && 'update_post_visibility' === $_POST['action']
        && isset($_POST['post_id'])
    ) {
        $post = array();
        $post['ID'] = $_POST['post_id'];
        switch ($_POST['visibility']) {
            case 'private':
                $post['post_status'] = 'private';
                break;
            case 'public':
                $post['post_status'] = 'publish';
                $post['post_password'] = '';
                break;
            case 'password':
                $post['post_status'] = 'publish';
                $post['post_password'] = $_POST['post_password'];
                break;
        }
        wp_update_post($post);
    }
?>