aboutsummaryrefslogtreecommitdiff
path: root/appl/dceutils/k5dcecon.c
diff options
context:
space:
mode:
Diffstat (limited to 'appl/dceutils/k5dcecon.c')
-rw-r--r--appl/dceutils/k5dcecon.c792
1 files changed, 0 insertions, 792 deletions
diff --git a/appl/dceutils/k5dcecon.c b/appl/dceutils/k5dcecon.c
deleted file mode 100644
index 88cdf281fe71..000000000000
--- a/appl/dceutils/k5dcecon.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * (c) Copyright 1995 HEWLETT-PACKARD COMPANY
- *
- * To anyone who acknowledges that this file is provided
- * "AS IS" without any express or implied warranty:
- * permission to use, copy, modify, and distribute this
- * file for any purpose is hereby granted without fee,
- * provided that the above copyright notice and this
- * notice appears in all copies, and that the name of
- * Hewlett-Packard Company not be used in advertising or
- * publicity pertaining to distribution of the software
- * without specific, written prior permission. Hewlett-
- * Packard Company makes no representations about the
- * suitability of this software for any purpose.
- *
- */
-/*
- * k5dcecon - Program to convert a K5 TGT to a DCE context,
- * for use with DFS and its PAG.
- *
- * The program is designed to be called as a sub process,
- * and return via stdout the name of the cache which implies
- * the PAG which should be used. This program itself does not
- * use the cache or PAG itself, so the PAG in the kernel for
- * this program may not be set.
- *
- * The calling program can then use the name of the cache
- * to set the KRB5CCNAME and PAG for itself and its children.
- *
- * If no ticket was passed, an attemplt to join an existing
- * PAG will be made.
- *
- * If a forwarded K5 TGT is passed in, either a new DCE
- * context will be created, or an existing one will be updated.
- * If the same ticket was already used to create an existing
- * context, it will be joined instead.
- *
- * Parts of this program are based on k5dceauth,c which was
- * given to me by HP and by the k5dcelogin.c which I developed.
- * A slightly different version of k5dcelogin.c, was added to
- * DCE 1.2.2
- *
- * D. E. Engert 6/17/97 ANL
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <locale.h>
-#include <pwd.h>
-#include <string.h>
-#include <time.h>
-
-#include <errno.h>
-#include "k5dce.h"
-
-#include <dce/sec_login.h>
-#include <dce/dce_error.h>
-#include <dce/passwd.h>
-
-/* #define DEBUG */
-#if defined(DEBUG)
-#define DEEDEBUG(A) fprintf(stderr,A); fflush(stderr)
-#define DEEDEBUG2(A,B) fprintf(stderr,A,B); fflush(stderr)
-#else
-#define DEEDEBUG(A)
-#define DEEDEBUG2(A,B)
-#endif
-
-#ifdef __hpux
-#define seteuid(A) setresuid(-1,A,-1)
-#endif
-
-
-int k5dcecreate (uid_t, char *, char*, krb5_creds **);
-int k5dcecon (uid_t, char *, char *);
-int k5dcegettgt (krb5_ccache *, char *, char *, krb5_creds **);
-int k5dcematch (uid_t, char *, char *, off_t *, krb5_creds **);
-int k5dcesession (uid_t, char *, krb5_creds **, int *,krb5_flags);
-
-
-char *progname = "k5dcecon";
-static time_t now;
-
-#ifdef notdef
-#ifdef _AIX
-/*---------------------------------------------*/
- /* AIX with DCE 1.1 does not have the com_err in the libdce.a
- * do a half hearted job of substituting for it.
- */
-void com_err(char *p1, int code, ...)
-{
- int lst;
- dce_error_string_t err_string;
- dce_error_inq_text(code, err_string, &lst);
- fprintf(stderr,"Error %d in %s: %s\n", code, p1, err_string );
-}
-
-/*---------------------------------------------*/
-void krb5_init_ets()
-{
-
-}
-#endif
-#endif
-
-
-/*------------------------------------------------*/
-/* find a cache to use for our new pag */
-/* Since there is no simple way to determine which
- * caches are associated with a pag, we will have
- * do look around and see what makes most sense on
- * different systems.
- * on a Solaris system, and in the DCE source,
- * the pags always start with a 41.
- * this is not true on the IBM, where there does not
- * appear to be any pattern.
- *
- * But since we are always certifing our creds when
- * they are received, we can us that fact, and look
- * at the first word of the associated data file
- * to see that it has a "5". If not don't use.
- */
-
-int k5dcesession(luid, pname, tgt, ppag, tflags)
- uid_t luid;
- char *pname;
- krb5_creds **tgt;
- int *ppag;
- krb5_flags tflags;
-{
- DIR *dirp;
- struct dirent *direntp;
- off_t size;
- krb5_timestamp endtime;
- int better = 0;
- krb5_creds *xtgt;
-
- char prev_name[17] = "";
- krb5_timestamp prev_endtime;
- off_t prev_size;
- u_long prev_pag = 0;
-
- char ccname[64] = "FILE:/opt/dcelocal/var/security/creds/";
-
- error_status_t st;
- sec_login_handle_t lcontext = 0;
- dce_error_string_t err_string;
- int lst;
-
- DEEDEBUG2("k5dcesession looking for flags %8.8x\n",tflags);
-
- dirp = opendir("/opt/dcelocal/var/security/creds/");
- if (dirp == NULL) {
- return 1;
- }
-
- while ( (direntp = readdir( dirp )) != NULL ) {
-
-/*
- * (but root has the ffffffff which we are not interested in)
- */
- if (!strncmp(direntp->d_name,"dcecred_",8)
- && (strlen(direntp->d_name) == 16)) {
-
- /* looks like a cache name, lets do the stat, etc */
-
- strcpy(ccname+38,direntp->d_name);
- if (!k5dcematch(luid, pname, ccname, &size, &xtgt)) {
-
- /* it's one of our caches, see if it is better
- * i.e. the endtime is farther, and if the endtimes
- * are the same, take the larger, as he who has the
- * most tickets wins.
- * it must also had the same set of flags at least
- * i.e. if the forwarded TGT is forwardable, this one must
- * be as well.
- */
-
- DEEDEBUG2("Cache:%s",direntp->d_name);
- DEEDEBUG2(" size:%d",size);
- DEEDEBUG2(" flags:%8.8x",xtgt->ticket_flags);
- DEEDEBUG2(" %s",ctime((time_t *)&xtgt->times.endtime));
-
- if ((xtgt->ticket_flags & tflags) == tflags ) {
- if (prev_name[0]) {
- if (xtgt->times.endtime > prev_endtime) {
- better = 1;
- } else if ((xtgt->times.endtime = prev_endtime)
- && (size > prev_size)){
- better = 1;
- }
- } else { /* the first */
- if (xtgt->times.endtime >= now) {
- better = 1;
- }
- }
- if (better) {
- strcpy(prev_name, direntp->d_name);
- prev_endtime = xtgt->times.endtime;
- prev_size = size;
- sscanf(prev_name+8,"%8X",&prev_pag);
- *tgt = xtgt;
- better = 0;
- }
- }
- }
- }
- }
- (void)closedir( dirp );
-
- if (!prev_name[0])
- return 1; /* failed to find one */
-
- DEEDEBUG2("Best: %s\n",prev_name);
-
- if (ppag)
- *ppag = prev_pag;
-
- strcpy(ccname+38,prev_name);
- setenv("KRB5CCNAME",ccname,1);
-
- return(0);
-}
-
-
-/*----------------------------------------------*/
-/* see if this cache is for this this principal */
-
-int k5dcematch(luid, pname, ccname, sizep, tgt)
- uid_t luid;
- char *pname;
- char *ccname;
- off_t *sizep; /* size of the file */
- krb5_creds **tgt;
-{
-
- krb5_ccache cache;
- struct stat stbuf;
- char ccdata[256];
- int fd;
- int status;
-
- /* DEEDEBUG2("k5dcematch called: cache=%s\n",ccname+38); */
-
- if (!strncmp(ccname,"FILE:",5)) {
-
- strcpy(ccdata,ccname+5);
- strcat(ccdata,".data");
-
- /* DEEDEBUG2("Checking the .data file for %s\n",ccdata); */
-
- if (stat(ccdata, &stbuf))
- return(1);
-
- if (stbuf.st_uid != luid)
- return(1);
-
- if ((fd = open(ccdata,O_RDONLY)) == -1)
- return(1);
-
- if ((read(fd,&status,4)) != 4) {
- close(fd);
- return(1);
- }
-
- /* DEEDEBUG2(".data file status = %d\n", status); */
-
- if (status != 5)
- return(1);
-
- if (stat(ccname+5, &stbuf))
- return(1);
-
- if (stbuf.st_uid != luid)
- return(1);
-
- *sizep = stbuf.st_size;
- }
-
- return(k5dcegettgt(&cache, ccname, pname, tgt));
-}
-
-
-/*----------------------------------------*/
-/* k5dcegettgt - get the tgt from a cache */
-
-int k5dcegettgt(pcache, ccname, pname, tgt)
- krb5_ccache *pcache;
- char *ccname;
- char *pname;
- krb5_creds **tgt;
-
-{
- krb5_ccache cache;
- krb5_cc_cursor cur;
- krb5_creds creds;
- int code;
- int found = 1;
- krb5_principal princ;
- char *kusername;
- krb5_flags flags;
- char *sname, *realm, *tgtname = NULL;
-
- /* Since DCE does not expose much of the Kerberos interface,
- * we will have to use what we can. This means setting the
- * KRB5CCNAME for each file we want to test
- * We will also not worry about freeing extra cache structures
- * as this this routine is also not exposed, and this should not
- * effect this module.
- * We should also free the creds contents, but that is not exposed
- * either.
- */
-
- setenv("KRB5CCNAME",ccname,1);
- cache = NULL;
- *tgt = NULL;
-
- if (code = krb5_cc_default(pcache)) {
- com_err(progname, code, "while getting ccache");
- goto return2;
- }
-
- DEEDEBUG("Got cache\n");
- flags = 0;
- if (code = krb5_cc_set_flags(*pcache, flags)) {
- com_err(progname, code,"While setting flags");
- goto return2;
- }
- DEEDEBUG("Set flags\n");
- if (code = krb5_cc_get_principal(*pcache, &princ)) {
- com_err(progname, code, "While getting princ");
- goto return1;
- }
- DEEDEBUG("Got principal\n");
- if (code = krb5_unparse_name(princ, &kusername)) {
- com_err(progname, code, "While unparsing principal");
- goto return1;
- }
-
- DEEDEBUG2("Unparsed to \"%s\"\n", kusername);
- DEEDEBUG2("pname is \"%s\"\n", pname);
- if (strcmp(kusername, pname)) {
- DEEDEBUG("Principals not equal\n");
- goto return1;
- }
- DEEDEBUG("Principals equal\n");
-
- realm = strchr(pname,'@');
- realm++;
-
- if ((tgtname = malloc(9 + 2 * strlen(realm))) == 0) {
- fprintf(stderr,"Malloc failed for tgtname\n");
- goto return1;
- }
-
- strcpy(tgtname,"krbtgt/");
- strcat(tgtname,realm);
- strcat(tgtname,"@");
- strcat(tgtname,realm);
-
- DEEDEBUG2("Getting tgt %s\n", tgtname);
- if (code = krb5_cc_start_seq_get(*pcache, &cur)) {
- com_err(progname, code, "while starting to retrieve tickets");
- goto return1;
- }
-
- while (!(code = krb5_cc_next_cred(*pcache, &cur, &creds))) {
- krb5_creds *cred = &creds;
-
- if (code = krb5_unparse_name(cred->server, &sname)) {
- com_err(progname, code, "while unparsing server name");
- continue;
- }
-
- if (strncmp(sname, tgtname, strlen(tgtname)) == 0) {
- DEEDEBUG("FOUND\n");
- if (code = krb5_copy_creds(&creds, tgt)) {
- com_err(progname, code, "while copying TGT");
- goto return1;
- }
- found = 0;
- break;
- }
- /* we should do a krb5_free_cred_contents(creds); */
- }
-
- if (code = krb5_cc_end_seq_get(*pcache, &cur)) {
- com_err(progname, code, "while finishing retrieval");
- goto return2;
- }
-
-return1:
- flags = KRB5_TC_OPENCLOSE;
- krb5_cc_set_flags(*pcache, flags); /* force a close */
-
-return2:
- if (tgtname)
- free(tgtname);
-
- return(found);
-}
-
-
-/*------------------------------------------*/
-/* Convert a forwarded TGT to a DCE context */
-int k5dcecon(luid, luser, pname)
- uid_t luid;
- char *luser;
- char *pname;
-{
-
- krb5_creds *ftgt = NULL;
- krb5_creds *tgt = NULL;
- unsigned32 dfspag;
- boolean32 reset_passwd = 0;
- int lst;
- dce_error_string_t err_string;
- char *shell_prog;
- krb5_ccache fcache;
- char *ccname;
- char *kusername;
- char *urealm;
- char *cp;
- int pag;
- int code;
- krb5_timestamp endtime;
-
-
- /* If there is no cache to be converted, we should not be here */
-
- if ((ccname = getenv("KRB5CCNAME")) == NULL) {
- DEEDEBUG("No KRB5CCNAME\n");
- return(1);
- }
-
- if (k5dcegettgt(&fcache, ccname, pname, &ftgt)) {
- fprintf(stderr, "%s: Did not find TGT\n", progname);
- return(1);
- }
-
-
- DEEDEBUG2("flags=%x\n",ftgt->ticket_flags);
- if (!(ftgt->ticket_flags & TKT_FLG_FORWARDABLE)){
- fprintf(stderr,"Ticket not forwardable\n");
- return(0); /* but OK to continue */
- }
-
- setenv("KRB5CCNAME","",1);
-
-#define TKT_ACCEPTABLE (TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE \
- | TKT_FLG_MAY_POSTDATE | TKT_FLG_RENEWABLE | TKT_FLG_HW_AUTH \
- | TKT_FLG_PRE_AUTH)
-
- if (!k5dcesession(luid, pname, &tgt, &pag,
- (ftgt->ticket_flags & TKT_ACCEPTABLE))) {
- if (ftgt->times.endtime > tgt->times.endtime) {
- DEEDEBUG("Updating existing cache\n");
- return(k5dceupdate(&ftgt, pag));
- } else {
- DEEDEBUG("Using existing cache\n");
- return(0); /* use the original one */
- }
- }
- /* see if the tgts match up */
-
- if ((code = k5dcecreate(luid, luser, pname, &ftgt))) {
- return (code);
- }
-
- /*
- * Destroy the Kerberos5 cred cache file.
- * but dont care aout the return code.
- */
-
- DEEDEBUG("Destroying the old cache\n");
- if ((code = krb5_cc_destroy(fcache))) {
- com_err(progname, code, "while destroying Kerberos5 ccache");
- }
- return (0);
-}
-
-
-/*--------------------------------------------------*/
-/* k5dceupdate - update the cache with a new TGT */
-/* Assumed that the KRB5CCNAME has been set */
-
-int k5dceupdate(krbtgt, pag)
- krb5_creds **krbtgt;
- int pag;
-{
-
- krb5_ccache ccache;
- int code;
-
- if (code = krb5_cc_default(&ccache)) {
- com_err(progname, code, "while opening cache for update");
- return(2);
- }
-
- if (code = ccache->ops->init(ccache,(*krbtgt)->client)) {
- com_err(progname, code, "while reinitilizing cache");
- return(3);
- }
-
- /* krb5_cc_store_cred */
- if (code = ccache->ops->store(ccache, *krbtgt)) {
- com_err(progname, code, "while updating cache");
- return(2);
- }
-
- sec_login_pag_new_tgt(pag, (*krbtgt)->times.endtime);
- return(0);
-}
-/*--------------------------------------------------*/
-/* k5dcecreate - create a new DCE context */
-
-int k5dcecreate(luid, luser, pname, krbtgt)
- uid_t luid;
- char *luser;
- char *pname;
- krb5_creds **krbtgt;
-{
-
- char *cp;
- char *urealm;
- char *username;
- char *defrealm;
- uid_t uid;
-
- error_status_t st;
- sec_login_handle_t lcontext = 0;
- sec_login_auth_src_t auth_src = 0;
- boolean32 reset_passwd = 0;
- int lst;
- dce_error_string_t err_string;
-
- setenv("KRB5CCNAME","",1); /* make sure it not misused */
-
- uid = getuid();
- DEEDEBUG2("uid=%d\n",uid);
-
- /* if run as root, change to user, so as to have the
- * cache created for the local user even if cross-cell
- * If run as a user, let standard file protection work.
- */
-
- if (uid == 0) {
- if (seteuid(luid) < 0)
- goto abort;
- }
-
- cp = strchr(pname,'@');
- *cp = '\0';
- urealm = ++cp;
-
- DEEDEBUG2("basename=%s\n",cp);
- DEEDEBUG2("realm=%s\n",urealm);
-
- /* now build the username as a single string or a /.../cell/user
- * if this is a cross cell
- */
-
- if ((username = malloc(7+strlen(pname)+strlen(urealm))) == 0) {
- fprintf(stderr,"Malloc failed for username\n");
- goto abort;
- }
- if (krb5_get_default_realm(&defrealm)) {
- DEEDEBUG("krb5_get_default_realm failed\n");
- goto abort;
- }
-
-
- if (!strcmp(urealm,defrealm)) {
- strcpy(username,pname);
- } else {
- strcpy(username,"/.../");
- strcat(username,urealm);
- strcat(username,"/");
- strcat(username,pname);
- }
-
- /*
- * Setup a DCE login context
- */
-
- if (sec_login_setup_identity((unsigned_char_p_t)username,
- (sec_login_external_tgt|sec_login_proxy_cred),
- &lcontext, &st)) {
- /*
- * Add our TGT.
- */
- DEEDEBUG("Adding our new TGT\n");
- sec_login_krb5_add_cred(lcontext, *krbtgt, &st);
- if (st) {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Error while adding credentials for %s because %s\n",
- username, err_string);
- goto abort;
- }
- DEEDEBUG("validating and certifying\n");
- /*
- * Now "validate" and certify the identity,
- * usually we would pass a password here, but...
- * sec_login_valid_and_cert_ident
- * sec_login_validate_identity
- */
-
- if (sec_login_validate_identity(lcontext, 0, &reset_passwd,
- &auth_src, &st)) {
- DEEDEBUG2("validate_identity st=%d\n",st);
- if (st) {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr, "Validation error for %s because %s\n",
- username, err_string);
- goto abort;
- }
- if (!sec_login_certify_identity(lcontext,&st)) {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Credentials not certified because %s\n",err_string);
- }
- if (reset_passwd) {
- fprintf(stderr,
- "Password must be changed for %s\n", username);
- }
- if (auth_src == sec_login_auth_src_local) {
- fprintf(stderr,
- "Credentials obtained from local registry for %s\n",
- username);
- }
- if (auth_src == sec_login_auth_src_overridden) {
- fprintf(stderr, "Validated %s from local override entry, no network credentials obtained\n", username);
- goto abort;
-
- }
- /*
- * Actually create the cred files.
- */
- DEEDEBUG("Ceating new cred files.\n");
- sec_login_set_context(lcontext, &st);
- if (st) {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Unable to set context for %s because %s\n",
- username, err_string);
- goto abort;
- }
-
- /*
- * Now free up the local context and leave the
- * network context with its pag
- */
-#if 0
- sec_login_release_context(&lcontext, &st);
- if (st) {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Unable to release context for %s because %s\n",
- username, err_string);
- goto abort;
- }
-#endif
- }
- else {
- DEEDEBUG2("validate failed %d\n",st);
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Unable to validate %s because %s\n", username,
- err_string);
- goto abort;
- }
- }
- else {
- dce_error_inq_text(st, err_string, &lst);
- fprintf(stderr,
- "Unable to setup login entry for %s because %s\n",
- username, err_string);
- goto abort;
- }
-
- done:
- /* if we were root, get back to root */
-
- DEEDEBUG2("sec_login_inq_pag %8.8x\n",
- sec_login_inq_pag(lcontext, &st));
-
- if (uid == 0) {
- seteuid(0);
- }
-
- DEEDEBUG("completed\n");
- return(0);
-
- abort:
- if (uid == 0) {
- seteuid(0);
- }
-
- DEEDEBUG("Aborting\n");
- return(2);
-}
-
-
-
-/*-------------------------------------------------*/
-main(argc, argv)
- int argc;
- char *argv[];
-{
- int status;
- extern int optind;
- extern char *optarg;
- int rv;
-
- char *lusername = NULL;
- char *pname = NULL;
- int fflag = 0;
- struct passwd *pw;
- uid_t luid;
- uid_t myuid;
- char *ccname;
- krb5_creds *tgt = NULL;
-
-#ifdef DEBUG
- close(2);
- open("/tmp/k5dce.debug",O_WRONLY|O_CREAT|O_APPEND, 0600);
-#endif
-
- if (myuid = getuid()) {
- DEEDEBUG2("UID = %d\n",myuid);
- exit(33); /* must be root to run this, get out now */
- }
-
- while ((rv = getopt(argc,argv,"l:p:fs")) != -1) {
- DEEDEBUG2("Arg = %c\n", rv);
- switch(rv) {
- case 'l': /* user name */
- lusername = optarg;
- DEEDEBUG2("Optarg = %s\n", optarg);
- break;
- case 'p': /* principal name */
- pname = optarg;
- DEEDEBUG2("Optarg = %s\n", optarg);
- break;
- case 'f': /* convert a forwarded TGT to a context */
- fflag++;
- break;
- case 's': /* old test parameter, ignore it */
- break;
- }
- }
-
- setlocale(LC_ALL, "");
- krb5_init_ets();
- time(&now); /* set time to check expired tickets */
-
- /* if lusername == NULL, Then user is passed as the USER= variable */
-
- if (!lusername) {
- lusername = getenv("USER");
- if (!lusername) {
- fprintf(stderr, "USER not in environment\n");
- return(3);
- }
- }
-
- if ((pw = getpwnam(lusername)) == NULL) {
- fprintf(stderr, "Who are you?\n");
- return(44);
- }
-
- luid = pw->pw_uid;
-
- if (fflag) {
- status = k5dcecon(luid, lusername, pname);
- } else {
- status = k5dcesession(luid, pname, &tgt, NULL, 0);
- }
-
- if (!status) {
- printf("%s",getenv("KRB5CCNAME")); /* return via stdout to caller */
- DEEDEBUG2("KRB5CCNAME=%s\n",getenv("KRB5CCNAME"));
- }
-
- DEEDEBUG2("Returning status %d\n",status);
- return (status);
-}