2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008-2010
5 Copyright (C) Kamen Mazdrashki <kamen.mazdrashki@postpath.com> 2009
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.
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.
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/>.
24 #include "auth/credentials/pycredentials.h"
25 #include "libcli/security/security.h"
26 #include "lib/events/events.h"
27 #include "param/param.h"
28 #include "param/pyparam.h"
33 struct libnet_context
*libnet_ctx
;
34 struct tevent_context
*ev
;
37 static PyObject
*py_net_join(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
43 const char *kwnames
[] = { "domain_name", "netbios_name", "join_type", "level", NULL
};
45 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "ssii:Join", discard_const_p(char *, kwnames
),
46 &r
.in
.domain_name
, &r
.in
.netbios_name
,
47 &r
.in
.join_type
, &r
.in
.level
))
50 mem_ctx
= talloc_new(self
->mem_ctx
);
52 status
= libnet_Join(self
->libnet_ctx
, mem_ctx
, &r
);
53 if (NT_STATUS_IS_ERR(status
)) {
54 PyErr_SetString(PyExc_RuntimeError
, r
.out
.error_string
?r
.out
.error_string
:nt_errstr(status
));
59 result
= Py_BuildValue("sss", r
.out
.join_password
,
60 dom_sid_string(mem_ctx
, r
.out
.domain_sid
),
68 static const char py_net_join_doc
[] = "join(domain_name, netbios_name, join_type, level) -> (join_password, domain_sid, domain_name)\n\n" \
69 "Join the domain with the specified name.";
71 static PyObject
*py_net_set_password(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
73 union libnet_SetPassword r
;
77 struct tevent_context
*ev
;
78 const char *kwnames
[] = { "account_name", "domain_name", "newpassword", "credentials", NULL
};
80 r
.generic
.level
= LIBNET_SET_PASSWORD_GENERIC
;
82 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "sssO:set_password", discard_const_p(char *, kwnames
),
83 &r
.generic
.in
.account_name
, &r
.generic
.in
.domain_name
,
84 &r
.generic
.in
.newpassword
, &py_creds
)) {
88 /* FIXME: we really need to get a context from the caller or we may end
89 * up with 2 event contexts */
90 ev
= s4_event_context_init(NULL
);
91 mem_ctx
= talloc_new(ev
);
93 status
= libnet_SetPassword(self
->libnet_ctx
, mem_ctx
, &r
);
94 if (NT_STATUS_IS_ERR(status
)) {
95 PyErr_SetString(PyExc_RuntimeError
,
96 r
.generic
.out
.error_string
?r
.generic
.out
.error_string
:nt_errstr(status
));
101 talloc_free(mem_ctx
);
106 static const char py_net_set_password_doc
[] = "set_password(account_name, domain_name, newpassword) -> True\n\n" \
107 "Set password for a user. You must supply credential with enough rights to do this.\n\n" \
108 "Sample usage is:\n" \
109 "net.set_password(account_name=<account_name>,\n" \
110 " domain_name=domain_name,\n" \
111 " newpassword=new_pass)\n";
114 static PyObject
*py_net_export_keytab(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
116 struct libnet_export_keytab r
;
118 const char *kwnames
[] = { "keytab", NULL
};
121 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s:export_keytab", discard_const_p(char *, kwnames
),
122 &r
.in
.keytab_name
)) {
126 mem_ctx
= talloc_new(self
->mem_ctx
);
128 status
= libnet_export_keytab(self
->libnet_ctx
, mem_ctx
, &r
);
129 if (NT_STATUS_IS_ERR(status
)) {
130 PyErr_SetString(PyExc_RuntimeError
,
131 r
.out
.error_string
?r
.out
.error_string
:nt_errstr(status
));
132 talloc_free(mem_ctx
);
136 talloc_free(mem_ctx
);
141 static const char py_net_export_keytab_doc
[] = "export_keytab(keytab, name)\n\n"
142 "Export the DC keytab to a keytab file.";
144 static PyObject
*py_net_time(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
146 const char *kwnames
[] = { "server_name", NULL
};
147 union libnet_RemoteTOD r
;
154 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s",
155 discard_const_p(char *, kwnames
), &r
.generic
.in
.server_name
))
158 r
.generic
.level
= LIBNET_REMOTE_TOD_GENERIC
;
160 mem_ctx
= talloc_new(NULL
);
161 if (mem_ctx
== NULL
) {
166 status
= libnet_RemoteTOD(self
->libnet_ctx
, mem_ctx
, &r
);
167 if (!NT_STATUS_IS_OK(status
)) {
168 PyErr_SetString(PyExc_RuntimeError
,
169 r
.generic
.out
.error_string
?r
.generic
.out
.error_string
:nt_errstr(status
));
170 talloc_free(mem_ctx
);
174 ZERO_STRUCT(timestr
);
175 tm
= localtime(&r
.generic
.out
.time
);
176 strftime(timestr
, sizeof(timestr
)-1, "%c %Z",tm
);
178 ret
= PyString_FromString(timestr
);
180 talloc_free(mem_ctx
);
185 static const char py_net_time_doc
[] = "time(server_name) -> timestr\n"
186 "Retrieve the remote time on a server";
188 static PyObject
*py_net_user_create(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
190 const char *kwnames
[] = { "username", NULL
};
193 struct libnet_CreateUser r
;
195 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s", discard_const_p(char *, kwnames
),
199 r
.in
.domain_name
= cli_credentials_get_domain(self
->libnet_ctx
->cred
);
201 mem_ctx
= talloc_new(NULL
);
202 if (mem_ctx
== NULL
) {
207 status
= libnet_CreateUser(self
->libnet_ctx
, mem_ctx
, &r
);
208 if (!NT_STATUS_IS_OK(status
)) {
209 PyErr_SetString(PyExc_RuntimeError
, r
.out
.error_string
?r
.out
.error_string
:nt_errstr(status
));
210 talloc_free(mem_ctx
);
214 talloc_free(mem_ctx
);
219 static const char py_net_create_user_doc
[] = "create_user(username)\n"
220 "Create a new user.";
222 static PyObject
*py_net_user_delete(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
224 const char *kwnames
[] = { "username", NULL
};
227 struct libnet_DeleteUser r
;
229 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s", discard_const_p(char *, kwnames
),
233 r
.in
.domain_name
= cli_credentials_get_domain(self
->libnet_ctx
->cred
);
235 mem_ctx
= talloc_new(NULL
);
236 if (mem_ctx
== NULL
) {
241 status
= libnet_DeleteUser(self
->libnet_ctx
, mem_ctx
, &r
);
242 if (!NT_STATUS_IS_OK(status
)) {
243 PyErr_SetString(PyExc_RuntimeError
, r
.out
.error_string
?r
.out
.error_string
:nt_errstr(status
));
244 talloc_free(mem_ctx
);
248 talloc_free(mem_ctx
);
253 static const char py_net_delete_user_doc
[] = "delete_user(username)\n"
256 static PyObject
*py_dom_sid_FromSid(struct dom_sid
*sid
)
258 PyObject
*mod_security
, *dom_sid_Type
;
260 mod_security
= PyImport_ImportModule("samba.dcerpc.security");
261 if (mod_security
== NULL
)
264 dom_sid_Type
= PyObject_GetAttrString(mod_security
, "dom_sid");
265 if (dom_sid_Type
== NULL
)
268 return py_talloc_reference((PyTypeObject
*)dom_sid_Type
, sid
);
271 static PyObject
*py_net_vampire(py_net_Object
*self
, PyObject
*args
, PyObject
*kwargs
)
273 const char *kwnames
[] = { "domain", "target_dir", NULL
};
277 struct libnet_Vampire r
;
279 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "s|z", discard_const_p(char *, kwnames
),
280 &r
.in
.domain_name
, &r
.in
.targetdir
)) {
284 r
.in
.netbios_name
= lp_netbios_name(self
->libnet_ctx
->lp_ctx
);
285 r
.out
.error_string
= NULL
;
287 mem_ctx
= talloc_new(NULL
);
288 if (mem_ctx
== NULL
) {
293 status
= libnet_Vampire(self
->libnet_ctx
, mem_ctx
, &r
);
295 if (!NT_STATUS_IS_OK(status
)) {
296 PyErr_SetString(PyExc_RuntimeError
,
297 r
.out
.error_string
? r
.out
.error_string
: nt_errstr(status
));
298 talloc_free(mem_ctx
);
302 ret
= Py_BuildValue("(sO)", r
.out
.domain_name
, py_dom_sid_FromSid(r
.out
.domain_sid
));
304 talloc_free(mem_ctx
);
309 static const char py_net_vampire_doc
[] = "vampire(domain, target_dir=None)\n"
312 static PyMethodDef net_obj_methods
[] = {
313 {"join", (PyCFunction
)py_net_join
, METH_VARARGS
|METH_KEYWORDS
, py_net_join_doc
},
314 {"set_password", (PyCFunction
)py_net_set_password
, METH_VARARGS
|METH_KEYWORDS
, py_net_set_password_doc
},
315 {"export_keytab", (PyCFunction
)py_net_export_keytab
, METH_VARARGS
|METH_KEYWORDS
, py_net_export_keytab_doc
},
316 {"time", (PyCFunction
)py_net_time
, METH_VARARGS
|METH_KEYWORDS
, py_net_time_doc
},
317 {"create_user", (PyCFunction
)py_net_user_create
, METH_VARARGS
|METH_KEYWORDS
, py_net_create_user_doc
},
318 {"delete_user", (PyCFunction
)py_net_user_delete
, METH_VARARGS
|METH_KEYWORDS
, py_net_delete_user_doc
},
319 {"vampire", (PyCFunction
)py_net_vampire
, METH_VARARGS
|METH_KEYWORDS
, py_net_vampire_doc
},
323 static void py_net_dealloc(py_net_Object
*self
)
325 talloc_free(self
->mem_ctx
);
328 static PyObject
*net_obj_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwargs
)
330 PyObject
*py_creds
, *py_lp
= Py_None
;
331 const char *kwnames
[] = { "creds", "lp", NULL
};
333 struct loadparm_context
*lp
;
335 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "O|O",
336 discard_const_p(char *, kwnames
), &py_creds
, &py_lp
))
339 ret
= PyObject_New(py_net_Object
, type
);
344 /* FIXME: we really need to get a context from the caller or we may end
345 * up with 2 event contexts */
346 ret
->ev
= s4_event_context_init(NULL
);
347 ret
->mem_ctx
= talloc_new(ret
->ev
);
349 lp
= lp_from_py_object(ret
->mem_ctx
, py_lp
);
355 ret
->libnet_ctx
= libnet_context_init(ret
->ev
, lp
);
356 if (ret
->libnet_ctx
== NULL
) {
357 PyErr_SetString(PyExc_RuntimeError
, "Unable to initialize net");
362 ret
->libnet_ctx
->cred
= cli_credentials_from_py_object(py_creds
);
363 if (ret
->libnet_ctx
->cred
== NULL
) {
364 PyErr_SetString(PyExc_TypeError
, "Expected credentials object");
369 return (PyObject
*)ret
;
373 PyTypeObject py_net_Type
= {
374 PyObject_HEAD_INIT(NULL
) 0,
375 .tp_name
= "net.Net",
376 .tp_basicsize
= sizeof(py_net_Object
),
377 .tp_dealloc
= (destructor
)py_net_dealloc
,
378 .tp_methods
= net_obj_methods
,
379 .tp_new
= net_obj_new
,
386 if (PyType_Ready(&py_net_Type
) < 0)
389 m
= Py_InitModule3("net", NULL
, NULL
);
393 Py_INCREF(&py_net_Type
);
394 PyModule_AddObject(m
, "Net", (PyObject
*)&py_net_Type
);