Exemple #1
0
static void
krb5_get_afs_tokens (const struct passwd *pwd)
{
    char cell[64];
    char *pw_dir;
    krb5_error_code ret;

    if (!k_hasafs ())
	return;

    ret = krb5_cc_default(context, &id2);

    if (ret == 0) {
	pw_dir = pwd->pw_dir;

	if (!pag_set) {
	    k_setpag();
	    pag_set = 1;
	}

	if(k_afs_cell_of_file(pw_dir, cell, sizeof(cell)) == 0)
	    krb5_afslog_uid_home (context, id2,
				  cell, NULL, pwd->pw_uid, pwd->pw_dir);
	krb5_afslog_uid_home (context, id2, NULL, NULL,
			      pwd->pw_uid, pwd->pw_dir);
	krb5_cc_close (context, id2);
    }
}
Exemple #2
0
krb5_error_code
krb5_afslog_home(krb5_context context,
		 krb5_ccache id,
		 const char *cell,
		 krb5_const_realm realm,
		 const char *homedir)
{
    return krb5_afslog_uid_home (context, id, cell, realm, getuid(), homedir);
}
Exemple #3
0
krb5_error_code
krb5_afslog_uid(krb5_context context,
		krb5_ccache id,
		const char *cell,
		krb5_const_realm realm,
		uid_t uid)
{
    return krb5_afslog_uid_home (context, id, cell, realm, uid, NULL);
}
Exemple #4
0
static void
doit (void)
{
    u_char buf[BUFSIZ];
    u_char *p;
    struct sockaddr_storage thisaddr_ss;
    struct sockaddr *thisaddr = (struct sockaddr *)&thisaddr_ss;
    struct sockaddr_storage thataddr_ss;
    struct sockaddr *thataddr = (struct sockaddr *)&thataddr_ss;
    struct sockaddr_storage erraddr_ss;
    struct sockaddr *erraddr = (struct sockaddr *)&erraddr_ss;
    socklen_t thisaddr_len, thataddr_len;
    int port;
    int errsock = -1;
    char *client_user = NULL, *server_user = NULL, *cmd = NULL;
    struct passwd *pwd;
    int s = STDIN_FILENO;
    char **env;
    int ret;
    char that_host[NI_MAXHOST];

    thisaddr_len = sizeof(thisaddr_ss);
    if (getsockname (s, thisaddr, &thisaddr_len) < 0)
	syslog_and_die("getsockname: %s", strerror(errno));
    thataddr_len = sizeof(thataddr_ss);
    if (getpeername (s, thataddr, &thataddr_len) < 0)
	syslog_and_die ("getpeername: %s", strerror(errno));

    /* check for V4MAPPED addresses? */

    if (do_kerberos == 0 && !is_reserved(socket_get_port(thataddr)))
	fatal(s, NULL, "Permission denied.");

    p = buf;
    port = 0;
    for(;;) {
	if (net_read (s, p, 1) != 1)
	    syslog_and_die ("reading port number: %s", strerror(errno));
	if (*p == '\0')
	    break;
	else if (isdigit(*p))
	    port = port * 10 + *p - '0';
	else
	    syslog_and_die ("non-digit in port number: %c", *p);
    }

    if (do_kerberos  == 0 && !is_reserved(htons(port)))
	fatal(s, NULL, "Permission denied.");

    if (port) {
	int priv_port = IPPORT_RESERVED - 1;

	/*
	 * There's no reason to require a ``privileged'' port number
	 * here, but for some reason the brain dead rsh clients
	 * do... :-(
	 */

	erraddr->sa_family = thataddr->sa_family;
	socket_set_address_and_port (erraddr,
				     socket_get_address (thataddr),
				     htons(port));

	/*
	 * we only do reserved port for IPv4
	 */

	if (erraddr->sa_family == AF_INET)
	    errsock = rresvport (&priv_port);
	else
	    errsock = socket (erraddr->sa_family, SOCK_STREAM, 0);
	if (errsock < 0)
	    syslog_and_die ("socket: %s", strerror(errno));
	if (connect (errsock,
		     erraddr,
		     socket_sockaddr_size (erraddr)) < 0) {
	    syslog (LOG_WARNING, "connect: %s", strerror(errno));
	    close (errsock);
	}
    }

    if(do_kerberos) {
	if (net_read (s, buf, 4) != 4)
	    syslog_and_die ("reading auth info: %s", strerror(errno));

#ifdef KRB5
	    if((do_kerberos & DO_KRB5) &&
	       recv_krb5_auth (s, buf, thisaddr, thataddr,
			       &client_user,
			       &server_user,
			       &cmd) == 0)
		auth_method = AUTH_KRB5;
	    else
#endif /* KRB5 */
		syslog_and_die ("unrecognized auth protocol: %x %x %x %x",
				buf[0], buf[1], buf[2], buf[3]);
    } else {
	if(recv_bsd_auth (s, buf,
			  (struct sockaddr_in *)thisaddr,
			  (struct sockaddr_in *)thataddr,
			  &client_user,
			  &server_user,
			  &cmd) == 0) {
	    auth_method = AUTH_BROKEN;
	    if(do_vacuous) {
		printf("Remote host requires Kerberos authentication\n");
		exit(0);
	    }
	} else
	    syslog_and_die("recv_bsd_auth failed");
    }

    if (client_user == NULL || server_user == NULL || cmd == NULL)
	syslog_and_die("mising client/server/cmd");

    pwd = getpwnam (server_user);
    if (pwd == NULL)
	fatal (s, NULL, "Login incorrect.");

    if (*pwd->pw_shell == '\0')
	pwd->pw_shell = _PATH_BSHELL;

    if (pwd->pw_uid != 0 && access (_PATH_NOLOGIN, F_OK) == 0)
	fatal (s, NULL, "Login disabled.");


    ret = getnameinfo_verified (thataddr, thataddr_len,
				that_host, sizeof(that_host),
				NULL, 0, 0);
    if (ret)
	fatal (s, NULL, "getnameinfo: %s", gai_strerror(ret));

    if (login_access(pwd, that_host) == 0) {
	syslog(LOG_NOTICE, "Kerberos rsh denied to %s from %s",
	       server_user, that_host);
	fatal(s, NULL, "Permission denied.");
    }

#ifdef HAVE_GETSPNAM
    {
	struct spwd *sp;
	long    today;

	sp = getspnam(server_user);
	if (sp != NULL) {
	    today = time(0)/(24L * 60 * 60);
	    if (sp->sp_expire > 0)
		if (today > sp->sp_expire)
		    fatal(s, NULL, "Account has expired.");
	}
    }
#endif


#ifdef HAVE_SETLOGIN
    if (setlogin(pwd->pw_name) < 0)
	syslog(LOG_ERR, "setlogin() failed: %s", strerror(errno));
#endif

#ifdef HAVE_SETPCRED
    if (setpcred (pwd->pw_name, NULL) == -1)
	syslog(LOG_ERR, "setpcred() failure: %s", strerror(errno));
#endif /* HAVE_SETPCRED */

    /* Apply limits if not root */
    if(pwd->pw_uid != 0) {
	 const char *file = _PATH_LIMITS_CONF;
	 read_limits_conf(file, pwd);
    }

    if (initgroups (pwd->pw_name, pwd->pw_gid) < 0)
	fatal (s, "initgroups", "Login incorrect.");

    if (setgid(pwd->pw_gid) < 0)
	fatal (s, "setgid", "Login incorrect.");

    if (setuid (pwd->pw_uid) < 0)
	fatal (s, "setuid", "Login incorrect.");

    if (chdir (pwd->pw_dir) < 0)
	fatal (s, "chdir", "Remote directory.");

    if (errsock >= 0) {
	if (dup2 (errsock, STDERR_FILENO) < 0)
	    fatal (s, "dup2", "Cannot dup stderr.");
	close (errsock);
    } else {
	if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0)
	    fatal (s, "dup2", "Cannot dup stderr.");
    }

