Add this to samba-head.
[ddiss/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
7 enum acl_mode
8 {
9     SMB_ACL_GET,
10     SMB_ACL_SET,
11     SMB_ACL_DELETE,
12     SMB_ACL_MODIFY,
13     SMB_ACL_ADD,
14     SMB_ACL_CHOWN,
15     SMB_ACL_CHGRP
16 };
17
18 static void
19 get_auth_data_fn(const char * pServer,
20                  const char * pShare,
21                  char * pWorkgroup,
22                  int maxLenWorkgroup,
23                  char * pUsername,
24                  int maxLenUsername,
25                  char * pPassword,
26                  int maxLenPassword)
27     
28 {
29     char temp[128];
30     
31     fprintf(stdout, "Workgroup: [%s] ", pWorkgroup);
32     fgets(temp, sizeof(temp), stdin);
33     
34     if (temp[strlen(temp) - 1] == '\n') /* A new line? */
35     {
36         temp[strlen(temp) - 1] = '\0';
37     }
38     
39     if (temp[0] != '\0')
40     {
41         strncpy(pWorkgroup, temp, maxLenWorkgroup - 1);
42     }
43     
44     fprintf(stdout, "Username: [%s] ", pUsername);
45     fgets(temp, sizeof(temp), stdin);
46     
47     if (temp[strlen(temp) - 1] == '\n') /* A new line? */
48     {
49         temp[strlen(temp) - 1] = '\0';
50     }
51     
52     if (temp[0] != '\0')
53     {
54         strncpy(pUsername, temp, maxLenUsername - 1);
55     }
56     
57     fprintf(stdout, "Password: ");
58     fgets(temp, sizeof(temp), stdin);
59     
60     if (temp[strlen(temp) - 1] == '\n') /* A new line? */
61     {
62         temp[strlen(temp) - 1] = '\0';
63     }
64     
65     if (temp[0] != '\0')
66     {
67         strncpy(pPassword, temp, maxLenPassword - 1);
68     }
69 }
70
71
72 int main(int argc, const char *argv[])
73 {
74     int opt;
75     int flags;
76     int debug = 0;
77     int numeric = 0;
78     enum acl_mode mode = SMB_ACL_GET;
79     static char *the_acl = NULL;
80     int ret;
81     char *p;
82     char *debugstr;
83     char path[1024];
84     char value[1024];
85     poptContext pc;
86     struct poptOption long_options[] =
87         {
88             POPT_AUTOHELP
89             {
90                 "numeric", 'n', POPT_ARG_NONE, &numeric,
91                 1, "Don't resolve sids or masks to names"
92             },
93             {
94                 "debug", 'd', POPT_ARG_INT, &debug,
95                 0, "Set debug level (0-100)"
96             },
97             {
98                 "delete", 'D', POPT_ARG_STRING, NULL,
99                 'D', "Delete an acl", "ACL"
100             },
101             {
102                 "modify", 'M', POPT_ARG_STRING, NULL,
103                 'M', "Modify an acl", "ACL"
104             },
105             {
106                 "add", 'a', POPT_ARG_STRING, NULL,
107                 'a', "Add an acl", "ACL"
108             },
109             {
110                 "set", 'S', POPT_ARG_STRING, NULL,
111                 'S', "Set acls", "ACLS"
112             },
113             {
114                 "chown", 'C', POPT_ARG_STRING, NULL,
115                 'C', "Change ownership of a file", "USERNAME"
116             },
117             {
118                 "chgrp", 'G', POPT_ARG_STRING, NULL,
119                 'G', "Change group ownership of a file", "GROUPNAME"
120             },
121             {
122                 "get", 'g', POPT_ARG_STRING, NULL,
123                 'g', "Get a specific acl attribute", "ACL"
124             },
125             {
126                 NULL
127             }
128         };
129     
130     setbuf(stdout, NULL);
131
132     pc = poptGetContext("smbcacls", argc, argv, long_options, 0);
133     
134     poptSetOtherOptionHelp(pc, "smb://server1/share1/filename");
135     
136     while ((opt = poptGetNextOpt(pc)) != -1) {
137         switch (opt) {
138         case 'S':
139             the_acl = strdup(poptGetOptArg(pc));
140             mode = SMB_ACL_SET;
141             break;
142             
143         case 'D':
144             the_acl = strdup(poptGetOptArg(pc));
145             mode = SMB_ACL_DELETE;
146             break;
147             
148         case 'M':
149             the_acl = strdup(poptGetOptArg(pc));
150             mode = SMB_ACL_MODIFY;
151             break;
152             
153         case 'a':
154             the_acl = strdup(poptGetOptArg(pc));
155             mode = SMB_ACL_ADD;
156             break;
157
158         case 'g':
159             the_acl = strdup(poptGetOptArg(pc));
160             mode = SMB_ACL_GET;
161             break;
162
163         case 'C':
164             the_acl = strdup(poptGetOptArg(pc));
165             mode = SMB_ACL_CHOWN;
166             break;
167
168         case 'G':
169             the_acl = strdup(poptGetOptArg(pc));
170             mode = SMB_ACL_CHGRP;
171             break;
172         }
173     }
174     
175     /* Make connection to server */
176     if(!poptPeekArg(pc)) { 
177         poptPrintUsage(pc, stderr, 0);
178         return 1;
179     }
180     
181     strcpy(path, poptGetArg(pc));
182     
183     if (smbc_init(get_auth_data_fn, debug) != 0)
184     {
185         printf("Could not initialize smbc_ library\n");
186         return 1;
187     }
188     
189     /* Perform requested action */
190     
191     switch(mode)
192     {
193     case SMB_ACL_GET:
194         if (the_acl == NULL)
195         {
196             if (numeric)
197             {
198                 the_acl = "system.nt_sec_desc.*";
199             }
200             else
201             {
202                 the_acl = "system.nt_sec_desc.*+";
203             }
204         }
205         ret = smbc_getxattr(path, the_acl, value, sizeof(value));
206         if (ret < 0)
207         {
208             printf("Could not get attributes for [%s] %d: %s\n",
209                    path, errno, strerror(errno));
210             return 1;
211         }
212         
213         printf("Attributes for [%s] are:\n%s\n", path, value);
214         break;
215
216     case SMB_ACL_ADD:
217         flags = SMBC_XATTR_FLAG_CREATE;
218         debugstr = "add attributes";
219         goto do_set;
220         
221     case SMB_ACL_MODIFY:
222         flags = SMBC_XATTR_FLAG_REPLACE;
223         debugstr = "modify attributes";
224         goto do_set;
225
226     case SMB_ACL_CHOWN:
227         snprintf(value, sizeof(value),
228                  "system.nt_sec_desc.owner%s:%s",
229                  numeric ? "" : "+", the_acl);
230         the_acl = value;
231         debugstr = "chown owner";
232         goto do_set;
233
234     case SMB_ACL_CHGRP:
235         snprintf(value, sizeof(value),
236                  "system.nt_sec_desc.group%s:%s",
237                  numeric ? "" : "+", the_acl);
238         the_acl = value;
239         debugstr = "change group";
240         goto do_set;
241
242     case SMB_ACL_SET:
243         flags = 0;
244         debugstr = "set attributes";
245         
246       do_set:
247         if ((p = strchr(the_acl, ':')) == NULL)
248         {
249             printf("Missing value.  ACL must be name:value pair\n");
250             return 1;
251         }
252
253         *p++ = '\0';
254         
255         ret = smbc_setxattr(path, the_acl, p, strlen(p), flags);
256         if (ret < 0)
257         {
258             printf("Could not %s for [%s] %d: %s\n",
259                    debugstr, path, errno, strerror(errno));
260             return 1;
261         }
262         break;
263
264     case SMB_ACL_DELETE:
265         ret = smbc_removexattr(path, the_acl);
266         if (ret < 0)
267         {
268             printf("Could not remove attribute %s for [%s] %d:%s\n",
269                    the_acl, path, errno, strerror(errno));
270             return 1;
271         }
272         break;
273
274     default:
275         printf("operation not yet implemented\n");
276         break;
277     }
278     
279     return 0;
280 }