LCOV - code coverage report
Current view: top level - source3/smbd - pysmbd.c (source / functions) Hit Total Coverage
Test: coverage report for vadcx-master-patch-75612 fe003de8 Lines: 347 594 58.4 %
Date: 2024-02-29 22:57:05 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Set NT and POSIX ACLs and other VFS operations from Python
       4             : 
       5             :    Copyrigyt (C) Andrew Bartlett 2012
       6             :    Copyright (C) Jeremy Allison 1994-2009.
       7             :    Copyright (C) Andreas Gruenbacher 2002.
       8             :    Copyright (C) Simo Sorce <idra@samba.org> 2009.
       9             :    Copyright (C) Simo Sorce 2002
      10             :    Copyright (C) Eric Lorimer 2002
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : #include "lib/replace/system/python.h"
      27             : #include "includes.h"
      28             : #include "python/py3compat.h"
      29             : #include "python/modules.h"
      30             : #include "smbd/smbd.h"
      31             : #include "libcli/util/pyerrors.h"
      32             : #include "librpc/rpc/pyrpc_util.h"
      33             : #include <pytalloc.h>
      34             : #include "system/filesys.h"
      35             : #include "passdb.h"
      36             : #include "secrets.h"
      37             : #include "auth.h"
      38             : 
      39             : extern const struct generic_mapping file_generic_mapping;
      40             : 
      41             : #undef  DBGC_CLASS
      42             : #define DBGC_CLASS DBGC_ACLS
      43             : 
      44             : #ifdef O_DIRECTORY
      45             : #define DIRECTORY_FLAGS O_RDONLY|O_DIRECTORY
      46             : #else
      47             : /* POSIX allows us to open a directory with O_RDONLY. */
      48             : #define DIRECTORY_FLAGS O_RDONLY
      49             : #endif
      50             : 
      51             : 
      52        3822 : static connection_struct *get_conn_tos(
      53             :         const char *service,
      54             :         const struct auth_session_info *session_info)
      55             : {
      56        3822 :         struct conn_struct_tos *c = NULL;
      57        3822 :         int snum = -1;
      58         115 :         NTSTATUS status;
      59        3822 :         char *cwd = NULL;
      60        3822 :         struct smb_filename cwd_fname = {0};
      61         115 :         int ret;
      62             : 
      63        3822 :         if (!posix_locking_init(false)) {
      64           0 :                 PyErr_NoMemory();
      65           0 :                 return NULL;
      66             :         }
      67             : 
      68        3822 :         if (service) {
      69        2522 :                 snum = lp_servicenumber(service);
      70        2522 :                 if (snum == -1) {
      71           0 :                         PyErr_SetString(PyExc_RuntimeError, "unknown service");
      72           0 :                         return NULL;
      73             :                 }
      74             :         }
      75             : 
      76             :         /*
      77             :          * Make sure that session unix info is filled,
      78             :          * which is required by vfs operations.
      79             :          */
      80        3822 :         if (session_info->unix_info == NULL) {
      81           0 :                 PyErr_SetString(PyExc_RuntimeError,
      82             :                                 "Session unix info not initialized");
      83           0 :                 return NULL;
      84             :         }
      85        3822 :         if (session_info->unix_info->unix_name == NULL) {
      86           0 :                 PyErr_SetString(PyExc_RuntimeError,
      87             :                                 "Session unix info not available");
      88           0 :                 return NULL;
      89             :         }
      90             : 
      91        3822 :         status = create_conn_struct_tos(NULL,
      92             :                                         snum,
      93             :                                         "/",
      94             :                                         session_info,
      95             :                                         &c);
      96        3822 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
      97             : 
      98             :         /* Ignore read-only and share restrictions */
      99        3822 :         c->conn->read_only = false;
     100        3822 :         c->conn->share_access = SEC_RIGHTS_FILE_ALL;
     101             : 
     102             :         /* Provided by libreplace if not present. Always mallocs. */
     103        3822 :         cwd = get_current_dir_name();
     104        3822 :         if (cwd == NULL) {
     105           0 :                 PyErr_NoMemory();
     106           0 :                 return NULL;
     107             :         }
     108             : 
     109        3822 :         cwd_fname.base_name = cwd;
     110             :         /*
     111             :          * We need to call vfs_ChDir() to initialize
     112             :          * conn->cwd_fsp correctly. Change directory
     113             :          * to current directory (so no change for process).
     114             :          */
     115        3822 :         ret = vfs_ChDir(c->conn, &cwd_fname);
     116        3822 :         if (ret != 0) {
     117           0 :                 status = map_nt_error_from_unix(errno);
     118           0 :                 SAFE_FREE(cwd);
     119           0 :                 PyErr_NTSTATUS_IS_ERR_RAISE(status);
     120             :         }
     121             : 
     122        3822 :         SAFE_FREE(cwd);
     123             : 
     124        3822 :         return c->conn;
     125             : }
     126             : 
     127         186 : static int set_sys_acl_conn(const char *fname,
     128             :                                  SMB_ACL_TYPE_T acltype,
     129             :                                  SMB_ACL_T theacl, connection_struct *conn)
     130             : {
     131           5 :         int ret;
     132         186 :         struct smb_filename *smb_fname = NULL;
     133         186 :         TALLOC_CTX *frame = talloc_stackframe();
     134           5 :         NTSTATUS status;
     135             : 
     136         186 :         smb_fname = synthetic_smb_fname_split(frame,
     137             :                                         fname,
     138         186 :                                         lp_posix_pathnames());
     139         186 :         if (smb_fname == NULL) {
     140           0 :                 TALLOC_FREE(frame);
     141           0 :                 return -1;
     142             :         }
     143             : 
     144         186 :         status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
     145         186 :         if (!NT_STATUS_IS_OK(status)) {
     146           0 :                 TALLOC_FREE(frame);
     147           0 :                 errno = map_errno_from_nt_status(status);
     148           0 :                 return -1;
     149             :         }
     150             : 
     151         186 :         ret = SMB_VFS_SYS_ACL_SET_FD(smb_fname->fsp, acltype, theacl);
     152             : 
     153         186 :         status = fd_close(smb_fname->fsp);
     154         186 :         if (!NT_STATUS_IS_OK(status)) {
     155           0 :                 TALLOC_FREE(frame);
     156           0 :                 errno = map_errno_from_nt_status(status);
     157           0 :                 return -1;
     158             :         }
     159             : 
     160         186 :         TALLOC_FREE(frame);
     161         181 :         return ret;
     162             : }
     163             : 
     164             : 
     165        3667 : static NTSTATUS init_files_struct(TALLOC_CTX *mem_ctx,
     166             :                                   const char *fname,
     167             :                                   struct connection_struct *conn,
     168             :                                   int flags,
     169             :                                   struct files_struct **_fsp)
     170             : {
     171        3667 :         struct vfs_open_how how = { .flags = flags, .mode = 0644 };
     172        3667 :         struct smb_filename *smb_fname = NULL;
     173         195 :         int fd;
     174         195 :         mode_t saved_umask;
     175         195 :         struct files_struct *fsp;
     176        3667 :         struct files_struct *fspcwd = NULL;
     177         195 :         NTSTATUS status;
     178             : 
     179        3667 :         fsp = talloc_zero(mem_ctx, struct files_struct);
     180        3667 :         if (fsp == NULL) {
     181           0 :                 return NT_STATUS_NO_MEMORY;
     182             :         }
     183        3667 :         fsp->fh = fd_handle_create(fsp);
     184        3667 :         if (fsp->fh == NULL) {
     185           0 :                 return NT_STATUS_NO_MEMORY;
     186             :         }
     187        3667 :         fsp->conn = conn;
     188             : 
     189        3667 :         smb_fname = synthetic_smb_fname_split(fsp,
     190             :                                               fname,
     191        3667 :                                               lp_posix_pathnames());
     192        3667 :         if (smb_fname == NULL) {
     193           0 :                 return NT_STATUS_NO_MEMORY;
     194             :         }
     195             : 
     196        3667 :         fsp->fsp_name = smb_fname;
     197             : 
     198        3667 :         status = vfs_at_fspcwd(fsp, conn, &fspcwd);
     199        3667 :         if (!NT_STATUS_IS_OK(status)) {
     200           0 :                 return status;
     201             :         }
     202             : 
     203             :         /*
     204             :          * we want total control over the permissions on created files,
     205             :          * so set our umask to 0 (this matters if flags contains O_CREAT)
     206             :          */
     207        3667 :         saved_umask = umask(0);
     208             : 
     209        3667 :         fd = SMB_VFS_OPENAT(conn,
     210             :                             fspcwd,
     211             :                             smb_fname,
     212             :                             fsp,
     213             :                             &how);
     214             : 
     215        3667 :         umask(saved_umask);
     216             : 
     217        3667 :         if (fd == -1) {
     218        1490 :                 int err = errno;
     219        1490 :                 if (err == ENOENT) {
     220           4 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     221             :                 }
     222        1486 :                 return NT_STATUS_INVALID_PARAMETER;
     223             :         }
     224        2177 :         fsp_set_fd(fsp, fd);
     225             : 
     226        2177 :         status = vfs_stat_fsp(fsp);
     227        2177 :         if (!NT_STATUS_IS_OK(status)) {
     228             :                 /* If we have an fd, this stat should succeed. */
     229           0 :                 DEBUG(0,("Error doing fstat on open file %s (%s)\n",
     230             :                          smb_fname_str_dbg(smb_fname),
     231             :                          nt_errstr(status) ));
     232           0 :                 return status;
     233             :         }
     234             : 
     235        2177 :         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
     236        2177 :         fsp->vuid = UID_FIELD_INVALID;
     237        2177 :         fsp->file_pid = 0;
     238        2177 :         fsp->fsp_flags.can_lock = true;
     239        2177 :         fsp->fsp_flags.can_read = true;
     240        2177 :         fsp->fsp_flags.can_write = true;
     241        2177 :         fsp->print_file = NULL;
     242        2177 :         fsp->fsp_flags.modified = false;
     243        2177 :         fsp->sent_oplock_break = NO_BREAK_SENT;
     244        2177 :         fsp->fsp_flags.is_directory = S_ISDIR(smb_fname->st.st_ex_mode);
     245             : 
     246        2177 :         *_fsp = fsp;
     247             : 
     248        2177 :         return NT_STATUS_OK;
     249             : }
     250             : 
     251        1968 : static NTSTATUS set_nt_acl_conn(const char *fname,
     252             :                                 uint32_t security_info_sent, const struct security_descriptor *sd,
     253             :                                 connection_struct *conn)
     254             : {
     255        1968 :         TALLOC_CTX *frame = talloc_stackframe();
     256        1968 :         struct files_struct *fsp = NULL;
     257        1968 :         NTSTATUS status = NT_STATUS_OK;
     258             : 
     259             :         /* first, try to open it as a file with flag O_RDWR */
     260        1968 :         status = init_files_struct(frame,
     261             :                                    fname,
     262             :                                    conn,
     263             :                                    O_RDWR,
     264             :                                    &fsp);
     265        1968 :         if (!NT_STATUS_IS_OK(status) && errno == EISDIR) {
     266             :                 /* if fail, try to open as dir */
     267        1474 :                 status = init_files_struct(frame,
     268             :                                            fname,
     269             :                                            conn,
     270             :                                            DIRECTORY_FLAGS,
     271             :                                            &fsp);
     272             :         }
     273             : 
     274        1968 :         if (!NT_STATUS_IS_OK(status)) {
     275           4 :                 DBG_ERR("init_files_struct failed: %s\n",
     276             :                         nt_errstr(status));
     277           4 :                 if (fsp != NULL) {
     278           0 :                         fd_close(fsp);
     279             :                 }
     280           4 :                 TALLOC_FREE(frame);
     281           4 :                 return status;
     282             :         }
     283             : 
     284        1964 :         status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp), security_info_sent, sd);
     285        1964 :         if (!NT_STATUS_IS_OK(status)) {
     286           0 :                 DEBUG(0,("set_nt_acl_conn: fset_nt_acl returned %s.\n", nt_errstr(status)));
     287             :         }
     288             : 
     289        1964 :         fd_close(fsp);
     290             : 
     291        1964 :         TALLOC_FREE(frame);
     292        1964 :         return status;
     293             : }
     294             : 
     295         530 : static NTSTATUS get_nt_acl_conn(TALLOC_CTX *mem_ctx,
     296             :                                 const char *fname,
     297             :                                 connection_struct *conn,
     298             :                                 uint32_t security_info_wanted,
     299             :                                 struct security_descriptor **sd)
     300             : {
     301         530 :         TALLOC_CTX *frame = talloc_stackframe();
     302           0 :         NTSTATUS status;
     303         530 :         struct smb_filename *smb_fname =  NULL;
     304             : 
     305         530 :         smb_fname = synthetic_smb_fname_split(frame,
     306             :                                         fname,
     307         530 :                                         lp_posix_pathnames());
     308             : 
     309         530 :         if (smb_fname == NULL) {
     310           0 :                 TALLOC_FREE(frame);
     311           0 :                 return NT_STATUS_NO_MEMORY;
     312             :         }
     313             : 
     314         530 :         status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
     315         530 :         if (!NT_STATUS_IS_OK(status)) {
     316           0 :                 TALLOC_FREE(frame);
     317           0 :                 return status;
     318             :         }
     319             : 
     320         530 :         status = SMB_VFS_FGET_NT_ACL(metadata_fsp(smb_fname->fsp),
     321             :                                 security_info_wanted,
     322             :                                 mem_ctx,
     323             :                                 sd);
     324         530 :         if (!NT_STATUS_IS_OK(status)) {
     325           0 :                 DBG_ERR("fget_nt_acl_at returned %s.\n",
     326             :                         nt_errstr(status));
     327             :         }
     328             : 
     329         530 :         status = fd_close(smb_fname->fsp);
     330         530 :         if (!NT_STATUS_IS_OK(status)) {
     331           0 :                 TALLOC_FREE(frame);
     332           0 :                 return status;
     333             :         }
     334             : 
     335         530 :         TALLOC_FREE(frame);
     336             : 
     337         530 :         return status;
     338             : }
     339             : 
     340         846 : static int set_acl_entry_perms(SMB_ACL_ENTRY_T entry, mode_t perm_mask)
     341             : {
     342         846 :         SMB_ACL_PERMSET_T perms = NULL;
     343             : 
     344         846 :         if (sys_acl_get_permset(entry, &perms) != 0) {
     345           0 :                 return -1;
     346             :         }
     347             : 
     348         846 :         if (sys_acl_clear_perms(perms) != 0) {
     349           0 :                 return -1;
     350             :         }
     351             : 
     352        1572 :         if ((perm_mask & SMB_ACL_READ) != 0 &&
     353         726 :             sys_acl_add_perm(perms, SMB_ACL_READ) != 0) {
     354           0 :                 return -1;
     355             :         }
     356             : 
     357        1242 :         if ((perm_mask & SMB_ACL_WRITE) != 0 &&
     358         396 :             sys_acl_add_perm(perms, SMB_ACL_WRITE) != 0) {
     359           0 :                 return -1;
     360             :         }
     361             : 
     362        1392 :         if ((perm_mask & SMB_ACL_EXECUTE) != 0 &&
     363         546 :             sys_acl_add_perm(perms, SMB_ACL_EXECUTE) != 0) {
     364           0 :                 return -1;
     365             :         }
     366             : 
     367         846 :         if (sys_acl_set_permset(entry, perms) != 0) {
     368           0 :                 return -1;
     369             :         }
     370             : 
     371         821 :         return 0;
     372             : }
     373             : 
     374         186 : static SMB_ACL_T make_simple_acl(TALLOC_CTX *mem_ctx,
     375             :                         gid_t gid,
     376             :                         mode_t chmod_mode)
     377             : {
     378         186 :         mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE;
     379             : 
     380         186 :         mode_t mode_user = (chmod_mode & 0700) >> 6;
     381         186 :         mode_t mode_group = (chmod_mode & 070) >> 3;
     382         186 :         mode_t mode_other = chmod_mode &  07;
     383           5 :         SMB_ACL_ENTRY_T entry;
     384         186 :         SMB_ACL_T acl = sys_acl_init(mem_ctx);
     385             : 
     386         186 :         if (!acl) {
     387           0 :                 return NULL;
     388             :         }
     389             : 
     390         186 :         if (sys_acl_create_entry(&acl, &entry) != 0) {
     391           0 :                 TALLOC_FREE(acl);
     392           0 :                 return NULL;
     393             :         }
     394             : 
     395         186 :         if (sys_acl_set_tag_type(entry, SMB_ACL_USER_OBJ) != 0) {
     396           0 :                 TALLOC_FREE(acl);
     397           0 :                 return NULL;
     398             :         }
     399             : 
     400         186 :         if (set_acl_entry_perms(entry, mode_user) != 0) {
     401           0 :                 TALLOC_FREE(acl);
     402           0 :                 return NULL;
     403             :         }
     404             : 
     405         186 :         if (sys_acl_create_entry(&acl, &entry) != 0) {
     406           0 :                 TALLOC_FREE(acl);
     407           0 :                 return NULL;
     408             :         }
     409             : 
     410         186 :         if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP_OBJ) != 0) {
     411           0 :                 TALLOC_FREE(acl);
     412           0 :                 return NULL;
     413             :         }
     414             : 
     415         186 :         if (set_acl_entry_perms(entry, mode_group) != 0) {
     416           0 :                 TALLOC_FREE(acl);
     417           0 :                 return NULL;
     418             :         }
     419             : 
     420         186 :         if (sys_acl_create_entry(&acl, &entry) != 0) {
     421           0 :                 TALLOC_FREE(acl);
     422           0 :                 return NULL;
     423             :         }
     424             : 
     425         186 :         if (sys_acl_set_tag_type(entry, SMB_ACL_OTHER) != 0) {
     426           0 :                 TALLOC_FREE(acl);
     427           0 :                 return NULL;
     428             :         }
     429             : 
     430         186 :         if (set_acl_entry_perms(entry, mode_other) != 0) {
     431           0 :                 TALLOC_FREE(acl);
     432           0 :                 return NULL;
     433             :         }
     434             : 
     435         186 :         if (gid != -1) {
     436         102 :                 if (sys_acl_create_entry(&acl, &entry) != 0) {
     437           0 :                         TALLOC_FREE(acl);
     438           0 :                         return NULL;
     439             :                 }
     440             : 
     441         102 :                 if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP) != 0) {
     442           0 :                         TALLOC_FREE(acl);
     443           0 :                         return NULL;
     444             :                 }
     445             : 
     446         102 :                 if (sys_acl_set_qualifier(entry, &gid) != 0) {
     447           0 :                         TALLOC_FREE(acl);
     448           0 :                         return NULL;
     449             :                 }
     450             : 
     451         102 :                 if (set_acl_entry_perms(entry, mode_group) != 0) {
     452           0 :                         TALLOC_FREE(acl);
     453           0 :                         return NULL;
     454             :                 }
     455             :         }
     456             : 
     457         186 :         if (sys_acl_create_entry(&acl, &entry) != 0) {
     458           0 :                 TALLOC_FREE(acl);
     459           0 :                 return NULL;
     460             :         }
     461             : 
     462         186 :         if (sys_acl_set_tag_type(entry, SMB_ACL_MASK) != 0) {
     463           0 :                 TALLOC_FREE(acl);
     464           0 :                 return NULL;
     465             :         }
     466             : 
     467         186 :         if (set_acl_entry_perms(entry, mode) != 0) {
     468           0 :                 TALLOC_FREE(acl);
     469           0 :                 return NULL;
     470             :         }
     471             : 
     472         186 :         return acl;
     473             : }
     474             : 
     475             : /*
     476             :   set a simple ACL on a file, as a test
     477             :  */
     478         186 : static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject *kwargs)
     479             : {
     480         186 :         const char * const kwnames[] = {
     481             :                 "fname",
     482             :                 "mode",
     483             :                 "session_info",
     484             :                 "gid",
     485             :                 "service",
     486             :                 NULL
     487             :         };
     488         186 :         char *fname, *service = NULL;
     489         186 :         PyObject *py_session = Py_None;
     490         186 :         struct auth_session_info *session_info = NULL;
     491           5 :         int ret;
     492         186 :         int mode, gid = -1;
     493           5 :         SMB_ACL_T acl;
     494           5 :         TALLOC_CTX *frame;
     495           5 :         connection_struct *conn;
     496             : 
     497         186 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|iz",
     498             :                                          discard_const_p(char *, kwnames),
     499             :                                          &fname,
     500             :                                          &mode,
     501             :                                          &py_session,
     502             :                                          &gid,
     503             :                                          &service))
     504           0 :                 return NULL;
     505             : 
     506         186 :         if (!py_check_dcerpc_type(py_session,
     507             :                                   "samba.dcerpc.auth",
     508             :                                   "session_info")) {
     509           0 :                 return NULL;
     510             :         }
     511         186 :         session_info = pytalloc_get_type(py_session,
     512             :                                          struct auth_session_info);
     513         186 :         if (session_info == NULL) {
     514           0 :                 PyErr_Format(PyExc_TypeError,
     515             :                              "Expected auth_session_info for session_info argument got %s",
     516             :                              pytalloc_get_name(py_session));
     517           0 :                 return NULL;
     518             :         }
     519             : 
     520         186 :         frame = talloc_stackframe();
     521             : 
     522         186 :         acl = make_simple_acl(frame, gid, mode);
     523         186 :         if (acl == NULL) {
     524           0 :                 TALLOC_FREE(frame);
     525           0 :                 return NULL;
     526             :         }
     527             : 
     528         186 :         conn = get_conn_tos(service, session_info);
     529         186 :         if (!conn) {
     530           0 :                 TALLOC_FREE(frame);
     531           0 :                 return NULL;
     532             :         }
     533             : 
     534         186 :         ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);
     535             : 
     536         186 :         if (ret != 0) {
     537           0 :                 TALLOC_FREE(frame);
     538           0 :                 errno = ret;
     539           0 :                 return PyErr_SetFromErrno(PyExc_OSError);
     540             :         }
     541             : 
     542         186 :         TALLOC_FREE(frame);
     543             : 
     544         186 :         Py_RETURN_NONE;
     545             : }
     546             : 
     547             : /*
     548             :   chown a file
     549             :  */
     550          78 : static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs)
     551             : {
     552          78 :         const char * const kwnames[] = {
     553             :                 "fname",
     554             :                 "uid",
     555             :                 "gid",
     556             :                 "session_info",
     557             :                 "service",
     558             :                 NULL
     559             :         };
     560           5 :         connection_struct *conn;
     561           5 :         int ret;
     562           5 :         NTSTATUS status;
     563          78 :         char *fname, *service = NULL;
     564          78 :         PyObject *py_session = Py_None;
     565          78 :         struct auth_session_info *session_info = NULL;
     566           5 :         int uid, gid;
     567           5 :         TALLOC_CTX *frame;
     568          78 :         struct files_struct *fsp = NULL;
     569             : 
     570          78 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siiO|z",
     571             :                                          discard_const_p(char *, kwnames),
     572             :                                          &fname,
     573             :                                          &uid,
     574             :                                          &gid,
     575             :                                          &py_session,
     576             :                                          &service))
     577           0 :                 return NULL;
     578             : 
     579          78 :         if (!py_check_dcerpc_type(py_session,
     580             :                                   "samba.dcerpc.auth",
     581             :                                   "session_info")) {
     582           0 :                 return NULL;
     583             :         }
     584          78 :         session_info = pytalloc_get_type(py_session,
     585             :                                          struct auth_session_info);
     586          78 :         if (session_info == NULL) {
     587           0 :                 PyErr_Format(PyExc_TypeError,
     588             :                              "Expected auth_session_info for session_info argument got %s",
     589             :                              pytalloc_get_name(py_session));
     590           0 :                 return NULL;
     591             :         }
     592             : 
     593          78 :         frame = talloc_stackframe();
     594             : 
     595          78 :         conn = get_conn_tos(service, session_info);
     596          78 :         if (!conn) {
     597           0 :                 TALLOC_FREE(frame);
     598           0 :                 return NULL;
     599             :         }
     600             : 
     601             :         /* first, try to open it as a file with flag O_RDWR */
     602          78 :         status = init_files_struct(frame,
     603             :                                    fname,
     604             :                                    conn,
     605             :                                    O_RDWR,
     606             :                                    &fsp);
     607          78 :         if (!NT_STATUS_IS_OK(status) && errno == EISDIR) {
     608             :                 /* if fail, try to open as dir */
     609          12 :                 status = init_files_struct(frame,
     610             :                                            fname,
     611             :                                            conn,
     612             :                                            DIRECTORY_FLAGS,
     613             :                                            &fsp);
     614             :         }
     615             : 
     616          78 :         if (!NT_STATUS_IS_OK(status)) {
     617           0 :                 DBG_ERR("init_files_struct failed: %s\n",
     618             :                         nt_errstr(status));
     619           0 :                 if (fsp != NULL) {
     620           0 :                         fd_close(fsp);
     621             :                 }
     622           0 :                 TALLOC_FREE(frame);
     623             :                 /*
     624             :                  * The following macro raises a python
     625             :                  * error then returns NULL.
     626             :                  */
     627           0 :                 PyErr_NTSTATUS_IS_ERR_RAISE(status);
     628             :         }
     629             : 
     630          78 :         ret = SMB_VFS_FCHOWN(fsp, uid, gid);
     631          78 :         if (ret != 0) {
     632           0 :                 int saved_errno = errno;
     633           0 :                 fd_close(fsp);
     634           0 :                 TALLOC_FREE(frame);
     635           0 :                 errno = saved_errno;
     636           0 :                 return PyErr_SetFromErrno(PyExc_OSError);
     637             :         }
     638             : 
     639          78 :         fd_close(fsp);
     640          78 :         TALLOC_FREE(frame);
     641             : 
     642          78 :         Py_RETURN_NONE;
     643             : }
     644             : 
     645             : /*
     646             :   unlink a file
     647             :  */
     648         279 : static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
     649             : {
     650         279 :         const char * const kwnames[] = {
     651             :                 "fname",
     652             :                 "session_info",
     653             :                 "service",
     654             :                 NULL
     655             :         };
     656           0 :         connection_struct *conn;
     657           0 :         int ret;
     658         279 :         struct smb_filename *smb_fname = NULL;
     659         279 :         struct smb_filename *parent_fname = NULL;
     660         279 :         struct smb_filename *at_fname = NULL;
     661         279 :         PyObject *py_session = Py_None;
     662         279 :         struct auth_session_info *session_info = NULL;
     663         279 :         char *fname, *service = NULL;
     664           0 :         TALLOC_CTX *frame;
     665           0 :         NTSTATUS status;
     666             : 
     667         279 :         frame = talloc_stackframe();
     668             : 
     669         279 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|z",
     670             :                                          discard_const_p(char *, kwnames),
     671             :                                          &fname,
     672             :                                          &py_session ,
     673             :                                          &service)) {
     674           0 :                 TALLOC_FREE(frame);
     675           0 :                 return NULL;
     676             :         }
     677             : 
     678         279 :         if (!py_check_dcerpc_type(py_session,
     679             :                                   "samba.dcerpc.auth",
     680             :                                   "session_info")) {
     681           0 :                 TALLOC_FREE(frame);
     682           0 :                 return NULL;
     683             :         }
     684         279 :         session_info = pytalloc_get_type(py_session,
     685             :                                          struct auth_session_info);
     686         279 :         if (session_info == NULL) {
     687           0 :                 PyErr_Format(PyExc_TypeError,
     688             :                              "Expected auth_session_info for session_info argument got %s",
     689             :                              pytalloc_get_name(py_session));
     690           0 :                 TALLOC_FREE(frame);
     691           0 :                 return NULL;
     692             :         }
     693             : 
     694         279 :         conn = get_conn_tos(service, session_info);
     695         279 :         if (!conn) {
     696           0 :                 TALLOC_FREE(frame);
     697           0 :                 return NULL;
     698             :         }
     699             : 
     700         279 :         smb_fname = synthetic_smb_fname_split(frame,
     701             :                                         fname,
     702         279 :                                         lp_posix_pathnames());
     703         279 :         if (smb_fname == NULL) {
     704           0 :                 TALLOC_FREE(frame);
     705           0 :                 return PyErr_NoMemory();
     706             :         }
     707             : 
     708         279 :         status = parent_pathref(frame,
     709             :                                 conn->cwd_fsp,
     710             :                                 smb_fname,
     711             :                                 &parent_fname,
     712             :                                 &at_fname);
     713         279 :         if (!NT_STATUS_IS_OK(status)) {
     714           0 :                 TALLOC_FREE(frame);
     715           0 :                 return PyErr_NoMemory();
     716             :         }
     717             : 
     718         279 :         ret = SMB_VFS_UNLINKAT(conn,
     719             :                         parent_fname->fsp,
     720             :                         at_fname,
     721             :                         0);
     722         279 :         if (ret != 0) {
     723           0 :                 TALLOC_FREE(frame);
     724           0 :                 errno = ret;
     725           0 :                 return PyErr_SetFromErrno(PyExc_OSError);
     726             :         }
     727             : 
     728         279 :         TALLOC_FREE(frame);
     729             : 
     730         279 :         Py_RETURN_NONE;
     731             : }
     732             : 
     733             : /*
     734             :   check if we have ACL support
     735             :  */
     736           0 : static PyObject *py_smbd_have_posix_acls(PyObject *self,
     737             :                 PyObject *Py_UNUSED(ignored))
     738             : {
     739             : #ifdef HAVE_POSIX_ACLS
     740           0 :         return PyBool_FromLong(true);
     741             : #else
     742             :         return PyBool_FromLong(false);
     743             : #endif
     744             : }
     745             : 
     746             : /*
     747             :   set the NT ACL on a file
     748             :  */
     749        1968 : static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args, PyObject *kwargs)
     750             : {
     751        1968 :         const char * const kwnames[] = {
     752             :                 "fname",
     753             :                 "security_info_sent",
     754             :                 "sd",
     755             :                 "session_info",
     756             :                 "service",
     757             :                 NULL
     758             :         };
     759             : 
     760         105 :         NTSTATUS status;
     761        1968 :         char *fname, *service = NULL;
     762         105 :         int security_info_sent;
     763         105 :         PyObject *py_sd;
     764         105 :         struct security_descriptor *sd;
     765        1968 :         PyObject *py_session = Py_None;
     766        1968 :         struct auth_session_info *session_info = NULL;
     767         105 :         connection_struct *conn;
     768         105 :         TALLOC_CTX *frame;
     769             : 
     770        1968 :         frame = talloc_stackframe();
     771             : 
     772        1968 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siOO|z",
     773             :                                          discard_const_p(char *, kwnames),
     774             :                                          &fname,
     775             :                                          &security_info_sent,
     776             :                                          &py_sd,
     777             :                                          &py_session,
     778             :                                          &service)) {
     779           0 :                 TALLOC_FREE(frame);
     780           0 :                 return NULL;
     781             :         }
     782             : 
     783        1968 :         if (!py_check_dcerpc_type(py_sd, "samba.dcerpc.security", "descriptor")) {
     784           0 :                 TALLOC_FREE(frame);
     785           0 :                 return NULL;
     786             :         }
     787             : 
     788        1968 :         if (!py_check_dcerpc_type(py_session,
     789             :                                   "samba.dcerpc.auth",
     790             :                                   "session_info")) {
     791           0 :                 TALLOC_FREE(frame);
     792           0 :                 return NULL;
     793             :         }
     794        1968 :         session_info = pytalloc_get_type(py_session,
     795             :                                          struct auth_session_info);
     796        1968 :         if (session_info == NULL) {
     797           0 :                 PyErr_Format(PyExc_TypeError,
     798             :                              "Expected auth_session_info for session_info argument got %s",
     799             :                              pytalloc_get_name(py_session));
     800           0 :                 return NULL;
     801             :         }
     802             : 
     803        1968 :         conn = get_conn_tos(service, session_info);
     804        1968 :         if (!conn) {
     805           0 :                 TALLOC_FREE(frame);
     806           0 :                 return NULL;
     807             :         }
     808             : 
     809        1968 :         sd = pytalloc_get_type(py_sd, struct security_descriptor);
     810             : 
     811        1968 :         status = set_nt_acl_conn(fname, security_info_sent, sd, conn);
     812        1968 :         TALLOC_FREE(frame);
     813        1968 :         if (NT_STATUS_IS_ERR(status)) {
     814           4 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     815             :                         /*
     816             :                          * This will show up as a FileNotFoundError in python.
     817             :                          */
     818           4 :                         PyErr_SetFromErrnoWithFilename(PyExc_OSError, fname);
     819             :                 } else {
     820           0 :                         PyErr_SetNTSTATUS(status);
     821             :                 }
     822           4 :                 return NULL;
     823             :         }
     824             : 
     825        1964 :         Py_RETURN_NONE;
     826             : }
     827             : 
     828             : /*
     829             :   Return the NT ACL on a file
     830             :  */
     831         530 : static PyObject *py_smbd_get_nt_acl(PyObject *self, PyObject *args, PyObject *kwargs)
     832             : {
     833         530 :         const char * const kwnames[] = {
     834             :                 "fname",
     835             :                 "security_info_wanted",
     836             :                 "session_info",
     837             :                 "service",
     838             :                 NULL
     839             :         };
     840         530 :         char *fname, *service = NULL;
     841           0 :         int security_info_wanted;
     842           0 :         PyObject *py_sd;
     843           0 :         struct security_descriptor *sd;
     844         530 :         TALLOC_CTX *frame = talloc_stackframe();
     845         530 :         PyObject *py_session = Py_None;
     846         530 :         struct auth_session_info *session_info = NULL;
     847           0 :         connection_struct *conn;
     848           0 :         NTSTATUS status;
     849         530 :         int ret = 1;
     850             : 
     851         530 :         ret = PyArg_ParseTupleAndKeywords(args,
     852             :                                           kwargs,
     853             :                                           "siO|z",
     854             :                                           discard_const_p(char *, kwnames),
     855             :                                           &fname,
     856             :                                           &security_info_wanted,
     857             :                                           &py_session,
     858             :                                           &service);
     859         530 :         if (!ret) {
     860           0 :                 TALLOC_FREE(frame);
     861           0 :                 return NULL;
     862             :         }
     863             : 
     864         530 :         if (!py_check_dcerpc_type(py_session,
     865             :                                   "samba.dcerpc.auth",
     866             :                                   "session_info")) {
     867           0 :                 TALLOC_FREE(frame);
     868           0 :                 return NULL;
     869             :         }
     870         530 :         session_info = pytalloc_get_type(py_session,
     871             :                                          struct auth_session_info);
     872         530 :         if (session_info == NULL) {
     873           0 :                 PyErr_Format(
     874             :                         PyExc_TypeError,
     875             :                         "Expected auth_session_info for "
     876             :                         "session_info argument got %s",
     877             :                         pytalloc_get_name(py_session));
     878           0 :                 TALLOC_FREE(frame);
     879           0 :                 return NULL;
     880             :         }
     881             : 
     882         530 :         conn = get_conn_tos(service, session_info);
     883         530 :         if (!conn) {
     884           0 :                 TALLOC_FREE(frame);
     885           0 :                 return NULL;
     886             :         }
     887             : 
     888         530 :         status = get_nt_acl_conn(frame, fname, conn, security_info_wanted, &sd);
     889         530 :         if (NT_STATUS_IS_ERR(status)) {
     890           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     891             :                         /*
     892             :                          * This will show up as a FileNotFoundError in python,
     893             :                          * from which samba-tool can at least produce a short
     894             :                          * message containing the problematic filename.
     895             :                          */
     896           0 :                         PyErr_SetFromErrnoWithFilename(PyExc_OSError, fname);
     897             :                 } else {
     898           0 :                         PyErr_SetNTSTATUS(status);
     899             :                 }
     900           0 :                 TALLOC_FREE(frame);
     901           0 :                 return NULL;
     902             :         }
     903             : 
     904         530 :         py_sd = py_return_ndr_struct("samba.dcerpc.security", "descriptor", sd, sd);
     905             : 
     906         530 :         TALLOC_FREE(frame);
     907             : 
     908         530 :         return py_sd;
     909             : }
     910             : 
     911             : /*
     912             :   set the posix (or similar) ACL on a file
     913             :  */
     914           0 : static PyObject *py_smbd_set_sys_acl(PyObject *self, PyObject *args, PyObject *kwargs)
     915             : {
     916           0 :         const char * const kwnames[] = {
     917             :                 "fname",
     918             :                 "acl_type",
     919             :                 "acl",
     920             :                 "session_info",
     921             :                 "service",
     922             :                 NULL
     923             :         };
     924           0 :         TALLOC_CTX *frame = talloc_stackframe();
     925           0 :         int ret;
     926           0 :         char *fname, *service = NULL;
     927           0 :         PyObject *py_acl;
     928           0 :         PyObject *py_session = Py_None;
     929           0 :         struct auth_session_info *session_info = NULL;
     930           0 :         struct smb_acl_t *acl;
     931           0 :         int acl_type;
     932           0 :         connection_struct *conn;
     933             : 
     934           0 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siOO|z",
     935             :                                          discard_const_p(char *, kwnames),
     936             :                                          &fname,
     937             :                                          &acl_type,
     938             :                                          &py_acl,
     939             :                                          &py_session,
     940             :                                          &service)) {
     941           0 :                 TALLOC_FREE(frame);
     942           0 :                 return NULL;
     943             :         }
     944             : 
     945           0 :         if (!py_check_dcerpc_type(py_acl, "samba.dcerpc.smb_acl", "t")) {
     946           0 :                 TALLOC_FREE(frame);
     947           0 :                 return NULL;
     948             :         }
     949             : 
     950           0 :         if (!py_check_dcerpc_type(py_session,
     951             :                                   "samba.dcerpc.auth",
     952             :                                   "session_info")) {
     953           0 :                 TALLOC_FREE(frame);
     954           0 :                 return NULL;
     955             :         }
     956           0 :         session_info = pytalloc_get_type(py_session,
     957             :                                          struct auth_session_info);
     958           0 :         if (session_info == NULL) {
     959           0 :                 PyErr_Format(PyExc_TypeError,
     960             :                              "Expected auth_session_info for session_info argument got %s",
     961             :                              pytalloc_get_name(py_session));
     962           0 :                 TALLOC_FREE(frame);
     963           0 :                 return NULL;
     964             :         }
     965             : 
     966           0 :         conn = get_conn_tos(service, session_info);
     967           0 :         if (!conn) {
     968           0 :                 TALLOC_FREE(frame);
     969           0 :                 return NULL;
     970             :         }
     971             : 
     972           0 :         acl = pytalloc_get_type(py_acl, struct smb_acl_t);
     973             : 
     974           0 :         ret = set_sys_acl_conn(fname, acl_type, acl, conn);
     975           0 :         if (ret != 0) {
     976           0 :                 TALLOC_FREE(frame);
     977           0 :                 errno = ret;
     978           0 :                 return PyErr_SetFromErrno(PyExc_OSError);
     979             :         }
     980             : 
     981           0 :         TALLOC_FREE(frame);
     982           0 :         Py_RETURN_NONE;
     983             : }
     984             : 
     985             : /*
     986             :   Return the posix (or similar) ACL on a file
     987             :  */
     988          96 : static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args, PyObject *kwargs)
     989             : {
     990          96 :         const char * const kwnames[] = {
     991             :                 "fname",
     992             :                 "acl_type",
     993             :                 "session_info",
     994             :                 "service",
     995             :                 NULL
     996             :         };
     997           0 :         char *fname;
     998           0 :         PyObject *py_acl;
     999          96 :         PyObject *py_session = Py_None;
    1000          96 :         struct auth_session_info *session_info = NULL;
    1001           0 :         struct smb_acl_t *acl;
    1002           0 :         int acl_type;
    1003          96 :         TALLOC_CTX *frame = talloc_stackframe();
    1004           0 :         connection_struct *conn;
    1005          96 :         char *service = NULL;
    1006          96 :         struct smb_filename *smb_fname = NULL;
    1007           0 :         NTSTATUS status;
    1008             : 
    1009          96 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|z",
    1010             :                                          discard_const_p(char *, kwnames),
    1011             :                                          &fname,
    1012             :                                          &acl_type,
    1013             :                                          &py_session,
    1014             :                                          &service)) {
    1015           0 :                 TALLOC_FREE(frame);
    1016           0 :                 return NULL;
    1017             :         }
    1018             : 
    1019          96 :         if (!py_check_dcerpc_type(py_session,
    1020             :                                   "samba.dcerpc.auth",
    1021             :                                   "session_info")) {
    1022           0 :                 TALLOC_FREE(frame);
    1023           0 :                 return NULL;
    1024             :         }
    1025          96 :         session_info = pytalloc_get_type(py_session,
    1026             :                                          struct auth_session_info);
    1027          96 :         if (session_info == NULL) {
    1028           0 :                 PyErr_Format(PyExc_TypeError,
    1029             :                              "Expected auth_session_info for session_info argument got %s",
    1030             :                              pytalloc_get_name(py_session));
    1031           0 :                 TALLOC_FREE(frame);
    1032           0 :                 return NULL;
    1033             :         }
    1034             : 
    1035          96 :         conn = get_conn_tos(service, session_info);
    1036          96 :         if (!conn) {
    1037           0 :                 TALLOC_FREE(frame);
    1038           0 :                 return NULL;
    1039             :         }
    1040             : 
    1041          96 :         smb_fname = synthetic_smb_fname_split(frame,
    1042             :                                         fname,
    1043          96 :                                         lp_posix_pathnames());
    1044          96 :         if (smb_fname == NULL) {
    1045           0 :                 TALLOC_FREE(frame);
    1046           0 :                 return NULL;
    1047             :         }
    1048             : 
    1049          96 :         status = openat_pathref_fsp(conn->cwd_fsp, smb_fname);
    1050          96 :         if (!NT_STATUS_IS_OK(status)) {
    1051           0 :                 TALLOC_FREE(frame);
    1052           0 :                 PyErr_SetNTSTATUS(status);
    1053           0 :                 return NULL;
    1054             :         }
    1055             : 
    1056          96 :         acl = SMB_VFS_SYS_ACL_GET_FD(smb_fname->fsp, acl_type, frame);
    1057          96 :         if (!acl) {
    1058           0 :                 TALLOC_FREE(frame);
    1059           0 :                 return PyErr_SetFromErrno(PyExc_OSError);
    1060             :         }
    1061             : 
    1062          96 :         status = fd_close(smb_fname->fsp);
    1063          96 :         if (!NT_STATUS_IS_OK(status)) {
    1064           0 :                 TALLOC_FREE(frame);
    1065           0 :                 PyErr_SetNTSTATUS(status);
    1066           0 :                 return NULL;
    1067             :         }
    1068             : 
    1069          96 :         py_acl = py_return_ndr_struct("samba.dcerpc.smb_acl", "t", acl, acl);
    1070             : 
    1071          96 :         TALLOC_FREE(frame);
    1072             : 
    1073          96 :         return py_acl;
    1074             : }
    1075             : 
    1076         550 : static PyObject *py_smbd_mkdir(PyObject *self, PyObject *args, PyObject *kwargs)
    1077             : {
    1078         550 :         const char * const kwnames[] = {
    1079             :                 "fname",
    1080             :                 "session_info",
    1081             :                 "service",
    1082             :                 NULL
    1083             :         };
    1084         550 :         char *fname, *service = NULL;
    1085         550 :         PyObject *py_session = Py_None;
    1086         550 :         struct auth_session_info *session_info = NULL;
    1087         550 :         TALLOC_CTX *frame = talloc_stackframe();
    1088         550 :         struct connection_struct *conn = NULL;
    1089         550 :         struct smb_filename *smb_fname = NULL;
    1090         550 :         struct smb_filename *parent_fname = NULL;
    1091         550 :         struct smb_filename *base_name = NULL;
    1092           0 :         NTSTATUS status;
    1093           0 :         int ret;
    1094           0 :         mode_t saved_umask;
    1095             : 
    1096         550 :         if (!PyArg_ParseTupleAndKeywords(args,
    1097             :                                          kwargs,
    1098             :                                          "sO|z",
    1099             :                                          discard_const_p(char *,
    1100             :                                                          kwnames),
    1101             :                                          &fname,
    1102             :                                          &py_session,
    1103             :                                          &service)) {
    1104           0 :                 TALLOC_FREE(frame);
    1105           0 :                 return NULL;
    1106             :         }
    1107             : 
    1108         550 :         if (!py_check_dcerpc_type(py_session,
    1109             :                                   "samba.dcerpc.auth",
    1110             :                                   "session_info")) {
    1111           0 :                 TALLOC_FREE(frame);
    1112           0 :                 return NULL;
    1113             :         }
    1114         550 :         session_info = pytalloc_get_type(py_session,
    1115             :                                          struct auth_session_info);
    1116         550 :         if (session_info == NULL) {
    1117           0 :                 PyErr_Format(PyExc_TypeError,
    1118             :                              "Expected auth_session_info for session_info argument got %s",
    1119             :                              pytalloc_get_name(py_session));
    1120           0 :                 TALLOC_FREE(frame);
    1121           0 :                 return NULL;
    1122             :         }
    1123             : 
    1124         550 :         conn = get_conn_tos(service, session_info);
    1125         550 :         if (!conn) {
    1126           0 :                 TALLOC_FREE(frame);
    1127           0 :                 return NULL;
    1128             :         }
    1129             : 
    1130         550 :         smb_fname = synthetic_smb_fname(talloc_tos(),
    1131             :                                         fname,
    1132             :                                         NULL,
    1133             :                                         NULL,
    1134             :                                         0,
    1135         550 :                                         lp_posix_pathnames() ?
    1136             :                                         SMB_FILENAME_POSIX_PATH : 0);
    1137             : 
    1138         550 :         if (smb_fname == NULL) {
    1139           0 :                 TALLOC_FREE(frame);
    1140           0 :                 return NULL;
    1141             :         }
    1142             : 
    1143         550 :         status = parent_pathref(talloc_tos(),
    1144             :                                 conn->cwd_fsp,
    1145             :                                 smb_fname,
    1146             :                                 &parent_fname,
    1147             :                                 &base_name);
    1148         550 :         if (!NT_STATUS_IS_OK(status)) {
    1149           0 :                 TALLOC_FREE(frame);
    1150           0 :                 return NULL;
    1151             :         }
    1152             : 
    1153             :         /* we want total control over the permissions on created files,
    1154             :            so set our umask to 0 */
    1155         550 :         saved_umask = umask(0);
    1156             : 
    1157         550 :         ret = SMB_VFS_MKDIRAT(conn,
    1158             :                         parent_fname->fsp,
    1159             :                         base_name,
    1160             :                         00755);
    1161             : 
    1162         550 :         umask(saved_umask);
    1163             : 
    1164         550 :         if (ret == -1) {
    1165           0 :                 DBG_ERR("mkdirat error=%d (%s)\n", errno, strerror(errno));
    1166           0 :                 TALLOC_FREE(frame);
    1167           0 :                 return NULL;
    1168             :         }
    1169             : 
    1170         550 :         TALLOC_FREE(frame);
    1171         550 :         Py_RETURN_NONE;
    1172             : }
    1173             : 
    1174             : 
    1175             : /*
    1176             :   Create an empty file
    1177             :  */
    1178         135 : static PyObject *py_smbd_create_file(PyObject *self, PyObject *args, PyObject *kwargs)
    1179             : {
    1180         135 :         const char * const kwnames[] = {
    1181             :                 "fname",
    1182             :                 "session_info",
    1183             :                 "service",
    1184             :                 NULL
    1185             :         };
    1186         135 :         char *fname, *service = NULL;
    1187         135 :         PyObject *py_session = Py_None;
    1188         135 :         struct auth_session_info *session_info = NULL;
    1189         135 :         TALLOC_CTX *frame = talloc_stackframe();
    1190         135 :         struct connection_struct *conn = NULL;
    1191         135 :         struct files_struct *fsp = NULL;
    1192           0 :         NTSTATUS status;
    1193             : 
    1194         135 :         if (!PyArg_ParseTupleAndKeywords(args,
    1195             :                                          kwargs,
    1196             :                                          "sO|z",
    1197             :                                          discard_const_p(char *,
    1198             :                                                          kwnames),
    1199             :                                          &fname,
    1200             :                                          &py_session,
    1201             :                                          &service)) {
    1202           0 :                 TALLOC_FREE(frame);
    1203           0 :                 return NULL;
    1204             :         }
    1205             : 
    1206         135 :         if (!py_check_dcerpc_type(py_session,
    1207             :                                   "samba.dcerpc.auth",
    1208             :                                   "session_info")) {
    1209           0 :                 TALLOC_FREE(frame);
    1210           0 :                 return NULL;
    1211             :         }
    1212         135 :         session_info = pytalloc_get_type(py_session,
    1213             :                                          struct auth_session_info);
    1214         135 :         if (session_info == NULL) {
    1215           0 :                 PyErr_Format(PyExc_TypeError,
    1216             :                              "Expected auth_session_info for session_info argument got %s",
    1217             :                              pytalloc_get_name(py_session));
    1218           0 :                 TALLOC_FREE(frame);
    1219           0 :                 return NULL;
    1220             :         }
    1221             : 
    1222         135 :         conn = get_conn_tos(service, session_info);
    1223         135 :         if (!conn) {
    1224           0 :                 TALLOC_FREE(frame);
    1225           0 :                 return NULL;
    1226             :         }
    1227             : 
    1228         135 :         status = init_files_struct(frame,
    1229             :                                    fname,
    1230             :                                    conn,
    1231             :                                    O_CREAT|O_EXCL|O_RDWR,
    1232             :                                    &fsp);
    1233         135 :         if (!NT_STATUS_IS_OK(status)) {
    1234           0 :                 DBG_ERR("init_files_struct failed: %s\n",
    1235             :                         nt_errstr(status));
    1236         135 :         } else if (fsp != NULL) {
    1237         135 :                 fd_close(fsp);
    1238             :         }
    1239             : 
    1240         135 :         TALLOC_FREE(frame);
    1241         135 :         PyErr_NTSTATUS_NOT_OK_RAISE(status);
    1242         135 :         Py_RETURN_NONE;
    1243             : }
    1244             : 
    1245             : 
    1246             : static PyMethodDef py_smbd_methods[] = {
    1247             :         { "have_posix_acls",
    1248             :                 (PyCFunction)py_smbd_have_posix_acls, METH_NOARGS,
    1249             :                 NULL },
    1250             :         { "set_simple_acl",
    1251             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_simple_acl),
    1252             :                 METH_VARARGS|METH_KEYWORDS,
    1253             :                 NULL },
    1254             :         { "set_nt_acl",
    1255             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_nt_acl),
    1256             :                 METH_VARARGS|METH_KEYWORDS,
    1257             :                 NULL },
    1258             :         { "get_nt_acl",
    1259             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_get_nt_acl),
    1260             :                 METH_VARARGS|METH_KEYWORDS,
    1261             :                 NULL },
    1262             :         { "get_sys_acl",
    1263             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_get_sys_acl),
    1264             :                 METH_VARARGS|METH_KEYWORDS,
    1265             :                 NULL },
    1266             :         { "set_sys_acl",
    1267             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_sys_acl),
    1268             :                 METH_VARARGS|METH_KEYWORDS,
    1269             :                 NULL },
    1270             :         { "chown",
    1271             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_chown),
    1272             :                 METH_VARARGS|METH_KEYWORDS,
    1273             :                 NULL },
    1274             :         { "unlink",
    1275             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_unlink),
    1276             :                 METH_VARARGS|METH_KEYWORDS,
    1277             :                 NULL },
    1278             :         { "mkdir",
    1279             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_mkdir),
    1280             :                 METH_VARARGS|METH_KEYWORDS,
    1281             :                 NULL },
    1282             :         { "create_file",
    1283             :                 PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_create_file),
    1284             :                 METH_VARARGS|METH_KEYWORDS,
    1285             :                 NULL },
    1286             :         {0}
    1287             : };
    1288             : 
    1289             : void initsmbd(void);
    1290             : 
    1291             : static struct PyModuleDef moduledef = {
    1292             :     PyModuleDef_HEAD_INIT,
    1293             :     .m_name = "smbd",
    1294             :     .m_doc = "Python bindings for the smbd file server.",
    1295             :     .m_size = -1,
    1296             :     .m_methods = py_smbd_methods,
    1297             : };
    1298             : 
    1299        2816 : MODULE_INIT_FUNC(smbd)
    1300             : {
    1301        2816 :         PyObject *m = NULL;
    1302             : 
    1303        2816 :         m = PyModule_Create(&moduledef);
    1304        2816 :         return m;
    1305             : }

Generated by: LCOV version 1.14