s3-pysmbd: Add set_nt_acl() function based on parts of vfstest
authorAndrew Bartlett <abartlet@samba.org>
Thu, 2 Aug 2012 03:35:24 +0000 (13:35 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 2 Aug 2012 09:35:19 +0000 (11:35 +0200)
This will allow us to set the full NT ACL on a file, using the VFS
layer, during provision of the AD DC.

Andrew Bartlett

source3/smbd/pysmbd.c
source3/wscript_build

index 5badb3a74450b56decbaba9f30807de50d2da6ae..647831975628cf958af3bd684357026ec3d44663 100644 (file)
@@ -4,6 +4,8 @@
    Copyright (C) Jeremy Allison 1994-2009.
    Copyright (C) Andreas Gruenbacher 2002.
    Copyright (C) Simo Sorce <idra@samba.org> 2009.
+   Copyright (C) Simo Sorce 2002
+   Copyright (C) Eric Lorimer 2002
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,6 +25,9 @@
 #include "smbd/smbd.h"
 #include <Python.h>
 #include "libcli/util/pyerrors.h"
+#include "librpc/rpc/pyrpc_util.h"
+#include <pytalloc.h>
+#include "system/filesys.h"
 
 extern const struct generic_mapping file_generic_mapping;
 
@@ -66,6 +71,83 @@ static NTSTATUS set_sys_acl_no_snum(const char *fname,
        return status;
 }
 
+static NTSTATUS set_nt_acl_no_snum(const char *fname,
+                                  uint32 security_info_sent, const struct security_descriptor *sd)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       connection_struct *conn;
+       NTSTATUS status = NT_STATUS_OK;
+       files_struct *fsp;
+       struct smb_filename *smb_fname = NULL;
+       int flags;
+
+       conn = talloc_zero(frame, connection_struct);
+       if (conn == NULL) {
+               DEBUG(0, ("talloc failed\n"));
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!(conn->params = talloc(conn, struct share_params))) {
+               DEBUG(0,("get_nt_acl_no_snum: talloc() failed!\n"));
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       conn->params->service = -1;
+
+       set_conn_connectpath(conn, "/");
+
+       smbd_vfs_init(conn);
+
+       fsp = talloc(frame, struct files_struct);
+       if (fsp == NULL) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+       fsp->fh = talloc(fsp, struct fd_handle);
+       if (fsp->fh == NULL) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_NO_MEMORY;
+       }
+       fsp->conn = conn;
+
+       status = create_synthetic_smb_fname_split(fsp, fname, NULL,
+                                                 &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       fsp->fsp_name = smb_fname;
+
+#ifdef O_DIRECTORY
+       flags = O_RDONLY|O_DIRECTORY;
+#else
+       /* POSIX allows us to open a directory with O_RDONLY. */
+       flags = O_RDONLY;
+#endif
+
+       fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, 00400);
+       if (fsp->fh->fd == -1 && errno == EISDIR) {
+               fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, O_RDWR, 00400);
+       }
+       if (fsp->fh->fd == -1) {
+               printf("open: error=%d (%s)\n", errno, strerror(errno));
+               TALLOC_FREE(frame);
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       status = SMB_VFS_FSET_NT_ACL( fsp, security_info_sent, sd);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status)));
+       }
+
+       conn_free(conn);
+       TALLOC_FREE(frame);
+
+       return status;
+}
+
 
 static SMB_ACL_T make_simple_acl(uid_t uid, gid_t gid)
 {
@@ -195,6 +277,32 @@ static PyObject *py_smbd_have_posix_acls(PyObject *self, PyObject *args)
 #endif
 }
 
+/*
+  set a simple ACL on a file, as a test
+ */
+static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args)
+{
+       NTSTATUS status;
+       char *fname;
+       int security_info_sent;
+       PyObject *py_sd;
+       struct security_descriptor *sd;
+
+       if (!PyArg_ParseTuple(args, "siO", &fname, &security_info_sent, &py_sd))
+               return NULL;
+
+       if (!py_check_dcerpc_type(py_sd, "samba.dcerpc.security", "descriptor")) {
+               return NULL;
+       }
+
+       sd = pytalloc_get_type(py_sd, struct security_descriptor);
+
+       status = set_nt_acl_no_snum(fname, security_info_sent, sd);
+       PyErr_NTSTATUS_IS_ERR_RAISE(status);
+
+       Py_RETURN_NONE;
+}
+
 static PyMethodDef py_smbd_methods[] = {
        { "have_posix_acls",
                (PyCFunction)py_smbd_have_posix_acls, METH_VARARGS,
@@ -202,6 +310,9 @@ static PyMethodDef py_smbd_methods[] = {
        { "set_simple_acl",
                (PyCFunction)py_smbd_set_simple_acl, METH_VARARGS,
                NULL },
+       { "set_nt_acl",
+               (PyCFunction)py_smbd_set_nt_acl, METH_VARARGS,
+               NULL },
        { NULL }
 };
 
index bed31a15ff3444fcbfaf14988a58bbdd24a49761..40afdd759a8738eefa578964a807ce48267f1784 100755 (executable)
@@ -1585,7 +1585,7 @@ bld.SAMBA3_BINARY('vlp',
 
 bld.SAMBA3_PYTHON('pysmbd',
                   source='smbd/pysmbd.c',
-                  deps='smbd_base',
+                  deps='smbd_base pyrpc_util',
                   realname='samba/samba3/smbd.so'
                   )