int autheph_check_to0(struct sip_msg *_m) { str username = {0, 0}; if (eph_auth_api.pre_auth == NULL) { LM_ERR("autheph_check_to() with no username parameter " "cannot be used without the auth module\n"); return CHECK_ERROR; } if (_m == NULL) { LM_ERR("invalid parameters\n"); return CHECK_ERROR; } if (get_cred(_m, &username) < 0) { LM_ERR("call autheph_(check|proxy|www) before calling " " check_to() with no username parameter\n"); return CHECK_ERROR; } return check_to(_m, &username); }
void tasks_test_saved(void) { struct task_struct *p; struct cred *cred =NULL; struct mm_struct *mm; unsigned long vsize = 0, vrss = 0; printk("\nThe following trace is a kernel tasks test and not a bug!\n"); printk("USER\tPID\tVSIZE\tRSS\tSTATE\tNAME\n"); write_lock_irq(&tasklist_lock); for_each_process(p) { cred = (struct cred *)get_cred((struct cred *) __task_cred(p)); vsize = 0; vrss = 0; mm = get_task_mm(p); if (mm) { tasks_mem_get(mm, &vsize, &vrss); } printk("%d\t%d\t%ld\t%ld\t%s\t%s\n", cred->uid, task_pid_nr(p), vsize, vrss, get_task_state(p), p->comm); } write_unlock_irq(&tasklist_lock); }
/* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. */ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file * f; int acct; acct = (get_exec_ub() == get_ub0()); /* * Privileged users can go above max_files */ if (acct && get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; if (ub_file_charge(f)) goto fail_ch; if (acct) percpu_counter_inc(&nr_files); if (security_file_alloc(f)) goto fail_sec; INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); f->f_cred = get_cred(cred); spin_lock_init(&f->f_lock); eventpoll_init_file(f); /* f->f_version: 0 */ return f; over: /* Ran out of filps - report that */ if (get_nr_files() > old_max) { pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } goto fail; fail_sec: file_free(f); fail: return NULL; fail_ch: kmem_cache_free(filp_cachep, f); return NULL; }
static inline void task_state(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *p) { struct group_info *group_info; int g; struct fdtable *fdt = NULL; const struct cred *cred; pid_t ppid, tpid; rcu_read_lock(); ppid = pid_alive(p) ? task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; tpid = 0; if (pid_alive(p)) { struct task_struct *tracer = tracehook_tracer_task(p); if (tracer) tpid = task_pid_nr_ns(tracer, ns); } cred = get_cred((struct cred *) __task_cred(p)); seq_printf(m, "State:\t%s\n" "Tgid:\t%d\n" "Pid:\t%d\n" "PPid:\t%d\n" "TracerPid:\t%d\n" "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), task_tgid_nr_ns(p, ns), pid_nr_ns(pid, ns), ppid, tpid, cred->uid, cred->euid, cred->suid, cred->fsuid, cred->gid, cred->egid, cred->sgid, cred->fsgid); task_lock(p); if (p->files) fdt = files_fdtable(p->files); seq_printf(m, "FDSize:\t%d\n" "Groups:\t", fdt ? fdt->max_fds : 0); rcu_read_unlock(); group_info = cred->group_info; task_unlock(p); for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) seq_printf(m, "%d ", GROUP_AT(group_info, g)); put_cred(cred); seq_printf(m, "\n"); }
struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file * f; /* */ if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; percpu_counter_inc(&nr_files); f->f_cred = get_cred(cred); if (security_file_alloc(f)) goto fail_sec; INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); eventpoll_init_file(f); /* */ return f; over: /* */ if (get_nr_files() > old_max) { pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } goto fail; fail_sec: file_free(f); fail: return NULL; }
cred_t * crget(void) { cred_t *tmp; tmp = kmalloc(sizeof(cred_t), GFP_NOFS); if (!tmp) osi_Panic("crget: No more memory for creds!\n"); #if defined(STRUCT_TASK_STRUCT_HAS_CRED) get_cred(tmp); #else atomic_set(&tmp->cr_ref, 1); #endif return tmp; }
/* Find an unused file structure and return a pointer to it. * Returns an error pointer if some error happend e.g. we over file * structures limit, run out of memory or operation is not permitted. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. */ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file *f; int error; /* * Privileged users can go above max_files */ if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (unlikely(!f)) return ERR_PTR(-ENOMEM); percpu_counter_inc(&nr_files); f->f_cred = get_cred(cred); error = security_file_alloc(f); if (unlikely(error)) { file_free(f); return ERR_PTR(error); } INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); eventpoll_init_file(f); /* f->f_version: 0 */ return f; over: /* Ran out of filps - report that */ if (get_nr_files() > old_max) { pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } return ERR_PTR(-ENFILE); }
/** * vfs_dup_fc_config: Duplicate a filesystem context. * @src_fc: The context to copy. */ struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc) { struct fs_context *fc; int ret; if (!src_fc->ops->dup) return ERR_PTR(-EOPNOTSUPP); fc = kmemdup(src_fc, sizeof(struct fs_context), GFP_KERNEL); if (!fc) return ERR_PTR(-ENOMEM); mutex_init(&fc->uapi_mutex); fc->fs_private = NULL; fc->s_fs_info = NULL; fc->source = NULL; fc->security = NULL; get_filesystem(fc->fs_type); get_net(fc->net_ns); get_user_ns(fc->user_ns); get_cred(fc->cred); if (fc->log) refcount_inc(&fc->log->usage); /* Can't call put until we've called ->dup */ ret = fc->ops->dup(fc, src_fc); if (ret < 0) goto err_fc; ret = security_fs_context_dup(fc, src_fc); if (ret < 0) goto err_fc; return fc; err_fc: put_fs_context(fc); return ERR_PTR(ret); }
struct sock *__vsock_create(struct net *net, struct socket *sock, struct sock *parent, gfp_t priority, unsigned short type, int kern) { struct sock *sk; struct vsock_sock *psk; struct vsock_sock *vsk; sk = sk_alloc(net, AF_VSOCK, priority, &vsock_proto, kern); if (!sk) return NULL; sock_init_data(sock, sk); /* sk->sk_type is normally set in sock_init_data, but only if sock is * non-NULL. We make sure that our sockets always have a type by * setting it here if needed. */ if (!sock) sk->sk_type = type; vsk = vsock_sk(sk); vsock_addr_init(&vsk->local_addr, VMADDR_CID_ANY, VMADDR_PORT_ANY); vsock_addr_init(&vsk->remote_addr, VMADDR_CID_ANY, VMADDR_PORT_ANY); sk->sk_destruct = vsock_sk_destruct; sk->sk_backlog_rcv = vsock_queue_rcv_skb; sock_reset_flag(sk, SOCK_DONE); INIT_LIST_HEAD(&vsk->bound_table); INIT_LIST_HEAD(&vsk->connected_table); vsk->listener = NULL; INIT_LIST_HEAD(&vsk->pending_links); INIT_LIST_HEAD(&vsk->accept_queue); vsk->rejected = false; vsk->sent_request = false; vsk->ignore_connecting_rst = false; vsk->peer_shutdown = 0; psk = parent ? vsock_sk(parent) : NULL; if (parent) { vsk->trusted = psk->trusted; vsk->owner = get_cred(psk->owner); vsk->connect_timeout = psk->connect_timeout; } else { vsk->trusted = capable(CAP_NET_ADMIN); vsk->owner = get_current_cred(); vsk->connect_timeout = VSOCK_DEFAULT_CONNECT_TIMEOUT; } if (transport->init(vsk, psk) < 0) { sk_free(sk); return NULL; } if (sock) vsock_insert_unbound(vsk); return sk; }
/* * create an authorisation token for /sbin/request-key or whoever to gain * access to the caller's security data */ struct key *request_key_auth_new(struct key *target, const void *callout_info, size_t callout_len, struct key *dest_keyring) { struct request_key_auth *rka, *irka; const struct cred *cred = current->cred; struct key *authkey = NULL; char desc[20]; int ret; kenter("%d,", target->serial); /* allocate a auth record */ rka = kmalloc(sizeof(*rka), GFP_KERNEL); if (!rka) { kleave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); } rka->callout_info = kmalloc(callout_len, GFP_KERNEL); if (!rka->callout_info) { kleave(" = -ENOMEM"); kfree(rka); return ERR_PTR(-ENOMEM); } /* see if the calling process is already servicing the key request of * another process */ if (cred->request_key_auth) { /* it is - use that instantiation context here too */ down_read(&cred->request_key_auth->sem); /* if the auth key has been revoked, then the key we're * servicing is already instantiated */ if (test_bit(KEY_FLAG_REVOKED, &cred->request_key_auth->flags)) goto auth_key_revoked; irka = cred->request_key_auth->payload.data; rka->cred = get_cred(irka->cred); rka->pid = irka->pid; up_read(&cred->request_key_auth->sem); } else { /* it isn't - use this process as the context */ rka->cred = get_cred(cred); rka->pid = current->pid; } rka->target_key = key_get(target); rka->dest_keyring = key_get(dest_keyring); memcpy(rka->callout_info, callout_info, callout_len); rka->callout_len = callout_len; /* allocate the auth key */ sprintf(desc, "%x", target->serial); authkey = key_alloc(&key_type_request_key_auth, desc, cred->fsuid, cred->fsgid, cred, KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); if (IS_ERR(authkey)) { ret = PTR_ERR(authkey); goto error_alloc; } /* construct the auth key */ ret = key_instantiate_and_link(authkey, rka, 0, NULL, NULL); if (ret < 0) goto error_inst; kleave(" = {%d,%d}", authkey->serial, atomic_read(&authkey->usage)); return authkey; auth_key_revoked: up_read(&cred->request_key_auth->sem); kfree(rka->callout_info); kfree(rka); kleave("= -EKEYREVOKED"); return ERR_PTR(-EKEYREVOKED); error_inst: key_revoke(authkey); key_put(authkey); error_alloc: key_put(rka->target_key); key_put(rka->dest_keyring); kfree(rka->callout_info); kfree(rka); kleave("= %d", ret); return ERR_PTR(ret); } /* end request_key_auth_new() */
/* Find an unused file structure and return a pointer to it. * Returns NULL, if there are no more free file structures or * we run out of memory. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. */ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file * f; /* * Privileged users can go above max_files */ if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (f == NULL) goto fail; percpu_counter_inc(&nr_files); f->f_cred = get_cred(cred); if (security_file_alloc(f)) goto fail_sec; INIT_LIST_HEAD(&f->f_u.fu_list); atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); eventpoll_init_file(f); /* f->f_version: 0 */ return f; over: /* Ran out of filps - report that */ if (get_nr_files() > old_max) { #ifdef FILE_OVER_MAX static int fd_dump_all_files = 0; if(!fd_dump_all_files) { struct task_struct *p; xlog_printk(ANDROID_LOG_INFO, FS_TAG, "(PID:%d)files %d over old_max:%d", current->pid, get_nr_files(), old_max); for_each_process(p) { pid_t pid = p->pid; struct files_struct *files = p->files; struct fdtable *fdt = files_fdtable(files); if(files && fdt) { fd_show_open_files(pid, files, fdt); } } fd_dump_all_files = 0x1; } #endif pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } goto fail; fail_sec: file_free(f); fail: return NULL; }
/* Hold a reference on the credential and group info */ void crhold(cred_t *cr) { (void)get_cred((const cred_t *)cr); (void)get_group_info(cr->group_info); }
/* * Log to a cell. If the cell has already been logged to, return without * doing anything. Otherwise, log to it and mark that it has been logged * to. */ static int auth_to_cell(krb5_context context, char *cell, char *realm) { int status = AKLOG_SUCCESS; char username[BUFSIZ]; /* To hold client username structure */ char name[ANAME_SZ]; /* Name of afs key */ char instance[INST_SZ]; /* Instance of afs key */ char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */ char local_cell[MAXCELLCHARS+1]; char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */ krb5_creds *v5cred = NULL; #ifdef HAVE_KRB4 CREDENTIALS c; #endif struct ktc_principal aserver; struct ktc_principal aclient; struct ktc_token atoken, btoken; struct afsconf_cell ak_cellconfig; /* General information about the cell */ int i; int getLinkedCell = 0; /* try to avoid an expensive call to get_cellconfig */ if (cell && ll_string_check(&authedcells, cell)) { if (dflag) printf("Already authenticated to %s (or tried to)\n", cell); return(AKLOG_SUCCESS); } memset(name, 0, sizeof(name)); memset(instance, 0, sizeof(instance)); memset(realm_of_user, 0, sizeof(realm_of_user)); memset(realm_of_cell, 0, sizeof(realm_of_cell)); memset(&ak_cellconfig, 0, sizeof(ak_cellconfig)); /* NULL or empty cell returns information on local cell */ if (status = get_cellconfig(cell, &ak_cellconfig, local_cell)) return(status); linkedCell: if (getLinkedCell) strncpy(cell_to_use, ak_cellconfig.linkedCell, MAXCELLCHARS); else strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS); cell_to_use[MAXCELLCHARS] = 0; if (ll_string_check(&authedcells, cell_to_use)) { if (dflag) printf("Already authenticated to %s (or tried to)\n", cell_to_use); status = AKLOG_SUCCESS; goto done2; } /* * Record that we have attempted to log to this cell. We do this * before we try rather than after so that we will not try * and fail repeatedly for one cell. */ (void)ll_add_string(&authedcells, cell_to_use); if (dflag) printf("Authenticating to cell %s.\n", cell_to_use); /* We use the afs.<cellname> convention here... */ strcpy(name, AFSKEY); strncpy(instance, cell_to_use, sizeof(instance)); instance[sizeof(instance)-1] = '\0'; /* * Extract the session key from the ticket file and hand-frob an * afs style authenticator. */ if (usev5) { /* using krb5 */ int retry = 1; int realm_fallback = 0; if ((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) { char * msg; if (pkrb5_get_error_message) msg = pkrb5_get_error_message(context, status); else msg = (char *)error_message(status); fprintf(stderr, "%s: Couldn't determine realm of user: %s\n", progname, msg); if (pkrb5_free_error_message) pkrb5_free_error_message(context, msg); status = AKLOG_KERBEROS; goto done; } if ( strchr(name,'.') != NULL ) { fprintf(stderr, "%s: Can't support principal names including a dot.\n", progname); status = AKLOG_MISC; goto done; } try_v5: if (realm && realm[0]) { if (dflag) printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm); status = get_v5cred(context, name, instance, realm, #ifdef HAVE_KRB4 use524 ? &c : NULL, #else NULL, #endif &v5cred); strcpy(realm_of_cell, realm); } else { strcpy(realm_of_cell, afs_realm_of_cell5(context, &ak_cellconfig, realm_fallback)); if (retry == 1 && realm_fallback == 0) { /* Only try the realm_of_user once */ status = -1; if (dflag) printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_user); status = get_v5cred(context, name, instance, realm_of_user, #ifdef HAVE_KRB4 use524 ? &c : NULL, #else NULL, #endif &v5cred); if (status == 0) { /* we have determined that the client realm * is a valid cell realm */ strcpy(realm_of_cell, realm_of_user); } } if (status != 0 && (!retry || retry && strcmp(realm_of_user,realm_of_cell))) { if (dflag) printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell); status = get_v5cred(context, name, instance, realm_of_cell, #ifdef HAVE_KRB4 use524 ? &c : NULL, #else NULL, #endif &v5cred); if (!status && !strlen(realm_of_cell)) copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred); } } if (!realm_fallback && status == KRB5_ERR_HOST_REALM_UNKNOWN) { realm_fallback = 1; goto try_v5; } else if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) { if (!realm_fallback && !realm_of_cell[0]) { realm_fallback = 1; goto try_v5; } if (dflag) printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell); status = get_v5cred(context, name, "", realm_of_cell, #ifdef HAVE_KRB4 use524 ? &c : NULL, #else NULL, #endif &v5cred); if (!status && !strlen(realm_of_cell)) copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred); } if ( status == KRB5KRB_AP_ERR_MSG_TYPE && retry ) { retry = 0; realm_fallback = 0; goto try_v5; } } else { #ifdef HAVE_KRB4 if (realm && realm[0]) strcpy(realm_of_cell, realm); else strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig)); /* * Try to obtain AFS tickets. Because there are two valid service * names, we will try both, but trying the more specific first. * * afs.<cell>@<realm> * afs@<realm> */ if (dflag) printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell); status = get_cred(name, instance, realm_of_cell, &c); if (status == KDC_PR_UNKNOWN) { if (dflag) printf("Getting tickets: %s@%s\n", name, realm_of_cell); status = get_cred(name, "", realm_of_cell, &c); } #else status = AKLOG_MISC; goto done; #endif } if (status != KSUCCESS) { char * msg = NULL; if (dflag) printf("Kerberos error code returned by get_cred: %d\n", status); if (usev5) { if (pkrb5_get_error_message) msg = pkrb5_get_error_message(context, status); else msg = (char *)error_message(status); } #ifdef HAVE_KRB4 else msg = krb_err_text(status); #endif fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n", progname, cell_to_use, msg?msg:"(unknown error)"); if (usev5 && pkrb5_free_error_message) pkrb5_free_error_message(context, msg); status = AKLOG_KERBEROS; goto done; } strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1); strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1); strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1); if (usev5 && !use524) { /* This code inserts the entire K5 ticket into the token * No need to perform a krb524 translation which is * commented out in the code below */ char * p; int len; len = min(v5cred->client->data[0].length,MAXKTCNAMELEN - 1); strncpy(username, v5cred->client->data[0].data, len); username[len] = '\0'; if ( v5cred->client->length > 1 ) { strcat(username, "."); p = username + strlen(username); len = min(v5cred->client->data[1].length, (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1)); strncpy(p, v5cred->client->data[1].data, len); p[len] = '\0'; } memset(&atoken, '\0', sizeof(atoken)); atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5; atoken.startTime = v5cred->times.starttime; atoken.endTime = v5cred->times.endtime; memcpy(&atoken.sessionKey, v5cred->keyblock.contents, v5cred->keyblock.length); atoken.ticketLen = v5cred->ticket.length; memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen); } else { #ifdef HAVE_KRB4 strcpy (username, c.pname); if (c.pinst[0]) { strcat(username, "."); strcat(username, c.pinst); } atoken.kvno = c.kvno; atoken.startTime = c.issue_date; /* ticket lifetime is in five-minutes blocks. */ atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60); memcpy(&atoken.sessionKey, c.session, 8); atoken.ticketLen = c.ticket_st.length; memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen); #else status = AKLOG_MISC; goto done; #endif } if (!force && !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) && atoken.kvno == btoken.kvno && atoken.ticketLen == btoken.ticketLen && !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) { if (dflag) printf("Identical tokens already exist; skipping.\n"); status = AKLOG_SUCCESS; goto done2; } if (noprdb) { if (dflag) printf("Not resolving name %s to id (-noprdb set)\n", username); } else { if (!usev5) { #ifdef HAVE_KRB4 if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS) { fprintf(stderr, "%s: Couldn't determine realm of user: %s)", progname, krb_err_text(status)); status = AKLOG_KERBEROS; goto done; } #else status = AKLOG_MISC; goto done; #endif } /* For Network Identity Manager append the realm to the name */ strcat(username, "@"); strcat(username, realm_of_user); ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use, #ifdef HAVE_KRB4 &c, #else NULL, #endif &status, &aclient, &aserver, &atoken); } if (dflag) printf("Set username to %s\n", username); /* Reset the "aclient" structure before we call ktc_SetToken. * This structure was first set by the ktc_GetToken call when * we were comparing whether identical tokens already existed. */ strncpy(aclient.name, username, MAXKTCNAMELEN - 1); strcpy(aclient.instance, ""); if (usev5 && !use524) { int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1); strncpy(aclient.cell, v5cred->client->realm.data, len); aclient.cell[len] = '\0'; } #ifdef HAVE_KRB4 else strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1); #endif for ( i=0; aclient.cell[i]; i++ ) { if ( islower(aclient.cell[i]) ) aclient.cell[i] = toupper(aclient.cell[i]); } if (dflag) printf("Getting tokens.\n"); if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0)) { afs_com_err(progname, status, "while obtaining tokens for cell %s\n", cell_to_use); status = AKLOG_TOKEN; } done2: if (ak_cellconfig.linkedCell && !getLinkedCell) { getLinkedCell = 1; goto linkedCell; } done: #if 0 /* * intentionally leak the linkedCell field because it was allocated * using a different C RTL version. */ if (ak_cellconfig.linkedCell) free(ak_cellconfig.linkedCell); #endif return(status); }
/* Find an unused file structure and return a pointer to it. * Returns an error pointer if some error happend e.g. we over file * structures limit, run out of memory or operation is not permitted. * * Be very careful using this. You are responsible for * getting write access to any mount that you might assign * to this filp, if it is opened for write. If this is not * done, you will imbalance int the mount's writer count * and a warning at __fput() time. */ struct file *get_empty_filp(void) { const struct cred *cred = current_cred(); static long old_max; struct file *f; int error; /* * Privileged users can go above max_files */ if (get_nr_files() >= files_stat.max_files && !capable(CAP_SYS_ADMIN)) { /* * percpu_counters are inaccurate. Do an expensive check before * we go and fail. */ if (percpu_counter_sum_positive(&nr_files) >= files_stat.max_files) goto over; } f = kmem_cache_zalloc(filp_cachep, GFP_KERNEL); if (unlikely(!f)) return ERR_PTR(-ENOMEM); percpu_counter_inc(&nr_files); f->f_cred = get_cred(cred); error = security_file_alloc(f); if (unlikely(error)) { file_free(f); return ERR_PTR(error); } atomic_long_set(&f->f_count, 1); rwlock_init(&f->f_owner.lock); spin_lock_init(&f->f_lock); mutex_init(&f->f_pos_lock); eventpoll_init_file(f); /* f->f_version: 0 */ return f; over: /* Ran out of filps - report that */ if (get_nr_files() > old_max) { #ifdef FD_OVER_CHECK static int fd_dump_all_files; if (!fd_dump_all_files) { struct task_struct *p; struct files_struct *files; pid_t pid; fd_dump_all_files = 0x1; for_each_process(p) { if (p->flags & PF_KTHREAD) continue; files = p->files; if (files) { struct fdtable *fdt = files_fdtable(files); if (fdt) { pid = p->pid; pr_err("[FDLEAK]dump FDs for [%d:%s]\n", pid, p->comm); fd_show_open_files(pid, files, fdt); } } } } #endif pr_info("VFS: file-max limit %lu reached\n", get_max_files()); old_max = get_nr_files(); } return ERR_PTR(-ENFILE); }
/* * Log to a cell. If the cell has already been logged to, return without * doing anything. Otherwise, log to it and mark that it has been logged * to. */ static int auth_to_cell(char *cell, char *realm) { int status = AKLOG_SUCCESS; char username[BUFSIZ]; /* To hold client username structure */ long viceId; /* AFS uid of user */ char name[ANAME_SZ]; /* Name of afs key */ char instance[INST_SZ]; /* Instance of afs key */ char realm_of_user[REALM_SZ]; /* Kerberos realm of user */ char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */ char local_cell[MAXCELLCHARS+1]; char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */ int i,j; CREDENTIALS c; struct ktc_principal aserver; struct ktc_principal aclient; struct ktc_token atoken, btoken; /* try to avoid an expensive call to get_cellconfig */ if (cell && ll_string_check(&authedcells, cell)) { if (dflag) printf("Already authenticated to %s (or tried to)\n", cell); return(AKLOG_SUCCESS); } memset(name, 0, sizeof(name)); memset(instance, 0, sizeof(instance)); memset(realm_of_user, 0, sizeof(realm_of_user)); memset(realm_of_cell, 0, sizeof(realm_of_cell)); /* NULL or empty cell returns information on local cell */ if (status = get_cellconfig(cell, &ak_cellconfig, local_cell)) return(status); strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS); cell_to_use[MAXCELLCHARS] = 0; if (ll_string_check(&authedcells, cell_to_use)) { if (dflag) printf("Already authenticated to %s (or tried to)\n", cell_to_use); return(AKLOG_SUCCESS); } /* * Record that we have attempted to log to this cell. We do this * before we try rather than after so that we will not try * and fail repeatedly for one cell. */ (void)ll_add_string(&authedcells, cell_to_use); if (dflag) printf("Authenticating to cell %s.\n", cell_to_use); if (realm && realm[0]) strcpy(realm_of_cell, realm); else strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig)); /* We use the afs.<cellname> convention here... */ strcpy(name, AFSKEY); strncpy(instance, cell_to_use, sizeof(instance)); instance[sizeof(instance)-1] = '\0'; /* * Extract the session key from the ticket file and hand-frob an * afs style authenticator. */ /* * Try to obtain AFS tickets. Because there are two valid service * names, we will try both, but trying the more specific first. * * afs.<cell>@<realm> * afs@<realm> */ if (dflag) printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell); status = get_cred(name, instance, realm_of_cell, &c); if (status == KDC_PR_UNKNOWN) { if (dflag) printf("Getting tickets: %s@%s\n", name, realm_of_cell); status = get_cred(name, "", realm_of_cell, &c); } if (status != KSUCCESS) { if (dflag) printf("Kerberos error code returned by get_cred: %d\n", status); fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n", progname, cell_to_use, krb_err_txt[status]); return(AKLOG_KERBEROS); } strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1); strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1); strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1); strcpy (username, c.pname); if (c.pinst[0]) { strcat(username, "."); strcat(username, c.pinst); } atoken.kvno = c.kvno; atoken.startTime = c.issue_date; /* ticket lifetime is in five-minutes blocks. */ atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60); memcpy(&atoken.sessionKey, c.session, 8); atoken.ticketLen = c.ticket_st.length; memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen); if (!force && !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) && atoken.kvno == btoken.kvno && atoken.ticketLen == btoken.ticketLen && !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) && !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen)) { if (dflag) printf("Identical tokens already exist; skipping.\n"); return 0; } if (noprdb) { if (dflag) printf("Not resolving name %s to id (-noprdb set)\n", username); } else { if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS) { fprintf(stderr, "%s: Couldn't determine realm of user: %s)", progname, krb_err_txt[status]); return(AKLOG_KERBEROS); } if (strcmp(realm_of_user, realm_of_cell)) { strcat(username, "@"); strcat(username, realm_of_user); } if (dflag) printf("About to resolve name %s to id\n", username); if (!pr_Initialize (0, AFSDIR_CLIENT_ETC_DIRPATH, aserver.cell)) status = pr_SNameToId (username, &viceId); if (dflag) { if (status) printf("Error %d\n", status); else printf("Id %d\n", viceId); } /* * This is a crock, but it is Transarc's crock, so * we have to play along in order to get the * functionality. The way the afs id is stored is * as a string in the username field of the token. * Contrary to what you may think by looking at * the code for tokens, this hack (AFS ID %d) will * not work if you change %d to something else. */ if ((status == 0) && (viceId != ANONYMOUSID)) sprintf (username, "AFS ID %d", viceId); } if (dflag) printf("Set username to %s\n", username); /* Reset the "aclient" structure before we call ktc_SetToken. * This structure was first set by the ktc_GetToken call when * we were comparing whether identical tokens already existed. */ strncpy(aclient.name, username, MAXKTCNAMELEN - 1); strcpy(aclient.instance, ""); strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1); if (dflag) printf("Getting tokens.\n"); if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0)) { fprintf(stderr, "%s: unable to obtain tokens for cell %s (status: %d).\n", progname, cell_to_use, status); status = AKLOG_TOKEN; } return(status); }
/* Hold a reference on the credential */ void crhold(cred_t *cr) { (void) get_cred((const cred_t *)cr); }