static void do_login(const struct passwd *pwd, char *tty, char *ttyn) { #ifdef HAVE_GETSPNAM struct spwd *sp; #endif int rootlogin = (pwd->pw_uid == 0); gid_t tty_gid; struct group *gr; const char *home_dir; int i; if(!rootlogin) checknologin(); #ifdef HAVE_GETSPNAM sp = getspnam(pwd->pw_name); #endif update_utmp(pwd->pw_name, remote_host ? remote_host : "", tty, ttyn); gr = getgrnam ("tty"); if (gr != NULL) tty_gid = gr->gr_gid; else tty_gid = pwd->pw_gid; if (chown (ttyn, pwd->pw_uid, tty_gid) < 0) { warn("chown %s", ttyn); if (rootlogin == 0) exit (1); } if (chmod (ttyn, S_IRUSR | S_IWUSR | S_IWGRP) < 0) { warn("chmod %s", ttyn); if (rootlogin == 0) exit (1); } #ifdef HAVE_SETLOGIN if(setlogin(pwd->pw_name)){ warn("setlogin(%s)", pwd->pw_name); if(rootlogin == 0) exit(1); } #endif if(rootlogin == 0) { const char *file = login_conf_get_string("limits"); if(file == NULL) file = _PATH_LIMITS_CONF; read_limits_conf(file, pwd); } #ifdef HAVE_SETPCRED if (setpcred (pwd->pw_name, NULL) == -1) warn("setpcred(%s)", pwd->pw_name); #endif /* HAVE_SETPCRED */ #ifdef HAVE_INITGROUPS if(initgroups(pwd->pw_name, pwd->pw_gid)){ warn("initgroups(%s, %u)", pwd->pw_name, (unsigned)pwd->pw_gid); if(rootlogin == 0) exit(1); } #endif if(do_osfc2_magic(pwd->pw_uid)) exit(1); if(setgid(pwd->pw_gid)){ warn("setgid(%u)", (unsigned)pwd->pw_gid); if(rootlogin == 0) exit(1); } if(setuid(pwd->pw_uid) || (pwd->pw_uid != 0 && setuid(0) == 0)) { warn("setuid(%u)", (unsigned)pwd->pw_uid); if(rootlogin == 0) exit(1); } /* make sure signals are set to default actions, apparently some OS:es like to ignore SIGINT, which is not very convenient */ for (i = 1; i < NSIG; ++i) signal(i, SIG_DFL); /* all kinds of different magic */ #ifdef HAVE_GETSPNAM check_shadow(pwd, sp); #endif #if defined(HAVE_GETUDBNAM) && defined(HAVE_SETLIM) { struct udb *udb; long t; const long maxcpu = 46116860184; /* some random constant */ udb = getudbnam(pwd->pw_name); if(udb == UDB_NULL) errx(1, "Failed to get UDB entry."); t = udb->ue_pcpulim[UDBRC_INTER]; if(t == 0 || t > maxcpu) t = CPUUNLIM; else t *= 100 * CLOCKS_PER_SEC; if(limit(C_PROC, 0, L_CPU, t) < 0) warn("limit C_PROC"); t = udb->ue_jcpulim[UDBRC_INTER]; if(t == 0 || t > maxcpu) t = CPUUNLIM; else t *= 100 * CLOCKS_PER_SEC; if(limit(C_JOBPROCS, 0, L_CPU, t) < 0) warn("limit C_JOBPROCS"); nice(udb->ue_nice[UDBRC_INTER]); } #endif #if defined(HAVE_SGI_GETCAPABILITYBYNAME) && defined(HAVE_CAP_SET_PROC) /* XXX SGI capability hack IRIX 6.x (x >= 0?) has something called capabilities, that allow you to give away permissions (such as chown) to specific processes. From 6.5 this is default on, and the default capability set seems to not always be the empty set. The problem is that the runtime linker refuses to do just about anything if the process has *any* capabilities set, so we have to remove them here (unless otherwise instructed by /etc/capability). In IRIX < 6.5, these functions was called sgi_cap_setproc, etc, but we ignore this fact (it works anyway). */ { struct user_cap *ucap = sgi_getcapabilitybyname(pwd->pw_name); cap_t cap; if(ucap == NULL) cap = cap_from_text("all="); else cap = cap_from_text(ucap->ca_default); if(cap == NULL) err(1, "cap_from_text"); if(cap_set_proc(cap) < 0) err(1, "cap_set_proc"); cap_free(cap); free(ucap); } #endif home_dir = pwd->pw_dir; if (chdir(home_dir) < 0) { fprintf(stderr, "No home directory \"%s\"!\n", pwd->pw_dir); if (chdir("/")) exit(0); home_dir = "/"; fprintf(stderr, "Logging in with home = \"/\".\n"); } #ifdef KRB5 if (auth == AUTH_KRB5) { krb5_start_session (pwd); } krb5_get_afs_tokens (pwd); krb5_finish (); #endif /* KRB5 */ add_env("PATH", _PATH_DEFPATH); { const char *str = login_conf_get_string("environment"); char buf[MAXPATHLEN]; if(str == NULL) { login_read_env(_PATH_ETC_ENVIRONMENT); } else { while(strsep_copy(&str, ",", buf, sizeof(buf)) != -1) { if(buf[0] == '\0') continue; login_read_env(buf); } } } { const char *str = login_conf_get_string("motd"); char buf[MAXPATHLEN]; if(str != NULL) { while(strsep_copy(&str, ",", buf, sizeof(buf)) != -1) { if(buf[0] == '\0') continue; show_file(buf); } } else { str = login_conf_get_string("welcome"); if(str != NULL) show_file(str); } } add_env("HOME", home_dir); add_env("USER", pwd->pw_name); add_env("LOGNAME", pwd->pw_name); add_env("SHELL", pwd->pw_shell); exec_shell(pwd->pw_shell, rootlogin); }
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) { krb5_error_code ret = 0; int min = 0, max = -1, n; char c; const char *p = orig; n = sscanf(p, "%d%c%d/", &min, &c, &max); if(n == 2){ if(c == '/') { if(min < 0){ max = -min; min = 0; }else{ max = min; } } } if(n){ p = strchr(p, '/'); if(p == NULL) { krb5_set_error_message(context, HEIM_ERR_LOG_PARSE, N_("failed to parse \"%s\"", ""), orig); return HEIM_ERR_LOG_PARSE; } p++; } if(strcmp(p, "STDERR") == 0){ ret = open_file(context, f, min, max, NULL, NULL, stderr, 1); }else if(strcmp(p, "CONSOLE") == 0){ ret = open_file(context, f, min, max, "/dev/console", "w", NULL, 0); }else if(strncmp(p, "FILE", 4) == 0 && (p[4] == ':' || p[4] == '=')){ char *fn; FILE *file = NULL; int keep_open = 0; fn = strdup(p + 5); if(fn == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } if(p[4] == '='){ int i = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_APPEND, 0666); if(i < 0) { ret = errno; krb5_set_error_message(context, ret, N_("open(%s) logile: %s", ""), fn, strerror(ret)); free(fn); return ret; } rk_cloexec(i); file = fdopen(i, "a"); if(file == NULL){ ret = errno; close(i); krb5_set_error_message(context, ret, N_("fdopen(%s) logfile: %s", ""), fn, strerror(ret)); free(fn); return ret; } keep_open = 1; } ret = open_file(context, f, min, max, fn, "a", file, keep_open); }else if(strncmp(p, "DEVICE", 6) == 0 && (p[6] == ':' || p[6] == '=')){ ret = open_file(context, f, min, max, strdup(p + 7), "w", NULL, 0); }else if(strncmp(p, "SYSLOG", 6) == 0 && (p[6] == '\0' || p[6] == ':')){ char severity[128] = ""; char facility[128] = ""; p += 6; if(*p != '\0') p++; if(strsep_copy(&p, ":", severity, sizeof(severity)) != -1) strsep_copy(&p, ":", facility, sizeof(facility)); if(*severity == '\0') strlcpy(severity, "ERR", sizeof(severity)); if(*facility == '\0') strlcpy(facility, "AUTH", sizeof(facility)); ret = open_syslog(context, f, min, max, severity, facility); }else{ ret = HEIM_ERR_LOG_PARSE; /* XXX */ krb5_set_error_message (context, ret, N_("unknown log type: %s", ""), p); } return ret; }
static int do_list(struct list_options *opt, const char *keytab_str) { krb5_error_code ret; krb5_keytab keytab; krb5_keytab_entry entry; krb5_kt_cursor cursor; rtbl_t table; /* XXX specialcase the ANY type */ if(strncasecmp(keytab_str, "ANY:", 4) == 0) { int flag = 0; char buf[1024]; keytab_str += 4; ret = 0; while (strsep_copy((const char**)&keytab_str, ",", buf, sizeof(buf)) != -1) { if(flag) printf("\n"); if(do_list(opt, buf)) ret = 1; flag = 1; } return ret; } ret = krb5_kt_resolve(context, keytab_str, &keytab); if (ret) { krb5_warn(context, ret, "resolving keytab %s", keytab_str); return ret; } ret = krb5_kt_start_seq_get(context, keytab, &cursor); if(ret) { krb5_warn(context, ret, "krb5_kt_start_seq_get %s", keytab_str); krb5_kt_close(context, keytab); return ret; } printf ("%s:\n\n", keytab_str); table = rtbl_create(); rtbl_add_column_by_id(table, 0, "Vno", RTBL_ALIGN_RIGHT); rtbl_add_column_by_id(table, 1, "Type", 0); rtbl_add_column_by_id(table, 2, "Principal", 0); if (opt->timestamp_flag) rtbl_add_column_by_id(table, 3, "Date", 0); if(opt->keys_flag) rtbl_add_column_by_id(table, 4, "Key", 0); rtbl_add_column_by_id(table, 5, "Aliases", 0); rtbl_set_separator(table, " "); while(krb5_kt_next_entry(context, keytab, &entry, &cursor) == 0){ char buf[1024], *s; snprintf(buf, sizeof(buf), "%d", entry.vno); rtbl_add_column_entry_by_id(table, 0, buf); ret = krb5_enctype_to_string(context, entry.keyblock.keytype, &s); if (ret != 0) { snprintf(buf, sizeof(buf), "unknown (%d)", entry.keyblock.keytype); rtbl_add_column_entry_by_id(table, 1, buf); } else { rtbl_add_column_entry_by_id(table, 1, s); free(s); } krb5_unparse_name_fixed(context, entry.principal, buf, sizeof(buf)); rtbl_add_column_entry_by_id(table, 2, buf); if (opt->timestamp_flag) { krb5_format_time(context, entry.timestamp, buf, sizeof(buf), FALSE); rtbl_add_column_entry_by_id(table, 3, buf); } if(opt->keys_flag) { int i; s = malloc(2 * entry.keyblock.keyvalue.length + 1); if (s == NULL) { krb5_warnx(context, "malloc failed"); ret = ENOMEM; goto out; } for(i = 0; i < entry.keyblock.keyvalue.length; i++) snprintf(s + 2 * i, 3, "%02x", ((unsigned char*)entry.keyblock.keyvalue.data)[i]); rtbl_add_column_entry_by_id(table, 4, s); free(s); } if (entry.aliases) { unsigned int i; struct rk_strpool *p = NULL; for (i = 0; i< entry.aliases->len; i++) { krb5_unparse_name_fixed(context, entry.principal, buf, sizeof(buf)); rk_strpoolprintf(p, "%s%s", buf, i + 1 < entry.aliases->len ? ", " : ""); } rtbl_add_column_entry_by_id(table, 5, rk_strpoolcollect(p)); } krb5_kt_free_entry(context, &entry); } ret = krb5_kt_end_seq_get(context, keytab, &cursor); rtbl_format(table, stdout); out: rtbl_destroy(table); krb5_kt_close(context, keytab); return ret; }
static int arange_parse_addr (krb5_context context, const char *address, krb5_address *addr) { char buf[1024], *p; krb5_address low0, high0; struct arange *a; krb5_error_code ret; if(strncasecmp(address, "RANGE:", 6) != 0) return -1; address += 6; p = strrchr(address, '/'); if (p) { krb5_addresses addrmask; char *q; long num; if (strlcpy(buf, address, sizeof(buf)) > sizeof(buf)) return -1; buf[p - address] = '\0'; ret = krb5_parse_address(context, buf, &addrmask); if (ret) return ret; if(addrmask.len != 1) { krb5_free_addresses(context, &addrmask); return -1; } address += p - address + 1; num = strtol(address, &q, 10); if (q == address || *q != '\0' || num < 0) { krb5_free_addresses(context, &addrmask); return -1; } ret = krb5_address_prefixlen_boundary(context, &addrmask.val[0], num, &low0, &high0); krb5_free_addresses(context, &addrmask); if (ret) return ret; } else { krb5_addresses low, high; strsep_copy(&address, "-", buf, sizeof(buf)); ret = krb5_parse_address(context, buf, &low); if(ret) return ret; if(low.len != 1) { krb5_free_addresses(context, &low); return -1; } strsep_copy(&address, "-", buf, sizeof(buf)); ret = krb5_parse_address(context, buf, &high); if(ret) { krb5_free_addresses(context, &low); return ret; } if(high.len != 1 && high.val[0].addr_type != low.val[0].addr_type) { krb5_free_addresses(context, &low); krb5_free_addresses(context, &high); return -1; } ret = krb5_copy_address(context, &high.val[0], &high0); if (ret == 0) { ret = krb5_copy_address(context, &low.val[0], &low0); if (ret) krb5_free_address(context, &high0); } krb5_free_addresses(context, &low); krb5_free_addresses(context, &high); if (ret) return ret; } krb5_data_alloc(&addr->address, sizeof(*a)); addr->addr_type = KRB5_ADDRESS_ARANGE; a = addr->address.data; if(krb5_address_order(context, &low0, &high0) < 0) { a->low = low0; a->high = high0; } else { a->low = high0; a->high = low0; } return 0; }