svcauth.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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/sched.h>
  13. #include <linux/sunrpc/types.h>
  14. #include <linux/sunrpc/xdr.h>
  15. #include <linux/sunrpc/svcauth.h>
  16. #include <linux/sunrpc/svcsock.h>
  17. #define RPCDBG_FACILITY RPCDBG_AUTH
  18. /*
  19.  * Type of authenticator function
  20.  */
  21. typedef void (*auth_fn_t)(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
  22. /*
  23.  * Builtin auth flavors
  24.  */
  25. static void svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
  26. static void svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp);
  27. /*
  28.  * Max number of authentication flavors we support
  29.  */
  30. #define RPC_SVCAUTH_MAX 8
  31. /*
  32.  * Table of authenticators
  33.  */
  34. static auth_fn_t authtab[RPC_SVCAUTH_MAX] = {
  35. svcauth_null,
  36. svcauth_unix,
  37. NULL,
  38. };
  39. void
  40. svc_authenticate(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
  41. {
  42. u32 flavor;
  43. auth_fn_t func;
  44. *statp = rpc_success;
  45. *authp = rpc_auth_ok;
  46. svc_getlong(&rqstp->rq_argbuf, flavor);
  47. flavor = ntohl(flavor);
  48. dprintk("svc: svc_authenticate (%d)n", flavor);
  49. if (flavor >= RPC_SVCAUTH_MAX || !(func = authtab[flavor])) {
  50. *authp = rpc_autherr_badcred;
  51. return;
  52. }
  53. rqstp->rq_cred.cr_flavor = flavor;
  54. func(rqstp, statp, authp);
  55. }
  56. int
  57. svc_auth_register(u32 flavor, auth_fn_t func)
  58. {
  59. if (flavor >= RPC_SVCAUTH_MAX || authtab[flavor])
  60. return -EINVAL;
  61. authtab[flavor] = func;
  62. return 0;
  63. }
  64. void
  65. svc_auth_unregister(u32 flavor)
  66. {
  67. if (flavor < RPC_SVCAUTH_MAX)
  68. authtab[flavor] = NULL;
  69. }
  70. static void
  71. svcauth_null(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
  72. {
  73. struct svc_buf *argp = &rqstp->rq_argbuf;
  74. struct svc_buf *resp = &rqstp->rq_resbuf;
  75. if ((argp->len -= 3) < 0) {
  76. *statp = rpc_garbage_args;
  77. return;
  78. }
  79. if (*(argp->buf)++ != 0) { /* we already skipped the flavor */
  80. dprintk("svc: bad null credn");
  81. *authp = rpc_autherr_badcred;
  82. return;
  83. }
  84. if (*(argp->buf)++ != RPC_AUTH_NULL || *(argp->buf)++ != 0) {
  85. dprintk("svc: bad null verfn");
  86. *authp = rpc_autherr_badverf;
  87. return;
  88. }
  89. /* Signal that mapping to nobody uid/gid is required */
  90. rqstp->rq_cred.cr_uid = (uid_t) -1;
  91. rqstp->rq_cred.cr_gid = (gid_t) -1;
  92. rqstp->rq_cred.cr_groups[0] = NOGROUP;
  93. /* Put NULL verifier */
  94. rqstp->rq_verfed = 1;
  95. svc_putlong(resp, RPC_AUTH_NULL);
  96. svc_putlong(resp, 0);
  97. }
  98. static void
  99. svcauth_unix(struct svc_rqst *rqstp, u32 *statp, u32 *authp)
  100. {
  101. struct svc_buf *argp = &rqstp->rq_argbuf;
  102. struct svc_buf *resp = &rqstp->rq_resbuf;
  103. struct svc_cred *cred = &rqstp->rq_cred;
  104. u32 *bufp = argp->buf, slen, i;
  105. int len   = argp->len;
  106. if ((len -= 3) < 0) {
  107. *statp = rpc_garbage_args;
  108. return;
  109. }
  110. bufp++; /* length */
  111. bufp++; /* time stamp */
  112. slen = (ntohl(*bufp++) + 3) >> 2; /* machname length */
  113. if (slen > 64 || (len -= slen + 3) < 0)
  114. goto badcred;
  115. bufp += slen; /* skip machname */
  116. cred->cr_uid = ntohl(*bufp++); /* uid */
  117. cred->cr_gid = ntohl(*bufp++); /* gid */
  118. slen = ntohl(*bufp++); /* gids length */
  119. if (slen > 16 || (len -= slen + 2) < 0)
  120. goto badcred;
  121. for (i = 0; i < NGROUPS && i < slen; i++)
  122. cred->cr_groups[i] = ntohl(*bufp++);
  123. if (i < NGROUPS)
  124. cred->cr_groups[i] = NOGROUP;
  125. bufp += (slen - i);
  126. if (*bufp++ != RPC_AUTH_NULL || *bufp++ != 0) {
  127. *authp = rpc_autherr_badverf;
  128. return;
  129. }
  130. argp->buf = bufp;
  131. argp->len = len;
  132. /* Put NULL verifier */
  133. rqstp->rq_verfed = 1;
  134. svc_putlong(resp, RPC_AUTH_NULL);
  135. svc_putlong(resp, 0);
  136. return;
  137. badcred:
  138. *authp = rpc_autherr_badcred;
  139. }