s3:pylibsmb: Add .set_acl API to SMB py bindings
authorTim Beale <timbeale@catalyst.net.nz>
Tue, 8 Jan 2019 01:42:05 +0000 (14:42 +1300)
committerJeremy Allison <jra@samba.org>
Thu, 17 Jan 2019 00:40:30 +0000 (01:40 +0100)
This is pretty similar code to py_smb_getacl(), except it's calling
cli_set_security_descriptor() instead of cli_query_security_descriptor()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=13676

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/libsmb/pylibsmb.c

index e0ce518d91b9e4edf2aa69d1f7df7b56db226fff..ee1d91b90ed482594dc6dce98a28e157f899a0be 100644 (file)
@@ -1525,6 +1525,54 @@ static PyObject *py_smb_getacl(struct py_cli_state *self, PyObject *args)
                                    sd, sd);
 }
 
+/*
+ * Set ACL on file/directory using given security descriptor object
+ */
+static PyObject *py_smb_setacl(struct py_cli_state *self, PyObject *args)
+{
+       NTSTATUS status;
+       char *filename = NULL;
+       PyObject *py_sd = NULL;
+       struct security_descriptor *sd = NULL;
+       unsigned int sinfo = SECINFO_DEFAULT_FLAGS;
+       uint16_t fnum;
+
+       /* there's no async version of cli_set_security_descriptor() */
+       if (self->thread_state != NULL) {
+               PyErr_SetString(PyExc_RuntimeError,
+                               "set_acl() is not supported on "
+                               "a multi_threaded connection");
+               return NULL;
+       }
+
+       if (!PyArg_ParseTuple(args, "sO|I:set_acl", &filename, &py_sd,
+                             &sinfo)) {
+               return NULL;
+       }
+
+       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(pytalloc_get_ptr(py_sd)));
+               return NULL;
+       }
+
+       status = cli_ntcreate(self->cli, filename, 0,
+                             SEC_FLAG_MAXIMUM_ALLOWED, 0,
+                             FILE_SHARE_READ|FILE_SHARE_WRITE,
+                             FILE_OPEN, 0x0, 0x0, &fnum, NULL);
+       PyErr_NTSTATUS_IS_ERR_RAISE(status);
+
+       status = cli_set_security_descriptor(self->cli, fnum, sinfo, sd);
+       PyErr_NTSTATUS_IS_ERR_RAISE(status);
+
+       status = cli_close(self->cli, fnum);
+       PyErr_NTSTATUS_IS_ERR_RAISE(status);
+
+       Py_RETURN_NONE;
+}
+
 static PyMethodDef py_cli_state_methods[] = {
        { "settimeout", (PyCFunction)py_cli_settimeout, METH_VARARGS,
          "settimeout(new_timeout_msecs) => return old_timeout_msecs" },
@@ -1577,6 +1625,9 @@ static PyMethodDef py_cli_state_methods[] = {
        { "get_acl", (PyCFunction)py_smb_getacl, METH_VARARGS,
          "get_acl(path[, security_info=0]) -> security_descriptor object\n\n"
          "\t\tGet security descriptor for file." },
+       { "set_acl", (PyCFunction)py_smb_setacl, METH_VARARGS,
+         "set_acl(path, security_descriptor[, security_info=0]) -> None\n\n"
+         "\t\tSet security descriptor for file." },
        { NULL, NULL, 0, NULL }
 };