Пример #1
0
int iruserok(unsigned long raddr, int superuser,
    const char *ruser, const char *luser)
{
    /* Returns 0 if ok, -1 if not ok. */
    struct passwd *pwd;
    FILE *hostf;
    int i, r;
    char pbuf[PATH_MAX];

    for (i = 0; i < 2; i++) {
	if (i == 0) {
	    strcpy(pbuf, _PATH_HEQUIV);
	} else {
	    if (!__check_rhosts_file) return (-1);
	    if ((pwd = getpwnam(luser)) == NULL) return (-1);
	    (void)strcpy(pbuf, pwd->pw_dir);
	    (void)strcat(pbuf, "/.rhosts");
	}

	if ((hostf = fopen(pbuf, "r")) == NULL)
	{
		if (errno == ENOENT)
			continue;
		return (-1);
	}

	r = __ivaliduser(hostf, raddr, luser, ruser);
	(void)fclose(hostf);
	if (r == 0) return (0);
    }
    return (-1);
}
Пример #2
0
/*
 * New .rhosts strategy: We are passed an ip address. We spin through
 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
 * has ip addresses, we don't have to trust a nameserver.  When it
 * contains hostnames, we spin through the list of addresses the nameserver
 * gives us and look for a match.
 *
 * Returns 0 if ok, -1 if not ok.
 */
int ROKEN_LIB_FUNCTION
iruserok(unsigned raddr, int superuser, const char *ruser, const char *luser)
{
    char *cp;
    struct stat sbuf;
    struct passwd *pwd;
    FILE *hostf;
    uid_t uid;
    int first;
    char pbuf[MaxPathLen];

    first = 1;
    hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
again:
    if (hostf) {
        if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
            fclose(hostf);
            return (0);
        }
        fclose(hostf);
    }
    if (first == 1 && (__check_rhosts_file || superuser)) {
        first = 0;
        if ((pwd = k_getpwnam((char*)luser)) == NULL)
            return (-1);
        snprintf (pbuf, sizeof(pbuf), "%s/.rhosts", pwd->pw_dir);

        /*
         * Change effective uid while opening .rhosts.  If root and
         * reading an NFS mounted file system, can't read files that
         * are protected read/write owner only.
         */
        uid = geteuid();
        if (seteuid(pwd->pw_uid) < 0)
            return (-1);
        hostf = fopen(pbuf, "r");
        seteuid(uid);

        if (hostf == NULL)
            return (-1);
        /*
         * If not a regular file, or is owned by someone other than
         * user or root or if writeable by anyone but the owner, quit.
         */
        cp = NULL;
        if (lstat(pbuf, &sbuf) < 0)
            cp = ".rhosts lstat failed";
        else if (!S_ISREG(sbuf.st_mode))
            cp = ".rhosts not regular file";
        else if (fstat(fileno(hostf), &sbuf) < 0)
            cp = ".rhosts fstat failed";
        else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
            cp = "bad .rhosts owner";
        else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
            cp = ".rhosts writeable by other than owner";
        /* If there were any problems, quit. */
        if (cp) {
            __rcmd_errstr = cp;
            fclose(hostf);
            return (-1);
        }
        goto again;
    }
    return (-1);
}
Пример #3
0
static int
pam_iruserok(pam_handle_t *pamh,
	 struct _options *opts, U32 raddr, int superuser,
	 const char *ruser, const char *luser, const char *rhost)
{
    const char *cp;
    struct stat sbuf;
    struct passwd *pwd;
    FILE *hostf;
    uid_t uid;
    int answer;
    char pbuf[MAXPATHLEN];               /* potential buffer overrun */

    if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) {

	/* try to open system hosts.equiv file */
	hostf = fopen (_PATH_HEQUIV, "r");
	if (hostf) {
	    answer = __ivaliduser(pamh, opts, hostf, raddr, luser
				  , ruser, rhost);
	    (void) fclose(hostf);
	    if (answer == 0)
		return 0;      /* remote host is equivalent to localhost */
	} /* else {
	    No hosts.equiv file on system.
	} */
    }
    
    if ( opts->opt_no_rhosts )
	return 1;

    /*
     * Identify user's local .rhosts file
     */

    pwd = _pammodutil_getpwnam(pamh, luser);
    if (pwd == NULL) {
	/* 
	 * luser is assumed to be valid because of an earlier check for uid = 0
	 * we don't log this error twice. However, this shouldn't happen !
	 * --cristiang 
	 */
	return(1);
    }

    /* check for buffer overrun */
    if (strlen(pwd->pw_dir) + sizeof(USER_RHOSTS_FILE) + 2 >= MAXPATHLEN) {
	if (opts->opt_debug)
	    _pam_log(LOG_DEBUG,"home directory for `%s' is too long", luser);
	return 1;                               /* to dangerous to try */
    }

    (void) strcpy(pbuf, pwd->pw_dir);
    (void) strcat(pbuf, USER_RHOSTS_FILE);

    /*
     * Change effective uid while _reading_ .rhosts. (not just
     * opening).  If root and reading an NFS mounted file system,
     * can't read files that are 0600 as .rhosts files should be.
     */

    /* We are root, this will not fail */
#ifdef linux
    /* If we are on linux the better way is setfsuid */
    uid = setfsuid(pwd->pw_uid);
    hostf = fopen(pbuf, "r");
#else
    uid = geteuid();
    (void) seteuid(pwd->pw_uid);
    hostf = fopen(pbuf, "r");
#endif

    if (hostf == NULL) {
        if (opts->opt_debug)
	    _pam_log(LOG_DEBUG,"Could not open %s file",pbuf);
	answer = 1;
	goto exit_function;
    }

    /*
     * If not a regular file, or is owned by someone other than
     * user or root or if writeable by anyone but the owner, quit.
     */

    cp = NULL;
    if (lstat(pbuf, &sbuf) < 0 || !S_ISREG(sbuf.st_mode))
	cp = ".rhosts not regular file";
    else if (fstat(fileno(hostf), &sbuf) < 0)
	cp = ".rhosts fstat failed";
    else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
	cp = "bad .rhosts owner";
    else if (sbuf.st_mode & S_IWOTH)
	cp = ".rhosts writable by other!";
    else if (sbuf.st_mode & S_IWGRP) {

	/* private group caveat */
	if (opts->opt_private_group) {
	    struct group *grp = getgrgid(sbuf.st_gid);

	    if (NULL == grp || NULL == grp->gr_name
		|| strcmp(luser,grp->gr_name)) {
		cp = ".rhosts writable by public group";
	    } else if (grp->gr_mem) {
		int gcount;

		/* require at most one member (luser) of this group */
		for (gcount=0; grp->gr_mem[gcount]; ++gcount) {
		    if (strcmp(grp->gr_mem[gcount], luser)) {
			gcount = -1;
			break;
		    }
		}
		if (gcount < 0) {
		    cp = ".rhosts writable by other members of group";
		}
	    }
	} else {
	    cp = ".rhosts writable by group";
	}

    } /* It is _NOT_ safe to append an else here...  Do so prior to
       * S_IWGRP check */

    /* If there were any problems, quit. */
    if (cp) {
	opts->last_error = cp;
	answer = 1;
	goto exit_function;
    }

    answer = __ivaliduser (pamh, opts, hostf, raddr, luser, ruser, rhost);

exit_function:
    /*
     * Go here to exit after the fsuid/euid has been adjusted so that
     * they are reset before we exit.
     */

#ifdef linux
    setfsuid(uid);
#else
    (void)seteuid(uid);
#endif

    if (hostf != NULL)
        (void) fclose(hostf);

    return answer;
}