• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.0.25b/source/python/
1/*
2   Python wrappers for DCERPC/SMB client routines.
3
4   Copyright (C) Tim Potter, 2002
5
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.
10
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.
15
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.
19*/
20
21#include "python/py_samr.h"
22
23/*
24 * Exceptions raised by this module
25 */
26
27PyObject *samr_error;		/* This indicates a non-RPC related error
28				   such as name lookup failure */
29
30PyObject *samr_ntstatus;	/* This exception is raised when a RPC call
31				   returns a status code other than
32				   NT_STATUS_OK */
33
34/* SAMR group handle object */
35
36static void py_samr_group_hnd_dealloc(PyObject* self)
37{
38	PyObject_Del(self);
39}
40
41static PyMethodDef samr_group_methods[] = {
42	{ NULL }
43};
44
45static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
46{
47	return Py_FindMethod(samr_group_methods, self, attrname);
48}
49
50PyTypeObject samr_group_hnd_type = {
51	PyObject_HEAD_INIT(NULL)
52	0,
53	"SAMR Group Handle",
54	sizeof(samr_group_hnd_object),
55	0,
56	py_samr_group_hnd_dealloc, /*tp_dealloc*/
57	0,          /*tp_print*/
58	py_samr_group_hnd_getattr,          /*tp_getattr*/
59	0,          /*tp_setattr*/
60	0,          /*tp_compare*/
61	0,          /*tp_repr*/
62	0,          /*tp_as_number*/
63	0,          /*tp_as_sequence*/
64	0,          /*tp_as_mapping*/
65	0,          /*tp_hash */
66};
67
68PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
69				      POLICY_HND *pol)
70{
71	samr_group_hnd_object *o;
72
73	o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
74
75	o->cli = cli;
76	o->mem_ctx = mem_ctx;
77	memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
78
79	return (PyObject*)o;
80}
81
82/* Alias handle object */
83
84static void py_samr_alias_hnd_dealloc(PyObject* self)
85{
86	PyObject_Del(self);
87}
88
89static PyMethodDef samr_alias_methods[] = {
90	{ NULL }
91};
92
93static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
94{
95	return Py_FindMethod(samr_alias_methods, self, attrname);
96}
97
98PyTypeObject samr_alias_hnd_type = {
99	PyObject_HEAD_INIT(NULL)
100	0,
101	"SAMR Alias Handle",
102	sizeof(samr_alias_hnd_object),
103	0,
104	py_samr_alias_hnd_dealloc, /*tp_dealloc*/
105	0,          /*tp_print*/
106	py_samr_alias_hnd_getattr,          /*tp_getattr*/
107	0,          /*tp_setattr*/
108	0,          /*tp_compare*/
109	0,          /*tp_repr*/
110	0,          /*tp_as_number*/
111	0,          /*tp_as_sequence*/
112	0,          /*tp_as_mapping*/
113	0,          /*tp_hash */
114};
115
116PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
117				      POLICY_HND *pol)
118{
119	samr_alias_hnd_object *o;
120
121	o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
122
123	o->cli = cli;
124	o->mem_ctx = mem_ctx;
125	memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
126
127	return (PyObject*)o;
128}
129
130/* SAMR user handle object */
131
132static void py_samr_user_hnd_dealloc(PyObject* self)
133{
134	PyObject_Del(self);
135}
136
137static PyObject *samr_set_user_info2(PyObject *self, PyObject *args,
138				     PyObject *kw)
139{
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;
144	TALLOC_CTX *mem_ctx;
145	uchar sess_key[16];
146	NTSTATUS ntstatus;
147	int level;
148	union {
149		SAM_USER_INFO_16 id16;
150		SAM_USER_INFO_21 id21;
151	} pinfo;
152
153	if (!PyArg_ParseTupleAndKeywords(
154		    args, kw, "O!", kwlist, &PyDict_Type, &info))
155		return NULL;
156
157	if (!get_level_value(info, &level)) {
158		PyErr_SetString(samr_error, "invalid info level");
159		return NULL;
160	}
161
162	ZERO_STRUCT(ctr);
163
164	ctr.switch_value = level;
165
166	switch(level) {
167	case 16:
168		ctr.info.id16 = &pinfo.id16;
169
170		if (!py_to_SAM_USER_INFO_16(ctr.info.id16, info)) {
171			PyErr_SetString(
172				samr_error, "error converting user info");
173			goto done;
174		}
175
176		break;
177	case 21:
178		ctr.info.id21 = &pinfo.id21;
179
180		if (!py_to_SAM_USER_INFO_21(ctr.info.id21, info)) {
181			PyErr_SetString(
182				samr_error, "error converting user info");
183			goto done;
184		}
185
186		break;
187	default:
188		PyErr_SetString(samr_error, "unsupported info level");
189		goto done;
190	}
191
192	/* Call RPC function */
193
194	if (!(mem_ctx = talloc_init("samr_set_user_info2"))) {
195		PyErr_SetString(
196			samr_error, "unable to init talloc context\n");
197		goto done;
198	}
199
200	ntstatus = rpccli_samr_set_userinfo2(
201		user_hnd->cli, mem_ctx, &user_hnd->user_pol, level,
202		sess_key, &ctr);
203
204	talloc_destroy(mem_ctx);
205
206	if (!NT_STATUS_IS_OK(ntstatus)) {
207		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
208		goto done;
209	}
210
211	Py_INCREF(Py_None);
212	result = Py_None;
213
214done:
215	return result;
216}
217
218static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args,
219				      PyObject *kw)
220{
221	samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
222	static char *kwlist[] = { NULL };
223	NTSTATUS ntstatus;
224	TALLOC_CTX *mem_ctx;
225	PyObject *result = NULL;
226
227	if (!PyArg_ParseTupleAndKeywords(
228		    args, kw, "", kwlist))
229		return NULL;
230
231	if (!(mem_ctx = talloc_init("samr_delete_dom_user"))) {
232		PyErr_SetString(samr_error, "unable to init talloc context");
233		return NULL;
234	}
235
236	ntstatus = rpccli_samr_delete_dom_user(
237		user_hnd->cli, mem_ctx, &user_hnd->user_pol);
238
239	if (!NT_STATUS_IS_OK(ntstatus)) {
240		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
241		goto done;
242	}
243
244	Py_INCREF(Py_None);
245	result = Py_None;
246
247done:
248	talloc_destroy(mem_ctx);
249
250	return result;
251}
252
253static 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,
259	  "Set user info 2" },
260	{ NULL }
261};
262
263static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
264{
265	return Py_FindMethod(samr_user_methods, self, attrname);
266}
267
268PyTypeObject samr_user_hnd_type = {
269	PyObject_HEAD_INIT(NULL)
270	0,
271	"SAMR User Handle",
272	sizeof(samr_user_hnd_object),
273	0,
274	py_samr_user_hnd_dealloc, /*tp_dealloc*/
275	0,          /*tp_print*/
276	py_samr_user_hnd_getattr,          /*tp_getattr*/
277	0,          /*tp_setattr*/
278	0,          /*tp_compare*/
279	0,          /*tp_repr*/
280	0,          /*tp_as_number*/
281	0,          /*tp_as_sequence*/
282	0,          /*tp_as_mapping*/
283	0,          /*tp_hash */
284};
285
286PyObject *new_samr_user_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
287				   POLICY_HND *pol)
288{
289	samr_user_hnd_object *o;
290
291	o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
292
293	o->cli = cli;
294	o->mem_ctx = mem_ctx;
295	memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
296
297	return (PyObject*)o;
298}
299
300/* SAMR connect handle object */
301
302static void py_samr_connect_hnd_dealloc(PyObject* self)
303{
304	PyObject_Del(self);
305}
306
307PyObject *new_samr_domain_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
308				     POLICY_HND *pol)
309{
310	samr_domain_hnd_object *o;
311
312	o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
313
314	o->cli = cli;
315	o->mem_ctx = mem_ctx;
316	memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
317
318	return (PyObject*)o;
319}
320
321static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
322{
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;
326	char *sid_str;
327	DOM_SID sid;
328	TALLOC_CTX *mem_ctx = NULL;
329	POLICY_HND domain_pol;
330	NTSTATUS ntstatus;
331	PyObject *result = NULL;
332
333	if (!PyArg_ParseTupleAndKeywords(
334		    args, kw, "s|i", kwlist, &sid_str, &desired_access))
335		return NULL;
336
337	if (!string_to_sid(&sid, sid_str)) {
338		PyErr_SetString(PyExc_TypeError, "string is not a sid");
339		return NULL;
340	}
341
342	if (!(mem_ctx = talloc_init("samr_open_domain"))) {
343		PyErr_SetString(samr_error, "unable to init talloc context");
344		return NULL;
345	}
346
347	ntstatus = rpccli_samr_open_domain(
348		connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
349		desired_access, &sid, &domain_pol);
350
351	if (!NT_STATUS_IS_OK(ntstatus)) {
352		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
353		goto done;
354	}
355
356	result = new_samr_domain_hnd_object(
357		connect_hnd->cli, mem_ctx, &domain_pol);
358
359done:
360	if (!result) {
361		if (mem_ctx)
362			talloc_destroy(mem_ctx);
363	}
364
365	return result;
366}
367
368static PyMethodDef samr_connect_methods[] = {
369	{ "open_domain", (PyCFunction)samr_open_domain,
370	  METH_VARARGS | METH_KEYWORDS,
371	  "Open a handle on a domain" },
372
373	{ NULL }
374};
375
376static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
377{
378	return Py_FindMethod(samr_connect_methods, self, attrname);
379}
380
381PyTypeObject samr_connect_hnd_type = {
382	PyObject_HEAD_INIT(NULL)
383	0,
384	"SAMR Connect Handle",
385	sizeof(samr_connect_hnd_object),
386	0,
387	py_samr_connect_hnd_dealloc, /*tp_dealloc*/
388	0,          /*tp_print*/
389	py_samr_connect_hnd_getattr,          /*tp_getattr*/
390	0,          /*tp_setattr*/
391	0,          /*tp_compare*/
392	0,          /*tp_repr*/
393	0,          /*tp_as_number*/
394	0,          /*tp_as_sequence*/
395	0,          /*tp_as_mapping*/
396	0,          /*tp_hash */
397};
398
399PyObject *new_samr_connect_hnd_object(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
400				      POLICY_HND *pol)
401{
402	samr_connect_hnd_object *o;
403
404	o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
405
406	o->cli = cli;
407	o->mem_ctx = mem_ctx;
408	memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
409
410	return (PyObject*)o;
411}
412
413/* SAMR domain handle object */
414
415static void py_samr_domain_hnd_dealloc(PyObject* self)
416{
417	PyObject_Del(self);
418}
419
420static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args,
421				      PyObject *kw)
422{
423	samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
424	static char *kwlist[] = { NULL };
425	TALLOC_CTX *mem_ctx;
426/*	uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
427	uint32 start_idx, size, num_dom_groups;
428	struct acct_info *dom_groups;
429	NTSTATUS result;
430	PyObject *py_result = NULL;
431
432	if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
433		return NULL;
434
435	if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
436		PyErr_SetString(samr_error, "unable to init talloc context");
437		return NULL;
438	}
439
440	start_idx = 0;
441	size = 0xffff;
442
443	do {
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);
447
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,
451					  num_dom_groups);
452		}
453
454	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
455
456	return py_result;
457}
458
459static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
460				      PyObject *kw)
461{
462	samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
463	static char *kwlist[] = { "account_name", "acb_info", NULL };
464	char *account_name;
465	NTSTATUS ntstatus;
466	uint32 unknown = 0xe005000b; /* Access mask? */
467	uint32 user_rid;
468	PyObject *result = NULL;
469	TALLOC_CTX *mem_ctx;
470	uint32 acb_info = ACB_NORMAL;
471	POLICY_HND user_pol;
472
473	if (!PyArg_ParseTupleAndKeywords(
474		    args, kw, "s|i", kwlist, &account_name, &acb_info))
475		return NULL;
476
477	if (!(mem_ctx = talloc_init("samr_create_dom_user"))) {
478		PyErr_SetString(samr_error, "unable to init talloc context");
479		return NULL;
480	}
481
482	ntstatus = rpccli_samr_create_dom_user(
483		domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
484		account_name, acb_info, unknown, &user_pol, &user_rid);
485
486	if (!NT_STATUS_IS_OK(ntstatus)) {
487		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
488		talloc_destroy(mem_ctx);
489		goto done;
490	}
491
492	result = new_samr_user_hnd_object(
493		domain_hnd->cli, mem_ctx, &user_pol);
494
495done:
496
497	return result;
498}
499
500static PyMethodDef samr_domain_methods[] = {
501	{ "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
502	  METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
503	{ "create_domain_user", (PyCFunction)samr_create_dom_user,
504	  METH_VARARGS | METH_KEYWORDS, "Create domain user" },
505  	{ NULL }
506};
507
508static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
509{
510	return Py_FindMethod(samr_domain_methods, self, attrname);
511}
512
513PyTypeObject samr_domain_hnd_type = {
514	PyObject_HEAD_INIT(NULL)
515	0,
516	"SAMR Domain Handle",
517	sizeof(samr_domain_hnd_object),
518	0,
519	py_samr_domain_hnd_dealloc, /*tp_dealloc*/
520	0,          /*tp_print*/
521	py_samr_domain_hnd_getattr,          /*tp_getattr*/
522	0,          /*tp_setattr*/
523	0,          /*tp_compare*/
524	0,          /*tp_repr*/
525	0,          /*tp_as_number*/
526	0,          /*tp_as_sequence*/
527	0,          /*tp_as_mapping*/
528	0,          /*tp_hash */
529};
530
531static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
532{
533	static char *kwlist[] = { "server", "creds", "access", NULL };
534	uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
535	char *server, *errstr;
536	struct cli_state *cli = NULL;
537	POLICY_HND hnd;
538	TALLOC_CTX *mem_ctx = NULL;
539	PyObject *result = NULL, *creds = NULL;
540	NTSTATUS ntstatus;
541
542	if (!PyArg_ParseTupleAndKeywords(
543		    args, kw, "s|Oi", kwlist, &server, &creds,
544		    &desired_access))
545		return NULL;
546
547	if (server[0] != '\\' || server[1] != '\\') {
548		PyErr_SetString(PyExc_ValueError, "UNC name required");
549		return NULL;
550	}
551
552	server += 2;
553
554	if (creds && creds != Py_None && !PyDict_Check(creds)) {
555		PyErr_SetString(PyExc_TypeError,
556				"credentials must be dictionary or None");
557		return NULL;
558	}
559
560	if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
561		PyErr_SetString(samr_error, errstr);
562		free(errstr);
563		return NULL;
564	}
565
566	if (!(mem_ctx = talloc_init("samr_connect"))) {
567		PyErr_SetString(samr_ntstatus,
568				"unable to init talloc context\n");
569		goto done;
570	}
571
572	ntstatus = rpccli_samr_connect(cli->pipe_list, mem_ctx, desired_access, &hnd);
573
574	if (!NT_STATUS_IS_OK(ntstatus)) {
575		cli_shutdown(cli);
576		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
577		goto done;
578	}
579
580	result = new_samr_connect_hnd_object(cli->pipe_list, mem_ctx, &hnd);
581
582done:
583	if (!result) {
584		if (cli)
585			cli_shutdown(cli);
586
587		if (mem_ctx)
588			talloc_destroy(mem_ctx);
589	}
590
591	return result;
592}
593
594/*
595 * Module initialisation
596 */
597
598static PyMethodDef samr_methods[] = {
599
600	/* Open/close samr connect handles */
601
602	{ "connect", (PyCFunction)samr_connect,
603	  METH_VARARGS | METH_KEYWORDS,
604	  "Open a connect handle" },
605
606	{ NULL }
607};
608
609static struct const_vals {
610	char *name;
611	uint32 value;
612} module_const_vals[] = {
613
614	/* Account control bits */
615
616	{ "ACB_DISABLED", 0x0001 },
617	{ "ACB_HOMDIRREQ", 0x0002 },
618	{ "ACB_PWNOTREQ", 0x0004 },
619	{ "ACB_TEMPDUP", 0x0008 },
620	{ "ACB_NORMAL", 0x0010 },
621	{ "ACB_MNS", 0x0020 },
622	{ "ACB_DOMTRUST", 0x0040 },
623	{ "ACB_WSTRUST", 0x0080 },
624	{ "ACB_SVRTRUST", 0x0100 },
625	{ "ACB_PWNOEXP", 0x0200 },
626	{ "ACB_AUTOLOCK", 0x0400 },
627
628	{ NULL }
629};
630
631static void const_init(PyObject *dict)
632{
633	struct const_vals *tmp;
634	PyObject *obj;
635
636	for (tmp = module_const_vals; tmp->name; tmp++) {
637		obj = PyInt_FromLong(tmp->value);
638		PyDict_SetItemString(dict, tmp->name, obj);
639		Py_DECREF(obj);
640	}
641}
642
643void initsamr(void)
644{
645	PyObject *module, *dict;
646
647	/* Initialise module */
648
649	module = Py_InitModule("samr", samr_methods);
650	dict = PyModule_GetDict(module);
651
652	samr_error = PyErr_NewException("samr.error", NULL, NULL);
653	PyDict_SetItemString(dict, "error", samr_error);
654
655	samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
656	PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
657
658	/* Initialise policy handle object */
659
660	samr_connect_hnd_type.ob_type = &PyType_Type;
661	samr_domain_hnd_type.ob_type = &PyType_Type;
662	samr_user_hnd_type.ob_type = &PyType_Type;
663	samr_group_hnd_type.ob_type = &PyType_Type;
664	samr_alias_hnd_type.ob_type = &PyType_Type;
665
666	/* Initialise constants */
667
668	const_init(dict);
669
670	/* Do samba initialisation */
671
672	py_samba_init();
673
674	setup_logging("samr", True);
675	DEBUGLEVEL = 10;
676}
677