summaryrefslogtreecommitdiffstats
path: root/source3/lib/afs_settoken.c
blob: 6421c0a55b47454ad0c86a1f9854cdce1c346ef7 (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
generated by cgit  (git 2.34.1) at 2025-10-05 00:36:09 +0000
 


>\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.AuthHandle) != 1) {
		DEBUG(10, ("sscanf AuthHandle failed\n"));
		return False;
	}
		
	if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	blob = base64_decode_data_blob(t);

	if ( (blob.data == NULL) ||
	     (blob.length != sizeof(result_ct.HandShakeKey) )) {
		DEBUG(10, ("invalid key: %x/%d\n", (uint32)blob.data,
			   blob.length));
		return False;
	}

	memcpy(result_ct.HandShakeKey, blob.data, blob.length);

	data_blob_free(&blob);

	if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.ViceId) != 1) {
		DEBUG(10, ("sscanf ViceId failed\n"));
		return False;
	}
		
	if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.BeginTimestamp) != 1) {
		DEBUG(10, ("sscanf BeginTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	if (sscanf(t, "%u", &result_ct.EndTimestamp) != 1) {
		DEBUG(10, ("sscanf EndTimestamp failed\n"));
		return False;
	}
		
	if ((t = strtok_r(NULL, "\n", &saveptr)) == NULL) {
		DEBUG(10, ("strtok_r failed\n"));
		return False;
	}

	blob = base64_decode_data_blob(t);

	if (blob.data == NULL) {
		DEBUG(10, ("Could not get ticket\n"));
		return False;
	}

	*ticket = blob;
	*ct = result_ct;

	return True;
}

/*
  Put an AFS token into the Kernel so that it can authenticate against
  the AFS server. This assumes correct local uid settings.

  This is currently highly Linux and OpenAFS-specific. The correct API
  call for this would be ktc_SetToken. But to do that we would have to
  import a REALLY big bunch of libraries which I would currently like
  to avoid. 
*/

static bool afs_settoken(const char *cell,
			 const struct ClearToken *ctok,
			 DATA_BLOB ticket)
{
	int ret;
	struct {
		char *in, *out;
		uint16 in_size, out_size;
	} iob;

	char buf[1024];
	char *p = buf;
	int tmp;

	memcpy(p, &ticket.length, sizeof(uint32));
	p += sizeof(uint32);
	memcpy(p, ticket.data, ticket.length);
	p += ticket.length;

	tmp = sizeof(struct ClearToken);
	memcpy(p, &tmp, sizeof(uint32));
	p += sizeof(uint32);
	memcpy(p, ctok, tmp);
	p += tmp;

	tmp = 0;

	memcpy(p, &tmp, sizeof(uint32));
	p += sizeof(uint32);

	tmp = strlen(cell);
	if (tmp >= MAXKTCREALMLEN) {
		DEBUG(1, ("Realm too long\n"));
		return False;
	}

	strncpy(p, cell, tmp);
	p += tmp;
	*p = 0;
	p +=1;

	iob.in = buf;
	iob.in_size = PTR_DIFF(p,buf);
	iob.out = buf;
	iob.out_size = sizeof(buf);

#if 0
	file_save("/tmp/ioctlbuf", iob.in, iob.in_size);
#endif

	ret = afs_syscall(AFSCALL_PIOCTL, 0, VIOCSETTOK, (char *)&iob, 0);

	DEBUG(10, ("afs VIOCSETTOK returned %d\n", ret));
	return (ret == 0);
}

bool afs_settoken_str(const char *token_string)
{
	DATA_BLOB ticket;
	struct ClearToken ct;
	bool result;
	char *cell;

	if (!afs_decode_token(token_string, &cell, &ticket, &ct))
		return False;

	if (geteuid() != 0)
		ct.ViceId = getuid();

	result = afs_settoken(cell, &ct, ticket);

	SAFE_FREE(cell);
	data_blob_free(&ticket);

	return result;
}

#else

bool afs_settoken_str(const char *token_string)
{
	return False;
}

#endif