s4/ntvfs/posix/python: python3 (get|set)xattr value should be bytes
[samba.git] / source4 / ntvfs / posix / python / pyxattr_tdb.c
1 /*
2    Unix SMB/CIFS implementation. Xattr manipulation bindings.
3    Copyright (C) Matthieu Patou <mat@matws.net> 2009-2010
4    Base on work of pyglue.c by Jelmer Vernooij <jelmer@samba.org> 2007 and
5     Matthias Dieter Wallnöfer 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include <Python.h>
22 #include "python/py3compat.h"
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include <tdb.h>
26 #include "lib/tdb_wrap/tdb_wrap.h"
27 #include "librpc/ndr/libndr.h"
28 #include "ntvfs/posix/posix_eadb.h"
29 #include "libcli/util/pyerrors.h"
30 #include "param/pyparam.h"
31 #include "lib/dbwrap/dbwrap.h"
32 #include "lib/dbwrap/dbwrap_open.h"
33 #include "lib/dbwrap/dbwrap_tdb.h"
34 #include "source3/lib/xattr_tdb.h"
35
36 static PyObject *py_is_xattr_supported(PyObject *self)
37 {
38         return Py_True;
39 }
40
41 static PyObject *py_wrap_setxattr(PyObject *self, PyObject *args)
42 {
43         char *filename, *attribute, *tdbname;
44         DATA_BLOB blob;
45         Py_ssize_t blobsize;
46         int ret;
47         TALLOC_CTX *mem_ctx;
48         struct loadparm_context *lp_ctx;
49         struct db_context *eadb = NULL;
50         struct file_id id;
51         struct stat sbuf;
52
53         if (!PyArg_ParseTuple(args, "sss"PYARG_BYTES_LEN, &tdbname, &filename, &attribute,
54                                                   &blob.data, &blobsize))
55                 return NULL;
56
57         blob.length = blobsize;
58         mem_ctx = talloc_new(NULL);
59
60         lp_ctx = py_default_loadparm_context(mem_ctx);
61         eadb = db_open_tdb(mem_ctx, tdbname, 50000,
62                            lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT),
63                            O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
64                            DBWRAP_FLAG_NONE);
65
66         if (eadb == NULL) {
67                 PyErr_SetFromErrno(PyExc_IOError);
68                 talloc_free(mem_ctx);
69                 return NULL;
70         }
71
72         ret = stat(filename, &sbuf);
73         if (ret < 0) {
74                 PyErr_SetFromErrno(PyExc_IOError);
75                 talloc_free(mem_ctx);
76                 return NULL;
77         }
78
79         ZERO_STRUCT(id);
80         id.devid = sbuf.st_dev;
81         id.inode = sbuf.st_ino;
82
83         ret = xattr_tdb_setattr(eadb, &id, attribute, blob.data, blob.length, 0);
84         if (ret < 0) {
85                 PyErr_SetFromErrno(PyExc_TypeError);
86                 talloc_free(mem_ctx);
87                 return NULL;
88         }
89         talloc_free(mem_ctx);
90         Py_RETURN_NONE;
91 }
92
93 static PyObject *py_wrap_getxattr(PyObject *self, PyObject *args)
94 {
95         char *filename, *attribute, *tdbname;
96         TALLOC_CTX *mem_ctx;
97         struct loadparm_context *lp_ctx;
98         DATA_BLOB blob;
99         PyObject *ret_obj;
100         int ret;
101         ssize_t xattr_size;
102         struct db_context *eadb = NULL;
103         struct file_id id;
104         struct stat sbuf;
105
106         if (!PyArg_ParseTuple(args, "sss", &tdbname, &filename, &attribute))
107                 return NULL;
108
109         mem_ctx = talloc_new(NULL);
110
111         lp_ctx = py_default_loadparm_context(mem_ctx);
112         eadb = db_open_tdb(mem_ctx, tdbname, 50000,
113                            lpcfg_tdb_flags(lp_ctx, TDB_DEFAULT),
114                            O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
115                            DBWRAP_FLAG_NONE);
116
117         if (eadb == NULL) {
118                 PyErr_SetFromErrno(PyExc_IOError);
119                 talloc_free(mem_ctx);
120                 return NULL;
121         }
122
123         ret = stat(filename, &sbuf);
124         if (ret < 0) {
125                 PyErr_SetFromErrno(PyExc_IOError);
126                 talloc_free(mem_ctx);
127                 return NULL;
128         }
129
130         ZERO_STRUCT(id);
131         id.devid = sbuf.st_dev;
132         id.inode = sbuf.st_ino;
133
134         xattr_size = xattr_tdb_getattr(eadb, mem_ctx, &id, attribute, &blob);
135         if (xattr_size < 0) {
136                 PyErr_SetFromErrno(PyExc_TypeError);
137                 talloc_free(mem_ctx);
138                 return NULL;
139         }
140         ret_obj = Py_BuildValue(PYARG_BYTES_LEN, blob.data, xattr_size);
141         talloc_free(mem_ctx);
142         return ret_obj;
143 }
144
145 static PyMethodDef py_xattr_methods[] = {
146         { "wrap_getxattr", (PyCFunction)py_wrap_getxattr, METH_VARARGS,
147                 "wrap_getxattr(filename,attribute) -> blob\n"
148                 "Retrieve given attribute on the given file." },
149         { "wrap_setxattr", (PyCFunction)py_wrap_setxattr, METH_VARARGS,
150                 "wrap_setxattr(filename,attribute,value)\n"
151                 "Set the given attribute to the given value on the given file." },
152         { "is_xattr_supported", (PyCFunction)py_is_xattr_supported, METH_NOARGS,
153                 "Return true if xattr are supported on this system\n"},
154         { NULL }
155 };
156
157 static struct PyModuleDef moduledef = {
158     PyModuleDef_HEAD_INIT,
159     .m_name = "xattr_tdb",
160     .m_doc = "Python bindings for xattr manipulation.",
161     .m_size = -1,
162     .m_methods = py_xattr_methods,
163 };
164
165 MODULE_INIT_FUNC(xattr_tdb)
166 {
167         PyObject *m;
168
169         m = PyModule_Create(&moduledef);
170
171         if (m == NULL)
172                 return NULL;
173
174         return m;
175 }
176