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 8enum 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 20int 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} 240