~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/lib/afs_settoken.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 *  Unix SMB/CIFS implementation.
3
 
 *  Generate AFS tickets
4
 
 *  Copyright (C) Volker Lendecke 2004
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *  
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *  
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
 */
20
 
 
21
 
#include "includes.h"
22
 
 
23
 
#ifdef WITH_FAKE_KASERVER
24
 
 
25
 
#define NO_ASN1_TYPEDEFS 1
26
 
 
27
 
#include <afs/stds.h>
28
 
#include <afs/afs.h>
29
 
#include <afs/auth.h>
30
 
#include <afs/venus.h>
31
 
#include <asm/unistd.h>
32
 
#include <openssl/des.h>
33
 
#include <sys/syscall.h>
34
 
 
35
 
int afs_syscall( int subcall,
36
 
          char * path,
37
 
          int cmd,
38
 
          char * cmarg,
39
 
          int follow)
40
 
{
41
 
        return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
42
 
}
43
 
 
44
 
struct ClearToken {
45
 
        uint32 AuthHandle;
46
 
        char HandShakeKey[8];
47
 
        uint32 ViceId;
48
 
        uint32 BeginTimestamp;
49
 
        uint32 EndTimestamp;
50
 
};
51
 
 
52
 
static BOOL afs_decode_token(const char *string, char **cell,
53
 
                             DATA_BLOB *ticket, struct ClearToken *ct)
54
 
{
55
 
        DATA_BLOB blob;
56
 
        struct ClearToken result_ct;
57
 
 
58
 
        char *s = SMB_STRDUP(string);
59
 
 
60
 
        char *t;
61
 
 
62
 
        if ((t = strtok(s, "\n")) == NULL) {
63
 
                DEBUG(10, ("strtok failed\n"));
64
 
                return False;
65
 
        }
66
 
 
67
 
        *cell = SMB_STRDUP(t);
68
 
 
69
 
        if ((t = strtok(NULL, "\n")) == NULL) {
70
 
                DEBUG(10, ("strtok failed\n"));
71
 
                return False;
72
 
        }
73
 
 
74
 
        if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
75
 
                DEBUG(10, ("sscanf AuthHandle failed\n"));
76
 
                return False;
77
 
        }
78
 
                
79
 
        if ((t = strtok(NULL, "\n")) == NULL) {
80
 
                DEBUG(10, ("strtok failed\n"));
81
 
                return False;
82
 
        }
83
 
 
84
 
        blob = base64_decode_data_blob(t);
85
 
 
86
 
        if ( (blob.data == NULL) ||
87
 
             (blob.length != sizeof(result_ct.HandShakeKey) )) {
88
 
                DEBUG(10, ("invalid key: %x/%d\n", (uint32)blob.data,
89
 
                           blob.length));
90
 
                return False;
91
 
        }
92
 
 
93
 
        memcpy(result_ct.HandShakeKey, blob.data, blob.length);
94
 
 
95
 
        data_blob_free(&blob);
96
 
 
97
 
        if ((t = strtok(NULL, "\n")) == NULL) {
98
 
                DEBUG(10, ("strtok failed\n"));
99
 
                return False;
100
 
        }
101
 
 
102
 
        if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
103
 
                DEBUG(10, ("sscanf ViceId failed\n"));
104
 
                return False;
105
 
        }
106
 
                
107
 
        if ((t = strtok(NULL, "\n")) == NULL) {
108
 
                DEBUG(10, ("strtok failed\n"));
109
 
                return False;
110
 
        }
111
 
 
112
 
        if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
113
 
                DEBUG(10, ("sscanf BeginTimestamp failed\n"));
114
 
                return False;
115
 
        }
116
 
                
117
 
        if ((t = strtok(NULL, "\n")) == NULL) {
118
 
                DEBUG(10, ("strtok failed\n"));
119
 
                return False;
120
 
        }
121
 
 
122
 
        if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