#ifdef KRB5
    {
	int fd;

	if (!do_unique_tkfile)
	    snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_%lu",
		     (unsigned long)pwd->pw_uid);
	else if (*tkfile=='\0') {
	    snprintf(tkfile,sizeof(tkfile),"FILE:/tmp/krb5cc_XXXXXX");
	    fd = mkstemp(tkfile+5);
	    close(fd);
	    unlink(tkfile+5);
	}

	if (kerberos_status)
	    krb5_start_session();
    }
#endif

    setup_environment (&env, pwd);

    if (do_encrypt) {
	setup_copier (errsock >= 0);
    } else {
	if (net_write (s, "", 1) != 1)
	    fatal (s, "net_write", "write failed");
    }

#if defined(KRB5)
    if(k_hasafs()) {
	char cell[64];

	if(do_newpag)
	    k_setpag();

	/* XXX */
       if (kerberos_status) {
	   krb5_ccache ccache;
	   krb5_error_code status;

	   status = krb5_cc_resolve (context, tkfile, &ccache);
	   if (!status) {
	       if (k_afs_cell_of_file (pwd->pw_dir, cell, sizeof(cell)) == 0)
		   krb5_afslog_uid_home(context, ccache, cell, NULL,
					pwd->pw_uid, pwd->pw_dir);
	       krb5_afslog_uid_home(context, ccache, NULL, NULL,
				    pwd->pw_uid, pwd->pw_dir);
	       krb5_cc_close (context, ccache);
	   }
       }
    }
