smbd: Remove NT4 compatability handling in posix -> NT ACL conversion
[metze/samba/wip.git] / source4 / libcli / pysmb.c
index afa85ab5dad4475b9f5ac9ede828faf77383061b..fb981c7f18994544cb12785704fa23b12c2ca3f0 100644 (file)
@@ -53,7 +53,6 @@ struct smb_private_data {
        struct smbcli_tree *tree;
 };
 
-
 static void dos_format(char *s)
 {
        string_replace(s, '/', '\\');
@@ -103,7 +102,7 @@ static NTSTATUS do_smb_connect(TALLOC_CTX *mem_ctx, struct smb_private_data *spd
 /*
  * Read SMB file and return the contents of the file as python string
  */
-static PyObject * py_smb_loadfile(py_talloc_Object *self, PyObject *args)
+static PyObject * py_smb_loadfile(pytalloc_Object *self, PyObject *args)
 {
        struct smb_composite_loadfile io;
        const char *filename;
@@ -128,7 +127,7 @@ static PyObject * py_smb_loadfile(py_talloc_Object *self, PyObject *args)
 /*
  * Create a SMB file with given string as the contents
  */
-static PyObject * py_smb_savefile(py_talloc_Object *self, PyObject *args)
+static PyObject * py_smb_savefile(pytalloc_Object *self, PyObject *args)
 {
        struct smb_composite_savefile io;
        const char *filename;
@@ -151,7 +150,6 @@ static PyObject * py_smb_savefile(py_talloc_Object *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-
 /*
  * Callback function to accumulate directory contents in a python list
  */
@@ -183,11 +181,10 @@ static void py_smb_list_callback(struct clilist_file_info *f, const char *mask,
        }
 }
 
-
 /*
  * List the directory contents for specified directory (Ignore '.' and '..' dirs)
  */
-static PyObject *py_smb_list(py_talloc_Object *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_smb_list(pytalloc_Object *self, PyObject *args, PyObject *kwargs)
 {
        struct smb_private_data *spdata;
        PyObject *py_dirlist;
@@ -225,11 +222,10 @@ static PyObject *py_smb_list(py_talloc_Object *self, PyObject *args, PyObject *k
        return py_dirlist;
 }
 
-
 /*
  * Create a directory
  */
-static PyObject *py_smb_mkdir(py_talloc_Object *self, PyObject *args)
+static PyObject *py_smb_mkdir(pytalloc_Object *self, PyObject *args)
 {
        NTSTATUS status;
        const char *dirname;
@@ -246,11 +242,10 @@ static PyObject *py_smb_mkdir(py_talloc_Object *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-
 /*
  * Remove a directory
  */
-static PyObject *py_smb_rmdir(py_talloc_Object *self, PyObject *args)
+static PyObject *py_smb_rmdir(pytalloc_Object *self, PyObject *args)
 {
        NTSTATUS status;
        const char *dirname;
@@ -267,11 +262,32 @@ static PyObject *py_smb_rmdir(py_talloc_Object *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
+/*
+ * Remove a directory and all its contents
+ */
+static PyObject *py_smb_deltree(pytalloc_Object *self, PyObject *args)
+{
+       int status;
+       const char *dirname;
+       struct smb_private_data *spdata;
+
+       if (!PyArg_ParseTuple(args, "s:deltree", &dirname)) {
+               return NULL;
+       }
+
+       spdata = self->ptr;
+       status = smbcli_deltree(spdata->tree, dirname);
+       if (status <= 0) {
+               return NULL;
+       }
+
+       Py_RETURN_NONE;
+}
 
 /*
  * Check existence of a path
  */
-static PyObject *py_smb_chkpath(py_talloc_Object *self, PyObject *args)
+static PyObject *py_smb_chkpath(pytalloc_Object *self, PyObject *args)
 {
        NTSTATUS status;
        const char *path;
@@ -291,20 +307,21 @@ static PyObject *py_smb_chkpath(py_talloc_Object *self, PyObject *args)
        Py_RETURN_FALSE;
 }
 
-
 /*
  * Read ACL on a given file/directory as a security descriptor object
  */
-static PyObject *py_smb_getacl(py_talloc_Object *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_smb_getacl(pytalloc_Object *self, PyObject *args, PyObject *kwargs)
 {
        NTSTATUS status;
        union smb_open io;
        union smb_fileinfo fio;
        struct smb_private_data *spdata;
        const char *filename;
+       uint32_t sinfo = 0;
+       int access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        int fnum;
 
-       if (!PyArg_ParseTuple(args, "s:get_acl", &filename)) {
+       if (!PyArg_ParseTuple(args, "s|Ii:get_acl", &filename, &sinfo, &access_mask)) {
                return NULL;
        }
 
@@ -315,7 +332,7 @@ static PyObject *py_smb_getacl(py_talloc_Object *self, PyObject *args, PyObject
        io.generic.level = RAW_OPEN_NTCREATEX;
        io.ntcreatex.in.root_fid.fnum = 0;
        io.ntcreatex.in.flags = 0;
-       io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       io.ntcreatex.in.access_mask = access_mask;
        io.ntcreatex.in.create_options = 0;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | 
@@ -335,16 +352,18 @@ static PyObject *py_smb_getacl(py_talloc_Object *self, PyObject *args, PyObject
 
        fio.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
        fio.query_secdesc.in.file.fnum = fnum;
-       fio.query_secdesc.in.secinfo_flags = SECINFO_OWNER |
+       if (sinfo)
+               fio.query_secdesc.in.secinfo_flags = sinfo;
+       else
+               fio.query_secdesc.in.secinfo_flags = SECINFO_OWNER |
                                                SECINFO_GROUP |
                                                SECINFO_DACL |
                                                SECINFO_PROTECTED_DACL |
                                                SECINFO_UNPROTECTED_DACL |
-                                               SECINFO_DACL |
+                                               SECINFO_SACL |
                                                SECINFO_PROTECTED_SACL |
                                                SECINFO_UNPROTECTED_SACL;
 
-
        status = smb_raw_query_secdesc(spdata->tree, self->talloc_ctx, &fio);
        smbcli_close(spdata->tree, fnum);
 
@@ -354,11 +373,10 @@ static PyObject *py_smb_getacl(py_talloc_Object *self, PyObject *args, PyObject
                                self->talloc_ctx, fio.query_secdesc.out.sd);
 }
 
-
 /*
  * Set ACL on file/directory using given security descriptor object
  */
-static PyObject *py_smb_setacl(py_talloc_Object *self, PyObject *args, PyObject *kwargs)
+static PyObject *py_smb_setacl(pytalloc_Object *self, PyObject *args, PyObject *kwargs)
 {
        NTSTATUS status;
        union smb_open io;
@@ -367,19 +385,20 @@ static PyObject *py_smb_setacl(py_talloc_Object *self, PyObject *args, PyObject
        const char *filename;
        PyObject *py_sd;
        struct security_descriptor *sd;
+       uint32_t sinfo = 0;
        int fnum;
 
-       if (!PyArg_ParseTuple(args, "sO:set_acl", &filename, &py_sd)) {
+       if (!PyArg_ParseTuple(args, "sO|I:get_acl", &filename, &py_sd, &sinfo)) {
                return NULL;
        }
 
        spdata = self->ptr;
 
-       sd = py_talloc_get_type(py_sd, struct security_descriptor);
+       sd = pytalloc_get_type(py_sd, struct security_descriptor);
        if (!sd) {
                PyErr_Format(PyExc_TypeError, 
                        "Expected dcerpc.security.descriptor as argument, got %s", 
-                       talloc_get_name(py_talloc_get_ptr(py_sd)));
+                       talloc_get_name(pytalloc_get_ptr(py_sd)));
                return NULL;
        }
 
@@ -410,7 +429,18 @@ static PyObject *py_smb_setacl(py_talloc_Object *self, PyObject *args, PyObject
 
        fio.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
        fio.set_secdesc.in.file.fnum = fnum;
-       fio.set_secdesc.in.secinfo_flags = 0;
+       if (sinfo)
+               fio.set_secdesc.in.secinfo_flags = sinfo;
+       else
+               fio.set_secdesc.in.secinfo_flags = SECINFO_OWNER |
+                                               SECINFO_GROUP |
+                                               SECINFO_DACL |
+                                               SECINFO_PROTECTED_DACL |
+                                               SECINFO_UNPROTECTED_DACL |
+                                               SECINFO_SACL |
+                                               SECINFO_PROTECTED_SACL |
+                                               SECINFO_UNPROTECTED_SACL;
+
        fio.set_secdesc.in.sd = sd;
 
        status = smb_raw_set_secdesc(spdata->tree, &fio);
@@ -421,6 +451,82 @@ static PyObject *py_smb_setacl(py_talloc_Object *self, PyObject *args, PyObject
        Py_RETURN_NONE;
 }
 
+/*
+ * Open the file with the parameters passed in and return an object if OK
+ */
+static PyObject *py_open_file(pytalloc_Object *self, PyObject *args, PyObject *kwargs)
+{
+       NTSTATUS status;
+       union smb_open io;
+       struct smb_private_data *spdata;
+       const char *filename;
+       uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       uint32_t share_access = NTCREATEX_SHARE_ACCESS_READ |
+                               NTCREATEX_SHARE_ACCESS_WRITE;
+        uint32_t open_disposition = NTCREATEX_DISP_OPEN;
+        uint32_t create_options = 0;
+       TALLOC_CTX *mem_ctx;
+       int fnum;
+
+       if (!PyArg_ParseTuple(args, "s|iiii:open_file", 
+                               &filename, 
+                               &access_mask,
+                               &share_access,
+                               &open_disposition,
+                               &create_options)) {
+               return NULL;
+       }
+
+       ZERO_STRUCT(io);
+
+       spdata = self->ptr;     
+
+       mem_ctx = talloc_new(NULL);
+
+       io.generic.level = RAW_OPEN_NTCREATEX;
+       io.ntcreatex.in.root_fid.fnum = 0;
+       io.ntcreatex.in.flags = 0;
+       io.ntcreatex.in.access_mask = access_mask;
+       io.ntcreatex.in.create_options = create_options;
+       io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+       io.ntcreatex.in.share_access = share_access;
+       io.ntcreatex.in.alloc_size = 0;
+       io.ntcreatex.in.open_disposition = open_disposition;
+       io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+       io.ntcreatex.in.security_flags = 0;
+       io.ntcreatex.in.fname = filename;
+       
+       status = smb_raw_open(spdata->tree, mem_ctx, &io);
+       talloc_free(mem_ctx);
+
+       PyErr_NTSTATUS_IS_ERR_RAISE(status);
+
+       fnum = io.ntcreatex.out.file.fnum;
+
+       return Py_BuildValue("i", fnum);
+}
+
+/*
+ * Close the file based on the fnum passed in
+ */
+static PyObject *py_close_file(pytalloc_Object *self, PyObject *args, PyObject *kwargs)
+{
+       struct smb_private_data *spdata;
+       int fnum;
+
+       if (!PyArg_ParseTuple(args, "i:close_file", &fnum)) {
+               return NULL;
+       }
+
+       spdata = self->ptr;     
+
+       /*
+        * Should check the status ...
+        */
+       smbcli_close(spdata->tree, fnum);
+
+       Py_RETURN_NONE;
+}
 
 static PyMethodDef py_smb_methods[] = {
        { "loadfile", (PyCFunction)py_smb_loadfile, METH_VARARGS,
@@ -443,19 +549,27 @@ static PyMethodDef py_smb_methods[] = {
        { "rmdir", (PyCFunction)py_smb_rmdir, METH_VARARGS,
                "rmdir(path) -> None\n\n \
                Delete a directory." },
+       { "deltree", (PyCFunction)py_smb_deltree, METH_VARARGS,
+               "deltree(path) -> None\n\n \
+               Delete a directory and all its contents." },
        { "chkpath", (PyCFunction)py_smb_chkpath, METH_VARARGS,
                "chkpath(path) -> True or False\n\n \
                Return true if path exists, false otherwise." },
        { "get_acl", (PyCFunction)py_smb_getacl, METH_VARARGS,
-               "get_acl(path) -> security_descriptor object\n\n \
+               "get_acl(path[, security_info=0]) -> security_descriptor object\n\n \
                Get security descriptor for file." },
        { "set_acl", (PyCFunction)py_smb_setacl, METH_VARARGS,
-               "set_acl(path, security_descriptor) -> None\n\n \
+               "set_acl(path, security_descriptor[, security_info=0]) -> None\n\n \
                Set security descriptor for file." },
+       { "open_file", (PyCFunction)py_open_file, METH_VARARGS,
+               "open_file(path, access_mask[, share_access[, open_disposition[, create_options]]] -> fnum\n\n \
+               Open a file. Throws NTSTATUS exceptions on errors." },
+       { "close_file", (PyCFunction)py_close_file, METH_VARARGS,
+               "close_file(fnum) -> None\n\n \
+               Close the file based on fnum."},
        { NULL },
 };
 
-
 static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
        PyObject *py_creds = Py_None;
@@ -463,7 +577,7 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
        const char *kwnames[] = { "hostname", "service", "creds", "lp", NULL };
        const char *hostname = NULL;
        const char *service = NULL;
-       py_talloc_Object *smb;
+       pytalloc_Object *smb;
        struct smb_private_data *spdata;
        NTSTATUS status;
 
@@ -473,7 +587,7 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
                return NULL;
        }
 
-       smb = (py_talloc_Object *)type->tp_alloc(type, 0);
+       smb = (pytalloc_Object *)type->tp_alloc(type, 0);
        if (smb == NULL) {
                PyErr_NoMemory();
                return NULL;
@@ -515,21 +629,20 @@ static PyObject *py_smb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs
        return (PyObject *)smb;
 }
 
-
 static PyTypeObject PySMB = {
        .tp_name = "smb.SMB",
-       .tp_basicsize = sizeof(py_talloc_Object),
+       .tp_basicsize = sizeof(pytalloc_Object),
        .tp_new = py_smb_new,
        .tp_flags = Py_TPFLAGS_DEFAULT,
        .tp_methods = py_smb_methods,
-       .tp_doc = "SMB(hostname, service[, lp[, creds]]) -> SMB connection object\n",
+       .tp_doc = "SMB(hostname, service[, creds[, lp]]) -> SMB connection object\n",
 
 };
 
 void initsmb(void)
 {
        PyObject *m;
-       PyTypeObject *talloc_type = PyTalloc_GetObjectType();
+       PyTypeObject *talloc_type = pytalloc_GetObjectType();
        if (talloc_type == NULL) {
                return;
        }