2 Python wrappers for DCERPC/SMB client routines.
4 Copyright (C) Tim Potter, 2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "python/py_samr.h"
24 * Exceptions raised by this module
27 PyObject
*samr_error
; /* This indicates a non-RPC related error
28 such as name lookup failure */
30 PyObject
*samr_ntstatus
; /* This exception is raised when a RPC call
31 returns a status code other than
34 /* SAMR group handle object */
36 static void py_samr_group_hnd_dealloc(PyObject
* self
)
41 static PyMethodDef samr_group_methods
[] = {
45 static PyObject
*py_samr_group_hnd_getattr(PyObject
*self
, char *attrname
)
47 return Py_FindMethod(samr_group_methods
, self
, attrname
);
50 PyTypeObject samr_group_hnd_type
= {
51 PyObject_HEAD_INIT(NULL
)
54 sizeof(samr_group_hnd_object
),
56 py_samr_group_hnd_dealloc
, /*tp_dealloc*/
58 py_samr_group_hnd_getattr
, /*tp_getattr*/
68 PyObject
*new_samr_group_hnd_object(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
71 samr_group_hnd_object
*o
;
73 o
= PyObject_New(samr_group_hnd_object
, &samr_group_hnd_type
);
77 memcpy(&o
->group_pol
, pol
, sizeof(POLICY_HND
));
82 /* Alias handle object */
84 static void py_samr_alias_hnd_dealloc(PyObject
* self
)
89 static PyMethodDef samr_alias_methods
[] = {
93 static PyObject
*py_samr_alias_hnd_getattr(PyObject
*self
, char *attrname
)
95 return Py_FindMethod(samr_alias_methods
, self
, attrname
);
98 PyTypeObject samr_alias_hnd_type
= {
99 PyObject_HEAD_INIT(NULL
)
102 sizeof(samr_alias_hnd_object
),
104 py_samr_alias_hnd_dealloc
, /*tp_dealloc*/
106 py_samr_alias_hnd_getattr
, /*tp_getattr*/
111 0, /*tp_as_sequence*/
116 PyObject
*new_samr_alias_hnd_object(struct cli_state
*cli
, TALLOC_CTX
*mem_ctx
,
119 samr_alias_hnd_object
*o
;
121 o
= PyObject_New(samr_alias_hnd_object
, &samr_alias_hnd_type
);
124 o
->mem_ctx
= mem_ctx
;
125 memcpy(&o
->alias_pol
, pol
, sizeof(POLICY_HND
));
130 /* SAMR user handle object */
132 static void py_samr_user_hnd_dealloc(PyObject
* self
)
137 static PyObject
*samr_set_user_info2(PyObject
*self
, PyObject
*args
,
140 samr_user_hnd_object
*user_hnd
= (samr_user_hnd_object
*)self
;
141 static char *kwlist
[] = { "dict", NULL
};
142 PyObject
*info
, *result
= NULL
;
143 SAM_USERINFO_CTR ctr
;
149 SAM_USER_INFO_16 id16
;
150 SAM_USER_INFO_21 id21
;
153 if (!PyArg_ParseTupleAndKeywords(
154 args
, kw
, "O!", kwlist
, &PyDict_Type
, &info
))
157 if (!get_level_value(info
, &level
)) {
158 PyErr_SetString(samr_error
, "invalid info level");
164 ctr
.switch_value
= level
;
168 ctr
.info
.id16
= &pinfo
.id16
;
170 if (!py_to_SAM_USER_INFO_16(ctr
.info
.id16
, info
)) {
172 samr_error
, "error converting user info");
178 ctr
.info
.id21
= &pinfo
.id21
;
180 if (!py_to_SAM_USER_INFO_21(ctr
.info
.id21
, info
)) {
182 samr_error
, "error converting user info");
188 PyErr_SetString(samr_error
, "unsupported info level");
192 /* Call RPC function */
194 if (!(mem_ctx
= talloc_init("samr_set_user_info2"))) {
196 samr_error
, "unable to init talloc context\n");
200 ntstatus
= rpccli_samr_set_userinfo2(
201 user_hnd
->cli
, mem_ctx
, &user_hnd
->user_pol
, level
,
204 talloc_destroy(mem_ctx
);
206 if (!NT_STATUS_IS_OK(ntstatus
)) {
207 PyErr_SetObject(samr_ntstatus
, py_ntstatus_tuple(ntstatus
));
218 static PyObject
*samr_delete_dom_user(PyObject
*self
, PyObject
*args
,
221 samr_user_hnd_object
*user_hnd
= (samr_user_hnd_object
*)self
;
222 static char *kwlist
[] = { NULL
};
225 PyObject
*result
= NULL
;
227 if (!PyArg_ParseTupleAndKeywords(
228 args
, kw
, "", kwlist
))
231 if (!(mem_ctx
= talloc_init("samr_delete_dom_user"))) {
232 PyErr_SetString(samr_error
, "unable to init talloc context");
236 ntstatus
= rpccli_samr_delete_dom_user(
237 user_hnd
->cli
, mem_ctx
, &user_hnd
->user_pol
);
239 if (!NT_STATUS_IS_OK(ntstatus
)) {
240 PyErr_SetObject(samr_ntstatus
, py_ntstatus_tuple(ntstatus
));
248 talloc_destroy(mem_ctx
);
253 static PyMethodDef samr_user_methods
[] = {
254 { "delete_domain_user", (PyCFunction
)samr_delete_dom_user
,
255 METH_VARARGS
| METH_KEYWORDS
,
256 "Delete domain user." },
257 { "set_user_info2", (PyCFunction
)samr_set_user_info2
,
258 METH_VARARGS
| METH_KEYWORDS
,
263 static PyObject
*py_samr_user_hnd_getattr(PyObject
*self
, char *attrname
)
265 return Py_FindMethod(samr_user_methods
, self
, attrname
);
268 PyTypeObject samr_user_hnd_type
= {
269 PyObject_HEAD_INIT(NULL
)
272 sizeof(samr_user_hnd_object
),
274 py_samr_user_hnd_dealloc
, /*tp_dealloc*/
276 py_samr_user_hnd_getattr
, /*tp_getattr*/
281 0, /*tp_as_sequence*/
286 PyObject
*new_samr_user_hnd_object(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
289 samr_user_hnd_object
*o
;
291 o
= PyObject_New(samr_user_hnd_object
, &samr_user_hnd_type
);
294 o
->mem_ctx
= mem_ctx
;
295 memcpy(&o
->user_pol
, pol
, sizeof(POLICY_HND
));
300 /* SAMR connect handle object */
302 static void py_samr_connect_hnd_dealloc(PyObject
* self
)
307 PyObject
*new_samr_domain_hnd_object(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
310 samr_domain_hnd_object
*o
;
312 o
= PyObject_New(samr_domain_hnd_object
, &samr_domain_hnd_type
);
315 o
->mem_ctx
= mem_ctx
;
316 memcpy(&o
->domain_pol
, pol
, sizeof(POLICY_HND
));
321 static PyObject
*samr_open_domain(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
323 samr_connect_hnd_object
*connect_hnd
= (samr_connect_hnd_object
*)self
;
324 static char *kwlist
[] = { "sid", "access", NULL
};
325 uint32 desired_access
= MAXIMUM_ALLOWED_ACCESS
;
328 TALLOC_CTX
*mem_ctx
= NULL
;
329 POLICY_HND domain_pol
;
331 PyObject
*result
= NULL
;
333 if (!PyArg_ParseTupleAndKeywords(
334 args
, kw
, "s|i", kwlist
, &sid_str
, &desired_access
))
337 if (!string_to_sid(&sid
, sid_str
)) {
338 PyErr_SetString(PyExc_TypeError
, "string is not a sid");
342 if (!(mem_ctx
= talloc_init("samr_open_domain"))) {
343 PyErr_SetString(samr_error
, "unable to init talloc context");
347 ntstatus
= rpccli_samr_open_domain(
348 connect_hnd
->cli
, mem_ctx
, &connect_hnd
->connect_pol
,
349 desired_access
, &sid
, &domain_pol
);
351 if (!NT_STATUS_IS_OK(ntstatus
)) {
352 PyErr_SetObject(samr_ntstatus
, py_ntstatus_tuple(ntstatus
));
356 result
= new_samr_domain_hnd_object(
357 connect_hnd
->cli
, mem_ctx
, &domain_pol
);
362 talloc_destroy(mem_ctx
);
368 static PyMethodDef samr_connect_methods
[] = {
369 { "open_domain", (PyCFunction
)samr_open_domain
,
370 METH_VARARGS
| METH_KEYWORDS
,
371 "Open a handle on a domain" },
376 static PyObject
*py_samr_connect_hnd_getattr(PyObject
*self
, char *attrname
)
378 return Py_FindMethod(samr_connect_methods
, self
, attrname
);
381 PyTypeObject samr_connect_hnd_type
= {
382 PyObject_HEAD_INIT(NULL
)
384 "SAMR Connect Handle",
385 sizeof(samr_connect_hnd_object
),
387 py_samr_connect_hnd_dealloc
, /*tp_dealloc*/
389 py_samr_connect_hnd_getattr
, /*tp_getattr*/
394 0, /*tp_as_sequence*/
399 PyObject
*new_samr_connect_hnd_object(struct rpc_pipe_client
*cli
, TALLOC_CTX
*mem_ctx
,
402 samr_connect_hnd_object
*o
;
404 o
= PyObject_New(samr_connect_hnd_object
, &samr_connect_hnd_type
);
407 o
->mem_ctx
= mem_ctx
;
408 memcpy(&o
->connect_pol
, pol
, sizeof(POLICY_HND
));
413 /* SAMR domain handle object */
415 static void py_samr_domain_hnd_dealloc(PyObject
* self
)
420 static PyObject
*samr_enum_dom_groups(PyObject
*self
, PyObject
*args
,
423 samr_domain_hnd_object
*domain_hnd
= (samr_domain_hnd_object
*)self
;
424 static char *kwlist
[] = { NULL
};
426 /* uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
427 uint32 start_idx
, size
, num_dom_groups
;
428 struct acct_info
*dom_groups
;
430 PyObject
*py_result
= NULL
;
432 if (!PyArg_ParseTupleAndKeywords(args
, kw
, "", kwlist
))
435 if (!(mem_ctx
= talloc_init("samr_enum_dom_groups"))) {
436 PyErr_SetString(samr_error
, "unable to init talloc context");
444 result
= rpccli_samr_enum_dom_groups(
445 domain_hnd
->cli
, mem_ctx
, &domain_hnd
->domain_pol
,
446 &start_idx
, size
, &dom_groups
, &num_dom_groups
);
448 if (NT_STATUS_IS_OK(result
) ||
449 NT_STATUS_V(result
) == NT_STATUS_V(STATUS_MORE_ENTRIES
)) {
450 py_from_acct_info(&py_result
, dom_groups
,
454 } while (NT_STATUS_V(result
) == NT_STATUS_V(STATUS_MORE_ENTRIES
));
459 static PyObject
*samr_create_dom_user(PyObject
*self
, PyObject
*args
,
462 samr_domain_hnd_object
*domain_hnd
= (samr_domain_hnd_object
*)self
;
463 static char *kwlist
[] = { "account_name", "acb_info", NULL
};
466 uint32 acct_flags
= 0;
468 PyObject
*result
= NULL
;
470 uint32 acb_info
= ACB_NORMAL
;
473 if (!PyArg_ParseTupleAndKeywords(
474 args
, kw
, "s|i", kwlist
, &account_name
, &acb_info
))
477 if (!(mem_ctx
= talloc_init("samr_create_dom_user"))) {
478 PyErr_SetString(samr_error
, "unable to init talloc context");
482 acct_flags
= SAMR_GENERIC_READ
| SAMR_GENERIC_WRITE
|
483 SAMR_GENERIC_EXECUTE
| SAMR_STANDARD_WRITEDAC
|
484 SAMR_STANDARD_DELETE
| SAMR_USER_SETPASS
| SAMR_USER_GETATTR
|
486 DEBUG(10, ("Creating account with flags: %d\n",acct_flags
));
487 ntstatus
= rpccli_samr_create_dom_user(
488 domain_hnd
->cli
, mem_ctx
, &domain_hnd
->domain_pol
,
489 account_name
, acb_info
, acct_flags
, &user_pol
, &user_rid
);
491 if (!NT_STATUS_IS_OK(ntstatus
)) {
492 PyErr_SetObject(samr_ntstatus
, py_ntstatus_tuple(ntstatus
));
493 talloc_destroy(mem_ctx
);
497 result
= new_samr_user_hnd_object(
498 domain_hnd
->cli
, mem_ctx
, &user_pol
);
505 static PyMethodDef samr_domain_methods
[] = {
506 { "enum_domain_groups", (PyCFunction
)samr_enum_dom_groups
,
507 METH_VARARGS
| METH_KEYWORDS
, "Enumerate domain groups" },
508 { "create_domain_user", (PyCFunction
)samr_create_dom_user
,
509 METH_VARARGS
| METH_KEYWORDS
, "Create domain user" },
513 static PyObject
*py_samr_domain_hnd_getattr(PyObject
*self
, char *attrname
)
515 return Py_FindMethod(samr_domain_methods
, self
, attrname
);
518 PyTypeObject samr_domain_hnd_type
= {
519 PyObject_HEAD_INIT(NULL
)
521 "SAMR Domain Handle",
522 sizeof(samr_domain_hnd_object
),
524 py_samr_domain_hnd_dealloc
, /*tp_dealloc*/
526 py_samr_domain_hnd_getattr
, /*tp_getattr*/
531 0, /*tp_as_sequence*/
536 static PyObject
*samr_connect(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
538 static char *kwlist
[] = { "server", "creds", "access", NULL
};
539 uint32 desired_access
= MAXIMUM_ALLOWED_ACCESS
;
540 char *server
, *errstr
;
541 struct cli_state
*cli
= NULL
;
543 TALLOC_CTX
*mem_ctx
= NULL
;
544 PyObject
*result
= NULL
, *creds
= NULL
;
547 if (!PyArg_ParseTupleAndKeywords(
548 args
, kw
, "s|Oi", kwlist
, &server
, &creds
,
552 if (server
[0] != '\\' || server
[1] != '\\') {
553 PyErr_SetString(PyExc_ValueError
, "UNC name required");
559 if (creds
&& creds
!= Py_None
&& !PyDict_Check(creds
)) {
560 PyErr_SetString(PyExc_TypeError
,
561 "credentials must be dictionary or None");
565 if (!(cli
= open_pipe_creds(server
, creds
, PI_SAMR
, &errstr
))) {
566 PyErr_SetString(samr_error
, errstr
);
571 if (!(mem_ctx
= talloc_init("samr_connect"))) {
572 PyErr_SetString(samr_ntstatus
,
573 "unable to init talloc context\n");
577 ntstatus
= rpccli_samr_connect(cli
->pipe_list
, mem_ctx
, desired_access
, &hnd
);
579 if (!NT_STATUS_IS_OK(ntstatus
)) {
581 PyErr_SetObject(samr_ntstatus
, py_ntstatus_tuple(ntstatus
));
585 result
= new_samr_connect_hnd_object(cli
->pipe_list
, mem_ctx
, &hnd
);
593 talloc_destroy(mem_ctx
);
600 * Module initialisation
603 static PyMethodDef samr_methods
[] = {
605 /* Open/close samr connect handles */
607 { "connect", (PyCFunction
)samr_connect
,
608 METH_VARARGS
| METH_KEYWORDS
,
609 "Open a connect handle" },
614 static struct const_vals
{
617 } module_const_vals
[] = {
619 /* Account control bits */
621 { "ACB_DISABLED", 0x0001 },
622 { "ACB_HOMDIRREQ", 0x0002 },
623 { "ACB_PWNOTREQ", 0x0004 },
624 { "ACB_TEMPDUP", 0x0008 },
625 { "ACB_NORMAL", 0x0010 },
626 { "ACB_MNS", 0x0020 },
627 { "ACB_DOMTRUST", 0x0040 },
628 { "ACB_WSTRUST", 0x0080 },
629 { "ACB_SVRTRUST", 0x0100 },
630 { "ACB_PWNOEXP", 0x0200 },
631 { "ACB_AUTOLOCK", 0x0400 },
636 static void const_init(PyObject
*dict
)
638 struct const_vals
*tmp
;
641 for (tmp
= module_const_vals
; tmp
->name
; tmp
++) {
642 obj
= PyInt_FromLong(tmp
->value
);
643 PyDict_SetItemString(dict
, tmp
->name
, obj
);
650 PyObject
*module
, *dict
;
652 /* Initialise module */
654 module
= Py_InitModule("samr", samr_methods
);
655 dict
= PyModule_GetDict(module
);
657 samr_error
= PyErr_NewException("samr.error", NULL
, NULL
);
658 PyDict_SetItemString(dict
, "error", samr_error
);
660 samr_ntstatus
= PyErr_NewException("samr.ntstatus", NULL
, NULL
);
661 PyDict_SetItemString(dict
, "ntstatus", samr_ntstatus
);
663 /* Initialise policy handle object */
665 samr_connect_hnd_type
.ob_type
= &PyType_Type
;
666 samr_domain_hnd_type
.ob_type
= &PyType_Type
;
667 samr_user_hnd_type
.ob_type
= &PyType_Type
;
668 samr_group_hnd_type
.ob_type
= &PyType_Type
;
669 samr_alias_hnd_type
.ob_type
= &PyType_Type
;
671 /* Initialise constants */
675 /* Do samba initialisation */
679 setup_logging("samr", True
);