master
c 516 lines 16.2 KB
Raw
1 /*++
2
3 Copyright (c) Microsoft. All rights reserved.
4
5 Module Name:
6
7 Keymgmt.c
8
9 Abstract:
10
11 This file is a keymgmt test.
12
13 --*/
14
15 #include "lxtcommon.h"
16 #include "unittests.h"
17 #include <linux/keyctl.h>
18
19 #define LXT_NAME "Keymgmt"
20
21 #define LXT_KEYMGMT_DESCRIBE_LENGTH 128
22
23 #define LxtKeyCtl(_Cmd, _Arg2, _Arg3, _Arg4, _Arg5) syscall(SYS_keyctl, (_Cmd), (_Arg2), (_Arg3), (_Arg4), (_Arg5))
24 #define LxtAdd_Key(_Type, _Desc, _Payload, _Length, _KeyRing) \
25 syscall(SYS_add_key, (_Type), (_Desc), (_Payload), (_Length), (_KeyRing))
26 #define LxtRequest_Key(_Type, _Desc, _Info, _KeyRing) syscall(SYS_request_key, (_Type), (_Desc), (_Info), (_KeyRing))
27
28 #define KEY_POS_VIEW 0x01000000
29 #define KEY_POS_READ 0x02000000
30 #define KEY_POS_WRITE 0x04000000
31 #define KEY_POS_SEARCH 0x08000000
32 #define KEY_POS_LINK 0x10000000
33 #define KEY_POS_SETATTR 0x20000000
34 #define KEY_POS_ALL 0x3f000000
35 #define KEY_USR_VIEW 0x00010000
36 #define KEY_USR_READ 0x00020000
37 #define KEY_USR_WRITE 0x00040000
38 #define KEY_USR_SEARCH 0x00080000
39 #define KEY_USR_LINK 0x00100000
40 #define KEY_USR_SETATTR 0x00200000
41 #define KEY_USR_ALL 0x003f0000
42 #define KEY_GRP_VIEW 0x00000100
43 #define KEY_GRP_READ 0x00000200
44 #define KEY_GRP_WRITE 0x00000400
45 #define KEY_GRP_SEARCH 0x00000800
46 #define KEY_GRP_LINK 0x00001000
47 #define KEY_GRP_SETATTR 0x00002000
48 #define KEY_GRP_ALL 0x00003f00
49 #define KEY_OTH_VIEW 0x00000001
50 #define KEY_OTH_READ 0x00000002
51 #define KEY_OTH_WRITE 0x00000004
52 #define KEY_OTH_SEARCH 0x00000008
53 #define KEY_OTH_LINK 0x00000010
54 #define KEY_OTH_SETATTR 0x00000020
55 #define KEY_OTH_ALL 0x0000003f
56
57 #define KEY_INVALID -1
58
59 #define LXT_KEYMGMT_ALLPERMS (KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)
60
61 #define LXT_KEYMGMT_DEFAULTPERMS (0x3f130000)
62 #define LXT_KEYMGMT_DEFAULTPERMS_STRING "3f130000"
63
64 #define LXT_KEYMGMT_NEWPERMS (0x3f3f0000)
65 #define LXT_KEYMGMT_NEWPERMS_STRING "3f3f0000"
66
67 #define LXT_KEYMGMT_SESIONKEYRING_NAME "sessionkeyring"
68 #define LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS "keyring;0;0;" LXT_KEYMGMT_DEFAULTPERMS_STRING ";" LXT_KEYMGMT_SESIONKEYRING_NAME
69 #define LXT_KEYMGMT_SESIONKEYRING_NEWPERMS "keyring;0;0;" LXT_KEYMGMT_NEWPERMS_STRING ";" LXT_KEYMGMT_SESIONKEYRING_NAME
70
71 #define LXT_KEYMGMT_SESIONKEYRING2_NAME "sessionkeyring2"
72 #define LXT_KEYMGMT_SESIONKEYRING2_DEFAULTPERMS "keyring;0;0;" LXT_KEYMGMT_DEFAULTPERMS_STRING ";" LXT_KEYMGMT_SESIONKEYRING2_NAME
73
74 #define LX_KEYMGMT_LONG_NAME_SIZE (4096 + 1)
75
76 LXT_VARIATION_HANDLER KeymgmtSessionKeyringAssociation;
77
78 LXT_VARIATION_HANDLER KeymgmtJoinSessionKeyring;
79
80 LXT_VARIATION_HANDLER KeymgmtDescribe;
81
82 LXT_VARIATION_HANDLER KeymgmtSetPerm;
83
84 //
85 // Global constants
86 //
87
88 //
89 // TODO_LX: Enable KeymgmtSessionKeyringAssociation when supported.
90 //
91
92 static const LXT_VARIATION g_LxtVariations[] = {
93 {"Keymgmt - KEYCTL_JOIN_SESSION_KEYRING", KeymgmtJoinSessionKeyring},
94 {"Keymgmt - KEYCTL_DESCRIBE", KeymgmtDescribe},
95 {"Keymgmt - KEYCTL_SETPERM", KeymgmtSetPerm},
96 /*{"Keymgmt session keyring association", KeymgmtSessionKeyringAssociation}*/};
97
98 int KeymgmtTestEntry(int Argc, char* Argv[])
99
100 /*++
101 --*/
102
103 {
104
105 LXT_ARGS Args;
106 int Result;
107
108 LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
109 LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
110
111 ErrorExit:
112 LxtUninitialize();
113 return !LXT_SUCCESS(Result);
114 }
115
116 void* KeymgmtSessionKeyringAssociationThread(void* Args)
117
118 {
119
120 char KeyBufferNew[LXT_KEYMGMT_DESCRIBE_LENGTH];
121 int32_t* KeySerial;
122 int32_t KeySerialNew;
123 int KeyType;
124 int Result;
125
126 KeyType = KEY_SPEC_SESSION_KEYRING;
127
128 //
129 // Check that the session keyring id didn't change.
130 //
131
132 KeySerial = Args;
133 LxtCheckErrno(KeySerialNew = LxtKeyCtl(KEYCTL_GET_KEYRING_ID, KeyType, 0, 0, 0));
134 LxtCheckEqual(*KeySerial, KeySerialNew, "%d");
135 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerialNew, LXT_KEYMGMT_ALLPERMS, 0, 0));
136 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerialNew, KeyBufferNew, sizeof(KeyBufferNew), 0));
137 LxtCheckStringNotEqual(LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS, KeyBufferNew);
138
139 ErrorExit:
140 pthread_exit(&Result);
141 }
142
143 int KeymgmtSessionKeyringAssociation(PLXT_ARGS Args)
144
145 /*++
146 --*/
147
148 {
149
150 pid_t ChildPid;
151 char KeyBuffer[LXT_KEYMGMT_DESCRIBE_LENGTH];
152 char KeyBufferNew[LXT_KEYMGMT_DESCRIBE_LENGTH];
153 int32_t KeySerial;
154 int32_t KeySerialNew;
155 int32_t KeySerialOriginal;
156 int KeyType;
157 int Result;
158 pthread_t Thread = {0};
159
160 ChildPid = -1;
161 KeyType = KEY_SPEC_SESSION_KEYRING;
162
163 //
164 // This test checks to see where the session keyring is associated. The
165 // documentation is unclear if it is the threadgroup, thread, or user
166 // namespace. The test below validates that the session keyring is
167 // associated to the threadgroup and inherited across fork.
168 //
169
170 //
171 // Get the current session keyring and check that is changes when a new
172 // session keyring is created.
173 //
174
175 KeySerialOriginal = LxtKeyCtl(KEYCTL_GET_KEYRING_ID, KeyType, 0, 0, 0);
176 if (KeySerialOriginal == -1)
177 {
178 KeySerialOriginal = 0;
179 }
180
181 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
182 LxtCheckNotEqual(KeySerialOriginal, KeySerial, "%d");
183 LxtLogInfo("Key %d", KeySerial);
184 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
185 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS);
186
187 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_ALLPERMS, 0, 0));
188 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
189 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
190
191 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_DEFAULTPERMS, 0, 0));
192 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
193 LxtCheckStringEqual(KeyBuffer, KeyBufferNew);
194
195 //
196 // Create a child process and thread, checking that the session keyring id
197 // continues to be associated.
198 //
199
200 LxtCheckErrno(ChildPid = fork());
201 if (ChildPid == 0)
202 {
203 LxtCheckErrno(KeySerialNew = LxtKeyCtl(KEYCTL_GET_KEYRING_ID, KeyType, 0, 0, 0));
204 LxtCheckEqual(KeySerial, KeySerialNew, "%d");
205 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_ALLPERMS, 0, 0));
206 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
207 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
208 _exit(LXT_RESULT_SUCCESS);
209 }
210
211 LxtCheckResult(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
212
213 //
214 // The changes from the child threadgroup should reflect into the parent.
215 //
216
217 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
218 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
219 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_DEFAULTPERMS, 0, 0));
220 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
221 LxtCheckStringEqual(KeyBuffer, KeyBufferNew);
222
223 //
224 // Repeat the scenario with a thread.
225 //
226
227 LxtCheckErrno(pthread_create(&Thread, NULL, KeymgmtSessionKeyringAssociationThread, &KeySerial));
228
229 pthread_join(Thread, NULL);
230 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
231 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
232 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_DEFAULTPERMS, 0, 0));
233 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
234 LxtCheckStringEqual(KeyBuffer, KeyBufferNew);
235
236 //
237 // Create a user namespace and check that the session keyring id continues
238 // to be associated.
239 //
240
241 LxtCheckErrno(ChildPid = fork());
242 if (ChildPid == 0)
243 {
244 LxtCheckErrno(KeySerialNew = LxtKeyCtl(KEYCTL_GET_KEYRING_ID, KeyType, 0, 0, 0));
245 LxtCheckEqual(KeySerial, KeySerialNew, "%d");
246 LxtCheckErrno(unshare(CLONE_NEWUSER));
247 LxtCheckErrno(KeySerialNew = LxtKeyCtl(KEYCTL_GET_KEYRING_ID, KeyType, 0, 0, 0));
248 LxtCheckEqual(KeySerial, KeySerialNew, "%d");
249 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_ALLPERMS, 0, 0));
250 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
251 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
252 _exit(LXT_RESULT_SUCCESS);
253 }
254
255 LxtCheckResult(LxtWaitPidPoll(ChildPid, LXT_RESULT_SUCCESS));
256
257 //
258 // The changes from the child threadgroup should reflect into the parent.
259 //
260
261 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
262 LxtCheckStringNotEqual(KeyBuffer, KeyBufferNew);
263 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_DEFAULTPERMS, 0, 0));
264 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBufferNew, sizeof(KeyBufferNew), 0));
265 LxtCheckStringEqual(KeyBuffer, KeyBufferNew);
266
267 Result = LXT_RESULT_SUCCESS;
268
269 ErrorExit:
270 if (ChildPid == 0)
271 {
272 _exit(Result);
273 }
274
275 return Result;
276 }
277
278 int KeymgmtJoinSessionKeyring(PLXT_ARGS Args)
279
280 /*++
281 --*/
282
283 {
284
285 pid_t ChildPid = -1;
286 int Index;
287 char* LongName = NULL;
288 char KeyBuffer[LXT_KEYMGMT_DESCRIBE_LENGTH];
289 int32_t KeySerial;
290 int32_t KeySerial2;
291 LXT_PIPE Pipe = {-1, -1};
292 int Result;
293 char* ValidNames[] = {"1", "a", "1a", ";", "name with a space ", "name with a tab\t", "name with a new line\n"};
294
295 //
296 // This test checks how KEYCTL_JOIN_SESSION_KEYRING handles keyrings.
297 //
298
299 //
300 // Check for valid names.
301 //
302
303 for (Index = 0; Index < LXT_COUNT_OF(ValidNames); ++Index)
304 {
305 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, ValidNames[Index], 0, 0, 0));
306 }
307
308 //
309 // Check for a really long name.
310 //
311
312 LongName = LxtAlloc(LX_KEYMGMT_LONG_NAME_SIZE);
313 if (LongName == 0)
314 {
315 Result = LXT_RESULT_FAILURE;
316 goto ErrorExit;
317 }
318
319 memset(LongName, 'a', LX_KEYMGMT_LONG_NAME_SIZE);
320 LongName[LX_KEYMGMT_LONG_NAME_SIZE - 1] = 0;
321 LxtCheckErrnoFailure(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LongName, 0, 0, 0), EINVAL);
322 LongName[LX_KEYMGMT_LONG_NAME_SIZE - 2] = 0;
323 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LongName, 0, 0, 0));
324
325 //
326 // TODO_LX: Add support for NULL name when supported.
327 //
328
329 //
330 // Invalid parameters.
331 //
332
333 LxtCheckErrnoFailure(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, (void*)0x1, 0, 0, 0), EFAULT);
334
335 //
336 // Check for lifetime.
337 //
338
339 LxtCheckResult(LxtCreatePipe(&Pipe));
340 LxtCheckResult(ChildPid = fork());
341 if (ChildPid == 0)
342 {
343 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
344 LxtCheckErrno(write(Pipe.Write, &KeySerial, sizeof(KeySerial)));
345 _exit(0);
346 }
347
348 LxtCheckErrno(read(Pipe.Read, &KeySerial, sizeof(KeySerial)));
349 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
350 sleep(1);
351 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0), ENOKEY);
352
353 LxtCheckResult(ChildPid = fork());
354 if (ChildPid == 0)
355 {
356 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
357 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
358 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS);
359 LxtCheckErrno(KeySerial2 = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING2_NAME, 0, 0, 0));
360 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial2, KeyBuffer, sizeof(KeyBuffer), 0));
361 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING2_DEFAULTPERMS);
362 sleep(1);
363 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0), ENOKEY);
364 _exit(0);
365 }
366
367 LxtCheckResult(LxtWaitPidPoll(ChildPid, 0));
368 Result = LXT_RESULT_SUCCESS;
369
370 ErrorExit:
371 if (ChildPid == 0)
372 {
373 _exit(Result);
374 }
375
376 if (LongName != NULL)
377 {
378 LxtFree(LongName);
379 }
380
381 LxtClosePipe(&Pipe);
382 return Result;
383 }
384
385 int KeymgmtDescribe(PLXT_ARGS Args)
386
387 /*++
388 --*/
389
390 {
391
392 pid_t ChildPid = -1;
393 int BytesRequired;
394 char KeyBuffer[LXT_KEYMGMT_DESCRIBE_LENGTH];
395 int32_t KeySerial;
396 int Result;
397
398 //
399 // This test checks how KEYCTL_DESCRIBE handles parameters.
400 //
401
402 //
403 // Check for the default values.
404 //
405
406 LxtCheckResult(ChildPid = fork());
407 if (ChildPid == 0)
408 {
409 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
410 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
411 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS);
412 LxtCheckErrno(BytesRequired = LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, NULL, 0, 0));
413 LxtCheckEqual(BytesRequired, sizeof(LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS), "%d");
414 LxtCheckErrno(BytesRequired = LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, (void*)0x1, 1, 0));
415 LxtCheckEqual(BytesRequired, sizeof(LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS), "%d");
416 _exit(0);
417 }
418
419 LxtWaitPidPoll(ChildPid, 0);
420
421 //
422 // TODO_LX: Add support for NULL name when supported.
423 //
424
425 //
426 // Invalid parameters.
427 //
428
429 LxtCheckResult(ChildPid = fork());
430 if (ChildPid == 0)
431 {
432 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
433 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, (void*)0x1, sizeof(KeyBuffer), 0), EFAULT);
434 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_DESCRIBE, KEY_INVALID, KeyBuffer, sizeof(KeyBuffer), 0), ENOKEY);
435 _exit(0);
436 }
437
438 LxtWaitPidPoll(ChildPid, 0);
439 Result = LXT_RESULT_SUCCESS;
440
441 ErrorExit:
442 if (ChildPid == 0)
443 {
444 _exit(Result);
445 }
446
447 return Result;
448 }
449
450 int KeymgmtSetPerm(PLXT_ARGS Args)
451
452 /*++
453 --*/
454
455 {
456
457 pid_t ChildPid = -1;
458 int BytesRequired;
459 char KeyBuffer[LXT_KEYMGMT_DESCRIBE_LENGTH];
460 int32_t KeySerial;
461 int Result;
462
463 //
464 // This test checks how KEYCTL_SETPERM handles parameters.
465 //
466
467 //
468 // Check for the default values.
469 //
470
471 LxtCheckResult(ChildPid = fork());
472 if (ChildPid == 0)
473 {
474 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
475 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
476 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS);
477 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_DEFAULTPERMS, 0, 0));
478 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
479 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_DEFAULTPERMS);
480 LxtCheckErrno(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, LXT_KEYMGMT_NEWPERMS, 0, 0));
481 LxtCheckErrno(LxtKeyCtl(KEYCTL_DESCRIBE, KeySerial, KeyBuffer, sizeof(KeyBuffer), 0));
482 LxtCheckStringEqual(KeyBuffer, LXT_KEYMGMT_SESIONKEYRING_NEWPERMS);
483 _exit(0);
484 }
485
486 LxtWaitPidPoll(ChildPid, 0);
487
488 //
489 // TODO_LX: Add support for NULL name when supported.
490 //
491
492 //
493 // Invalid parameters.
494 //
495
496 LxtCheckResult(ChildPid = fork());
497 if (ChildPid == 0)
498 {
499 LxtCheckErrno(KeySerial = LxtKeyCtl(KEYCTL_JOIN_SESSION_KEYRING, LXT_KEYMGMT_SESIONKEYRING_NAME, 0, 0, 0));
500 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_SETPERM, 0, LXT_KEYMGMT_DEFAULTPERMS, 0, 0), EINVAL);
501 LxtCheckErrnoFailure(LxtKeyCtl(KEYCTL_SETPERM, KeySerial, -1, 0, 0), EINVAL);
502 _exit(0);
503 }
504
505 LxtWaitPidPoll(ChildPid, 0);
506
507 Result = LXT_RESULT_SUCCESS;
508
509 ErrorExit:
510 if (ChildPid == 0)
511 {
512 _exit(Result);
513 }
514
515 return Result;
516 }