LCOV - code coverage report
Current view: top level - libcli/smb - py_reparse_symlink.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 22 82 26.8 %
Date: 2024-04-21 15:09:00 Functions: 2 4 50.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  * Copyright (C) Volker Lendecke 2022
       4             :  *
       5             :  * This program is free software; you can redistribute it and/or modify
       6             :  * it under the terms of the GNU General Public License as published by
       7             :  * the Free Software Foundation; either version 3 of the License, or
       8             :  * (at your option) any later version.
       9             :  *
      10             :  * This program is distributed in the hope that it will be useful,
      11             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :  * GNU General Public License for more details.
      14             :  *
      15             :  * You should have received a copy of the GNU General Public License
      16             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             :  */
      18             : 
      19             : #include "lib/replace/system/python.h"
      20             : #include "replace.h"
      21             : #include "python/modules.h"
      22             : #include "python/py3compat.h"
      23             : #include "libcli/util/pyerrors.h"
      24             : #include "reparse.h"
      25             : #include "lib/util/iov_buf.h"
      26             : #include "smb_constants.h"
      27             : 
      28           0 : static PyObject *py_reparse_put(PyObject *module, PyObject *args)
      29             : {
      30           0 :         char *reparse = NULL;
      31             :         Py_ssize_t reparse_len;
      32           0 :         unsigned long long tag = 0;
      33           0 :         unsigned reserved = 0;
      34           0 :         uint8_t *buf = NULL;
      35             :         ssize_t buflen;
      36           0 :         PyObject *result = NULL;
      37           0 :         struct reparse_data_buffer reparse_buf = {};
      38             :         bool ok;
      39             : 
      40           0 :         ok = PyArg_ParseTuple(
      41             :                 args,
      42             :                 "Kk"PYARG_BYTES_LEN":put",
      43             :                 &tag,
      44             :                 &reserved,
      45             :                 &reparse,
      46             :                 &reparse_len);
      47           0 :         if (!ok) {
      48           0 :                 return NULL;
      49             :         }
      50             : 
      51           0 :         reparse_buf.tag = tag;
      52           0 :         reparse_buf.parsed.raw.data = (uint8_t *)reparse;
      53           0 :         reparse_buf.parsed.raw.length = reparse_len;
      54           0 :         reparse_buf.parsed.raw.reserved = reserved;
      55             : 
      56           0 :         buflen = reparse_data_buffer_marshall(&reparse_buf, NULL, 0);
      57           0 :         if (buflen == -1) {
      58           0 :                 errno = EINVAL;
      59           0 :                 PyErr_SetFromErrno(PyExc_RuntimeError);
      60           0 :                 return NULL;
      61             :         }
      62           0 :         buf = talloc_array(NULL, uint8_t, buflen);
      63           0 :         if (buf == NULL) {
      64           0 :                 PyErr_NoMemory();
      65           0 :                 return NULL;
      66             :         }
      67           0 :         reparse_data_buffer_marshall(&reparse_buf, buf, buflen);
      68             : 
      69           0 :         result = PyBytes_FromStringAndSize((char *)buf, buflen);
      70           0 :         TALLOC_FREE(buf);
      71           0 :         return result;
      72             : }
      73             : 
      74           0 : static PyObject *py_reparse_symlink_put(PyObject *module, PyObject *args)
      75             : {
      76           0 :         int unparsed = 0;
      77           0 :         int flags = 0;
      78           0 :         struct reparse_data_buffer reparse = {
      79             :                 .tag = IO_REPARSE_TAG_SYMLINK,
      80             :         };
      81           0 :         struct symlink_reparse_struct *lnk = &reparse.parsed.lnk;
      82             :         uint8_t stackbuf[1024];
      83           0 :         uint8_t *buf = stackbuf;
      84           0 :         ssize_t buflen = sizeof(stackbuf);
      85           0 :         PyObject *result = NULL;
      86             :         bool ok;
      87             : 
      88           0 :         ok = PyArg_ParseTuple(args,
      89             :                               "ssii:symlink_put",
      90             :                               &lnk->substitute_name,
      91             :                               &lnk->print_name,
      92             :                               &unparsed,
      93             :                               &flags);
      94           0 :         if (!ok) {
      95           0 :                 return NULL;
      96             :         }
      97           0 :         lnk->unparsed_path_length = unparsed;
      98           0 :         lnk->flags = flags;
      99             : 
     100           0 :         buflen = reparse_data_buffer_marshall(&reparse, buf, buflen);
     101             : 
     102           0 :         if ((buflen > 0) && ((size_t)buflen > sizeof(stackbuf))) {
     103           0 :                 buf = malloc(buflen);
     104           0 :                 buflen = reparse_data_buffer_marshall(&reparse, buf, buflen);
     105             :         }
     106             : 
     107           0 :         if (buflen == -1) {
     108           0 :                 PyErr_NoMemory();
     109             :         } else {
     110           0 :                 result = PyBytes_FromStringAndSize((char *)buf, buflen);
     111             :         }
     112             : 
     113           0 :         if (buf != stackbuf) {
     114           0 :                 free(buf);
     115             :         }
     116             : 
     117           0 :         return result;
     118             : }
     119             : 
     120           2 : static PyObject *py_reparse_symlink_get(PyObject *module, PyObject *args)
     121             : {
     122           2 :         char *buf = NULL;
     123             :         Py_ssize_t buflen;
     124           2 :         struct reparse_data_buffer *syml = NULL;
     125           2 :         struct symlink_reparse_struct *lnk = NULL;
     126           2 :         PyObject *result = NULL;
     127             :         NTSTATUS status;
     128             :         bool ok;
     129             : 
     130           2 :         ok = PyArg_ParseTuple(args, PYARG_BYTES_LEN ":get", &buf, &buflen);
     131           2 :         if (!ok) {
     132           0 :                 return NULL;
     133             :         }
     134             : 
     135           2 :         syml = talloc(NULL, struct reparse_data_buffer);
     136           2 :         if (syml == NULL) {
     137           0 :                 PyErr_NoMemory();
     138           0 :                 return NULL;
     139             :         }
     140             : 
     141           2 :         status = reparse_data_buffer_parse(syml, syml, (uint8_t *)buf, buflen);
     142           2 :         if (!NT_STATUS_IS_OK(status)) {
     143           0 :                 TALLOC_FREE(syml);
     144           0 :                 PyErr_SetNTSTATUS(status);
     145           0 :                 return NULL;
     146             :         }
     147             : 
     148           2 :         if (syml->tag != IO_REPARSE_TAG_SYMLINK) {
     149           0 :                 TALLOC_FREE(syml);
     150           0 :                 PyErr_SetNTSTATUS(NT_STATUS_INVALID_NETWORK_RESPONSE);
     151           0 :                 return NULL;
     152             :         }
     153           2 :         lnk = &syml->parsed.lnk;
     154             : 
     155           2 :         result = Py_BuildValue("ssII",
     156             :                                lnk->substitute_name,
     157             :                                lnk->print_name,
     158           2 :                                (unsigned)lnk->unparsed_path_length,
     159           2 :                                (unsigned)lnk->flags);
     160             : 
     161           2 :         TALLOC_FREE(syml);
     162           2 :         return result;
     163             : }
     164             : 
     165             : static PyMethodDef py_reparse_symlink_methods[] = {
     166             :         { "put",
     167             :           PY_DISCARD_FUNC_SIG(PyCFunction, py_reparse_put),
     168             :           METH_VARARGS,
     169             :           "Create a reparse point blob"},
     170             :         { "symlink_put",
     171             :           PY_DISCARD_FUNC_SIG(PyCFunction, py_reparse_symlink_put),
     172             :           METH_VARARGS,
     173             :           "Create a reparse symlink blob"},
     174             :         { "symlink_get",
     175             :           PY_DISCARD_FUNC_SIG(PyCFunction, py_reparse_symlink_get),
     176             :           METH_VARARGS,
     177             :           "Parse a reparse symlink blob"},
     178             :         {0},
     179             : };
     180             : 
     181             : static struct PyModuleDef moduledef = {
     182             :         PyModuleDef_HEAD_INIT,
     183             :         .m_name = "reparse_symlink",
     184             :         .m_doc = "[un]marshall reparse symlink blobs",
     185             :         .m_size = -1,
     186             :         .m_methods = py_reparse_symlink_methods,
     187             : };
     188             : 
     189           2 : MODULE_INIT_FUNC(reparse_symlink)
     190             : {
     191             :         PyObject *m;
     192             : 
     193           2 :         m = PyModule_Create(&moduledef);
     194           2 :         if (m == NULL)
     195           0 :                 return NULL;
     196             : 
     197           2 :         return m;
     198             : }

Generated by: LCOV version 1.14