root/source3/lib/afs_settoken.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. afs_syscall
  2. afs_decode_token
  3. afs_settoken
  4. afs_settoken_str
  5. afs_settoken_str

   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 3 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, see <http://www.gnu.org/licenses/>.
  18  */
  19 
  20 #include "includes.h"
  21 
  22 #ifdef WITH_FAKE_KASERVER
  23 
  24 #define NO_ASN1_TYPEDEFS 1
  25 
  26 #include <afs/param.h>
  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,
     /* [<][>][^][v][top][bottom][index][help] */
  36           char * path,
  37           int cmd,
  38           char * cmarg,
  39           int follow)
  40 {
  41 /*
  42         return( syscall( SYS_afs_syscall, subcall, path, cmd, cmarg, follow));
  43 */
  44         int errcode;
  45         struct afsprocdata afs_syscall_data;
  46         afs_syscall_data.syscall = subcall;
  47         afs_syscall_data.param1 = (long)path;
  48         afs_syscall_data.param2 = cmd;
  49         afs_syscall_data.param3 = (long)cmarg;
  50         afs_syscall_data.param4 = follow;
  51         int proc_afs_file = open(PROC_SYSCALL_FNAME, O_RDWR);
  52         if (proc_afs_file < 0)
  53                 proc_afs_file = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
  54         if (proc_afs_file < 0)
  55                 return -1;
  56         errcode = ioctl(proc_afs_file, VIOC_SYSCALL, &afs_syscall_data);
  57         close(proc_afs_file);
  58         return errcode;
  59 }
  60 
  61 struct ClearToken {
  62         uint32 AuthHandle;
  63         char HandShakeKey[8];
  64         uint32 ViceId;
  65         uint32 BeginTimestamp;
  66         uint32 EndTimestamp;
  67 };
  68 
  69 static bool afs_decode_token(const char *string, char **cell,
     /* [<][>][^][v][top][bottom][index][help] */
  70                              DATA_BLOB *ticket, struct ClearToken *ct)
  71 {
  72         DATA_BLOB blob;
  73         struct ClearToken result_ct;
  74         char *saveptr;
  75 
  76         char *s = SMB_STRDUP(string);
  77 
  78         char *t;
  79 
  80         if ((t = strtok_r(s, "\n", &saveptr)) == NULL) {
  81                 DEBUG(10, ("strtok_r failed\n"));
  82                 return False;
  83         }
  84 
  85         *cell = SMB_STRDUP(t);
  86 
  87         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
  88                 DEBUG(10, ("strtok_r failed\n"));
  89                 return False;
  90         }
  91 
  92         if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
  93                 DEBUG(10, ("sscanf AuthHandle failed\n"));
  94                 return False;
  95         }
  96                 
  97         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
  98                 DEBUG(10, ("strtok_r failed\n"));
  99                 return False;
 100         }
 101 
 102         blob = base64_decode_data_blob(t);
 103 
 104         if ( (blob.data == NULL) ||
 105              (blob.length != sizeof(result_ct.HandShakeKey) )) {
 106                 DEBUG(10, ("invalid key: %x/%d\n", (uint32)blob.data,
 107                            blob.length));
 108                 return False;
 109         }
 110 
 111         memcpy(result_ct.HandShakeKey, blob.data, blob.length);
 112 
 113         data_blob_free(&blob);
 114 
 115         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
 116                 DEBUG(10, ("strtok_r failed\n"));
 117                 return False;
 118         }
 119 
 120         if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
 121                 DEBUG(10, ("sscanf ViceId failed\n"));
 122                 return False;
 123         }
 124                 
 125         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
 126                 DEBUG(10, ("strtok_r failed\n"));
 127                 return False;
 128         }
 129 
 130         if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
 131                 DEBUG(10, ("sscanf BeginTimestamp failed\n"));
 132                 return False;
 133         }
 134                 
 135         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
 136                 DEBUG(10, ("strtok_r failed\n"));
 137                 return False;
 138         }
 139 
 140         if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
 141                 DEBUG(10, ("sscanf EndTimestamp failed\n"));
 142                 return False;
 143         }
 144                 
 145         if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
 146                 DEBUG(10, ("strtok_r failed\n"));
 147                 return False;
 148         }
 149 
 150         blob = base64_decode_data_blob(t);
 151 
 152         if (blob.data == NULL) {
 153                 DEBUG(10, ("Could not get ticket\n"));
 154                 return False;
 155         }
 156 
 157         *ticket = blob;
 158         *ct = result_ct;
 159 
 160         return True;
 161 }
 162 
 163 /*
 164   Put an AFS token into the Kernel so that it can authenticate against
 165   the AFS server. This assumes correct local uid settings.
 166 
 167   This is currently highly Linux and OpenAFS-specific. The correct API
 168   call for this would be ktc_SetToken. But to do that we would have to
 169   import a REALLY big bunch of libraries which I would currently like
 170   to avoid. 
 171 */
 172 
 173 static bool afs_settoken(const char *cell,
     /* [<][>][^][v][top][bottom][index][help] */
 174                          const struct ClearToken *ctok,
 175                          DATA_BLOB ticket)
 176 {
 177         int ret;
 178         struct {
 179                 char *in, *out;
 180                 uint16 in_size, out_size;
 181         } iob;
 182 
 183         char buf[1024];
 184         char *p = buf;
 185         int tmp;
 186 
 187         memcpy(p, &ticket.length, sizeof(uint32));
 188         p += sizeof(uint32);
 189         memcpy(p, ticket.data, ticket.length);
 190         p += ticket.length;
 191 
 192         tmp = sizeof(struct ClearToken);
 193         memcpy(p, &tmp, sizeof(uint32));
 194         p += sizeof(uint32);
 195         memcpy(p, ctok, tmp);
 196         p += tmp;
 197 
 198         tmp = 0;
 199 
 200         memcpy(p, &tmp, sizeof(uint32));
 201         p += sizeof(uint32);
 202 
 203         tmp = strlen(cell);
 204         if (tmp >= MAXKTCREALMLEN) {
 205                 DEBUG(1, ("Realm too long\n"));
 206                 return False;
 207         }
 208 
 209         strncpy(p, cell, tmp);
 210         p += tmp;
 211         *p = 0;
 212         p +=1;
 213 
 214         iob.in = buf;
 215         iob.in_size = PTR_DIFF(p,buf);
 216         iob.out = buf;
 217         iob.out_size = sizeof(buf);
 218 
 219 #if 0
 220         file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
 221 #endif
 222 
 223         ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);
 224 
 225         DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
 226         return (ret == 0);
 227 }
 228 
 229 bool afs_settoken_str(const char *token_string)
     /* [<][>][^][v][top][bottom][index][help] */
 230 {
 231         DATA_BLOB ticket;
 232         struct ClearToken ct;
 233         bool result;
 234         char *cell;
 235 
 236         if (!afs_decode_token(token_string, &cell, &ticket, &ct))
 237                 return False;
 238 
 239         if (geteuid() != 0)
 240                 ct.ViceId = getuid();
 241 
 242         result = afs_settoken(cell, &ct, ticket);
 243 
 244         SAFE_FREE(cell);
 245         data_blob_free(&ticket);
 246 
 247         return result;
 248 }
 249 
 250 #else
 251 
 252 bool afs_settoken_str(const char *token_string)
     /* [<][>][^][v][top][bottom][index][help] */
 253 {
 254         return False;
 255 }
 256 
 257 #endif

/* [<][>][^][v][top][bottom][index][help] */