예제 #1
0
bool sys_setresgid( int sc_num, pid_t pid, pid_state *state )
{
    if( state->state==pid_state::NONE ) {
        // Do we let the syscall proceed?
        state->context_state[0]=ptlib_get_argument( pid, 1 ); //rgid
        state->context_state[1]=ptlib_get_argument( pid, 2 ); //egid
        state->context_state[2]=ptlib_get_argument( pid, 3 ); //sgid

        // NOP the actual call
        ptlib_set_syscall( pid, PREF_NOP );
        state->state=pid_state::REDIRECT2;
    } else if( state->state==pid_state::REDIRECT2 ) {
        // Let's see if we want to perform the action
        bool success=true;
        gid_t new_gid=state->gid, new_egid=state->egid, new_sgid=state->sgid;

        if( state->context_state[0]!=(int_ptr)-1 ) {
            if( check_gids( state->context_state[0], state ) )
                new_gid=state->context_state[0];
            else
                success=false;
        }

        if( state->context_state[1]!=(int_ptr)-1 ) {
            if( success && check_gids( state->context_state[1], state ) )
                new_egid=state->context_state[1];
            else
                success=false;
        }

        if( state->context_state[2]!=(int_ptr)-1 ) {
            if( success && check_gids( state->context_state[2], state ) )
                new_sgid=state->context_state[2];
            else
                success=false;
        }

        // If all checks passed, commit the changes
        if( success ) {
            state->gid=new_gid;
            state->egid=new_egid;
            state->sgid=new_sgid;

            ptlib_set_retval( pid, 0 );
        } else {
            ptlib_set_error( pid, state->orig_sc, EPERM );
        }

        state->state=pid_state::NONE;
    }

    return true;
}
예제 #2
0
bool sys_setfsgid( int sc_num, pid_t pid, pid_state *state )
{
    if( state->state==pid_state::NONE ) {
        // Do we let the syscall proceed?
        state->context_state[0]=ptlib_get_argument( pid, 1 );

        // NOP the actual call
        ptlib_set_syscall( pid, PREF_NOP );
        state->state=pid_state::REDIRECT2;
    } else if( state->state==pid_state::REDIRECT2 ) {
        // Let's see if we want to perform the action
        gid_t gid=(gid_t)state->context_state[0];
        gid_t old_fsgid=state->fsgid;

        if( check_gids( gid, state ) ) {
            state->fsgid=gid;
        } else {
            // No permission - nothing to do
        }

        ptlib_set_retval( pid, old_fsgid );

        state->state=pid_state::NONE;
    }

    return true;
}
예제 #3
0
bool sys_setegid( int sc_num, pid_t pid, pid_state *state )
{
    if( state->state==pid_state::NONE ) {
        // Save the original arguments
        state->context_state[0]=ptlib_get_argument( pid, 1 );

        // NOP the actual call
        ptlib_set_syscall( pid, PREF_NOP );
        state->state=pid_state::REDIRECT2;
    } else if( state->state==pid_state::REDIRECT2 ) {
        // Let's see if we want to perform the action
        gid_t gid=(gid_t)state->context_state[0];

        if( check_gids( gid, state ) ) {
            state->egid=state->fsgid=gid;
            ptlib_set_retval( pid, 0 );
        } else {
            // No permission
            ptlib_set_error( pid, state->orig_sc, EPERM );
        }

        state->state=pid_state::NONE;
    }

    return true;
}
예제 #4
0
bool sys_setregid( int sc_num, pid_t pid, pid_state *state )
{
    if( state->state==pid_state::NONE ) {
        // Do we let the syscall proceed?
        state->context_state[0]=ptlib_get_argument( pid, 1 ); //rgid
        state->context_state[1]=ptlib_get_argument( pid, 2 ); //egid

        // NOP the actual call
        ptlib_set_syscall( pid, PREF_NOP );
        state->state=pid_state::REDIRECT2;
    } else if( state->state==pid_state::REDIRECT2 ) {
        // Let's see if we want to perform the action
        bool success=true;
        gid_t new_gid=state->gid, new_egid=state->egid, new_sgid=state->sgid;

        if( state->context_state[0]!=(int_ptr)-1 ) {
            // XXX Linux specific behavior
            if( state->egid==ROOT_GID || state->context_state[0]==state->gid || state->context_state[0]==state->sgid )
                new_gid=state->context_state[0];
            else
                success=false;
        }

        if( state->context_state[1]!=(int_ptr)-1 ) {
            if( success && check_gids( state->context_state[1], state ) )
                new_egid=state->context_state[1];
            else
                success=false;
        }

        // There is no POSIX documentation on what should happen to the saved UID. The following is the Linux logic
        if( success && (state->context_state[0]!=(int_ptr)-1 || 
                    ( state->context_state[1]!=(int_ptr)-1 && state->context_state[1]!=state->gid )) )
        {
            new_sgid=new_egid;
        }

        // If all checks passed, commit the changes
        if( success ) {
            state->gid=new_gid;
            state->egid=state->fsgid=new_egid;
            state->sgid=new_sgid;

            ptlib_set_retval( pid, 0 );
        } else {
            ptlib_set_error( pid, state->orig_sc, EPERM );
        }

        state->state=pid_state::NONE;
    }

    return true;
}
예제 #5
0
void test_ncache_both_gid(void **state)
{
    errno_t ret;
    struct ncache_test_ctx *test_ctx;

    test_ctx = talloc_get_type_abort(*state, struct ncache_test_ctx);
    assert_non_null(test_ctx);

    ret = sss_ncache_init(test_ctx, TIMEOUT, TIMEOUT, &test_ctx->ncache);
    assert_int_equal(ret, EOK);

    set_gids(test_ctx);

    check_gids(test_ctx, EEXIST, ENOENT, EEXIST, ENOENT);

    talloc_zfree(test_ctx->ncache);
}