Initial import
[samba] / examples / libsmbclient / testacl.c
diff --git a/examples/libsmbclient/testacl.c b/examples/libsmbclient/testacl.c
new file mode 100644 (file)
index 0000000..ce5694b
--- /dev/null
@@ -0,0 +1,228 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <popt.h>
+#include "libsmbclient.h"
+#include "get_auth_data_fn.h"
+
+enum acl_mode
+{
+    SMB_ACL_GET,
+    SMB_ACL_SET,
+    SMB_ACL_DELETE,
+    SMB_ACL_MODIFY,
+    SMB_ACL_ADD,
+    SMB_ACL_CHOWN,
+    SMB_ACL_CHGRP
+};
+
+
+int main(int argc, const char *argv[])
+{
+    int opt;
+    int flags;
+    int debug = 0;
+    int numeric = 0;
+    enum acl_mode mode = SMB_ACL_GET;
+    static char *the_acl = NULL;
+    int ret;
+    char *p;
+    char *debugstr;
+    char path[1024];
+    char value[1024];
+    poptContext pc;
+    struct poptOption long_options[] =
+        {
+            POPT_AUTOHELP
+            {
+                "numeric", 'n', POPT_ARG_NONE, &numeric,
+                1, "Don't resolve sids or masks to names"
+            },
+            {
+                "debug", 'd', POPT_ARG_INT, &debug,
+                0, "Set debug level (0-100)"
+            },
+            {
+                "delete", 'D', POPT_ARG_STRING, NULL,
+                'D', "Delete an acl", "ACL"
+            },
+            {
+                "modify", 'M', POPT_ARG_STRING, NULL,
+                'M', "Modify an acl", "ACL"
+            },
+            {
+                "add", 'a', POPT_ARG_STRING, NULL,
+                'a', "Add an acl", "ACL"
+            },
+            {
+                "set", 'S', POPT_ARG_STRING, NULL,
+                'S', "Set acls", "ACLS"
+            },
+            {
+                "chown", 'C', POPT_ARG_STRING, NULL,
+                'C', "Change ownership of a file", "USERNAME"
+            },
+            {
+                "chgrp", 'G', POPT_ARG_STRING, NULL,
+                'G', "Change group ownership of a file", "GROUPNAME"
+            },
+            {
+                "get", 'g', POPT_ARG_STRING, NULL,
+                'g', "Get a specific acl attribute", "ACL"
+            },
+            {
+                NULL
+            }
+        };
+    
+    setbuf(stdout, NULL);
+
+    pc = poptGetContext("smbcacls", argc, argv, long_options, 0);
+    
+    poptSetOtherOptionHelp(pc, "smb://server1/share1/filename");
+    
+    while ((opt = poptGetNextOpt(pc)) != -1) {
+        switch (opt) {
+        case 'S':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_SET;
+            break;
+            
+        case 'D':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_DELETE;
+            break;
+            
+        case 'M':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_MODIFY;
+            break;
+            
+        case 'a':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_ADD;
+            break;
+
+        case 'g':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_GET;
+            break;
+
+        case 'C':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_CHOWN;
+            break;
+
+        case 'G':
+            the_acl = strdup(poptGetOptArg(pc));
+            mode = SMB_ACL_CHGRP;
+            break;
+        }
+    }
+    
+    /* Make connection to server */
+    if(!poptPeekArg(pc)) { 
+        poptPrintUsage(pc, stderr, 0);
+        return 1;
+    }
+    
+    strcpy(path, poptGetArg(pc));
+    
+    if (smbc_init(get_auth_data_fn, debug) != 0)
+    {
+        printf("Could not initialize smbc_ library\n");
+        return 1;
+    }
+    
+    /* Perform requested action */
+    
+    switch(mode)
+    {
+    case SMB_ACL_GET:
+        if (the_acl == NULL)
+        {
+            if (numeric)
+            {
+                the_acl = "system.nt_sec_desc.*";
+            }
+            else
+            {
+                the_acl = "system.nt_sec_desc.*+";
+            }
+        }
+        ret = smbc_getxattr(path, the_acl, value, sizeof(value));
+        if (ret < 0)
+        {
+            printf("Could not get attributes for [%s] %d: %s\n",
+                   path, errno, strerror(errno));
+            return 1;
+        }
+        
+        printf("Attributes for [%s] are:\n%s\n", path, value);
+        break;
+
+    case SMB_ACL_ADD:
+        flags = SMBC_XATTR_FLAG_CREATE;
+        debugstr = "add attributes";
+        goto do_set;
+        
+    case SMB_ACL_MODIFY:
+        flags = SMBC_XATTR_FLAG_REPLACE;
+        debugstr = "modify attributes";
+        goto do_set;
+
+    case SMB_ACL_CHOWN:
+        snprintf(value, sizeof(value),
+                 "system.nt_sec_desc.owner%s:%s",
+                 numeric ? "" : "+", the_acl);
+        the_acl = value;
+        debugstr = "chown owner";
+        goto do_set;
+
+    case SMB_ACL_CHGRP:
+        snprintf(value, sizeof(value),
+                 "system.nt_sec_desc.group%s:%s",
+                 numeric ? "" : "+", the_acl);
+        the_acl = value;
+        debugstr = "change group";
+        goto do_set;
+
+    case SMB_ACL_SET:
+        flags = 0;
+        debugstr = "set attributes";
+        
+      do_set:
+        if ((p = strchr(the_acl, ':')) == NULL)
+        {
+            printf("Missing value.  ACL must be name:value pair\n");
+            return 1;
+        }
+
+        *p++ = '\0';
+        
+        ret = smbc_setxattr(path, the_acl, p, strlen(p), flags);
+        if (ret < 0)
+        {
+            printf("Could not %s for [%s] %d: %s\n",
+                   debugstr, path, errno, strerror(errno));
+            return 1;
+        }
+        break;
+
+    case SMB_ACL_DELETE:
+        ret = smbc_removexattr(path, the_acl);
+        if (ret < 0)
+        {
+            printf("Could not remove attribute %s for [%s] %d:%s\n",
+                   the_acl, path, errno, strerror(errno));
+            return 1;
+        }
+        break;
+
+    default:
+        printf("operation not yet implemented\n");
+        break;
+    }
+    
+    return 0;
+}