]> git.decadent.org.uk Git - nfs-utils.git/blob - utils/nfsidmap/nfsidmap.c
nfsidmap: Added -v and -t flags
[nfs-utils.git] / utils / nfsidmap / nfsidmap.c
1
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include <pwd.h>
8 #include <grp.h>
9 #include <keyutils.h>
10 #include <nfsidmap.h>
11
12 #include <unistd.h>
13 #include "xlog.h"
14
15 int verbose = 0;
16 char *usage="Usage: %s [-v] [-t timeout] key desc";
17
18 #define MAX_ID_LEN   11
19 #define IDMAP_NAMESZ 128
20 #define USER  1
21 #define GROUP 0
22
23 /*
24  * Find either a user or group id based on the name@domain string
25  */
26 int id_lookup(char *name_at_domain, key_serial_t key, int type)
27 {
28         char id[MAX_ID_LEN];
29         uid_t uid = 0;
30         gid_t gid = 0;
31         int rc;
32
33         if (type == USER) {
34                 rc = nfs4_owner_to_uid(name_at_domain, &uid);
35                 sprintf(id, "%u", uid);
36         } else {
37                 rc = nfs4_group_owner_to_gid(name_at_domain, &gid);
38                 sprintf(id, "%u", gid);
39         }
40         if (rc < 0)
41                 xlog_err("id_lookup: %s: failed: %m",
42                         (type == USER ? "nfs4_owner_to_uid" : "nfs4_group_owner_to_gid"));
43
44         if (rc == 0) {
45                 rc = keyctl_instantiate(key, id, strlen(id) + 1, 0);
46                 if (rc < 0)
47                         xlog_err("id_lookup: keyctl_instantiate failed: %m");
48         }
49
50         return rc;
51 }
52
53 /*
54  * Find the name@domain string from either a user or group id
55  */
56 int name_lookup(char *id, key_serial_t key, int type)
57 {
58         char name[IDMAP_NAMESZ];
59         char domain[NFS4_MAX_DOMAIN_LEN];
60         uid_t uid;
61         gid_t gid;
62         int rc;
63
64         rc = nfs4_get_default_domain(NULL, domain, NFS4_MAX_DOMAIN_LEN);
65         if (rc != 0) {
66                 rc = -1;
67                 xlog_err("name_lookup: nfs4_get_default_domain failed: %m");
68                 goto out;
69         }
70
71         if (type == USER) {
72                 uid = atoi(id);
73                 rc = nfs4_uid_to_name(uid, domain, name, IDMAP_NAMESZ);
74         } else {
75                 gid = atoi(id);
76                 rc = nfs4_gid_to_name(gid, domain, name, IDMAP_NAMESZ);
77         }
78         if (rc < 0)
79                 xlog_err("name_lookup: %s: failed: %m",
80                         (type == USER ? "nfs4_uid_to_name" : "nfs4_gid_to_name"));
81
82         if (rc == 0) {
83                 rc = keyctl_instantiate(key, &name, strlen(name), 0);
84                 if (rc < 0)
85                         xlog_err("name_lookup: keyctl_instantiate failed: %m");
86         }
87 out:
88         return rc;
89 }
90
91 int main(int argc, char **argv)
92 {
93         char *arg;
94         char *value;
95         char *type;
96         int rc = 1, opt;
97         int timeout = 600;
98         key_serial_t key;
99         char *progname;
100
101         /* Set the basename */
102         if ((progname = strrchr(argv[0], '/')) != NULL)
103                 progname++;
104         else
105                 progname = argv[0];
106
107         xlog_open(progname);
108         xlog_syslog(1);
109         xlog_stderr(0);
110
111         while ((opt = getopt(argc, argv, "t:v")) != -1) {
112                 switch (opt) {
113                 case 'v':
114                         verbose++;
115                         break;
116                 case 't':
117                         timeout = atoi(optarg);
118                         break;
119                 default:
120                         xlog_warn(usage, progname);
121                         break;
122                 }
123         }
124
125         if ((argc - optind) != 2) {
126                 xlog_err("Bad arg count. Check /etc/request-key.conf");
127                 xlog_warn(usage, progname);
128                 return 1;
129         }
130
131         if (verbose)
132                 nfs4_set_debug(verbose, NULL);
133
134         key = strtol(argv[optind++], NULL, 10);
135
136         arg = strdup(argv[optind]);
137         if (arg == NULL) {
138                 xlog_err("strdup failed: %m");
139                 return 1;
140         }
141         type = strtok(arg, ":");
142         value = strtok(NULL, ":");
143
144         if (verbose) {
145                 xlog_warn("key: %ld type: %s value: %s timeout %ld",
146                         key, type, value, timeout);
147         }
148
149         if (strcmp(type, "uid") == 0)
150                 rc = id_lookup(value, key, USER);
151         else if (strcmp(type, "gid") == 0)
152                 rc = id_lookup(value, key, GROUP);
153         else if (strcmp(type, "user") == 0)
154                 rc = name_lookup(value, key, USER);
155         else if (strcmp(type, "group") == 0)
156                 rc = name_lookup(value, key, GROUP);
157
158         /* Set timeout to 10 (600 seconds) minutes */
159         if (rc == 0)
160                 keyctl_set_timeout(key, timeout);
161
162         free(arg);
163         return rc;
164 }