cifs.upcall: use a MEMORY: ccache when instantiating from a keytab
[jlayton/cifs-utils.git] / idmap_plugin.c
1 /*
2  * ID Mapping Plugin interface for cifs-utils
3  * Copyright (C) 2012 Jeff Layton (jlayton@samba.org)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #include <dlfcn.h>
24 #include <errno.h>
25 #include <stdint.h>
26 #include <sys/types.h>
27
28 #include "cifsidmap.h"
29 #include "idmap_plugin.h"
30
31 const char *plugin_errmsg;
32 static void *plugin;
33
34 static void *
35 resolve_symbol(const char *symbol_name)
36 {
37         void *symbol;
38
39         dlerror();
40         symbol = dlsym(plugin, symbol_name);
41         if (!symbol)
42                 plugin_errmsg = dlerror();
43         return symbol;
44 }
45
46 /*
47  * open the plugin. Note that we leave it open over the life of the
48  * program. It gets closed on exit.
49  */
50 static int
51 open_plugin(void)
52 {
53         if (plugin)
54                 return 0;
55
56         plugin = dlopen(IDMAP_PLUGIN_PATH, RTLD_LAZY);
57         if (!plugin) {
58                 plugin_errmsg = dlerror();
59                 return -EIO;
60         }
61
62         return 0;
63 }
64
65 int
66 init_plugin(void **handle)
67 {
68         int ret;
69         int (*init)(void **, const char **);
70
71         ret = open_plugin();
72         if (ret)
73                 return ret;
74
75         init = resolve_symbol("cifs_idmap_init_plugin");
76         if (!init) {
77                 plugin_errmsg = "cifs_idmap_init_plugin not implemented";
78                 return -ENOSYS;
79         }
80         return (*init)(handle, &plugin_errmsg);
81 }
82
83 void
84 exit_plugin(void *handle)
85 {
86         int (*exit)(void *);
87
88         exit = resolve_symbol("cifs_idmap_exit_plugin");
89         if (exit)
90                 (*exit)(handle);
91 }
92
93 int
94 sid_to_str(void *handle, const struct cifs_sid *sid, char **name)
95 {
96         int (*entry)(void *, const struct cifs_sid *, char **);
97
98         *(void **)(&entry) = resolve_symbol("cifs_idmap_sid_to_str");
99         if (!entry) {
100                 plugin_errmsg = "cifs_idmap_sid_to_str not implemented";
101                 return -ENOSYS;
102         }
103
104         return (*entry)(handle, sid, name);
105 }
106
107 int
108 str_to_sid(void *handle, const char *name, struct cifs_sid *sid)
109 {
110         int (*entry)(void *, const char *, struct cifs_sid *);
111
112         *(void **)(&entry) = resolve_symbol("cifs_idmap_str_to_sid");
113         if (!entry) {
114                 plugin_errmsg = "cifs_idmap_str_to_sid not implemented";
115                 return -ENOSYS;
116         }
117
118         return (*entry)(handle, name, sid);
119 }
120
121 int
122 sids_to_ids(void *handle, const struct cifs_sid *sid, const size_t num,
123           struct cifs_uxid *cuxid)
124 {
125         int (*entry)(void *handle, const struct cifs_sid *sids,
126                         const size_t num, struct cifs_uxid *cuxid);
127
128         *(void **)(&entry) = resolve_symbol("cifs_idmap_sids_to_ids");
129         if (!entry) {
130                 plugin_errmsg = "cifs_idmap_sids_to_ids not implemented";
131                 return -ENOSYS;
132         }
133
134         return (*entry)(handle, sid, num, cuxid);
135 }
136
137 int
138 ids_to_sids(void *handle, const struct cifs_uxid *cuxid, const size_t num,
139                 struct cifs_sid *sid)
140 {
141         int (*entry)(void *handle, const struct cifs_uxid *cuxid,
142                         const size_t num, struct cifs_sid *sid);
143
144         *(void **)(&entry) = resolve_symbol("cifs_idmap_ids_to_sids");
145         if (!entry) {
146                 plugin_errmsg = "cifs_idmap_ids_to_sids not implemented";
147                 return -ENOSYS;
148         }
149
150         return (*entry)(handle, cuxid, num, sid);
151 }