3 * Copyright (C) Shirish Pargaonkar (shirishp@us.ibm.com) 2011
5 * Used by /sbin/request-key.conf for handling
6 * cifs upcall for SID to uig/gid and uid/gid to SID mapping.
7 * You should have keyutils installed and add
8 * this lines to /etc/request-key.conf file:
10 create cifs.idmap * * /usr/local/sbin/cifs.idmap %k
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #endif /* HAVE_CONFIG_H */
33 #include <sys/types.h>
45 static const char *prog = "cifs.idmap";
47 static const struct option long_options[] = {
48 {"version", 0, NULL, 'v'},
52 static void usage(void)
54 fprintf(stderr, "Usage: %s key_serial\n", prog);
57 char *strget(const char *str, char *substr)
59 int len, sublen, retlen;
60 char *retstr, *substrptr;
62 sublen = strlen(substr);
63 substrptr = strstr(str, substr);
65 len = strlen(substrptr);
68 retlen = len - sublen;
70 retstr = malloc(retlen + 1);
72 strncpy(retstr, substrptr, retlen);
82 cifs_idmap(const key_serial_t key, const char *key_descr)
88 struct wbcDomainSid sid;
91 * Use winbind to convert received string to a SID and lookup
92 * name and map that SID to an uid. If either of these
93 * function calls return with an error, return an error the
94 * upcall caller. Otherwise instanticate a key using that uid.
96 * The same applies to SID and gid mapping.
98 sidstr = strget(key_descr, "os:");
100 rc = wbcStringToSid(sidstr, &sid);
102 syslog(LOG_DEBUG, "Invalid owner string: %s, rc: %d",
105 rc = wbcSidToUid(&sid, &uid);
107 syslog(LOG_DEBUG, "SID %s to uid wbc error: %d",
110 if (!rc) { /* SID has been mapped to an uid */
111 rc = keyctl_instantiate(key, &uid, sizeof(uid_t), 0);
113 syslog(LOG_ERR, "%s: key inst: %s",
114 __func__, strerror(errno));
120 sidstr = strget(key_descr, "gs:");
122 rc = wbcStringToSid(sidstr, &sid);
124 syslog(LOG_DEBUG, "Invalid group string: %s, rc: %d",
127 rc = wbcSidToGid(&sid, &gid);
129 syslog(LOG_DEBUG, "SID %s to gid wbc error: %d",
132 if (!rc) { /* SID has been mapped to a gid */
133 rc = keyctl_instantiate(key, &gid, sizeof(gid_t), 0);
135 syslog(LOG_ERR, "%s: key inst: %s",
136 __func__, strerror(errno));
142 sidstr = strget(key_descr, "oi:");
145 syslog(LOG_DEBUG, "SID: %s, uid: %d", sidstr, uid);
146 rc = wbcUidToSid(uid, &sid);
148 syslog(LOG_DEBUG, "uid %d to SID error: %d", uid, rc);
149 if (!rc) { /* SID has been mapped to a uid */
150 rc = keyctl_instantiate(key, &sid,
151 sizeof(struct wbcDomainSid), 0);
153 syslog(LOG_ERR, "%s: key inst: %s",
154 __func__, strerror(errno));
160 sidstr = strget(key_descr, "gi:");
163 syslog(LOG_DEBUG, "SID: %s, gid: %d", sidstr, gid);
164 rc = wbcGidToSid(gid, &sid);
166 syslog(LOG_DEBUG, "gid %d to SID error: %d", gid, rc);
167 if (!rc) { /* SID has been mapped to a gid */
168 rc = keyctl_instantiate(key, &sid,
169 sizeof(struct wbcDomainSid), 0);
171 syslog(LOG_ERR, "%s: key inst: %s",
172 __func__, strerror(errno));
179 syslog(LOG_DEBUG, "Invalid key: %s", key_descr);
188 int main(const int argc, char *const argv[])
192 key_serial_t key = 0;
195 openlog(prog, 0, LOG_DAEMON);
197 while ((c = getopt_long(argc, argv, "v", long_options, NULL)) != -1) {
200 printf("version: %s\n", VERSION);
203 syslog(LOG_ERR, "unknown option: %c", c);
208 /* is there a key? */
209 if (argc <= optind) {
214 /* get key and keyring values */
216 key = strtol(argv[optind], NULL, 10);
219 syslog(LOG_ERR, "Invalid key format: %s", strerror(errno));
223 rc = keyctl_describe_alloc(key, &buf);
225 syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
231 syslog(LOG_DEBUG, "key description: %s", buf);
233 rc = cifs_idmap(key, buf);