svcauth.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * linux/net/sunrpc/svcauth.c
  3. *
  4. * The generic interface for RPC authentication on the server side.
  5. *
  6. * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
  7. *
  8. * CHANGES
  9. * 19-Apr-2000 Chris Evans - Security fix
  10. */
  11. #include <linux/types.h>
  12. #include <linux/module.h>
  13. #include <linux/sunrpc/types.h>
  14. #include <linux/sunrpc/xdr.h>
  15. #include <linux/sunrpc/svcsock.h>
  16. #include <linux/sunrpc/svcauth.h>
  17. #include <linux/err.h>
  18. #include <linux/hash.h>
  19. #define RPCDBG_FACILITY RPCDBG_AUTH
  20. /*
  21. * Table of authenticators
  22. */
  23. extern struct auth_ops svcauth_null;
  24. extern struct auth_ops svcauth_unix;
  25. static DEFINE_SPINLOCK(authtab_lock);
  26. static struct auth_ops *authtab[RPC_AUTH_MAXFLAVOR] = {
  27. [0] = &svcauth_null,
  28. [1] = &svcauth_unix,
  29. };
  30. int
  31. svc_authenticate(struct svc_rqst *rqstp, __be32 *authp)
  32. {
  33. rpc_authflavor_t flavor;
  34. struct auth_ops *aops;
  35. *authp = rpc_auth_ok;
  36. flavor = svc_getnl(&rqstp->rq_arg.head[0]);
  37. dprintk("svc: svc_authenticate (%d)\n", flavor);
  38. spin_lock(&authtab_lock);
  39. if (flavor >= RPC_AUTH_MAXFLAVOR || !(aops = authtab[flavor])
  40. || !try_module_get(aops->owner)) {
  41. spin_unlock(&authtab_lock);
  42. *authp = rpc_autherr_badcred;
  43. return SVC_DENIED;
  44. }
  45. spin_unlock(&authtab_lock);
  46. rqstp->rq_authop = aops;
  47. return aops->accept(rqstp, authp);
  48. }
  49. int svc_set_client(struct svc_rqst *rqstp)
  50. {
  51. return rqstp->rq_authop->set_client(rqstp);
  52. }
  53. /* A request, which was authenticated, has now executed.
  54. * Time to finalise the the credentials and verifier
  55. * and release and resources
  56. */
  57. int svc_authorise(struct svc_rqst *rqstp)
  58. {
  59. struct auth_ops *aops = rqstp->rq_authop;
  60. int rv = 0;
  61. rqstp->rq_authop = NULL;
  62. if (aops) {
  63. rv = aops->release(rqstp);
  64. module_put(aops->owner);
  65. }
  66. return rv;
  67. }
  68. int
  69. svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops)
  70. {
  71. int rv = -EINVAL;
  72. spin_lock(&authtab_lock);
  73. if (flavor < RPC_AUTH_MAXFLAVOR && authtab[flavor] == NULL) {
  74. authtab[flavor] = aops;
  75. rv = 0;
  76. }
  77. spin_unlock(&authtab_lock);
  78. return rv;
  79. }
  80. void
  81. svc_auth_unregister(rpc_authflavor_t flavor)
  82. {
  83. spin_lock(&authtab_lock);
  84. if (flavor < RPC_AUTH_MAXFLAVOR)
  85. authtab[flavor] = NULL;
  86. spin_unlock(&authtab_lock);
  87. }
  88. EXPORT_SYMBOL(svc_auth_unregister);
  89. /**************************************************
  90. * 'auth_domains' are stored in a hash table indexed by name.
  91. * When the last reference to an 'auth_domain' is dropped,
  92. * the object is unhashed and freed.
  93. * If auth_domain_lookup fails to find an entry, it will return
  94. * it's second argument 'new'. If this is non-null, it will
  95. * have been atomically linked into the table.
  96. */
  97. #define DN_HASHBITS 6
  98. #define DN_HASHMAX (1<<DN_HASHBITS)
  99. #define DN_HASHMASK (DN_HASHMAX-1)
  100. static struct hlist_head auth_domain_table[DN_HASHMAX];
  101. static spinlock_t auth_domain_lock =
  102. __SPIN_LOCK_UNLOCKED(auth_domain_lock);
  103. void auth_domain_put(struct auth_domain *dom)
  104. {
  105. if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) {
  106. hlist_del(&dom->hash);
  107. dom->flavour->domain_release(dom);
  108. spin_unlock(&auth_domain_lock);
  109. }
  110. }
  111. struct auth_domain *
  112. auth_domain_lookup(char *name, struct auth_domain *new)
  113. {
  114. struct auth_domain *hp;
  115. struct hlist_head *head;
  116. struct hlist_node *np;
  117. head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
  118. spin_lock(&auth_domain_lock);
  119. hlist_for_each_entry(hp, np, head, hash) {
  120. if (strcmp(hp->name, name)==0) {
  121. kref_get(&hp->ref);
  122. spin_unlock(&auth_domain_lock);
  123. return hp;
  124. }
  125. }
  126. if (new)
  127. hlist_add_head(&new->hash, head);
  128. spin_unlock(&auth_domain_lock);
  129. return new;
  130. }
  131. struct auth_domain *auth_domain_find(char *name)
  132. {
  133. return auth_domain_lookup(name, NULL);
  134. }