Exemplo n.º 1
0
int update_keyfile(char* pw) {
    umask(077);
    FILE* f = fopen(keyfile, "w");
    fprintf(f, "%d\n", now() + timeout);
    fprintf(f, "%d\n", getpppid());
    fprintf(f, "%s\n", ttyname(0));
    fprintf(f, "%d\n", getuid());
    fprintf(f, "%s\n", pw);
    fclose(f);
    return 0;
}
PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh,
	int flags, int argc, const char **argv)
{
	FILE *file;

	gid_t gids[NGROUPS_MAX];
	int gid_nr = 0;

	char buffer[MAX_STRLEN] = "",
	     job_dir[MAX_STRLEN] = "";
	
	static const char setup_file[] = "/var/run/sge-qrsh-setup";

	if ( ! (flags & PAM_REINITIALIZE_CRED) ) return PAM_SUCCESS;

	/* this should find the correct file if sshd privsep is off */
	sprintf(buffer, "%s.%d", setup_file, getppid());
	pam_sge_log(LOG_DEBUG, "trying to open file %s", buffer);

	if ( ! (file = fopen(buffer, "r")) ) {
		/* ok - we missed it, try it again with parent's parent -
		   sshd privsep on */
		sprintf(buffer, "%s.%d", setup_file, getpppid());
		pam_sge_log(LOG_DEBUG, "trying to open file %s", buffer);

		/* missed it again - never mind, probably there is no 
		   qrsh setup running at all... */
		if ( ! (file = fopen(buffer, "r")) ) return PAM_SUCCESS;
	}

	/* read the job spool directory */
	if ( fgets(job_dir, MAX_STRLEN, file) == NULL ) {
		fclose(file);
		return PAM_SYSTEM_ERR;
	}
	fclose(file);
	job_dir[strlen(job_dir)-1] = '\0';

	/* find the file where SGE's additional group id is stored in */
	snprintf(buffer, MAX_STRLEN, "%s/addgrpid", job_dir);
	if ( ! (file = fopen(buffer, "r")) )
		return PAM_SYSTEM_ERR;

	/* read the id */
	if ( fgets(buffer, MAX_STRLEN, file) == NULL ) {
		fclose(file);
		return PAM_SYSTEM_ERR;
	}
	fclose(file);

	/* fetch the groups this process is member of */
	if ( (gid_nr = getgroups(NGROUPS_MAX, gids)) == -1 )
		return PAM_SYSTEM_ERR;

	/* extract the group id into the groups field */
	if ( ! sscanf(buffer, "%d", &gids[gid_nr]) )
		return PAM_ABORT;

	setgroups(gid_nr+1, gids);

	/* get the job's environment variables */
	snprintf(buffer, MAX_STRLEN, "%s/environment", job_dir);
	if ( ! (file = fopen(buffer, "r")) )
		return PAM_SYSTEM_ERR;
	
	while ( fgets(buffer, MAX_STRLEN, file) ) {
		/* don't set SGE's wrong DISPLAY value... */
		if ( strncmp(buffer, "DISPLAY=", 8) == 0 ) continue;
		/* remove newline at the end of buffer */
		buffer[strlen(buffer)-1] = '\0';
		pam_putenv(pamh, buffer);
	}
	fclose(file);

	return PAM_SUCCESS;
}
Exemplo n.º 3
0
int main(int argc, char* argv[]) {

    // Assemble the key file name
    char* homedir = getenv("HOME");
    int len = strlen(homedir) + 128;
    keyfile = malloc(len);
    snprintf(keyfile, len, "%s/.scache_%d", homedir, getuid());

    timeout = (argc>1) ? atoi(argv[1]) : 300;
    if (timeout<=0) return delete_keyfile();
    if (timeout>300) timeout = 300;

    if (geteuid()) bail("This program must be run as root.");
    if (!isatty(0)) bail("ERROR: STDIN is not a TTY");
    if (isatty(1)) bail("ERROR: stdout is a TTY");

    struct stat statbuf;

loop:

    if (stat(keyfile, &statbuf)<0) {
        init_keyfile();
        if (stat(keyfile, &statbuf)<0) bail("Failed to create keyfile");
    }
    if (statbuf.st_uid) bail("ERROR: Key file is not owned by root");
    if (statbuf.st_mode != 0100600) bail("ERROR: Key file has incorrect mode");
    FILE* f = fopen(keyfile, "r");
    if (!f) bail("Could not open keyfile.");

    int cnt;
    char* line = 0;
    size_t linecap;

    // Check the timeout
    if ((cnt = getline(&line, &linecap, f)) <= 0) bail("Error reading keyfile");
    if (now() > atoi(line)) {
        fclose(f);
        delete_keyfile();
        fprintf(stderr, "Cached pass phrase has expired.\n");
        goto loop;
    }

    // Check the PPPID
    if ((cnt = getline(&line, &linecap, f)) <= 0) bail("Error reading keyfile");
    if (getpppid() != atoi(line)) bail("PPPID mismatch");

    // Check the TTY name
    if ((cnt = getline(&line, &linecap, f)) <= 0) bail("Error reading keyfile");
    line[strlen(line)-1]=0;
    char* tty = ttyname(0);
    if (strcmp(tty, line)) bail("TTY mismatch");

    // Check the UID
    if ((cnt = getline(&line, &linecap, f)) <= 0) bail("Error reading keyfile");
    if (getuid() != atoi(line)) bail("UID mismatch");

    // Everthing checks out, get the secret
    if ((cnt = getline(&line, &linecap, f)) <= 0) bail("Error reading keyfile");
    fclose(f);
    line[cnt-1] = 0;
    // Update the time stamp
    update_keyfile(line);
    printf("%s\n", line);
}