summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/appl/dceutils/testpag.c
blob: 8c9bf4a653b5ed6c04ded80fa03ae8b97d0c381a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* Test the k5dcepag routine by setting a pag, and
 * and execing a shell under this pag.
 *
 * This allows you to join a PAG which was created
 * earlier by some other means.
 * for example k5dcecon
 *
 * Must be run as root for testing only.
 *
 */

#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
#include <errno.h>

#define POSIX_SETJMP
#define POSIX_SIGNALS

#ifdef POSIX_SIGNALS
typedef struct sigaction handler;
#define handler_init(H,F)       (sigemptyset(&(H).sa_mask), \
                     (H).sa_flags=0, \
                     (H).sa_handler=(F))
#define handler_swap(S,NEW,OLD)     sigaction(S, &NEW, &OLD)
#define handler_set(S,OLD)      sigaction(S, &OLD, NULL)
#else
typedef sigtype (*handler)();
#define handler_init(H,F)       ((H) = (F))
#define handler_swap(S,NEW,OLD)     ((OLD) = signal ((S), (NEW)))

#define handler_set(S,OLD)      (signal ((S), (OLD)))
#endif

typedef void sigtype;

/*
 * We could include the dcedfs/syscall.h which should have these
 * numbers, but it has extra baggage. So for
 * simplicity sake now, we define these here.
 */


#define AFSCALL_SETPAG 2
#define AFSCALL_GETPAG 11

#if defined(sun)
#define AFS_SYSCALL  72

#elif defined(hpux)
/* assume HPUX 10 +  or is it 50 */
#define AFS_SYSCALL 326

#elif defined(_AIX)
#define DPAGAIX "dpagaix"
/* #define DPAGAIX "/krb5/sbin/dpagaix" */

#elif defined(sgi) || defined(_sgi)
#define AFS_SYSCALL  206+1000

#else
#define AFS_SYSCALL (Unknown_DFS_AFS_SYSCALL)
#endif

static sigjmp_buf setpag_buf;

static sigtype mysig()
{
  siglongjmp(setpag_buf, 1);
}


int  krb5_dfs_newpag(new_pag)
  int new_pag;
{
  handler sa1, osa1;
  handler sa2, osa2;
  int pag = -1;

  handler_init (sa1, mysig);
  handler_init (sa2, mysig);
  handler_swap (SIGSYS, sa1, osa1);
  handler_swap (SIGSEGV, sa2, osa2);

  if (sigsetjmp(setpag_buf, 1) == 0) {
#if defined(_AIX)
    int (*dpagaix)(int, int, int, int, int, int);

    if (dpagaix = load(DPAGAIX, 0, 0))
      pag = (*dpagaix)(AFSCALL_SETPAG, new_pag, 0, 0, 0, 0);
#else
    pag = syscall(AFS_SYSCALL,AFSCALL_SETPAG, new_pag, 0, 0, 0, 0);
#endif
    handler_set (SIGSYS, osa1);
    handler_set (SIGSEGV, osa2);
    return(pag);
  }

  fprintf(stderr,"Setpag failed with a system error\n");
  /* syscall failed! return 0 */
  handler_set (SIGSYS, osa1);
  handler_set (SIGSEGV, osa2);
  return(-1);
}

main(argc, argv)
	int argc;
	char *argv[];
{
  extern int optind;
  extern char *optarg;
  int rv;
  int rc;
  unsigned int pag;
  unsigned int newpag = 0;
  char ccname[256];
  int nflag = 0;

  while((rv = getopt(argc,argv,"n:")) != -1) {
    switch(rv) {
     case 'n':
       nflag++;
       sscanf(optarg,"%8x",&newpag);
       break;
     default:
       printf("Usage: k5dcepagt -n pag \n");
       exit(1);
    }
  }

  if (nflag) {
    fprintf (stderr,"calling k5dcepag newpag=%8.8x\n",newpag);
    pag = krb5_dfs_newpag(newpag);

    fprintf (stderr,"PAG returned = %8.8x\n",pag);
    if ((pag != 0) && (pag != -1)) {
      sprintf (ccname,
        "FILE:/opt/dcelocal/var/security/creds/dcecred_%8.8x",
        pag);
      esetenv("KRB5CCNAME",ccname,1);
      execl("/bin/csh", "csh", NULL);
    }
    else {
      fprintf(stderr," Not a good pag value\n");
    }
  }
}