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