123
 
                DEBUG(10, ("sscanf EndTimestamp failed\n"));
124
 
                return False;
125
 
        }
126
 
                
127
 
        if ((t = strtok(NULL, "\n")) == NULL) {
128
 
                DEBUG(10, ("strtok failed\n"));
129
 
                return False;
130
 
        }
131
 
 
132
 
        blob = base64_decode_data_blob(t);
133
 
 
134
 
        if (blob.data == NULL) {
135
 
                DEBUG(10, ("Could not get ticket\n"));
136
 
                return False;
137
 
        }
138
 
 
139
 
        *ticket = blob;
140
 
        *ct = result_ct;
141
 
 
142
 
        return True;
143
 
}
144
 
 
145
 
/*
146
 
  Put an AFS token into the Kernel so that it can authenticate against
147
 
  the AFS server. This assumes correct local uid settings.
148
 
 
149
 
  This is currently highly Linux and OpenAFS-specific. The correct API
150
 
  call for this would be ktc_SetToken. But to do that we would have to
151
 
  import a REALLY big bunch of libraries which I would currently like
152
 
  to avoid. 
153
 
*/
154
 
 
155
 
static BOOL afs_settoken(const char *cell,
156
 
                         const struct ClearToken *ctok,
157
 
                         DATA_BLOB ticket)
158
 
{
159
 
        int ret;
160
 
        struct {
161
 
                char *in, *out;
162
 
                uint16 in_size, out_size;
163
 
        } iob;
164
 
 
165
 
        char buf[1024];
166
 
        char *p = buf;
167
 
        int tmp;
168
 
 
169
 
        memcpy(p, &ticket.length, sizeof(uint32));
170
 
        p += sizeof(uint32);
171
 
        memcpy(p, ticket.data, ticket.length);
172
 
        p += ticket.length;
173
 
 
174
 
        tmp = sizeof(struct ClearToken);
175
 
        memcpy(p, &tmp, sizeof(uint32));
176
 
        p += sizeof(uint32);
177
 
        memcpy(p, ctok, tmp);
178
 
        p += tmp;
179
 
 
180
 
        tmp = 0;
181
 
 
182
 
        memcpy(p, &tmp, sizeof(uint32));
183
 
        p += sizeof(uint32);
184
 
 
185
 
        tmp = strlen(cell);
186
 
        if (tmp >= MAXKTCREALMLEN) {
187
 
                DEBUG(1, ("Realm too long\n"));
188
 
                return False;
189
 
        }
190
 
 
191
 
        strncpy(p, cell, tmp);
192
 
        p += tmp;
193
 
        *p = 0;
194
 
        p +=1;
195
 
 
196
 
        iob.in = buf;
197
 
        iob.in_size = PTR_DIFF(p,buf);
198
 
        iob.out = buf;
199
 
        iob.out_size = sizeof(buf);
200
 
 
201
 
#if 0
202
 
        file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
203
 
#endif
204
 
 
205
 
        ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
206
 
 
207
 
        DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
208
 
        return (ret == 0);
209
 
}
210
 
 
211
 
BOOL afs_settoken_str(const char *token_string)
212
 
{
213
 
        DATA_BLOB ticket;
214
 
        struct ClearToken ct;
215
 
        BOOL result;
216
 
        char *cell;
217
 
 
218
 
        if (!afs_decode_token(token_string, &cell, &ticket, &ct))
219
 
                return False;
220
 
 
221
 
        if (geteuid() != 0)
222
 
                ct.ViceId = getuid();
223
 
 
224
 
        result = afs_settoken(cell, &ct, ticket);
225
 
 
226
 
        SAFE_FREE(cell);
227
 
        data_blob_free(&ticket);
228
 
 
229
 
        return result;
230
 
}
231
 
 
232
 
#else
233
 
 
234
 
BOOL afs_settoken_str(const char *token_string)
235
 
{
236
 
        return False;
237
 
}
238
 
 
239
 
#endif