Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
47737de1
Commit
47737de1
authored
May 20, 2004
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RPCSEC_GSS: Fix module reference counting.
Clean up the interface to the GSSAPI code. Patch by Bruce Fields
parent
71aaeb7f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
178 additions
and
170 deletions
+178
-170
include/linux/sunrpc/gss_api.h
include/linux/sunrpc/gss_api.h
+28
-42
net/sunrpc/auth_gss/Makefile
net/sunrpc/auth_gss/Makefile
+1
-1
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/auth_gss.c
+10
-7
net/sunrpc/auth_gss/gss_krb5_mech.c
net/sunrpc/auth_gss/gss_krb5_mech.c
+16
-16
net/sunrpc/auth_gss/gss_mech_switch.c
net/sunrpc/auth_gss/gss_mech_switch.c
+108
-81
net/sunrpc/auth_gss/sunrpcgss_syms.c
net/sunrpc/auth_gss/sunrpcgss_syms.c
+6
-8
net/sunrpc/auth_gss/svcauth_gss.c
net/sunrpc/auth_gss/svcauth_gss.c
+9
-15
No files found.
include/linux/sunrpc/gss_api.h
View file @
47737de1
...
@@ -50,46 +50,36 @@ u32 gss_verify_mic(
...
@@ -50,46 +50,36 @@ u32 gss_verify_mic(
u32
gss_delete_sec_context
(
u32
gss_delete_sec_context
(
struct
gss_ctx
**
ctx_id
);
struct
gss_ctx
**
ctx_id
);
/* We maintain a list of the pseudoflavors (equivalently, mechanism-qop-service
struct
gss_api_mech
*
gss_mech_get_by_name
(
char
*
name
);
* triples) that we currently support: */
struct
gss_api_mech
*
gss_mech_get_by_pseudoflavor
(
u32
pseudoflavor
);
u32
gss_pseudoflavor_to_service
(
struct
gss_api_mech
*
,
u32
pseudoflavor
);
struct
sup_sec_triple
{
char
*
gss_service_to_auth_domain_name
(
struct
gss_api_mech
*
,
u32
service
);
struct
list_head
triples
;
u32
pseudoflavor
;
struct
pf_desc
{
struct
gss_api_mech
*
mech
;
u32
pseudoflavor
;
u32
qop
;
u32
qop
;
u32
service
;
u32
service
;
char
*
name
;
char
*
auth_domain_name
;
};
};
int
gss_register_triple
(
u32
pseudoflavor
,
struct
gss_api_mech
*
mech
,
u32
qop
,
u32
service
);
int
gss_unregister_triple
(
u32
pseudoflavor
);
int
gss_pseudoflavor_supported
(
u32
pseudoflavor
);
u32
gss_cmp_triples
(
u32
oid_len
,
char
*
oid_data
,
u32
qop
,
u32
service
);
u32
gss_get_pseudoflavor
(
struct
gss_ctx
*
ctx_id
,
u32
qop
,
u32
service
);
u32
gss_pseudoflavor_to_service
(
u32
pseudoflavor
);
/* Both return NULL on failure: */
struct
gss_api_mech
*
gss_pseudoflavor_to_mech
(
u32
pseudoflavor
);
int
gss_pseudoflavor_to_mechOID
(
u32
pseudoflavor
,
struct
xdr_netobj
*
mech
);
/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
* mechanisms may be dynamically registered or unregistered by modules.
* mechanisms may be dynamically registered or unregistered by modules. */
* Our only built-in mechanism is a trivial debugging mechanism that provides
* no actual security; the following function registers that mechanism: */
void
gss_mech_register_debug
(
void
);
/* Each mechanism is described by the following struct: */
/* Each mechanism is described by the following struct: */
struct
gss_api_mech
{
struct
gss_api_mech
{
struct
xdr_netobj
gm_oid
;
struct
list_head
gm_list
;
struct
list_head
gm_list
;
atomic_t
gm_count
;
struct
module
*
gm_owner
;
struct
xdr_netobj
gm_oid
;
char
*
gm_name
;
struct
gss_api_ops
*
gm_ops
;
struct
gss_api_ops
*
gm_ops
;
/* pseudoflavors supported by this mechanism: */
int
gm_pf_num
;
struct
pf_desc
gm_pfs
[];
};
};
/* and must provide the following operations: */
/* and must provide the following operations: */
struct
gss_api_ops
{
struct
gss_api_ops
{
char
*
name
;
u32
(
*
gss_import_sec_context
)(
u32
(
*
gss_import_sec_context
)(
struct
xdr_netobj
*
input_token
,
struct
xdr_netobj
*
input_token
,
struct
gss_ctx
*
ctx_id
);
struct
gss_ctx
*
ctx_id
);
...
@@ -107,29 +97,25 @@ struct gss_api_ops {
...
@@ -107,29 +97,25 @@ struct gss_api_ops {
void
*
internal_ctx_id
);
void
*
internal_ctx_id
);
};
};
/* Returns nonzero on failure. */
int
gss_mech_register
(
struct
gss_api_mech
*
);
int
gss_mech_register
(
struct
xdr_netobj
*
,
struct
gss_api_ops
*
);
void
gss_mech_unregister
(
struct
gss_api_mech
*
);
/* Returns nonzero iff someone still has a reference to this mech. */
/* returns a mechanism descriptor given an OID, and increments the mechanism's
int
gss_mech_unregister
(
struct
gss_api_mech
*
);
/* Returns nonzer iff someone still has a reference to some mech. */
int
gss_mech_unregister_all
(
void
);
/* returns a mechanism descriptor given an OID, an increments the mechanism's
* reference count. */
* reference count. */
struct
gss_api_mech
*
gss_mech_get_by_OID
(
struct
xdr_netobj
*
);
struct
gss_api_mech
*
gss_mech_get_by_OID
(
struct
xdr_netobj
*
);
/*
Similar, but get by name like "krb5", "spkm", etc., instead of OID
. */
/*
Returns a reference to a mechanism, given a name like "krb5" etc
. */
struct
gss_api_mech
*
gss_mech_get_by_name
(
char
*
);
struct
gss_api_mech
*
gss_mech_get_by_name
(
char
*
);
/* Similar, but get by pseudoflavor. */
struct
gss_api_mech
*
gss_mech_get_by_pseudoflavor
(
u32
);
/* Just increments the mechanism's reference count and returns its input: */
/* Just increments the mechanism's reference count and returns its input: */
struct
gss_api_mech
*
gss_mech_get
(
struct
gss_api_mech
*
);
struct
gss_api_mech
*
gss_mech_get
(
struct
gss_api_mech
*
);
/* Returns nonzero iff you've released the last reference to this mech.
/* For every succesful gss_mech_get or gss_mech_get_by_* call there must be a
* Note that for every succesful gss_get_mech call there must be exactly
* corresponding call to gss_mech_put. */
* one corresponding call to gss_mech_put.*/
void
gss_mech_put
(
struct
gss_api_mech
*
);
int
gss_mech_put
(
struct
gss_api_mech
*
);
#endif
/* __KERNEL__ */
#endif
/* __KERNEL__ */
#endif
/* _LINUX_SUNRPC_GSS_API_H */
#endif
/* _LINUX_SUNRPC_GSS_API_H */
...
...
net/sunrpc/auth_gss/Makefile
View file @
47737de1
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
obj-$(CONFIG_SUNRPC_GSS)
+=
auth_rpcgss.o
obj-$(CONFIG_SUNRPC_GSS)
+=
auth_rpcgss.o
auth_rpcgss-objs
:=
auth_gss.o gss_
pseudoflavors.o gss_
generic_token.o
\
auth_rpcgss-objs
:=
auth_gss.o gss_generic_token.o
\
sunrpcgss_syms.o gss_mech_switch.o svcauth_gss.o gss_krb5_crypto.o
sunrpcgss_syms.o gss_mech_switch.o svcauth_gss.o gss_krb5_crypto.o
obj-$(CONFIG_RPCSEC_GSS_KRB5)
+=
rpcsec_gss_krb5.o
obj-$(CONFIG_RPCSEC_GSS_KRB5)
+=
rpcsec_gss_krb5.o
...
...
net/sunrpc/auth_gss/auth_gss.c
View file @
47737de1
...
@@ -559,7 +559,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
...
@@ -559,7 +559,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
if
(
!
(
gss_auth
=
kmalloc
(
sizeof
(
*
gss_auth
),
GFP_KERNEL
)))
if
(
!
(
gss_auth
=
kmalloc
(
sizeof
(
*
gss_auth
),
GFP_KERNEL
)))
goto
out_dec
;
goto
out_dec
;
gss_auth
->
mech
=
gss_
pseudoflavor_to_mech
(
flavor
);
gss_auth
->
mech
=
gss_
mech_get_by_pseudoflavor
(
flavor
);
if
(
!
gss_auth
->
mech
)
{
if
(
!
gss_auth
->
mech
)
{
printk
(
KERN_WARNING
"%s: Pseudoflavor %d not found!"
,
printk
(
KERN_WARNING
"%s: Pseudoflavor %d not found!"
,
__FUNCTION__
,
flavor
);
__FUNCTION__
,
flavor
);
...
@@ -578,7 +578,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
...
@@ -578,7 +578,7 @@ gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
snprintf
(
gss_auth
->
path
,
sizeof
(
gss_auth
->
path
),
"%s/%s"
,
snprintf
(
gss_auth
->
path
,
sizeof
(
gss_auth
->
path
),
"%s/%s"
,
clnt
->
cl_pathname
,
clnt
->
cl_pathname
,
gss_auth
->
mech
->
gm_
ops
->
name
);
gss_auth
->
mech
->
gm_name
);
gss_auth
->
dentry
=
rpc_mkpipe
(
gss_auth
->
path
,
clnt
,
&
gss_upcall_ops
,
RPC_PIPE_WAIT_FOR_OPEN
);
gss_auth
->
dentry
=
rpc_mkpipe
(
gss_auth
->
path
,
clnt
,
&
gss_upcall_ops
,
RPC_PIPE_WAIT_FOR_OPEN
);
if
(
IS_ERR
(
gss_auth
->
dentry
))
if
(
IS_ERR
(
gss_auth
->
dentry
))
goto
err_free
;
goto
err_free
;
...
@@ -696,7 +696,8 @@ gss_marshal(struct rpc_task *task, u32 *p, int ruid)
...
@@ -696,7 +696,8 @@ gss_marshal(struct rpc_task *task, u32 *p, int ruid)
*
p
++
=
htonl
(
RPC_AUTH_GSS
);
*
p
++
=
htonl
(
RPC_AUTH_GSS
);
cred_len
=
p
++
;
cred_len
=
p
++
;
service
=
gss_pseudoflavor_to_service
(
gss_cred
->
gc_flavor
);
service
=
gss_pseudoflavor_to_service
(
ctx
->
gc_gss_ctx
->
mech_type
,
gss_cred
->
gc_flavor
);
if
(
service
==
0
)
{
if
(
service
==
0
)
{
dprintk
(
"RPC: %4u Bad pseudoflavor %d in gss_marshal
\n
"
,
dprintk
(
"RPC: %4u Bad pseudoflavor %d in gss_marshal
\n
"
,
task
->
tk_pid
,
gss_cred
->
gc_flavor
);
task
->
tk_pid
,
gss_cred
->
gc_flavor
);
...
@@ -785,7 +786,8 @@ gss_validate(struct rpc_task *task, u32 *p)
...
@@ -785,7 +786,8 @@ gss_validate(struct rpc_task *task, u32 *p)
if
(
gss_verify_mic
(
ctx
->
gc_gss_ctx
,
&
verf_buf
,
&
mic
,
&
qop_state
))
if
(
gss_verify_mic
(
ctx
->
gc_gss_ctx
,
&
verf_buf
,
&
mic
,
&
qop_state
))
goto
out_bad
;
goto
out_bad
;
service
=
gss_pseudoflavor_to_service
(
gss_cred
->
gc_flavor
);
service
=
gss_pseudoflavor_to_service
(
ctx
->
gc_gss_ctx
->
mech_type
,
gss_cred
->
gc_flavor
);
switch
(
service
)
{
switch
(
service
)
{
case
RPC_GSS_SVC_NONE
:
case
RPC_GSS_SVC_NONE
:
/* verifier data, flavor, length: */
/* verifier data, flavor, length: */
...
@@ -836,7 +838,8 @@ gss_wrap_req(struct rpc_task *task,
...
@@ -836,7 +838,8 @@ gss_wrap_req(struct rpc_task *task,
status
=
encode
(
rqstp
,
p
,
obj
);
status
=
encode
(
rqstp
,
p
,
obj
);
goto
out
;
goto
out
;
}
}
service
=
gss_pseudoflavor_to_service
(
gss_cred
->
gc_flavor
);
service
=
gss_pseudoflavor_to_service
(
ctx
->
gc_gss_ctx
->
mech_type
,
gss_cred
->
gc_flavor
);
switch
(
service
)
{
switch
(
service
)
{
case
RPC_GSS_SVC_NONE
:
case
RPC_GSS_SVC_NONE
:
status
=
encode
(
rqstp
,
p
,
obj
);
status
=
encode
(
rqstp
,
p
,
obj
);
...
@@ -908,7 +911,8 @@ gss_unwrap_resp(struct rpc_task *task,
...
@@ -908,7 +911,8 @@ gss_unwrap_resp(struct rpc_task *task,
if
(
ctx
->
gc_proc
!=
RPC_GSS_PROC_DATA
)
if
(
ctx
->
gc_proc
!=
RPC_GSS_PROC_DATA
)
goto
out_decode
;
goto
out_decode
;
service
=
gss_pseudoflavor_to_service
(
gss_cred
->
gc_flavor
);
service
=
gss_pseudoflavor_to_service
(
ctx
->
gc_gss_ctx
->
mech_type
,
gss_cred
->
gc_flavor
);
switch
(
service
)
{
switch
(
service
)
{
case
RPC_GSS_SVC_NONE
:
case
RPC_GSS_SVC_NONE
:
goto
out_decode
;
goto
out_decode
;
...
@@ -999,7 +1003,6 @@ static int __init init_rpcsec_gss(void)
...
@@ -999,7 +1003,6 @@ static int __init init_rpcsec_gss(void)
static
void
__exit
exit_rpcsec_gss
(
void
)
static
void
__exit
exit_rpcsec_gss
(
void
)
{
{
gss_svc_shutdown
();
gss_svc_shutdown
();
gss_mech_unregister_all
();
rpcauth_unregister
(
&
authgss_ops
);
rpcauth_unregister
(
&
authgss_ops
);
}
}
...
...
net/sunrpc/auth_gss/gss_krb5_mech.c
View file @
47737de1
...
@@ -40,7 +40,6 @@
...
@@ -40,7 +40,6 @@
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/auth.h>
#include <linux/in.h>
#include <linux/in.h>
#include <linux/sunrpc/svcauth_gss.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/xdr.h>
#include <linux/crypto.h>
#include <linux/crypto.h>
...
@@ -217,35 +216,36 @@ gss_get_mic_kerberos(struct gss_ctx *ctx,
...
@@ -217,35 +216,36 @@ gss_get_mic_kerberos(struct gss_ctx *ctx,
}
}
static
struct
gss_api_ops
gss_kerberos_ops
=
{
static
struct
gss_api_ops
gss_kerberos_ops
=
{
.
name
=
"krb5"
,
.
gss_import_sec_context
=
gss_import_sec_context_kerberos
,
.
gss_import_sec_context
=
gss_import_sec_context_kerberos
,
.
gss_get_mic
=
gss_get_mic_kerberos
,
.
gss_get_mic
=
gss_get_mic_kerberos
,
.
gss_verify_mic
=
gss_verify_mic_kerberos
,
.
gss_verify_mic
=
gss_verify_mic_kerberos
,
.
gss_delete_sec_context
=
gss_delete_sec_context_kerberos
,
.
gss_delete_sec_context
=
gss_delete_sec_context_kerberos
,
};
};
/* XXX error checking? reference counting? */
static
struct
gss_api_mech
gss_kerberos_mech
=
{
.
gm_name
=
"krb5"
,
.
gm_owner
=
THIS_MODULE
,
.
gm_ops
=
&
gss_kerberos_ops
,
.
gm_pf_num
=
2
,
.
gm_pfs
=
{
{
RPC_AUTH_GSS_KRB5
,
0
,
RPC_GSS_SVC_NONE
,
"krb5"
},
{
RPC_AUTH_GSS_KRB5I
,
0
,
RPC_GSS_SVC_INTEGRITY
,
"krb5i"
},
},
};
static
int
__init
init_kerberos_module
(
void
)
static
int
__init
init_kerberos_module
(
void
)
{
{
struct
gss_api_mech
*
gm
;
int
status
;
if
(
gss_mech_register
(
&
gss_mech_krb5_oid
,
&
gss_kerberos_ops
))
status
=
gss_mech_register
(
&
gss_kerberos_mech
);
if
(
status
)
printk
(
"Failed to register kerberos gss mechanism!
\n
"
);
printk
(
"Failed to register kerberos gss mechanism!
\n
"
);
gm
=
gss_mech_get_by_OID
(
&
gss_mech_krb5_oid
);
return
status
;
gss_register_triple
(
RPC_AUTH_GSS_KRB5
,
gm
,
0
,
RPC_GSS_SVC_NONE
);
gss_register_triple
(
RPC_AUTH_GSS_KRB5I
,
gm
,
0
,
RPC_GSS_SVC_INTEGRITY
);
if
(
svcauth_gss_register_pseudoflavor
(
RPC_AUTH_GSS_KRB5
,
"krb5"
))
printk
(
"Failed to register %s with server!
\n
"
,
"krb5"
);
if
(
svcauth_gss_register_pseudoflavor
(
RPC_AUTH_GSS_KRB5I
,
"krb5i"
))
printk
(
"Failed to register %s with server!
\n
"
,
"krb5i"
);
gss_mech_put
(
gm
);
return
0
;
}
}
static
void
__exit
cleanup_kerberos_module
(
void
)
static
void
__exit
cleanup_kerberos_module
(
void
)
{
{
gss_unregister_triple
(
RPC_AUTH_GSS_KRB5I
);
gss_mech_unregister
(
&
gss_kerberos_mech
);
gss_unregister_triple
(
RPC_AUTH_GSS_KRB5
);
}
}
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
net/sunrpc/auth_gss/gss_mech_switch.c
View file @
47737de1
...
@@ -36,9 +36,11 @@
...
@@ -36,9 +36,11 @@
#include <linux/types.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/socket.h>
#include <linux/module.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_asn1.h>
#include <linux/sunrpc/gss_asn1.h>
#include <linux/sunrpc/auth_gss.h>
#include <linux/sunrpc/auth_gss.h>
#include <linux/sunrpc/svcauth_gss.h>
#include <linux/sunrpc/gss_err.h>
#include <linux/sunrpc/gss_err.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/gss_api.h>
#include <linux/sunrpc/gss_api.h>
...
@@ -51,143 +53,168 @@
...
@@ -51,143 +53,168 @@
static
LIST_HEAD
(
registered_mechs
);
static
LIST_HEAD
(
registered_mechs
);
static
spinlock_t
registered_mechs_lock
=
SPIN_LOCK_UNLOCKED
;
static
spinlock_t
registered_mechs_lock
=
SPIN_LOCK_UNLOCKED
;
/* Reference counting: The reference count includes the reference in the
static
void
* global registered_mechs list. That reference will never diseappear
gss_mech_free
(
struct
gss_api_mech
*
gm
)
* (so the reference count will never go below 1) until after the mech
* is removed from the list. Nothing can be removed from the list without
* first getting the registered_mechs_lock, so a gss_api_mech won't diseappear
* from underneath us while we hold the registered_mech_lock. */
int
gss_mech_register
(
struct
xdr_netobj
*
mech_type
,
struct
gss_api_ops
*
ops
)
{
{
struct
gss_api_mech
*
gm
;
struct
pf_desc
*
pf
;
int
i
;
if
(
!
(
gm
=
kmalloc
(
sizeof
(
*
gm
),
GFP_KERNEL
)))
{
for
(
i
=
0
;
i
<
gm
->
gm_pf_num
;
i
++
)
{
printk
(
"Failed to allocate memory in gss_mech_register"
);
pf
=
&
gm
->
gm_pfs
[
i
];
return
-
1
;
if
(
pf
->
auth_domain_name
)
kfree
(
pf
->
auth_domain_name
);
pf
->
auth_domain_name
=
NULL
;
}
}
gm
->
gm_oid
.
len
=
mech_type
->
len
;
if
(
!
(
gm
->
gm_oid
.
data
=
kmalloc
(
mech_type
->
len
,
GFP_KERNEL
)))
{
kfree
(
gm
);
printk
(
"Failed to allocate memory in gss_mech_register"
);
return
-
1
;
}
memcpy
(
gm
->
gm_oid
.
data
,
mech_type
->
data
,
mech_type
->
len
);
/* We're counting the reference in the registered_mechs list: */
atomic_set
(
&
gm
->
gm_count
,
1
);
gm
->
gm_ops
=
ops
;
spin_lock
(
&
registered_mechs_lock
);
list_add
(
&
gm
->
gm_list
,
&
registered_mechs
);
spin_unlock
(
&
registered_mechs_lock
);
dprintk
(
"RPC: gss_mech_register: registered mechanism with oid:
\n
"
);
print_hexl
((
u32
*
)
mech_type
->
data
,
mech_type
->
len
,
0
);
return
0
;
}
}
/* The following must be called with spinlock held: */
static
inline
char
*
int
make_auth_domain_name
(
char
*
name
)
do_gss_mech_unregister
(
struct
gss_api_mech
*
gm
)
{
{
static
char
*
prefix
=
"gss/"
;
char
*
new
;
list_del
(
&
gm
->
gm_list
);
new
=
kmalloc
(
strlen
(
name
)
+
strlen
(
prefix
)
+
1
,
GFP_KERNEL
);
if
(
new
)
{
strcpy
(
new
,
prefix
);
strcat
(
new
,
name
);
}
return
new
;
}
static
int
gss_mech_svc_setup
(
struct
gss_api_mech
*
gm
)
{
struct
pf_desc
*
pf
;
int
i
,
status
;
dprintk
(
"RPC: unregistered mechanism with oid:
\n
"
);
for
(
i
=
0
;
i
<
gm
->
gm_pf_num
;
i
++
)
{
print_hexl
((
u32
*
)
gm
->
gm_oid
.
data
,
gm
->
gm_oid
.
len
,
0
);
pf
=
&
gm
->
gm_pfs
[
i
];
if
(
!
gss_mech_put
(
gm
))
{
pf
->
auth_domain_name
=
make_auth_domain_name
(
pf
->
name
);
dprintk
(
"RPC: We just unregistered a gss_mechanism which someone is still using.
\n
"
);
status
=
-
ENOMEM
;
return
-
1
;
if
(
pf
->
auth_domain_name
==
NULL
)
}
else
{
goto
out
;
return
0
;
status
=
svcauth_gss_register_pseudoflavor
(
pf
->
pseudoflavor
,
pf
->
auth_domain_name
);
if
(
status
)
goto
out
;
}
}
return
0
;
out:
gss_mech_free
(
gm
);
return
status
;
}
}
int
int
gss_mech_
un
register
(
struct
gss_api_mech
*
gm
)
gss_mech_register
(
struct
gss_api_mech
*
gm
)
{
{
int
status
;
int
status
;
status
=
gss_mech_svc_setup
(
gm
);
if
(
status
)
return
status
;
spin_lock
(
&
registered_mechs_lock
);
spin_lock
(
&
registered_mechs_lock
);
status
=
do_gss_mech_unregister
(
gm
);
list_add
(
&
gm
->
gm_list
,
&
registered_mechs
);
spin_unlock
(
&
registered_mechs_lock
);
spin_unlock
(
&
registered_mechs_lock
);
return
status
;
dprintk
(
"RPC: registered gss mechanism %s
\n
"
,
gm
->
gm_name
);
return
0
;
}
}
int
void
gss_mech_unregister
_all
(
void
)
gss_mech_unregister
(
struct
gss_api_mech
*
gm
)
{
{
struct
list_head
*
pos
;
struct
gss_api_mech
*
gm
;
int
status
=
0
;
spin_lock
(
&
registered_mechs_lock
);
spin_lock
(
&
registered_mechs_lock
);
while
(
!
list_empty
(
&
registered_mechs
))
{
list_del
(
&
gm
->
gm_list
);
pos
=
registered_mechs
.
next
;
gm
=
list_entry
(
pos
,
struct
gss_api_mech
,
gm_list
);
if
(
do_gss_mech_unregister
(
gm
))
status
=
-
1
;
}
spin_unlock
(
&
registered_mechs_lock
);
spin_unlock
(
&
registered_mechs_lock
);
return
status
;
dprintk
(
"RPC: unregistered gss mechanism %s
\n
"
,
gm
->
gm_name
);
gss_mech_free
(
gm
);
}
}
struct
gss_api_mech
*
struct
gss_api_mech
*
gss_mech_get
(
struct
gss_api_mech
*
gm
)
gss_mech_get
(
struct
gss_api_mech
*
gm
)
{
{
atomic_inc
(
&
gm
->
gm_count
);
__module_get
(
gm
->
gm_owner
);
return
gm
;
return
gm
;
}
}
struct
gss_api_mech
*
struct
gss_api_mech
*
gss_mech_get_by_
OID
(
struct
xdr_netobj
*
mech_typ
e
)
gss_mech_get_by_
name
(
char
*
nam
e
)
{
{
struct
gss_api_mech
*
pos
,
*
gm
=
NULL
;
struct
gss_api_mech
*
pos
,
*
gm
=
NULL
;
dprintk
(
"RPC: gss_mech_get_by_OID searching for mechanism with OID:
\n
"
);
print_hexl
((
u32
*
)
mech_type
->
data
,
mech_type
->
len
,
0
);
spin_lock
(
&
registered_mechs_lock
);
spin_lock
(
&
registered_mechs_lock
);
list_for_each_entry
(
pos
,
&
registered_mechs
,
gm_list
)
{
list_for_each_entry
(
pos
,
&
registered_mechs
,
gm_list
)
{
if
(
(
pos
->
gm_oid
.
len
==
mech_type
->
len
)
if
(
0
==
strcmp
(
name
,
pos
->
gm_name
))
{
&&
!
memcmp
(
pos
->
gm_oid
.
data
,
mech_type
->
data
,
if
(
!
try_module_get
(
pos
->
gm_owner
))
mech_type
->
len
))
{
continue
;
gm
=
gss_mech_get
(
pos
)
;
gm
=
pos
;
break
;
break
;
}
}
}
}
spin_unlock
(
&
registered_mechs_lock
);
spin_unlock
(
&
registered_mechs_lock
);
dprintk
(
"RPC: gss_mech_get_by_OID %s it
\n
"
,
gm
?
"found"
:
"didn't find"
);
return
gm
;
return
gm
;
}
static
inline
int
mech_supports_pseudoflavor
(
struct
gss_api_mech
*
gm
,
u32
pseudoflavor
)
{
int
i
;
for
(
i
=
0
;
i
<
gm
->
gm_pf_num
;
i
++
)
{
if
(
gm
->
gm_pfs
[
i
].
pseudoflavor
==
pseudoflavor
)
return
1
;
}
return
0
;
}
}
struct
gss_api_mech
*
struct
gss_api_mech
*
gss_mech_get_by_
name
(
char
*
name
)
gss_mech_get_by_
pseudoflavor
(
u32
pseudoflavor
)
{
{
struct
gss_api_mech
*
pos
,
*
gm
=
NULL
;
struct
gss_api_mech
*
pos
,
*
gm
=
NULL
;
spin_lock
(
&
registered_mechs_lock
);
spin_lock
(
&
registered_mechs_lock
);
list_for_each_entry
(
pos
,
&
registered_mechs
,
gm_list
)
{
list_for_each_entry
(
pos
,
&
registered_mechs
,
gm_list
)
{
if
(
0
==
strcmp
(
name
,
pos
->
gm_ops
->
name
))
{
if
(
!
try_module_get
(
pos
->
gm_owner
))
gm
=
gss_mech_get
(
pos
);
continue
;
break
;
if
(
!
mech_supports_pseudoflavor
(
pos
,
pseudoflavor
))
{
module_put
(
pos
->
gm_owner
);
continue
;
}
}
gm
=
pos
;
break
;
}
}
spin_unlock
(
&
registered_mechs_lock
);
spin_unlock
(
&
registered_mechs_lock
);
return
gm
;
return
gm
;
}
u32
gss_pseudoflavor_to_service
(
struct
gss_api_mech
*
gm
,
u32
pseudoflavor
)
{
int
i
;
for
(
i
=
0
;
i
<
gm
->
gm_pf_num
;
i
++
)
{
if
(
gm
->
gm_pfs
[
i
].
pseudoflavor
==
pseudoflavor
)
return
gm
->
gm_pfs
[
i
].
service
;
}
return
0
;
}
}
int
char
*
gss_
mech_put
(
struct
gss_api_mech
*
gm
)
gss_
service_to_auth_domain_name
(
struct
gss_api_mech
*
gm
,
u32
service
)
{
{
if
(
atomic_dec_and_test
(
&
gm
->
gm_count
))
{
int
i
;
if
(
gm
->
gm_oid
.
len
>
0
)
kfree
(
gm
->
gm_oid
.
data
);
for
(
i
=
0
;
i
<
gm
->
gm_pf_num
;
i
++
)
{
kfree
(
gm
);
if
(
gm
->
gm_pfs
[
i
].
service
==
service
)
return
1
;
return
gm
->
gm_pfs
[
i
].
auth_domain_name
;
}
else
{
return
0
;
}
}
return
NULL
;
}
void
gss_mech_put
(
struct
gss_api_mech
*
gm
)
{
module_put
(
gm
->
gm_owner
);
}
}
/* The mech could probably be determined from the token instead, but it's just
/* The mech could probably be determined from the token instead, but it's just
...
...
net/sunrpc/auth_gss/sunrpcgss_syms.c
View file @
47737de1
...
@@ -12,20 +12,18 @@
...
@@ -12,20 +12,18 @@
#include <linux/sunrpc/gss_asn1.h>
#include <linux/sunrpc/gss_asn1.h>
#include <linux/sunrpc/gss_krb5.h>
#include <linux/sunrpc/gss_krb5.h>
/* sec_triples: */
/* svcauth_gss.c: */
EXPORT_SYMBOL
(
gss_register_triple
);
EXPORT_SYMBOL
(
gss_unregister_triple
);
EXPORT_SYMBOL
(
gss_cmp_triples
);
EXPORT_SYMBOL
(
gss_pseudoflavor_to_mechOID
);
EXPORT_SYMBOL
(
gss_pseudoflavor_supported
);
EXPORT_SYMBOL
(
gss_pseudoflavor_to_service
);
EXPORT_SYMBOL
(
svcauth_gss_register_pseudoflavor
);
EXPORT_SYMBOL
(
svcauth_gss_register_pseudoflavor
);
/* registering gss mechanisms to the mech switching code: */
/* registering gss mechanisms to the mech switching code: */
EXPORT_SYMBOL
(
gss_mech_register
);
EXPORT_SYMBOL
(
gss_mech_register
);
EXPORT_SYMBOL
(
gss_mech_unregister
);
EXPORT_SYMBOL
(
gss_mech_get
);
EXPORT_SYMBOL
(
gss_mech_get
);
EXPORT_SYMBOL
(
gss_mech_get_by_OID
);
EXPORT_SYMBOL
(
gss_mech_get_by_pseudoflavor
);
EXPORT_SYMBOL
(
gss_mech_get_by_name
);
EXPORT_SYMBOL
(
gss_mech_put
);
EXPORT_SYMBOL
(
gss_mech_put
);
EXPORT_SYMBOL
(
gss_pseudoflavor_to_service
);
EXPORT_SYMBOL
(
gss_service_to_auth_domain_name
);
/* generic functionality in gss code: */
/* generic functionality in gss code: */
EXPORT_SYMBOL
(
g_make_token_header
);
EXPORT_SYMBOL
(
g_make_token_header
);
...
...
net/sunrpc/auth_gss/svcauth_gss.c
View file @
47737de1
...
@@ -617,19 +617,15 @@ struct gss_domain {
...
@@ -617,19 +617,15 @@ struct gss_domain {
u32
pseudoflavor
;
u32
pseudoflavor
;
};
};
/* XXX this should be done in gss_pseudoflavors, and shouldn't be hardcoded: */
static
struct
auth_domain
*
static
struct
auth_domain
*
find_gss_auth_domain
(
struct
gss_ctx
*
ctx
,
u32
svc
)
find_gss_auth_domain
(
struct
gss_ctx
*
ctx
,
u32
svc
)
{
{
switch
(
gss_get_pseudoflavor
(
ctx
,
0
,
svc
))
{
char
*
name
;
case
RPC_AUTH_GSS_KRB5
:
return
auth_domain_find
(
"gss/krb5"
);
name
=
gss_service_to_auth_domain_name
(
ctx
->
mech_type
,
svc
);
case
RPC_AUTH_GSS_KRB5I
:
if
(
!
name
)
return
auth_domain_find
(
"gss/krb5i"
);
return
NULL
;
case
RPC_AUTH_GSS_KRB5P
:
return
auth_domain_find
(
name
);
return
auth_domain_find
(
"gss/krb5p"
);
}
return
NULL
;
}
}
int
int
...
@@ -637,19 +633,17 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
...
@@ -637,19 +633,17 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
{
{
struct
gss_domain
*
new
;
struct
gss_domain
*
new
;
struct
auth_domain
*
test
;
struct
auth_domain
*
test
;
static
char
*
prefix
=
"gss/"
;
int
stat
=
-
ENOMEM
;
int
stat
=
-
1
;
new
=
kmalloc
(
sizeof
(
*
new
),
GFP_KERNEL
);
new
=
kmalloc
(
sizeof
(
*
new
),
GFP_KERNEL
);
if
(
!
new
)
if
(
!
new
)
goto
out
;
goto
out
;
cache_init
(
&
new
->
h
.
h
);
cache_init
(
&
new
->
h
.
h
);
atomic_inc
(
&
new
->
h
.
h
.
refcnt
);
atomic_inc
(
&
new
->
h
.
h
.
refcnt
);
new
->
h
.
name
=
kmalloc
(
strlen
(
name
)
+
strlen
(
prefix
)
+
1
,
GFP_KERNEL
);
new
->
h
.
name
=
kmalloc
(
strlen
(
name
)
+
1
,
GFP_KERNEL
);
if
(
!
new
->
h
.
name
)
if
(
!
new
->
h
.
name
)
goto
out_free_dom
;
goto
out_free_dom
;
strcpy
(
new
->
h
.
name
,
prefix
);
strcpy
(
new
->
h
.
name
,
name
);
strcat
(
new
->
h
.
name
,
name
);
new
->
h
.
flavour
=
RPC_AUTH_GSS
;
new
->
h
.
flavour
=
RPC_AUTH_GSS
;
new
->
pseudoflavor
=
pseudoflavor
;
new
->
pseudoflavor
=
pseudoflavor
;
new
->
h
.
h
.
expiry_time
=
NEVER
;
new
->
h
.
h
.
expiry_time
=
NEVER
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment