Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / auth / userok.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12 #include <afs/stds.h>
13
14 #include <roken.h>
15 #include <afs/opr.h>
16
17 #include <ctype.h>
18
19 #include <afs/pthread_glock.h>
20 #include <rx/xdr.h>
21 #include <rx/rx.h>
22 #include <rx/rx_identity.h>
23 #include <afs/afsutil.h>
24 #include <afs/fileutil.h>
25
26 #include "base64.h"
27 #include "auth.h"
28 #include "cellconfig.h"
29 #include "keys.h"
30 #include "afs/audit.h"
31
32 /* The display names for localauth and noauth identities; they aren't used
33 * inside tickets or anything, but just serve as something to display in logs,
34 * etc. */
35 #define AFS_LOCALAUTH_NAME "<LocalAuth>"
36 #define AFS_LOCALAUTH_LEN (sizeof(AFS_LOCALAUTH_NAME)-1)
37 #define AFS_NOAUTH_NAME "<NoAuth>"
38 #define AFS_NOAUTH_LEN (sizeof(AFS_NOAUTH_NAME)-1)
39
40 static int ParseLine(char *buffer, struct rx_identity *user);
41
42 static void
43 UserListFileName(struct afsconf_dir *adir,
44 char *buffer, size_t len)
45 {
46 strcompose(buffer, len, adir->name, "/", AFSDIR_ULIST_FILE, (char *)NULL);
47 }
48
49 int
50 afsconf_CheckAuth(void *arock, struct rx_call *acall)
51 {
52 struct afsconf_dir *adir = (struct afsconf_dir *) arock;
53 int rc;
54 LOCK_GLOBAL_MUTEX;
55 rc = ((afsconf_SuperUser(adir, acall, NULL) == 0) ? 10029 : 0);
56 UNLOCK_GLOBAL_MUTEX;
57 return rc;
58 }
59
60 static int
61 GetNoAuthFlag(struct afsconf_dir *adir)
62 {
63 if (access(AFSDIR_SERVER_NOAUTH_FILEPATH, 0) == 0) {
64 osi_audit(NoAuthEvent, 0, AUD_END); /* some random server is running noauth */
65 return 1; /* if /usr/afs/local/NoAuth file exists, allow access */
66 }
67 return 0;
68 }
69
70
71 int
72 afsconf_GetNoAuthFlag(struct afsconf_dir *adir)
73 {
74 int rc;
75
76 LOCK_GLOBAL_MUTEX;
77 rc = GetNoAuthFlag(adir);
78 UNLOCK_GLOBAL_MUTEX;
79 return rc;
80 }
81
82 void
83 afsconf_SetNoAuthFlag(struct afsconf_dir *adir, int aflag)
84 {
85 afs_int32 code;
86
87 LOCK_GLOBAL_MUTEX;
88 if (aflag == 0) {
89 /* turn off noauth flag */
90 code = (unlink(AFSDIR_SERVER_NOAUTH_FILEPATH) ? errno : 0);
91 osi_audit(NoAuthDisableEvent, code, AUD_END);
92 } else {
93 /* try to create file */
94 code =
95 open(AFSDIR_SERVER_NOAUTH_FILEPATH, O_CREAT | O_TRUNC | O_RDWR,
96 0666);
97 if (code >= 0) {
98 close(code);
99 osi_audit(NoAuthEnableEvent, 0, AUD_END);
100 } else
101 osi_audit(NoAuthEnableEvent, errno, AUD_END);
102 }
103 UNLOCK_GLOBAL_MUTEX;
104 }
105
106 /*!
107 * Remove an identity from the UserList file
108 *
109 * This function removes the given identity from the user list file.
110 * For the purposes of identifying entries to remove, only the
111 * type and exportedName portions of the identity are used. Callers
112 * should remember that a given identity may be listed in the file in
113 * a number of different ways.
114 *
115 * @param adir
116 * A structure representing the configuration directory currently
117 * in use
118 * @param user
119 * The RX identity to delete
120 *
121 * @returns
122 * 0 on success, an error code on failure
123 */
124
125 int
126 afsconf_DeleteIdentity(struct afsconf_dir *adir, struct rx_identity *user)
127 {
128 char *filename, *nfilename;
129 char *buffer;
130 char *copy;
131 FILE *tf;
132 FILE *nf;
133 int flag;
134 char *tp;
135 int found;
136 struct stat tstat;
137 struct rx_identity identity;
138 afs_int32 code;
139
140 memset(&identity, 0, sizeof(struct rx_identity));
141
142 buffer = malloc(AFSDIR_PATH_MAX);
143 if (buffer == NULL)
144 return ENOMEM;
145 filename = malloc(AFSDIR_PATH_MAX);
146 if (filename == NULL) {
147 free(buffer);
148 return ENOMEM;
149 }
150
151 LOCK_GLOBAL_MUTEX;
152 UserListFileName(adir, filename, AFSDIR_PATH_MAX);
153 #ifndef AFS_NT40_ENV
154 {
155 /*
156 * We attempt to fully resolve this pathname, so that the rename
157 * of the temporary file will work even if UserList is a symlink
158 * into a different filesystem.
159 */
160 nfilename = malloc(AFSDIR_PATH_MAX);
161 if (nfilename == NULL) {
162 UNLOCK_GLOBAL_MUTEX;
163 free(filename);
164 free(buffer);
165 return ENOMEM;
166 }
167 if (realpath(filename, nfilename)) {
168 free(filename);
169 filename = nfilename;
170 } else {
171 free(nfilename);
172 }
173 }
174 #endif /* AFS_NT40_ENV */
175 if (asprintf(&nfilename, "%s.NXX", filename) < 0) {
176 UNLOCK_GLOBAL_MUTEX;
177 free(filename);
178 free(buffer);
179 return -1;
180 }
181 tf = fopen(filename, "r");
182 if (!tf) {
183 UNLOCK_GLOBAL_MUTEX;
184 free(filename);
185 free(nfilename);
186 free(buffer);
187 return -1;
188 }
189 code = stat(filename, &tstat);
190 if (code < 0) {
191 UNLOCK_GLOBAL_MUTEX;
192 free(filename);
193 free(nfilename);
194 free(buffer);
195 return code;
196 }
197 nf = fopen(nfilename, "w+");
198 if (!nf) {
199 fclose(tf);
200 UNLOCK_GLOBAL_MUTEX;
201 free(filename);
202 free(nfilename);
203 free(buffer);
204 return EIO;
205 }
206 flag = 0;
207 found = 0;
208 while (1) {
209 /* check for our user id */
210 tp = fgets(buffer, AFSDIR_PATH_MAX, tf);
211 if (tp == NULL)
212 break;
213
214 copy = strdup(buffer);
215 if (copy == NULL) {
216 flag = 1;
217 break;
218 }
219 code = ParseLine(copy, &identity);
220 if (code == 0 && rx_identity_match(user, &identity)) {
221 /* found the guy, don't copy to output file */
222 found = 1;
223 } else {
224 /* otherwise copy original line to output */
225 fprintf(nf, "%s", buffer);
226 }
227 free(copy);
228 rx_identity_freeContents(&identity);
229 }
230 fclose(tf);
231 free(buffer);
232 if (ferror(nf))
233 flag = 1;
234 if (fclose(nf) == EOF)
235 flag = 1;
236 if (flag == 0) {
237 /* try the rename */
238 flag = rk_rename(nfilename, filename);
239 if (flag == 0)
240 flag = chmod(filename, tstat.st_mode);
241 } else
242 unlink(nfilename);
243
244 /* finally, decide what to return to the caller */
245 UNLOCK_GLOBAL_MUTEX;
246 free(filename);
247 free(nfilename);
248 if (flag)
249 return EIO; /* something mysterious went wrong */
250 if (!found)
251 return ENOENT; /* entry wasn't found, no changes made */
252 return 0; /* everything was fine */
253 }
254
255 /*!
256 * Remove a legacy Kerberos 4 name from the UserList file.
257 *
258 * This function removes a Kerberos 4 name from the super user list. It
259 * can only remove names which were added by the afsconf_AddUser interface,
260 * or with an explicit Kerberos v4 type.
261 *
262 * @param[in] adir
263 * A structure representing the configuration directory
264 * @param[in] name
265 * The Kerberos v4 name to remove
266 *
267 * @returns
268 * 0 on success, an error code upon failure.
269 *
270 * Note that this function is deprecated. New callers should use
271 * afsconf_DeleteIdentity instead.
272 */
273
274 int
275 afsconf_DeleteUser(struct afsconf_dir *adir, char *name)
276 {
277 struct rx_identity *user;
278 int code;
279
280 user = rx_identity_new(RX_ID_KRB4, name, name, strlen(name));
281 if (!user)
282 return ENOMEM;
283
284 code = afsconf_DeleteIdentity(adir, user);
285
286 rx_identity_free(&user);
287
288 return code;
289 }
290
291 /* This is a multi-purpose funciton for use by either
292 * GetNthIdentity or GetNthUser. The parameter 'id' indicates
293 * whether we are counting all identities (if true), or just
294 * ones which can be represented by the old-style interfaces
295 * We return -1 for EOF, 0 for success, and >0 for all errors.
296 */
297 static int
298 GetNthIdentityOrUser(struct afsconf_dir *dir, int count,
299 struct rx_identity **identity, int id)
300 {
301 bufio_p bp;
302 char *tbuffer;
303 struct rx_identity fileUser;
304 afs_int32 code;
305
306 tbuffer = malloc(AFSDIR_PATH_MAX);
307 if (tbuffer == NULL)
308 return ENOMEM;
309
310 LOCK_GLOBAL_MUTEX;
311 UserListFileName(dir, tbuffer, AFSDIR_PATH_MAX);
312 bp = BufioOpen(tbuffer, O_RDONLY, 0);
313 if (!bp) {
314 UNLOCK_GLOBAL_MUTEX;
315 free(tbuffer);
316 return -1;
317 }
318 while (1) {
319 code = BufioGets(bp, tbuffer, AFSDIR_PATH_MAX);
320 if (code < 0) {
321 code = -1;
322 break;
323 }
324
325 code = ParseLine(tbuffer, &fileUser);
326 if (code != 0)
327 break;
328
329 if (id || fileUser.kind == RX_ID_KRB4)
330 count--;
331
332 if (count < 0)
333 break;
334 else
335 rx_identity_freeContents(&fileUser);
336 }
337 if (code == 0) {
338 *identity = rx_identity_copy(&fileUser);
339 rx_identity_freeContents(&fileUser);
340 }
341
342 BufioClose(bp);
343
344 UNLOCK_GLOBAL_MUTEX;
345 free(tbuffer);
346 return code;
347 }
348
349 /*!
350 * Return the Nth super user identity from the UserList
351 *
352 * @param[in] dir
353 * A structure representing the configuration directory
354 * @param[in] count
355 * A count (from zero) of the entries to return from the
356 * UserList
357 * @param[out] identity
358 * A pointer to the Nth identity
359 * @returns
360 * status code
361 * @retval 0 Success
362 * @retval -1 We have searched beyond the end of the list.
363 * @retval >0 Error
364 */
365
366 int
367 afsconf_GetNthIdentity(struct afsconf_dir *dir, int count,
368 struct rx_identity **identity)
369 {
370 return GetNthIdentityOrUser(dir, count, identity, 1);
371 }
372
373 /*!
374 * Return the Nth Kerberos v4 identity from the UserList
375 *
376 * This returns the Nth old, kerberos v4 style name from
377 * the UserList file. In counting entries it skips any other
378 * name types it encounters - so will hide any new-style
379 * identities from its callers.
380 *
381 * @param[in] dir
382 * A structure representing the configuration directory
383 * @param[in] count
384 * A count (from zero) of the entries to return from the
385 * UserList
386 * @param abuffer
387 * A string in which to write the name of the Nth identity
388 * @param abufferLen
389 * The length of the buffer passed in abuffer
390 * @returns
391 * status code
392 * @retval 0 Success
393 * @retval 1 Either an EPERM error, or we have searched beyond the end of the
394 * list.
395 * @retval >1 All other errors.
396 *
397 * This function is deprecated, all new callers should use
398 * GetNthIdentity instead. This function is particularly dangerous
399 * as it will hide any new-style identities from callers. It is also
400 * impossible to distinguish an EPERM error from a normal end-of-file
401 * condition with this function.
402 */
403
404 int
405 afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer,
406 afs_int32 abufferLen)
407 {
408 struct rx_identity *identity;
409 int code;
410
411 code = GetNthIdentityOrUser(adir, an, &identity, 0);
412 if (code == 0) {
413 strlcpy(abuffer, identity->displayName, abufferLen);
414 rx_identity_free(&identity);
415 }
416 if (code == -1) {
417 /* The new functions use -1 to indicate EOF, but the old interface
418 * uses 1 to indicate EOF. */
419 code = 1;
420 }
421 return code;
422 }
423
424 /*!
425 * Parse a UserList list
426 *
427 * Parse a line of data from a UserList file
428 *
429 * This parses a line of data in a UserList, and populates the passed
430 * rx_identity structure with the information about the user.
431 *
432 * @param buffer A string containing the line to be parsed
433 * @param user The user structure to be populated
434 *
435 * Note that the user->displayName, and user->exportedName.val fields
436 * must be freed with free() by the caller.
437 *
438 * This function damages the buffer thats passed to it. Callers are
439 * expected to make a copy if they want the buffer preserved.
440 *
441 * @return
442 * 0 on success, non-zero on failure.
443 */
444
445 static int
446 ParseLine(char *buffer, struct rx_identity *user)
447 {
448 char *ptr;
449 char *ename;
450 char *displayName;
451 char *decodedName;
452 char name[64+1];
453 int len;
454 int kind;
455 int code;
456
457 if (buffer[0] == ' ') { /* extended names have leading space */
458 ptr = buffer + 1;
459 code = sscanf(ptr, "%i", &kind);
460 if (code != 1)
461 return EINVAL;
462
463 strsep(&ptr, " "); /* skip the bit we just read with scanf */
464 ename = strsep(&ptr, " "); /* Pull out the ename */
465 displayName = strsep(&ptr, " "); /* Display name runs to the end */
466 if (ename == NULL || displayName == NULL)
467 return EINVAL;
468
469 decodedName = malloc(strlen(ename));
470 if (decodedName == NULL)
471 return ENOMEM;
472
473 len = base64_decode(ename, decodedName);
474 if (len<0) {
475 free(decodedName);
476 return EINVAL;
477 }
478
479 rx_identity_populate(user, kind, displayName, decodedName, len);
480 free(decodedName);
481
482 return 0; /* Success ! */
483 }
484
485 /* No extended name, try for a legacy name */
486 code = sscanf(buffer, "%64s", name);
487 if (code != 1)
488 return EINVAL;
489
490 rx_identity_populate(user, RX_ID_KRB4, name, name, strlen(name));
491 return 0;
492 }
493
494 /*!
495 * Check if a given identity is in the UserList file,
496 * and thus is a super user
497 *
498 * @param adir
499 * A structure representing the configuration directory to check
500 * @param user
501 * The identity to check
502 * @returns
503 * True if the user is listed in the UserList, otherwise false
504 */
505
506 int
507 afsconf_IsSuperIdentity(struct afsconf_dir *adir,
508 struct rx_identity *user)
509 {
510 bufio_p bp;
511 char *tbuffer;
512 struct rx_identity fileUser;
513 int match;
514 afs_int32 code;
515
516 if (user->kind == RX_ID_SUPERUSER)
517 return 1;
518
519 tbuffer = malloc(AFSDIR_PATH_MAX);
520 if (tbuffer == NULL)
521 return 0;
522
523 UserListFileName(adir, tbuffer, AFSDIR_PATH_MAX);
524 bp = BufioOpen(tbuffer, O_RDONLY, 0);
525 if (!bp) {
526 free(tbuffer);
527 return 0;
528 }
529 match = 0;
530 while (!match) {
531 code = BufioGets(bp, tbuffer, AFSDIR_PATH_MAX);
532 if (code < 0)
533 break;
534
535 code = ParseLine(tbuffer, &fileUser);
536 if (code != 0)
537 break;
538
539 match = rx_identity_match(user, &fileUser);
540
541 rx_identity_freeContents(&fileUser);
542 }
543 BufioClose(bp);
544 free(tbuffer);
545 return match;
546 }
547
548 /* add a user to the user list, checking for duplicates */
549 int
550 afsconf_AddIdentity(struct afsconf_dir *adir, struct rx_identity *user)
551 {
552 FILE *tf;
553 afs_int32 code;
554 char *ename;
555 char *tbuffer;
556
557 LOCK_GLOBAL_MUTEX;
558 if (afsconf_IsSuperIdentity(adir, user)) {
559 UNLOCK_GLOBAL_MUTEX;
560 return EEXIST; /* already in the list */
561 }
562
563 tbuffer = malloc(AFSDIR_PATH_MAX);
564 UserListFileName(adir, tbuffer, AFSDIR_PATH_MAX);
565 tf = fopen(tbuffer, "a+");
566 free(tbuffer);
567 if (!tf) {
568 UNLOCK_GLOBAL_MUTEX;
569 return EIO;
570 }
571 if (user->kind == RX_ID_KRB4) {
572 fprintf(tf, "%s\n", user->displayName);
573 } else {
574 base64_encode(user->exportedName.val, user->exportedName.len,
575 &ename);
576 fprintf(tf, " %d %s %s\n", user->kind, ename, user->displayName);
577 free(ename);
578 }
579 code = 0;
580 if (ferror(tf))
581 code = EIO;
582 if (fclose(tf))
583 code = EIO;
584 UNLOCK_GLOBAL_MUTEX;
585 return code;
586 }
587
588 int
589 afsconf_AddUser(struct afsconf_dir *adir, char *aname)
590 {
591 struct rx_identity *user;
592 int code;
593
594 user = rx_identity_new(RX_ID_KRB4, aname, aname, strlen(aname));
595 if (user == NULL)
596 return ENOMEM;
597
598 code = afsconf_AddIdentity(adir, user);
599
600 rx_identity_free(&user);
601
602 return code;
603 }
604
605 /* special CompFindUser routine that builds up a princ and then
606 calls finduser on it. If found, returns char * to user string,
607 otherwise returns NULL. The resulting string should be immediately
608 copied to other storage prior to release of mutex. */
609 static int
610 CompFindUser(struct afsconf_dir *adir, char *name, char *sep, char *inst,
611 char *realm, struct rx_identity **identity)
612 {
613 static char fullname[MAXKTCNAMELEN + MAXKTCNAMELEN + MAXKTCREALMLEN + 3];
614 struct rx_identity *testId;
615
616 /* always must have name */
617 if (!name || !name[0]) {
618 return 0;
619 }
620
621 if (strlcpy(fullname, name, sizeof(fullname)) >= sizeof(fullname))
622 return 0;
623
624 /* might have instance */
625 if (inst && inst[0]) {
626 if (!sep || !sep[0]) {
627 return 0;
628 }
629
630 if (strlcat(fullname, sep, sizeof(fullname)) >= sizeof(fullname))
631 return 0;
632
633 if (strlcat(fullname, inst, sizeof(fullname)) >= sizeof(fullname))
634 return 0;
635 }
636
637 /* might have realm */
638 if (realm && realm[0]) {
639 if (strlcat(fullname, "@", sizeof(fullname)) >= sizeof(fullname))
640 return 0;
641
642 if (strlcat(fullname, realm, sizeof(fullname)) >= sizeof(fullname))
643 return 0;
644 }
645
646 testId = rx_identity_new(RX_ID_KRB4, fullname, fullname, strlen(fullname));
647 if (afsconf_IsSuperIdentity(adir, testId)) {
648 if (identity)
649 *identity = testId;
650 else
651 rx_identity_free(&testId);
652 return 1;
653 }
654
655 rx_identity_free(&testId);
656 return 0;
657 }
658
659 static int
660 kerberosSuperUser(struct afsconf_dir *adir, char *tname, char *tinst,
661 char *tcell, struct rx_identity **identity)
662 {
663 char tcell_l[MAXKTCREALMLEN] = "";
664 int code;
665 afs_int32 islocal;
666 int flag;
667
668 /* generate lowercased version of cell name */
669 if (tcell)
670 opr_lcstring(tcell_l, tcell, sizeof(tcell_l));
671
672 code = afsconf_IsLocalRealmMatch(adir, &islocal, tname, tinst, tcell);
673 if (code) {
674 return 0;
675 }
676
677 /* start with no authorization */
678 flag = 0;
679
680 /* localauth special case */
681 if ((tinst == NULL || strlen(tinst) == 0) &&
682 (tcell == NULL || strlen(tcell) == 0)
683 && !strcmp(tname, AUTH_SUPERUSER)) {
684 if (identity)
685 *identity = rx_identity_new(RX_ID_KRB4, AFS_LOCALAUTH_NAME,
686 AFS_LOCALAUTH_NAME, AFS_LOCALAUTH_LEN);
687 flag = 1;
688
689 /* cell of connection matches local cell or one of the realms */
690 } else if (islocal) {
691 if (CompFindUser(adir, tname, ".", tinst, NULL, identity)) {
692 flag = 1;
693 }
694 /* cell of conn doesn't match local cell or realm */
695 } else {
696 if (CompFindUser(adir, tname, ".", tinst, tcell, identity)) {
697 flag = 1;
698 } else if (CompFindUser(adir, tname, ".", tinst, tcell_l, identity)) {
699 flag = 1;
700 }
701 }
702
703 return flag;
704 }
705
706 static int
707 rxkadSuperUser(struct afsconf_dir *adir, struct rx_call *acall,
708 struct rx_identity **identity)
709 {
710 char tname[MAXKTCNAMELEN]; /* authentication from ticket */
711 char tinst[MAXKTCNAMELEN];
712 char tcell[MAXKTCREALMLEN];
713
714 afs_uint32 exp;
715 int code;
716
717 /* get auth details from server connection */
718 code = rxkad_GetServerInfo(rx_ConnectionOf(acall), NULL, &exp, tname,
719 tinst, tcell, NULL);
720 if (code)
721 return 0; /* bogus connection/other error */
722
723 return kerberosSuperUser(adir, tname, tinst, tcell, identity);
724 }
725
726 /*!
727 * Check whether the user authenticated on a given RX call is a super
728 * user or not. If they are, return a pointer to the identity of that
729 * user.
730 *
731 * @param[in] adir
732 * The configuration directory currently in use
733 * @param[in] acall
734 * The RX call whose authenticated identity is being checked
735 * @param[out] identity
736 * The RX identity of the user. Caller must free this structure.
737 * @returns
738 * True if the user is a super user, or if the server is running
739 * in noauth mode. Otherwise, false.
740 */
741 afs_int32
742 afsconf_SuperIdentity(struct afsconf_dir *adir, struct rx_call *acall,
743 struct rx_identity **identity)
744 {
745 struct rx_connection *tconn;
746 afs_int32 code;
747 int flag;
748
749 LOCK_GLOBAL_MUTEX;
750 if (!adir) {
751 UNLOCK_GLOBAL_MUTEX;
752 return 0;
753 }
754
755 if (afsconf_GetNoAuthFlag(adir)) {
756 if (identity)
757 *identity = rx_identity_new(RX_ID_KRB4, AFS_NOAUTH_NAME,
758 AFS_NOAUTH_NAME, AFS_NOAUTH_LEN);
759 UNLOCK_GLOBAL_MUTEX;
760 return 1;
761 }
762
763 tconn = rx_ConnectionOf(acall);
764 code = rx_SecurityClassOf(tconn);
765 if (code == RX_SECIDX_NULL) {
766 UNLOCK_GLOBAL_MUTEX;
767 return 0; /* not authenticated at all, answer is no */
768 } else if (code == RX_SECIDX_VAB) {
769 /* bcrypt tokens */
770 UNLOCK_GLOBAL_MUTEX;
771 return 0; /* not supported any longer */
772 } else if (code == RX_SECIDX_KAD) {
773 flag = rxkadSuperUser(adir, acall, identity);
774 UNLOCK_GLOBAL_MUTEX;
775 return flag;
776 } else { /* some other auth type */
777 UNLOCK_GLOBAL_MUTEX;
778 return 0; /* mysterious, just say no */
779 }
780 }
781
782 /*!
783 * Check whether the user authenticated on a given RX call is a super
784 * user or not. If they are, return a pointer to the name of that
785 * user.
786 *
787 * @param[in] adir
788 * The configuration directory currently in use
789 * @param[in] acall
790 * The RX call whose authenticated identity is being checked
791 * @param[out] namep
792 * A printable version of the name of the user
793 * @returns
794 * True if the user is a super user, or if the server is running
795 * in noauth mode. Otherwise, false.
796 *
797 * This function is provided for backwards compatibility. New callers
798 * should use the afsconf_SuperIdentity function.
799 */
800
801 afs_int32
802 afsconf_SuperUser(struct afsconf_dir *adir, struct rx_call *acall,
803 char *namep)
804 {
805 struct rx_identity *identity;
806 int ret;
807
808 if (namep) {
809 ret = afsconf_SuperIdentity(adir, acall, &identity);
810 if (ret) {
811 if (identity->kind == RX_ID_KRB4) {
812 strlcpy(namep, identity->displayName, MAXKTCNAMELEN-1);
813 } else {
814 snprintf(namep, MAXKTCNAMELEN-1, "eName: %s",
815 identity->displayName);
816 }
817 rx_identity_free(&identity);
818 }
819 } else {
820 ret = afsconf_SuperIdentity(adir, acall, NULL);
821 }
822
823 return ret;
824 }
825
826 /*!
827 * Check whether the user authenticated on a given RX call is
828 * compatible with the access specified by needed_level.
829 *
830 * @param[in] adir
831 * The configuration directory currently in use
832 * @param[in] acall
833 * The RX call whose authenticated identity is being checked
834 * @param[in] needed_level
835 * Either RESTRICTED_QUERY_ANYUSER for allowing any access or
836 * RESTRICTED_QUERY_ADMIN for allowing super user only.
837 * @returns
838 * True if the user is compatible with needed_level.
839 * Otherwise, false.
840 */
841
842 int
843 afsconf_CheckRestrictedQuery(struct afsconf_dir *adir,
844 struct rx_call *acall,
845 int needed_level)
846 {
847 if (needed_level == RESTRICTED_QUERY_ANYUSER)
848 return 1;
849
850 return afsconf_SuperIdentity(adir, acall, NULL);
851 }