static void test_pam_env_functions(void **state) { int rv; const char *v; char **vlist; struct pwrap_test_ctx *test_ctx; test_ctx = (struct pwrap_test_ctx *) *state; rv = pam_putenv(test_ctx->ph, "KEY=value"); assert_int_equal(rv, PAM_SUCCESS); rv = pam_putenv(test_ctx->ph, "KEY2=value2"); assert_int_equal(rv, PAM_SUCCESS); v = pam_getenv(test_ctx->ph, "KEY"); assert_non_null(v); assert_string_equal(v, "value"); v = pam_getenv(test_ctx->ph, "KEY2"); assert_non_null(v); assert_string_equal(v, "value2"); vlist = pam_getenvlist(test_ctx->ph); assert_non_null(vlist); assert_non_null(vlist[0]); assert_string_equal(vlist[0], "KEY=value"); assert_non_null(vlist[1]); assert_string_equal(vlist[1], "KEY2=value2"); assert_null(vlist[2]); free_vlist(vlist); rv = pam_putenv(test_ctx->ph, "KEY2="); assert_int_equal(rv, PAM_SUCCESS); vlist = pam_getenvlist(test_ctx->ph); assert_non_null(vlist); assert_non_null(vlist[0]); assert_string_equal(vlist[0], "KEY=value"); assert_non_null(vlist[1]); assert_string_equal(vlist[1], "KEY2="); assert_null(vlist[2]); free_vlist(vlist); #ifndef HAVE_OPENPAM /* OpenPAM does not support this feature */ rv = pam_putenv(test_ctx->ph, "KEY2"); assert_int_equal(rv, PAM_SUCCESS); vlist = pam_getenvlist(test_ctx->ph); assert_non_null(vlist); assert_non_null(vlist[0]); assert_string_equal(vlist[0], "KEY=value"); assert_null(vlist[1]); free_vlist(vlist); #endif }
/* Terminate session management by destroying old xauthority file. */ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { int i; int debug = 0; const char *xauth; for (i = 0; i < argc; i++) { if (strcmp(argv[i], "debug") == 0) debug = 1; } xauth = pam_getenv(pamh, XAUTH); if (xauth == NULL) { syslog(LOG_ERR, "pam_xauthority: cannot get %s environment variable", XAUTH); return PAM_SESSION_ERR; } if (debug) syslog(LOG_DEBUG, "pam_xauthority: unlinking Xauthority file %s", xauth); if (unlink(xauth) != 0) { syslog(LOG_ERR, "pam_xauthority: unlink: %s", strerror(errno)); return PAM_SESSION_ERR; } return PAM_SUCCESS; }
std::string context::get(const std::string& name, bool* found) { const char* x = pam_getenv(_M_pamh, name.data()); if(found) *found = x; return x ? std::string(x) : std::string(); }
/* sends STOP accounting request to the remote TACACS+ server * returns PAM error only if the request was refused or there * were problems connection to the server */ PAM_EXTERN int pam_sm_close_session (pam_handle_t * pamh, int flags, int argc, const char **argv) { /* Retrieve cmd pam_env */ const char* cmd = pam_getenv(pamh, "cmd"); return _pam_account(pamh, argc, argv, TAC_PLUS_ACCT_FLAG_STOP, cmd); } /* pam_sm_close_session */
static const char* get_env(pam_handle_t *ph, const char *name) { const char *env = pam_getenv (ph, name); if (env && env[0]) { return env; } env = getenv (name); if (env && env[0]) { return env; } return NULL; }
/* * Get the name of a cache. Takes the name of the environment variable that * should be set to indicate which cache to use, either the permanent cache * (KRB5CCNAME) or the temporary cache (PAM_KRB5CCNAME). * * Treat an empty environment variable setting the same as if the variable * was not set, since on FreeBSD we can't delete the environment variable, * only set it to an empty value. */ const char * pamk5_get_krb5ccname(struct pam_args *args, const char *key) { const char *name; /* When refreshing a cache, we need to try the regular environment. */ name = pam_getenv(args->pamh, key); if (name == NULL || *name == '\0') name = getenv(key); if (name == NULL || *name == '\0') return NULL; else return name; }
int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { const char *user = NULL; int pam_err = PAM_SUCCESS; if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) return pam_err; const char *uri = pam_getenv(pamh, PAM_ENV_URI); const char *body = pam_getenv(pamh, PAM_ENV_BODY); const char *method = pam_getenv(pamh, PAM_ENV_METHOD); const char *access = pam_getenv(pamh, PAM_ENV_ACCESS); char buffer[MAX_STR_LENGTH * 6] = {}; sprintf(buffer, "%s='%s' %s='%s' %s='%s' %s='%s' %s='%s', GANETI_PATH='%s'" " python " PAM_LIB_PATH "/ganeti_basic/authorize.py", PAM_ENV_USER, STR(user), PAM_ENV_URI, STR(uri), PAM_ENV_BODY, STR(body), PAM_ENV_METHOD, STR(method), PAM_ENV_ACCESS, STR(access), GANETI_PATH); if (system(buffer)) return PAM_AUTH_ERR; return PAM_SUCCESS; }
const char *getHome(struct passwd *pwd, pam_handle_t * pamh) { const char *tmp = NULL; tmp = pam_getenv(pamh, "HOME"); if (!tmp || *tmp == '\0') { if (pwd->pw_dir && pwd->pw_dir != '\0') return pwd->pw_dir; else return NULL; } else return tmp; }
PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags, int argc, const char **argv) { char *user_name, *service; const char *login_username; unsigned int ctrl; int retval; /* pam_syslog(pamh, LOG_DEBUG, "pam_sm_close_session()"); */ D(("called.")); ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, "close_session - error recovering username"); return PAM_SESSION_ERR; /* How did we get authenticated with no username?! */ } retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, "close_session - error recovering service"); return PAM_SESSION_ERR; } login_username = pam_getenv(pamh, "LOGIN_USER"); if (login_username && (!user_name || (strcmp(login_username, user_name) != 0))) { pam_syslog(pamh, LOG_INFO, "session closed for user %s (%s)" ,login_username ,user_name); } else { pam_syslog(pamh, LOG_INFO, "session closed for user %s", user_name); } return PAM_SUCCESS; }
static const char* get_any_env (pam_handle_t *ph, const char *name) { const char *env; assert (name); /* We only return non-empty variables */ /* * Some PAMs decide to strdup the return value, not sure * how we can detect this. */ env = pam_getenv (ph, name); if (env && env[0]) return env; env = getenv (name); if (env && env[0]) return env; return NULL; }
/* Terminate session management by destroying old temporary file. */ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { int i; int debug = 0; const char *mktemp_buf; const char *var = NULL; for (i = 0; i < argc; i++) { if (strcmp(argv[i], "debug") == 0) debug = 1; else if (strncmp(argv[i], "var=", 4) == 0) var = argv[i] + 4; } if (var == NULL) { syslog(LOG_ERR, "pam_mktemp: Nothing to cleanup"); return PAM_SESSION_ERR; } mktemp_buf = pam_getenv(pamh, var); if (mktemp_buf == NULL) { syslog(LOG_ERR, "pam_mktemp: cannot get %s environment variable", var); return PAM_SESSION_ERR; } if (debug) syslog(LOG_DEBUG, "pam_mktemp: removing %s", mktemp_buf); if (remove(mktemp_buf) != 0) { syslog(LOG_ERR, "pam_mktemp: remove(): %m"); return PAM_SESSION_ERR; } return PAM_SUCCESS; }
const char* Authenticator::getenv(const std::string& key) { return pam_getenv(pam_handle, key.c_str()); }
int main(void) { pam_handle_t *pamh; struct pam_conv conv = { NULL, NULL }; char **env; size_t i; /* * Skip this test if the native PAM library doesn't support a PAM * environment, since we "break" pam_putenv to mirror the native behavior * in that case. */ #ifndef HAVE_PAM_GETENV skip_all("system doesn't support PAM environment"); #endif plan(33); /* Basic environment manipulation. */ if (pam_start("test", NULL, &conv, &pamh) != PAM_SUCCESS) sysbail("Fake PAM initialization failed"); is_int(PAM_BAD_ITEM, pam_putenv(pamh, "TEST"), "delete when NULL"); ok(pam_getenv(pamh, "TEST") == NULL, "getenv when NULL"); env = pam_getenvlist(pamh); ok(env != NULL, "getenvlist when NULL returns non-NULL"); is_string(NULL, env[0], "...but first element is NULL"); for (i = 0; env[i] != NULL; i++) free(env[i]); free(env); /* putenv and getenv. */ is_int(PAM_SUCCESS, pam_putenv(pamh, "TEST=foo"), "putenv TEST"); is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST"); is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=bar"), "putenv FOO"); is_int(PAM_SUCCESS, pam_putenv(pamh, "BAR=baz"), "putenv BAR"); is_string("foo", pam_getenv(pamh, "TEST"), "getenv TEST"); is_string("bar", pam_getenv(pamh, "FOO"), "getenv FOO"); is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR"); ok(pam_getenv(pamh, "BAZ") == NULL, "getenv BAZ is NULL"); /* Replacing and deleting environment variables. */ is_int(PAM_BAD_ITEM, pam_putenv(pamh, "BAZ"), "putenv nonexistent delete"); is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv replace"); is_int(PAM_SUCCESS, pam_putenv(pamh, "FOON=bar=n"), "putenv prefix"); is_string("foo", pam_getenv(pamh, "FOO"), "getenv FOO"); is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON"); is_int(PAM_BAD_ITEM, pam_putenv(pamh, "FO"), "putenv delete FO"); is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO"), "putenv delete FOO"); ok(pam_getenv(pamh, "FOO") == NULL, "getenv FOO is NULL"); is_string("bar=n", pam_getenv(pamh, "FOON"), "getenv FOON"); is_string("baz", pam_getenv(pamh, "BAR"), "getenv BAR"); /* pam_getenvlist. */ env = pam_getenvlist(pamh); ok(env != NULL, "getenvlist not NULL"); is_string("TEST=foo", env[0], "getenvlist TEST"); is_string("BAR=baz", env[1], "getenvlist BAR"); is_string("FOON=bar=n", env[2], "getenvlist FOON"); ok(env[3] == NULL, "getenvlist length"); for (i = 0; env[i] != NULL; i++) free(env[i]); free(env); is_int(PAM_SUCCESS, pam_putenv(pamh, "FOO=foo"), "putenv FOO"); is_string("TEST=foo", pamh->environ[0], "pamh environ TEST"); is_string("BAR=baz", pamh->environ[1], "pamh environ BAR"); is_string("FOON=bar=n", pamh->environ[2], "pamh environ FOON"); is_string("FOO=foo", pamh->environ[3], "pamh environ FOO"); ok(pamh->environ[4] == NULL, "pamh environ length"); pam_end(pamh, 0); return 0; }
static void setup_child (int inp[2], int outp[2], int errp[2], pam_handle_t *ph, struct passwd *pwd) { const char* display; int i, ret; #ifdef VALGRIND char *args[] = { VALGRIND, VALGRIND_ARG, MATE_KEYRING_DAEMON, "--daemonize", "--login", NULL}; #else char *args[] = { MATE_KEYRING_DAEMON, "--daemonize", "--login", NULL}; #endif assert (pwd); assert (pwd->pw_dir); /* Fix up our end of the pipes */ if (dup2 (inp[READ_END], STDIN) < 0 || dup2 (outp[WRITE_END], STDOUT) < 0 || dup2 (errp[WRITE_END], STDERR) < 0) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't setup pipes: %s", strerror (errno)); exit (EXIT_FAILURE); } /* Try valiantly to close unnecessary file descriptors */ for (i = STDERR; i < 64; ++i) close (i); /* Close unnecessary file descriptors */ close (inp[READ_END]); close (inp[WRITE_END]); close (outp[READ_END]); close (outp[WRITE_END]); close (errp[READ_END]); close (errp[WRITE_END]); /* We may be running effective as another user, revert that */ seteuid (getuid ()); setegid (getgid ()); /* Setup process credentials */ if (setgid (pwd->pw_gid) < 0 || setuid (pwd->pw_uid) < 0 || setegid (pwd->pw_gid) < 0 || seteuid (pwd->pw_uid) < 0) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't setup credentials: %s", strerror (errno)); exit (EXIT_FAILURE); } /* Setup environment variables */ ret = setup_pam_env (ph, "HOME", pwd->pw_dir); if (ret == PAM_SUCCESS && !pam_getenv (ph, "DISPLAY")) { display = getenv ("DISPLAY"); if (display) ret = setup_pam_env (ph, "DISPLAY", display); } /* Make sure that worked */ if (ret != PAM_SUCCESS) { syslog (GKR_LOG_ERR, "gkr-pam: couldn't setup environment: %s", pam_strerror (ph, ret)); exit (EXIT_FAILURE); } /* Now actually execute the process */ execve (args[0], args, pam_getenvlist (ph)); syslog (GKR_LOG_ERR, "gkr-pam: couldn't run mate-keyring-daemon: %s", strerror (errno)); exit (EXIT_FAILURE); }
int main(int argc, char **argv) { pam_handle_t *pamh=NULL; char *username=NULL; int retcode; /* did the user call with a username as an argument ? */ if (argc > 2) { fprintf(stderr,"usage: %s [username]\n",argv[0]); } else if (argc == 2) { username = argv[1]; } /* initialize the Linux-PAM library */ retcode = pam_start("blank", username, &conv, &pamh); bail_out(pamh,1,retcode,"pam_start"); /* test the environment stuff */ { #define MAXENV 15 const char *greek[MAXENV] = { "a=alpha", "b=beta", "c=gamma", "d=delta", "e=epsilon", "f=phi", "g=psi", "h=eta", "i=iota", "j=mu", "k=nu", "l=zeta", "h=", "d", "k=xi" }; char **env; int i; for (i=0; i<MAXENV; ++i) { retcode = pam_putenv(pamh,greek[i]); bail_out(pamh,0,retcode,"pam_putenv"); } env = pam_getenvlist(pamh); if (env) env = pam_misc_drop_env(env); else fprintf(stderr,"???\n"); fprintf(stderr,"a test: c=[%s], j=[%s]\n" , pam_getenv(pamh, "c"), pam_getenv(pamh, "j")); } /* to avoid using goto we abuse a loop here */ for (;;) { /* authenticate the user --- `0' here, could have been PAM_SILENT * | PAM_DISALLOW_NULL_AUTHTOK */ retcode = pam_authenticate(pamh, 0); bail_out(pamh,0,retcode,"pam_authenticate"); /* has the user proved themself valid? */ if (retcode != PAM_SUCCESS) { fprintf(stderr,"%s: invalid request\n",argv[0]); break; } /* the user is valid, but should they have access at this time? */ retcode = pam_acct_mgmt(pamh, 0); /* `0' could be as above */ bail_out(pamh,0,retcode,"pam_acct_mgmt"); if (retcode == PAM_NEW_AUTHTOK_REQD) { fprintf(stderr,"Application must request new password...\n"); retcode = pam_chauthtok(pamh,PAM_CHANGE_EXPIRED_AUTHTOK); bail_out(pamh,0,retcode,"pam_chauthtok"); } if (retcode != PAM_SUCCESS) { fprintf(stderr,"%s: invalid request\n",argv[0]); break; } /* `0' could be as above */ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED); bail_out(pamh,0,retcode,"pam_setcred1"); if (retcode != PAM_SUCCESS) { fprintf(stderr,"%s: problem setting user credentials\n" ,argv[0]); break; } /* open a session for the user --- `0' could be PAM_SILENT */ retcode = pam_open_session(pamh,0); bail_out(pamh,0,retcode,"pam_open_session"); if (retcode != PAM_SUCCESS) { fprintf(stderr,"%s: problem opening a session\n",argv[0]); break; } fprintf(stderr,"The user has been authenticated and `logged in'\n"); /* close a session for the user --- `0' could be PAM_SILENT * it is possible that this pam_close_call is in another program.. */ retcode = pam_close_session(pamh,0); bail_out(pamh,0,retcode,"pam_close_session"); if (retcode != PAM_SUCCESS) { fprintf(stderr,"%s: problem closing a session\n",argv[0]); break; } retcode = pam_setcred(pamh, PAM_DELETE_CRED); bail_out(pamh,0,retcode,"pam_setcred2"); break; /* don't go on for ever! */ } /* close the Linux-PAM library */ retcode = pam_end(pamh, PAM_SUCCESS); pamh = NULL; bail_out(pamh,1,retcode,"pam_end"); exit(0); }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { const void *ptr; const struct pam_conv *conv; struct pam_message msg; const struct pam_message *msgp; struct pam_response *resp; const char *user; char *crypt_password, *password, *key; int pam_err, retry; int system_is_down = 0; int stacked_pass = 0; int im_a_sandwich = 0; int skew = 3; char id [DOMAIN_LENGTH] = {0}; char id_path [DOMAIN_LENGTH] = {0}; FILE *id_file; const char *url = getarg("url", argc, argv); const char *folder = getarg("folder", argc, argv); const char *system = getarg("system_is_down", argc, argv); const char *stacked = getarg("stacked_pass", argc, argv); const char *sandwich = getarg("sandwich", argc, argv); const char *bottom = getarg("bottom", argc, argv); const char *skew_string = getarg("skew", argc, argv); const char *ldap_server = getarg("ldap_server", argc, argv); const char *ldap_uri = getarg("ldap_uri", argc, argv); const char *ldap_dn = getarg("ldap_dn", argc, argv); const char *ldap_user_attr = getarg("ldap_user_attr", argc, argv); const char *ldap_pig_attr = getarg("ldap_pig_attr", argc, argv); const char *password_prompt = getarg("prompt", argc, argv); const char *eat_me; char hash [7] = {0}; char cleaned_password[DOMAIN_LENGTH] = {0}; char tmp_password[DOMAIN_LENGTH] = {0}; if( system && (!strcmp("allow",system))) { system_is_down = 1; } if( stacked && (!strcmp("yes",stacked))) { stacked_pass = 1; } if( !password_prompt || password_prompt[0] == '\0') { password_prompt="Oink!:"; } if( sandwich && (!strcmp("yes", sandwich))) { im_a_sandwich = 1; } if( bottom && (!strcmp("yes", bottom))) { eat_me = pam_getenv(pamh,"SANDWICH"); if(eat_me && !strcmp("tasty",eat_me)) { log_message(LOG_ERR, pamh,"sandwich time"); pam_putenv(pamh, "SANDWICH"); return PAM_SUCCESS; } } if( skew_string) { skew = atoi(skew_string); } if(!url) url = ""; if(!folder) folder = "/etc/pig/"; /* identify user */ if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) return (pam_err); /* get password */ pam_err = pam_get_item(pamh, PAM_CONV, &ptr); if (pam_err != PAM_SUCCESS) return (PAM_SYSTEM_ERR); conv = ptr; msgp = &msg; msg.msg_style = PAM_PROMPT_ECHO_OFF; msg.msg = password_prompt; password = NULL; for (retry = 0; retry < 3; ++retry) { resp = NULL; pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr); if (resp != NULL) { if (pam_err == PAM_SUCCESS) { password = resp->resp; if(strlen(password) < 6) { if(stacked_pass || im_a_sandwich) strncpy(tmp_password, password, strlen(password)); else return (PAM_AUTH_ERR); } else { key = password + (strlen(password) - 6); strcpy(hash, key); if((stacked_pass || im_a_sandwich) && strlen(password) < 260) { strncpy(tmp_password, password, strlen(password)); } } } else { free(resp->resp); } free(resp); } if (pam_err == PAM_SUCCESS) break; } if (pam_err == PAM_CONV_ERR) return (pam_err); if (pam_err != PAM_SUCCESS) return (PAM_AUTH_ERR); if(!ldap_server) { strncat(id_path, folder, DOMAIN_LENGTH); strncat(id_path, "/ids/", DOMAIN_LENGTH); strncat(id_path, user, DOMAIN_LENGTH); if(!(id_file = fopen(id_path, "r"))) { strncat(id, user, DOMAIN_LENGTH); } else if(fread(id, DOMAIN_LENGTH,1, id_file) != 1) { fclose(id_file); if(!id || id[0] == '\0') { return PAM_AUTH_ERR; } } else fclose(id_file); } else { #ifdef HAVE_LIBLDAP strncat(id, ldap_get_user_id(ldap_server, ldap_uri, ldap_dn, ldap_user_attr, ldap_pig_attr, user), 20); if(id[0] = '\0') { return PAM_AUTH_ERR; } #else return PAM_AUTH_ERR; #endif } pam_err = check_key(id, url, hash, folder, skew, pamh); if(pam_err == PAM_SUCCESS) { log_message(LOG_ERR, pamh,"pig authenticated successfully."); } else { log_message(LOG_ERR, pamh,"pig did not authenticated successfully."); } if(stacked_pass) { if(strlen(tmp_password) > 5) { strncpy(cleaned_password, tmp_password, (strlen(password) - 6)); pam_set_item(pamh, PAM_AUTHTOK, cleaned_password); pam_set_item(pamh, PAM_OLDAUTHTOK, cleaned_password); } else { pam_set_item(pamh, PAM_AUTHTOK, tmp_password); pam_set_item(pamh, PAM_OLDAUTHTOK, tmp_password); } } if (pam_err == PAM_SUCCESS && im_a_sandwich && strlen(tmp_password) > 6) { strncpy(cleaned_password, tmp_password, (strlen(password) - 6)); pam_set_item(pamh, PAM_AUTHTOK, cleaned_password); pam_set_item(pamh, PAM_OLDAUTHTOK, cleaned_password); log_message(LOG_ERR, pamh,"login won so making a tasty sandwich."); pam_putenv(pamh, "SANDWICH=tasty"); } else if (pam_err == PAM_SUCCESS && im_a_sandwich && strlen(tmp_password) == 6) { log_message(LOG_ERR, pamh,"login won so making a tasty sandwich."); pam_putenv(pamh, "SANDWICH=tasty"); } else if(im_a_sandwich){ pam_set_item(pamh, PAM_AUTHTOK, tmp_password); pam_set_item(pamh, PAM_OLDAUTHTOK, tmp_password); pam_err = PAM_SUCCESS; log_message(LOG_ERR, pamh,"login failed so no sandwich."); } if (pam_err == PAM_AUTHINFO_UNAVAIL && system_is_down) { pam_err = PAM_SUCCESS; } return (pam_err); }
/* * PAM test callback to check whether we created a ticket cache and the ticket * cache is for the correct user. */ static void check_cache(pam_handle_t *pamh, const struct script_config *config, void *data) { struct extra *extra = data; const char *cache, *file; struct stat st; char *prefix; krb5_error_code code; krb5_context ctx = NULL; krb5_ccache ccache = NULL; krb5_principal princ = NULL; krb5_principal tgtprinc = NULL; krb5_creds in, out; char *principal = NULL; /* Check cache naming, ownership, and permissions. */ cache = pam_getenv(pamh, "KRB5CCNAME"); ok(cache != NULL, "KRB5CCNAME is set in PAM environment"); if (cache == NULL) return; basprintf(&prefix, "FILE:/tmp/krb5cc_%lu_", (unsigned long) getuid()); diag("KRB5CCNAME = %s", cache); ok(strncmp(prefix, cache, strlen(prefix)) == 0, "cache file name prefix is correct"); free(prefix); file = cache + strlen("FILE:"); is_int(0, stat(file, &st), "cache exists"); is_int(getuid(), st.st_uid, "...with correct UID"); is_int(getgid(), st.st_gid, "...with correct GID"); is_int(0600, (st.st_mode & 0777), "...with correct permissions"); /* Check the existence of the ticket cache and its principal. */ code = krb5_init_context(&ctx); if (code != 0) bail("cannot create Kerberos context"); code = krb5_cc_resolve(ctx, cache, &ccache); is_int(0, code, "able to resolve Kerberos ticket cache"); code = krb5_cc_get_principal(ctx, ccache, &princ); is_int(0, code, "able to get principal"); code = krb5_unparse_name(ctx, princ, &principal); is_int(0, code, "...and principal is valid"); is_string(config->extra[0], principal, "...and matches our principal"); /* Retrieve the krbtgt for the realm and check properties. */ code = krb5_build_principal_ext(ctx, &tgtprinc, strlen(extra->realm), extra->realm, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, strlen(extra->realm), extra->realm, NULL); if (code != 0) bail("cannot create krbtgt principal name"); memset(&in, 0, sizeof(in)); memset(&out, 0, sizeof(out)); in.server = tgtprinc; in.client = princ; code = krb5_cc_retrieve_cred(ctx, ccache, KRB5_TC_MATCH_SRV_NAMEONLY, &in, &out); is_int(0, code, "able to get krbtgt credentials"); ok(out.times.endtime > time(NULL) + 30 * 60, "...good for 30 minutes"); krb5_free_cred_contents(ctx, &out); /* Close things and release memory. */ krb5_free_principal(ctx, tgtprinc); krb5_free_unparsed_name(ctx, principal); krb5_free_principal(ctx, princ); krb5_cc_close(ctx, ccache); krb5_free_context(ctx); }
PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc, const char **argv) { char *user_name = NULL, *service = NULL; unsigned int ctrl = 0; int retval = 0; const char *login_name = NULL; const char *login_username = NULL; const char *old_tai = NULL; int names_different = 0; lpc_auth_method auth_method = lpcam_none; const char *user_remote = NULL, *user_local = NULL; /* pam_syslog(pamh, LOG_DEBUG, "pam_sm_open_session()"); */ D(("called.")); ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv); retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, "open_session - error recovering username"); return PAM_SESSION_ERR; /* How did we get authenticated with no username?! */ } retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service); if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) { pam_syslog(pamh, LOG_CRIT, "open_session - error recovering service"); return PAM_SESSION_ERR; } login_name = pam_modutil_getlogin(pamh); if (login_name == NULL) { login_name = ""; } login_username = pam_getenv(pamh, "LOGIN_USER"); if (login_username && (!user_name || (strcmp(login_username, user_name) != 0))) { names_different = 1; pam_syslog(pamh, LOG_INFO, "session opened for user %s (%s) by " "%s(uid=%lu)" ,login_username, user_name ,login_name, (unsigned long) getuid()); } else { names_different = 0; pam_syslog(pamh, LOG_INFO, "session opened for user %s by %s(uid=%lu)", user_name, login_name, (unsigned long)getuid()); } /* * Make sure TRUSTED_AUTH_INFO is set. The cases are: * * 1. Set to the magic string PAM_TRUSTED_AUTH_INFO_SET_STR. * This is how sshd signals us that it wants us to set it * ourselves; probably it means the user authenticated in some * non-PAM way, like with an ssh authorized key. * * (a) If user_name and login_name match, we'll assume that * their authentication was "local", and report it that way. * (This could be remote authentication if someone * introduced a new PAM module, but we'll stick with * Occam's Razor...) * * (b) If user_name and login_name do not match, this is * unexpected. This suggests it was a remote authentication, * but by a module that's not one we have modified to support * TRUSTED_AUTH_INFO. Since we don't know the situation, * leave it alone. * * 2. Set to something else. We'll presume it's set to some * real value here, and leave it alone. * * 3. Not set at all. We're not sure how this happened, but * leave it alone. */ old_tai = pam_getenv(pamh, "TRUSTED_AUTH_INFO"); if (old_tai == NULL) { /* Case 3 */ /* * Leave it unset. */ pam_syslog(pamh, LOG_DEBUG, "TRUSTED_AUTH_INFO: not set, " "leaving it alone"); } else if (!strcmp(old_tai, PAM_TRUSTED_AUTH_INFO_SET_STR)) { /*Case 1*/ if (login_username && user_name) { user_remote = login_username; user_local = user_name; } else { /* We know from above test that user_name is non-NULL */ user_remote = user_name; user_local = user_name; } if (names_different) { /* Case 1b */ pam_syslog(pamh, LOG_WARNING, "TRUSTED_AUTH_INFO: set " "requested, but two different usernames? " "(LOGIN_USER = '******', AUTH_USER = '******') " "Leaving it alone", user_remote, user_local); } else { /* Case 1a */ pam_syslog(pamh, LOG_DEBUG, "TRUSTED_AUTH_INFO: set " "requested, names match, presuming non-PAM local " "authentication, e.g. ssh authorized key"); auth_method = lpcam_local; } if (auth_method != lpcam_none) { pam_unix_set_trusted_auth_info(pamh, auth_method, user_remote, user_local); } } else { /* Case 2 */ /* * Leave it unset. */ pam_syslog(pamh, LOG_DEBUG, "TRUSTED_AUTH_INFO: already set, " "leaving it alone"); } return PAM_SUCCESS; }
static security_context_t context_from_env (pam_handle_t *pamh, security_context_t defaultcon, int env_params, int use_current_range, int debug) { security_context_t newcon = NULL; context_t new_context; context_t my_context = NULL; int mls_enabled = is_selinux_mls_enabled(); const char *env = NULL; char *type = NULL; if ((new_context = context_new(defaultcon)) == NULL) goto fail_set; if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') { if (debug) pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env); if (get_default_type(env, &type)) { pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env); goto fail_set; } else { if (context_role_set(new_context, env)) goto fail_set; if (context_type_set(new_context, type)) goto fail_set; } } if (mls_enabled) { if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') { if (debug) pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set"); use_current_range = 1; } if (use_current_range) { security_context_t mycon = NULL; if (getcon(&mycon) != 0) goto fail_set; my_context = context_new(mycon); if (my_context == NULL) { freecon(mycon); goto fail_set; } freecon(mycon); env = context_range_get(my_context); } else { env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED"); } if (env != NULL && env[0] != '\0') { if (debug) pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env); if (context_range_set(new_context, env)) goto fail_set; } } newcon = strdup(context_str(new_context)); if (newcon == NULL) goto fail_set; if (debug) pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon); /* Get the string value of the context and see if it is valid. */ if (security_check_context(newcon)) { pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon); send_audit_message(pamh, 0, defaultcon, newcon); freecon(newcon); newcon = NULL; goto fail_set; } /* we have to check that this user is allowed to go into the range they have specified ... role is tied to an seuser, so that'll be checked at setexeccon time */ if (mls_enabled && !mls_range_allowed(pamh, defaultcon, newcon, debug)) { pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon); send_audit_message(pamh, 0, defaultcon, newcon); freecon(newcon); newcon = NULL; } fail_set: free(type); context_free(my_context); context_free(new_context); send_audit_message(pamh, 0, defaultcon, NULL); return newcon; }