static int linuxset_user_group(char *user, int uid, int gid){
	if (set_caps(CAPS)!=0) __abort(-1,getuid()!= uid,"set_caps(CAPS) failed");
	__abort(-1,(prctl(PR_SET_KEEPCAPS,1,0,0,0) < 0),"prctl failed in linuxset_user_group");
	__abort(-1,(set_user_group(user,uid,gid)!=0),"set_user_group failed in linuxset_user_group");
	if (set_caps(CAPSMIN)!=0) __abort(-1,(getuid()!= uid),"set_caps(CAPSMIN) failed");
	return 0;
}
Пример #2
0
static bool checkuser(char *user, uid_t * uid, gid_t * gid)
{
    struct passwd *pwds = NULL;
    int status = 0;
    pid_t pid  = 0;

    /* Do we actually _have_ to switch user? */
    if (user == NULL)
        return true;

    pwds = getpwnam(user);
    if (pwds == NULL) {
        log_error("Invalid user name '%s' specified", user);
        return false;
    }

    *uid = pwds->pw_uid;
    *gid = pwds->pw_gid;

    /* Validate the user name in another process */
    pid = fork();
    if (pid == -1) {
        log_error("Cannot validate user name");
        return false;
    }

    /* If we're in the child process, let's validate */
    if (pid == 0) {
        if (set_user_group(user, *uid, *gid) != 0)
            exit(1);
        /* If we got here we switched user/group */
        exit(0);
    }

    while (waitpid(pid, &status, 0) != pid) {
        /* Just wait */
    }

    /* The child must have exited cleanly */
    if (WIFEXITED(status)) {
        status = WEXITSTATUS(status);

        /* If the child got out with 0 the user is ok */
        if (status == 0) {
            log_debug("User '%s' validated", user);
            return true;
        }
    }

    log_error("Error validating user '%s'", user);
    return false;
}
Пример #3
0
static int linuxset_user_group(const char *user, int uid, int gid)
{
    int caps_set = 0;

    if (user == NULL)
        return 0;
    /* set capabilities enough for binding port 80 setuid/getuid */
    if (getuid() == 0) {
        if (set_caps(CAPS) != 0) {
            if (getuid() != uid) {
                log_error("set_caps(CAPS) failed for user '%s'", user);
                return -1;
            }
            log_debug("set_caps(CAPS) failed for user '%s'", user);
        }
        /* make sure they are kept after setuid */
        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
            log_error("prctl failed in for user '%s'", user);
            return -1;
        }
        caps_set = 1;
    }

    /* set setuid/getuid */
    if (set_user_group(user, uid, gid) != 0) {
        log_error("set_user_group failed for user '%s'", user);
        return -1;
    }

    if (caps_set) {
        /* set capability to binding port 80 read conf */
        if (set_caps(CAPSMIN) != 0) {
            if (getuid() != uid) {
                log_error("set_caps(CAPSMIN) failed for user '%s'", user);
                return -1;
            }
            log_debug("set_caps(CAPSMIN) failed for user '%s'", user);
        }
    }

    return 0;
}
static int checkuser( char *user, uid_t *uid, gid_t *gid ) {
	struct passwd *pwds = NULL;
	int status = 0;
	pid_t pid = 0;
	__abort(1, user == NULL,"" );
	pwds = getpwnam( user );
	__abort(0, (pwds == NULL ),"Invalid user name '%s' specified", user );
	*uid = pwds->pw_uid;
	*gid = pwds->pw_gid;
	pid = fork( );
	__abort(0,( pid == -1 ), "Cannot validate user name" );
	if( pid == 0 ) {
		__die( set_user_group( user, *uid, *gid ) != 0,"set_user_group failed." );
		exit( 0 );
	}
	while( waitpid( pid, &status, 0 ) != pid );
	if( WIFEXITED( status ) ) {
		status = WEXITSTATUS( status );
		__abort(0, (status != 0),"User '%s' validated", user );
	}
	return 1;
}
Пример #5
0
static int child(arg_data *args, home_data *data, uid_t uid, gid_t gid)
{
    int ret = 0;

    /* check the pid file */
    ret = check_pid(args);
    if (args->vers != true && args->chck != true) {
        if (ret == 122)
            return ret;
        if (ret < 0)
            return ret;
    }

#ifdef OS_LINUX
    /* setuid()/setgid() only apply the current thread so we must do it now */
    if (linuxset_user_group(args->user, uid, gid) != 0)
        return 4;
#endif
    /* Initialize the Java VM */
    if (java_init(args, data) != true) {
        log_debug("java_init failed");
        return 1;
    }
    else
        log_debug("java_init done");

    /* Check wether we need to dump the VM version */
    if (args->vers == true) {
        log_error("jsvc (Apache Commons Daemon) " JSVC_VERSION_STRING);
        log_error("Copyright (c) 1999-2011 Apache Software Foundation.");
        if (java_version() != true) {
            return -1;
        }
        else
            return 0;
    }
    /* Check wether we need to dump the VM version */
    else if (args->vershow == true) {
        if (java_version() != true) {
            return 7;
        }
    }

    /* Do we have to do a "check-only" initialization? */
    if (args->chck == true) {
        if (java_check(args) != true)
            return 2;
        printf("Service \"%s\" checked successfully\n", args->clas);
        return 0;
    }

    /* Load the service */
    if (java_load(args) != true) {
        log_debug("java_load failed");
        return 3;
    }
    else
        log_debug("java_load done");

    /* Downgrade user */
#ifdef OS_LINUX
    if (args->user && set_caps(0) != 0) {
        log_debug("set_caps (0) failed");
        return 4;
    }
#else
    if (set_user_group(args->user, uid, gid) != 0)
        return 4;
#endif

    /* Start the service */
    umask(envmask);
    if (java_start() != true) {
        log_debug("java_start failed");
        return 5;
    }
    else
        log_debug("java_start done");

    /* Install signal handlers */
    handler_hup = signal_set(SIGHUP, handler);
    handler_usr1 = signal_set(SIGUSR1, handler);
    handler_usr2 = signal_set(SIGUSR2, handler);
    handler_trm = signal_set(SIGTERM, handler);
    handler_int = signal_set(SIGINT, handler);
    controlled = getpid();

    log_debug("Waiting for a signal to be delivered");
    create_tmp_file(args);
    while (!stopping) {
#if defined(OSD_POSIX)
        java_sleep(60);
        /* pause(); */
#else
        /* pause() is not threadsafe */
        sleep(60);
#endif
        if(doreopen) {
            doreopen = false;
            set_output(args->outfile, args->errfile, args->redirectstdin, args->procname);
        }
        if(dosignal) {
            dosignal = false;
            java_signal();
        }
    }
    remove_tmp_file(args);
    log_debug("Shutdown or reload requested: exiting");

    /* Stop the service */
    if (java_stop() != true)
        return 6;

    if (doreload == true)
        ret = 123;
    else
        ret = 0;

    /* Destroy the service */
    java_destroy();

    /* Destroy the Java VM */
    if (JVM_destroy(ret) != true)
        return 7;

    return ret;
}