#endif /* KRB5 */
    execle (pwd->pw_shell, pwd->pw_shell, "-c", cmd, NULL, env);
    err(1, "exec %s", pwd->pw_shell);
}
Exemple #5
0
static int
verify_krb5(struct passwd *pwd,
	    char *password,
	    int32_t *exp,
	    int quiet)
{
    krb5_context context;
    krb5_error_code ret;
    krb5_ccache ccache;
    krb5_principal principal;
    
    ret = krb5_init_context(&context);
    if (ret) {
	syslog(LOG_AUTH|LOG_DEBUG, "krb5_init_context failed: %d", ret);
	goto out;
    }

    ret = krb5_parse_name (context, pwd->pw_name, &principal);
    if (ret) {
	syslog(LOG_AUTH|LOG_DEBUG, "krb5_parse_name: %s", 
	       krb5_get_err_text(context, ret));
	goto out;
    }

    set_krb5ccname(pwd->pw_uid);
    ret = krb5_cc_resolve(context, krb5ccname, &ccache);
    if(ret) {
	syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_resolve: %s", 
	       krb5_get_err_text(context, ret));
	goto out;
    }

    ret = krb5_verify_user_lrealm(context,
				  principal,
				  ccache,
				  password,
				  TRUE,
				  NULL);
    if(ret) {
	syslog(LOG_AUTH|LOG_DEBUG, "krb5_verify_user: %s", 
	       krb5_get_err_text(context, ret));
	goto out;
    }

    if(chown(krb5_cc_get_name(context, ccache), pwd->pw_uid, pwd->pw_gid)) {
	syslog(LOG_AUTH|LOG_DEBUG, "chown: %s", 
	       krb5_get_err_text(context, errno));
	goto out;
    }

#ifdef KRB4
    {
	krb5_realm realm = NULL;
	krb5_boolean get_v4_tgt;

	krb5_get_default_realm(context, &realm);
	krb5_appdefault_boolean(context, "afskauthlib", 
				realm,
				"krb4_get_tickets", FALSE, &get_v4_tgt);
	if (get_v4_tgt) {
	    CREDENTIALS c;
	    krb5_creds mcred, cred;

	    krb5_cc_clear_mcred(&mcred);

	    krb5_make_principal(context, &mcred.server, realm,
				"krbtgt",
				realm,
				NULL);
	    ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
	    if(ret == 0) {
		ret = krb524_convert_creds_kdc_ccache(context, ccache, &cred, &c);
		if(ret)
		    krb5_warn(context, ret, "converting creds");
		else {
		    set_krbtkfile(pwd->pw_uid);
		    tf_setup(&c, c.pname, c.pinst); 
		}
		memset(&c, 0, sizeof(c));
		krb5_free_cred_contents(context, &cred);
	    } else
		syslog(LOG_AUTH|LOG_DEBUG, "krb5_cc_retrieve_cred: %s", 
		       krb5_get_err_text(context, ret));
	    
	    krb5_free_principal(context, mcred.server);
	}
	free (realm);
	if (!pag_set && k_hasafs()) {
	    k_setpag();
	    pag_set = 1;
	}

	if (pag_set)
	    krb5_afslog_uid_home(context, ccache, NULL, NULL, 
				 pwd->pw_uid, pwd->pw_dir);
    }
#endif
 out:
    if(ret && !quiet)
	printf ("%s\n", krb5_get_err_text (context, ret));
    return ret;
}