r6149: Fixes bugs #2498 and 2484.
[ira/wip.git] / examples / libsmbclient / testacl.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <popt.h>
5 #include "libsmbclient.h"
6 #include "get_auth_data_fn.h"
7
8 enum acl_mode
9 {
10     SMB_ACL_GET,
11     SMB_ACL_SET,
12     SMB_ACL_DELETE,
13     SMB_ACL_MODIFY,
14     SMB_ACL_ADD,
15     SMB_ACL_CHOWN,
16     SMB_ACL_CHGRP
17 };
18
19
20 int main(int argc, const char *argv[])
21 {
22     int opt;
23     int flags;
24     int debug = 0;
25     int numeric = 0;
26     enum acl_mode mode = SMB_ACL_GET;
27     static char *the_acl = NULL;
28     int ret;
29     char *p;
30     char *debugstr;
31     char path[1024];
32     char value[1024];
33     poptContext pc;
34     struct poptOption long_options[] =
35         {
36             POPT_AUTOHELP
37             {
38                 "numeric", 'n', POPT_ARG_NONE, &numeric,
39                 1, "Don't resolve sids or masks to names"
40             },
41             {
42                 "debug", 'd', POPT_ARG_INT, &debug,
43                 0, "Set debug level (0-100)"
44             },
45             {
46                 "delete", 'D', POPT_ARG_STRING, NULL,
47                 'D', "Delete an acl", "ACL"
48             },
49             {
50                 "modify", 'M', POPT_ARG_STRING, NULL,
51                 'M', "Modify an acl", "ACL"
52             },
53             {
54                 "add", 'a', POPT_ARG_STRING, NULL,
55                 'a', "Add an acl", "ACL"
56             },
57             {
58                 "set", 'S', POPT_ARG_STRING, NULL,
59                 'S', "Set acls", "ACLS"
60             },
61             {
62                 "chown", 'C', POPT_ARG_STRING, NULL,
63                 'C', "Change ownership of a file", "USERNAME"
64             },
65             {
66                 "chgrp", 'G', POPT_ARG_STRING, NULL,
67                 'G', "Change group ownership of a file", "GROUPNAME"
68             },
69             {
70                 "get", 'g', POPT_ARG_STRING, NULL,
71                 'g', "Get a specific acl attribute", "ACL"
72             },
73             {
74                 NULL
75             }
76         };
77     
78     setbuf(stdout, NULL);
79
80     pc = poptGetContext("smbcacls", argc, argv, long_options, 0);
81     
82     poptSetOtherOptionHelp(pc, "smb://server1/share1/filename");
83     
84     while ((opt = poptGetNextOpt(pc)) != -1) {
85         switch (opt) {
86         case 'S':
87             the_acl = strdup(poptGetOptArg(pc));
88             mode = SMB_ACL_SET;
89             break;
90             
91         case 'D':
92             the_acl = strdup(poptGetOptArg(pc));
93             mode = SMB_ACL_DELETE;
94             break;
95             
96         case 'M':
97             the_acl = strdup(poptGetOptArg(pc));
98             mode = SMB_ACL_MODIFY;
99             break;
100             
101         case 'a':
102             the_acl = strdup(poptGetOptArg(pc));
103             mode = SMB_ACL_ADD;
104             break;
105
106         case 'g':
107             the_acl = strdup(poptGetOptArg(pc));
108             mode = SMB_ACL_GET;
109             break;
110
111         case 'C':
112             the_acl = strdup(poptGetOptArg(pc));
113             mode = SMB_ACL_CHOWN;
114             break;
115
116         case 'G':
117             the_acl = strdup(poptGetOptArg(pc));
118             mode = SMB_ACL_CHGRP;
119             break;
120         }
121     }
122     
123     /* Make connection to server */
124     if(!poptPeekArg(pc)) { 
125         poptPrintUsage(pc, stderr, 0);
126         return 1;
127     }
128     
129     strcpy(path, poptGetArg(pc));
130     
131     if (smbc_init(get_auth_data_fn, debug) != 0)
132     {
133         printf("Could not initialize smbc_ library\n");
134         return 1;
135     }
136     
137     /* Perform requested action */
138     
139     switch(mode)
140     {
141     case SMB_ACL_GET:
142         if (the_acl == NULL)
143         {
144             if (numeric)
145             {
146                 the_acl = "system.nt_sec_desc.*";
147             }
148             else
149             {
150                 the_acl = "system.nt_sec_desc.*+";
151             }
152         }
153         ret = smbc_getxattr(path, the_acl, value, sizeof(value));
154         if (ret < 0)
155         {
156             printf("Could not get attributes for [%s] %d: %s\n",
157                    path, errno, strerror(errno));
158             return 1;
159         }
160         
161         printf("Attributes for [%s] are:\n%s\n", path, value);
162         break;
163
164     case SMB_ACL_ADD:
165         flags = SMBC_XATTR_FLAG_CREATE;
166         debugstr = "add attributes";
167         goto do_set;
168         
169     case SMB_ACL_MODIFY:
170         flags = SMBC_XATTR_FLAG_REPLACE;
171         debugstr = "modify attributes";
172         goto do_set;
173
174     case SMB_ACL_CHOWN:
175         snprintf(value, sizeof(value),
176                  "system.nt_sec_desc.owner%s:%s",
177                  numeric ? "" : "+", the_acl);
178         the_acl = value;
179         debugstr = "chown owner";
180         goto do_set;
181
182     case SMB_ACL_CHGRP:
183         snprintf(value, sizeof(value),
184                  "system.nt_sec_desc.group%s:%s",
185                  numeric ? "" : "+", the_acl);
186         the_acl = value;
187         debugstr = "change group";
188         goto do_set;
189
190     case SMB_ACL_SET:
191         flags = 0;
192         debugstr = "set attributes";
193         
194       do_set:
195         if ((p = strchr(the_acl, ':')) == NULL)
196         {
197             printf("Missing value.  ACL must be name:value pair\n");
198             return 1;
199         }
200
201         *p++ = '\0';
202         
203         ret = smbc_setxattr(path, the_acl, p, strlen(p), flags);
204         if (ret < 0)
205         {
206             printf("Could not %s for [%s] %d: %s\n",
207                    debugstr, path, errno, strerror(errno));
208             return 1;
209         }
210         break;
211
212     case SMB_ACL_DELETE:
213         ret = smbc_removexattr(path, the_acl);
214         if (ret < 0)
215         {
216             printf("Could not remove attribute %s for [%s] %d:%s\n",
217                    the_acl, path, errno, strerror(errno));
218             return 1;
219         }
220         break;
221
222     default:
223         printf("operation not yet implemented\n");
224         break;
225     }
226     
227     return 0;
228 }