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; }
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; }
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; }
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; }
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); }