s3:passdb: Zero password in secrets_{fetch,store}_trusted_domain_password()
[samba.git] / source3 / passdb / py_passdb.c
1 /*
2    Python interface to passdb
3
4    Copyright (C) Amitay Isaacs 2011
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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <Python.h>
21 #include <pytalloc.h>
22 #include "includes.h"
23 #include "python/py3compat.h"
24 #include "lib/util/talloc_stack.h"
25 #include "libcli/security/security.h"
26 #include "librpc/gen_ndr/idmap.h"
27 #include "passdb.h"
28 #include "secrets.h"
29 #include "idmap.h"
30 #include "lib/util/string_wrappers.h"
31
32 #ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */
33 #define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
34 #endif
35
36 #ifndef PY_CHECK_TYPE
37 #define PY_CHECK_TYPE(type, var, fail) \
38         if (!PyObject_TypeCheck(var, type)) {\
39                 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
40                 fail; \
41         }
42 #endif
43
44
45 static PyTypeObject *dom_sid_Type = NULL;
46 static PyTypeObject *security_Type = NULL;
47 static PyTypeObject *guid_Type = NULL;
48
49 static PyTypeObject PySamu;
50 static PyTypeObject PyGroupmap;
51 static PyTypeObject PyPDB;
52
53 static PyObject *py_pdb_error;
54
55 void initpassdb(void);
56
57
58 /************************** PIDL Autogeneratd ******************************/
59
60 static PyObject *py_samu_get_logon_time(PyObject *obj, void *closure)
61 {
62         TALLOC_CTX *frame = talloc_stackframe();
63         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
64         PyObject *py_logon_time;
65
66         py_logon_time = PyLong_FromLong(pdb_get_logon_time(sam_acct));
67         talloc_free(frame);
68         return py_logon_time;
69 }
70
71 static int py_samu_set_logon_time(PyObject *obj, PyObject *value, void *closure)
72 {
73         TALLOC_CTX *frame = talloc_stackframe();
74         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
75
76         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
77         if (!pdb_set_logon_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
78                 talloc_free(frame);
79                 return -1;
80         }
81         talloc_free(frame);
82         return 0;
83 }
84
85 static PyObject *py_samu_get_logoff_time(PyObject *obj, void *closure)
86 {
87         TALLOC_CTX *frame = talloc_stackframe();
88         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
89         PyObject *py_logoff_time;
90
91         py_logoff_time = PyLong_FromLong(pdb_get_logoff_time(sam_acct));
92         talloc_free(frame);
93         return py_logoff_time;
94 }
95
96 static int py_samu_set_logoff_time(PyObject *obj, PyObject *value, void *closure)
97 {
98         TALLOC_CTX *frame = talloc_stackframe();
99         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
100
101         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
102         if (!pdb_set_logoff_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
103                 talloc_free(frame);
104                 return -1;
105         }
106         talloc_free(frame);
107         return 0;
108 }
109
110 static PyObject *py_samu_get_kickoff_time(PyObject *obj, void *closure)
111 {
112         TALLOC_CTX *frame = talloc_stackframe();
113         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
114         PyObject *py_kickoff_time;
115
116         py_kickoff_time = PyLong_FromLong(pdb_get_kickoff_time(sam_acct));
117         talloc_free(frame);
118         return py_kickoff_time;
119 }
120
121 static int py_samu_set_kickoff_time(PyObject *obj, PyObject *value, void *closure)
122 {
123         TALLOC_CTX *frame = talloc_stackframe();
124         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
125
126         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
127         if (!pdb_set_kickoff_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
128                 talloc_free(frame);
129                 return -1;
130         }
131         talloc_free(frame);
132         return 0;
133 }
134
135 static PyObject *py_samu_get_bad_password_time(PyObject *obj, void *closure)
136 {
137         TALLOC_CTX *frame = talloc_stackframe();
138         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
139         PyObject *py_bad_password_time;
140
141         py_bad_password_time = PyLong_FromLong(pdb_get_bad_password_time(sam_acct));
142         talloc_free(frame);
143         return py_bad_password_time;
144 }
145
146 static int py_samu_set_bad_password_time(PyObject *obj, PyObject *value, void *closure)
147 {
148         TALLOC_CTX *frame = talloc_stackframe();
149         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
150
151         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
152         if (!pdb_set_bad_password_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
153                 talloc_free(frame);
154                 return -1;
155         }
156         talloc_free(frame);
157         return 0;
158 }
159
160 static PyObject *py_samu_get_pass_last_set_time(PyObject *obj, void *closure)
161 {
162         TALLOC_CTX *frame = talloc_stackframe();
163         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
164         PyObject *py_pass_last_set_time;
165
166         py_pass_last_set_time = PyLong_FromLong(pdb_get_pass_last_set_time(sam_acct));
167         talloc_free(frame);
168         return py_pass_last_set_time;
169 }
170
171 static int py_samu_set_pass_last_set_time(PyObject *obj, PyObject *value, void *closure)
172 {
173         TALLOC_CTX *frame = talloc_stackframe();
174         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
175
176         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
177         if (!pdb_set_pass_last_set_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
178                 talloc_free(frame);
179                 return -1;
180         }
181         talloc_free(frame);
182         return 0;
183 }
184
185 static PyObject *py_samu_get_pass_can_change_time(PyObject *obj, void *closure)
186 {
187         TALLOC_CTX *frame = talloc_stackframe();
188         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
189         PyObject *py_pass_can_change_time;
190
191         py_pass_can_change_time = PyLong_FromLong(pdb_get_pass_can_change_time(sam_acct));
192         talloc_free(frame);
193         return py_pass_can_change_time;
194 }
195
196 static int py_samu_set_pass_can_change_time(PyObject *obj, PyObject *value, void *closure)
197 {
198         TALLOC_CTX *frame = talloc_stackframe();
199         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
200
201         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
202         if (!pdb_set_pass_can_change_time(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
203                 talloc_free(frame);
204                 return -1;
205         }
206         talloc_free(frame);
207         return 0;
208 }
209
210 static PyObject *py_samu_get_pass_must_change_time(PyObject *obj, void *closure)
211 {
212         TALLOC_CTX *frame = talloc_stackframe();
213         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
214         PyObject *py_pass_must_change_time;
215
216         py_pass_must_change_time = PyLong_FromLong(pdb_get_pass_must_change_time(sam_acct));
217         talloc_free(frame);
218         return py_pass_must_change_time;
219 }
220
221 static int py_samu_set_pass_must_change_time(PyObject *obj, PyObject *value, void *closure)
222 {
223         TALLOC_CTX *frame = talloc_stackframe();
224         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
225
226         /* TODO: make this not a get/set or give a better exception */
227         talloc_free(frame);
228         return -1;
229 }
230
231 static PyObject *py_samu_get_username(PyObject *obj, void *closure)
232 {
233         TALLOC_CTX *frame = talloc_stackframe();
234         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
235         PyObject *py_username;
236         const char *username;
237
238         username = pdb_get_username(sam_acct);
239         if (username == NULL) {
240                 Py_RETURN_NONE;
241         }
242
243         py_username = PyUnicode_FromString(username);
244         talloc_free(frame);
245         return py_username;
246 }
247
248 static int py_samu_set_username(PyObject *obj, PyObject *value, void *closure)
249 {
250         TALLOC_CTX *frame = talloc_stackframe();
251         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
252
253         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
254         if (!pdb_set_username(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
255                 talloc_free(frame);
256                 return -1;
257         }
258         talloc_free(frame);
259         return 0;
260 }
261
262 static PyObject *py_samu_get_domain(PyObject *obj, void *closure)
263 {
264         TALLOC_CTX *frame = talloc_stackframe();
265         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
266         PyObject *py_domain;
267         const char *domain;
268
269         domain = pdb_get_domain(sam_acct);
270         if (domain == NULL) {
271                 Py_RETURN_NONE;
272         }
273
274         py_domain = PyUnicode_FromString(domain);
275         talloc_free(frame);
276         return py_domain;
277 }
278
279 static int py_samu_set_domain(PyObject *obj, PyObject *value, void *closure)
280 {
281         TALLOC_CTX *frame = talloc_stackframe();
282         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
283
284         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
285         if (!pdb_set_domain(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
286                 talloc_free(frame);
287                 return -1;
288         }
289         talloc_free(frame);
290         return 0;
291 }
292
293 static PyObject *py_samu_get_nt_username(PyObject *obj, void *closure)
294 {
295         TALLOC_CTX *frame = talloc_stackframe();
296         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
297         PyObject *py_nt_username;
298         const char *nt_username;
299
300         nt_username = pdb_get_nt_username(sam_acct);
301         if (nt_username == NULL) {
302                 Py_RETURN_NONE;
303         }
304
305         py_nt_username = PyUnicode_FromString(nt_username);
306         talloc_free(frame);
307         return py_nt_username;
308 }
309
310 static int py_samu_set_nt_username(PyObject *obj, PyObject *value, void *closure)
311 {
312         TALLOC_CTX *frame = talloc_stackframe();
313         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
314
315         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
316         if (!pdb_set_nt_username(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
317                 talloc_free(frame);
318                 return -1;
319         }
320         talloc_free(frame);
321         return 0;
322 }
323
324 static PyObject *py_samu_get_full_name(PyObject *obj, void *closure)
325 {
326         TALLOC_CTX *frame = talloc_stackframe();
327         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
328         PyObject *py_full_name;
329         const char *full_name;
330
331         full_name = pdb_get_fullname(sam_acct);
332         if (full_name == NULL) {
333                 Py_RETURN_NONE;
334         }
335
336         py_full_name = PyUnicode_FromString(full_name);
337         talloc_free(frame);
338         return py_full_name;
339 }
340
341 static int py_samu_set_full_name(PyObject *obj, PyObject *value, void *closure)
342 {
343         TALLOC_CTX *frame = talloc_stackframe();
344         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
345
346         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
347         if (!pdb_set_fullname(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
348                 talloc_free(frame);
349                 return -1;
350         }
351         talloc_free(frame);
352         return 0;
353 }
354
355 static PyObject *py_samu_get_home_dir(PyObject *obj, void *closure)
356 {
357         TALLOC_CTX *frame = talloc_stackframe();
358         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
359         PyObject *py_home_dir;
360         const char *home_dir;
361
362         home_dir = pdb_get_homedir(sam_acct);
363         if (home_dir == NULL) {
364                 Py_RETURN_NONE;
365         }
366
367         py_home_dir = PyUnicode_FromString(home_dir);
368         talloc_free(frame);
369         return py_home_dir;
370 }
371
372 static int py_samu_set_home_dir(PyObject *obj, PyObject *value, void *closure)
373 {
374         TALLOC_CTX *frame = talloc_stackframe();
375         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
376
377         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
378         if (!pdb_set_homedir(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
379                 talloc_free(frame);
380                 return -1;
381         }
382         talloc_free(frame);
383         return 0;
384 }
385
386 static PyObject *py_samu_get_dir_drive(PyObject *obj, void *closure)
387 {
388         TALLOC_CTX *frame = talloc_stackframe();
389         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
390         PyObject *py_dir_drive;
391         const char *dir_drive;
392
393         dir_drive = pdb_get_dir_drive(sam_acct);
394         if (dir_drive == NULL) {
395                 Py_RETURN_NONE;
396         }
397
398         py_dir_drive = PyUnicode_FromString(dir_drive);
399         talloc_free(frame);
400         return py_dir_drive;
401 }
402
403 static int py_samu_set_dir_drive(PyObject *obj, PyObject *value, void *closure)
404 {
405         TALLOC_CTX *frame = talloc_stackframe();
406         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
407
408         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
409         if (!pdb_set_dir_drive(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
410                 talloc_free(frame);
411                 return -1;
412         }
413         talloc_free(frame);
414         return 0;
415 }
416
417 static PyObject *py_samu_get_logon_script(PyObject *obj, void *closure)
418 {
419         TALLOC_CTX *frame = talloc_stackframe();
420         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
421         PyObject *py_logon_script;
422         const char *logon_script;
423
424         logon_script = pdb_get_logon_script(sam_acct);
425         if (logon_script == NULL) {
426                 Py_RETURN_NONE;
427         }
428
429         py_logon_script = PyUnicode_FromString(logon_script);
430         talloc_free(frame);
431         return py_logon_script;
432 }
433
434 static int py_samu_set_logon_script(PyObject *obj, PyObject *value, void *closure)
435 {
436         TALLOC_CTX *frame = talloc_stackframe();
437         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
438
439         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
440         if (!pdb_set_logon_script(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
441                 talloc_free(frame);
442                 return -1;
443         }
444         talloc_free(frame);
445         return 0;
446 }
447
448 static PyObject *py_samu_get_profile_path(PyObject *obj, void *closure)
449 {
450         TALLOC_CTX *frame = talloc_stackframe();
451         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
452         PyObject *py_profile_path;
453         const char *profile_path;
454
455         profile_path = pdb_get_profile_path(sam_acct);
456         if (profile_path == NULL) {
457                 Py_RETURN_NONE;
458         }
459
460         py_profile_path = PyUnicode_FromString(profile_path);
461         talloc_free(frame);
462         return py_profile_path;
463 }
464
465 static int py_samu_set_profile_path(PyObject *obj, PyObject *value, void *closure)
466 {
467         TALLOC_CTX *frame = talloc_stackframe();
468         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
469
470         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
471         if (!pdb_set_profile_path(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
472                 talloc_free(frame);
473                 return -1;
474         }
475         talloc_free(frame);
476         return 0;
477 }
478
479 static PyObject *py_samu_get_acct_desc(PyObject *obj, void *closure)
480 {
481         TALLOC_CTX *frame = talloc_stackframe();
482         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
483         PyObject *py_acct_desc;
484         const char *acct_desc;
485
486         acct_desc = pdb_get_acct_desc(sam_acct);
487         if (acct_desc == NULL) {
488                 Py_RETURN_NONE;
489         }
490
491         py_acct_desc = PyUnicode_FromString(acct_desc);
492         talloc_free(frame);
493         return py_acct_desc;
494 }
495
496 static int py_samu_set_acct_desc(PyObject *obj, PyObject *value, void *closure)
497 {
498         TALLOC_CTX *frame = talloc_stackframe();
499         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
500
501         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
502         if (!pdb_set_acct_desc(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
503                 talloc_free(frame);
504                 return -1;
505         }
506         talloc_free(frame);
507         return 0;
508 }
509
510 static PyObject *py_samu_get_workstations(PyObject *obj, void *closure)
511 {
512         TALLOC_CTX *frame = talloc_stackframe();
513         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
514         PyObject *py_workstations;
515         const char *workstations;
516
517         workstations = pdb_get_workstations(sam_acct);
518         if (workstations == NULL) {
519                 Py_RETURN_NONE;
520         }
521
522         py_workstations = PyUnicode_FromString(workstations);
523         talloc_free(frame);
524         return py_workstations;
525 }
526
527 static int py_samu_set_workstations(PyObject *obj, PyObject *value, void *closure)
528 {
529         TALLOC_CTX *frame = talloc_stackframe();
530         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
531
532         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
533         if (!pdb_set_workstations(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
534                 talloc_free(frame);
535                 return -1;
536         }
537         talloc_free(frame);
538         return 0;
539 }
540
541 static PyObject *py_samu_get_comment(PyObject *obj, void *closure)
542 {
543         TALLOC_CTX *frame = talloc_stackframe();
544         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
545         PyObject *py_comment;
546         const char *comment;
547
548         comment = pdb_get_comment(sam_acct);
549         if (comment == NULL) {
550                 Py_RETURN_NONE;
551         }
552
553         py_comment = PyUnicode_FromString(comment);
554         talloc_free(frame);
555         return py_comment;
556 }
557
558 static int py_samu_set_comment(PyObject *obj, PyObject *value, void *closure)
559 {
560         TALLOC_CTX *frame = talloc_stackframe();
561         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
562
563         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
564         if (!pdb_set_comment(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
565                 talloc_free(frame);
566                 return -1;
567         }
568         talloc_free(frame);
569         return 0;
570 }
571
572 static PyObject *py_samu_get_munged_dial(PyObject *obj, void *closure)
573 {
574         TALLOC_CTX *frame = talloc_stackframe();
575         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
576         PyObject *py_munged_dial;
577         const char *munged_dial;
578
579         munged_dial = pdb_get_munged_dial(sam_acct);
580         if (munged_dial == NULL) {
581                 Py_RETURN_NONE;
582         }
583
584         py_munged_dial = PyUnicode_FromString(munged_dial);
585         talloc_free(frame);
586         return py_munged_dial;
587 }
588
589 static int py_samu_set_munged_dial(PyObject *obj, PyObject *value, void *closure)
590 {
591         TALLOC_CTX *frame = talloc_stackframe();
592         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
593
594         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
595         if (!pdb_set_munged_dial(sam_acct, PyUnicode_AsUTF8(value), PDB_CHANGED)) {
596                 talloc_free(frame);
597                 return -1;
598         }
599         talloc_free(frame);
600         return 0;
601 }
602
603 static PyObject *py_samu_get_user_sid(PyObject *obj, void *closure)
604 {
605         TALLOC_CTX *frame = talloc_stackframe();
606         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
607         PyObject *py_user_sid;
608         const struct dom_sid *user_sid;
609         struct dom_sid *copy_user_sid;
610         TALLOC_CTX *mem_ctx;
611
612         user_sid = pdb_get_user_sid(sam_acct);
613         if(user_sid == NULL) {
614                 Py_RETURN_NONE;
615         }
616
617         mem_ctx = talloc_new(NULL);
618         if (mem_ctx == NULL) {
619                 PyErr_NoMemory();
620                 talloc_free(frame);
621                 return NULL;
622         }
623         copy_user_sid = dom_sid_dup(mem_ctx, user_sid);
624         if (copy_user_sid == NULL) {
625                 PyErr_NoMemory();
626                 talloc_free(mem_ctx);
627                 talloc_free(frame);
628                 return NULL;
629         }
630
631         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
632
633         talloc_free(mem_ctx);
634
635         talloc_free(frame);
636         return py_user_sid;
637 }
638
639 static int py_samu_set_user_sid(PyObject *obj, PyObject *value, void *closure)
640 {
641         TALLOC_CTX *frame = talloc_stackframe();
642         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
643
644         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
645         if (!pdb_set_user_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
646                 talloc_free(frame);
647                 return -1;
648         }
649         talloc_free(frame);
650         return 0;
651 }
652
653 static PyObject *py_samu_get_group_sid(PyObject *obj, void *closure)
654 {
655         TALLOC_CTX *frame = talloc_stackframe();
656         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
657         const struct dom_sid *group_sid;
658         struct dom_sid *copy_group_sid;
659
660         group_sid = pdb_get_group_sid(sam_acct);
661         if (group_sid == NULL) {
662                 Py_RETURN_NONE;
663         }
664
665         copy_group_sid = dom_sid_dup(NULL, group_sid);
666         if (copy_group_sid == NULL) {
667                 PyErr_NoMemory();
668                 talloc_free(frame);
669                 return NULL;
670         }
671
672         talloc_free(frame);
673         return pytalloc_steal(dom_sid_Type, copy_group_sid);
674 }
675
676 static int py_samu_set_group_sid(PyObject *obj, PyObject *value, void *closure)
677 {
678         TALLOC_CTX *frame = talloc_stackframe();
679         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
680
681         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
682         if (!pdb_set_group_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
683                 talloc_free(frame);
684                 return -1;
685         }
686         talloc_free(frame);
687         return 0;
688 }
689
690 static PyObject *py_samu_get_lanman_passwd(PyObject *obj, void *closure)
691 {
692         TALLOC_CTX *frame = talloc_stackframe();
693         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
694         PyObject *py_lm_pw;
695         const char *lm_pw;
696
697         lm_pw = (const char *)pdb_get_lanman_passwd(sam_acct);
698         if (lm_pw == NULL) {
699                 Py_RETURN_NONE;
700         }
701
702         py_lm_pw = PyBytes_FromStringAndSize(lm_pw, LM_HASH_LEN);
703         talloc_free(frame);
704         return py_lm_pw;
705 }
706
707 static int py_samu_set_lanman_passwd(PyObject *obj, PyObject *value, void *closure)
708 {
709         TALLOC_CTX *frame = talloc_stackframe();
710         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
711
712         PY_CHECK_TYPE(&PyBytes_Type, value, return -1;);
713         if (!pdb_set_lanman_passwd(sam_acct, (uint8_t *)PyBytes_AsString(value), PDB_CHANGED)) {
714                 talloc_free(frame);
715                 return -1;
716         }
717         talloc_free(frame);
718         return 0;
719 }
720
721 static PyObject *py_samu_get_nt_passwd(PyObject *obj, void *closure)
722 {
723         TALLOC_CTX *frame = talloc_stackframe();
724         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
725         PyObject *py_nt_pw;
726         const char *nt_pw;
727
728         nt_pw = (const char *)pdb_get_nt_passwd(sam_acct);
729         if (nt_pw == NULL) {
730                 Py_RETURN_NONE;
731         }
732
733         py_nt_pw = PyBytes_FromStringAndSize(nt_pw, NT_HASH_LEN);
734         talloc_free(frame);
735         return py_nt_pw;
736 }
737
738 static int py_samu_set_nt_passwd(PyObject *obj, PyObject *value, void *closure)
739 {
740         TALLOC_CTX *frame = talloc_stackframe();
741         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
742
743         if (!pdb_set_nt_passwd(sam_acct, (uint8_t *)PyBytes_AsString(value), PDB_CHANGED)) {
744                 talloc_free(frame);
745                 return -1;
746         }
747         talloc_free(frame);
748         return 0;
749 }
750
751 static PyObject *py_samu_get_pw_history(PyObject *obj, void *closure)
752 {
753         TALLOC_CTX *frame = talloc_stackframe();
754         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
755         PyObject *py_nt_pw_his;
756         const char *nt_pw_his;
757         uint32_t hist_len;
758
759         nt_pw_his = (const char *)pdb_get_pw_history(sam_acct, &hist_len);
760         if (nt_pw_his == NULL) {
761                 Py_RETURN_NONE;
762         }
763
764         py_nt_pw_his = PyBytes_FromStringAndSize(nt_pw_his, hist_len*PW_HISTORY_ENTRY_LEN);
765         talloc_free(frame);
766         return py_nt_pw_his;
767 }
768
769 static int py_samu_set_pw_history(PyObject *obj, PyObject *value, void *closure)
770 {
771         TALLOC_CTX *frame = talloc_stackframe();
772         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
773         char *nt_pw_his;
774         Py_ssize_t len;
775         uint32_t hist_len;
776
777         PyBytes_AsStringAndSize(value, &nt_pw_his, &len);
778         hist_len = len / PW_HISTORY_ENTRY_LEN;
779         if (!pdb_set_pw_history(sam_acct, (uint8_t *)nt_pw_his, hist_len, PDB_CHANGED)) {
780                 talloc_free(frame);
781                 return -1;
782         }
783         talloc_free(frame);
784         return 0;
785 }
786
787 static PyObject *py_samu_get_plaintext_passwd(PyObject *obj, void *closure)
788 {
789         TALLOC_CTX *frame = talloc_stackframe();
790         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
791         PyObject *py_plaintext_pw;
792         const char *plaintext_pw;
793
794         plaintext_pw = pdb_get_plaintext_passwd(sam_acct);
795         if (plaintext_pw == NULL) {
796                 Py_RETURN_NONE;
797         }
798
799         py_plaintext_pw = PyUnicode_FromString(plaintext_pw);
800         talloc_free(frame);
801         return py_plaintext_pw;
802 }
803
804 static int py_samu_set_plaintext_passwd(PyObject *obj, PyObject *value, void *closure)
805 {
806         TALLOC_CTX *frame = talloc_stackframe();
807         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
808
809         if (!pdb_set_plaintext_passwd(sam_acct, PyUnicode_AsUTF8(value))) {
810                 talloc_free(frame);
811                 return -1;
812         }
813         talloc_free(frame);
814         return 0;
815 }
816
817 static PyObject *py_samu_get_acct_ctrl(PyObject *obj, void *closure)
818 {
819         TALLOC_CTX *frame = talloc_stackframe();
820         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
821         PyObject *py_acct_ctrl;
822
823         py_acct_ctrl = PyLong_FromLong(pdb_get_acct_ctrl(sam_acct));
824         talloc_free(frame);
825         return py_acct_ctrl;
826 }
827
828 static int py_samu_set_acct_ctrl(PyObject *obj, PyObject *value, void *closure)
829 {
830         TALLOC_CTX *frame = talloc_stackframe();
831         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
832
833         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
834         if (!pdb_set_acct_ctrl(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
835                 talloc_free(frame);
836                 return -1;
837         }
838         talloc_free(frame);
839         return 0;
840 }
841
842 static PyObject *py_samu_get_logon_divs(PyObject *obj, void *closure)
843 {
844         TALLOC_CTX *frame = talloc_stackframe();
845         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
846         PyObject *py_logon_divs;
847
848         py_logon_divs = PyLong_FromLong(pdb_get_logon_divs(sam_acct));
849         talloc_free(frame);
850         return py_logon_divs;
851 }
852
853 static int py_samu_set_logon_divs(PyObject *obj, PyObject *value, void *closure)
854 {
855         TALLOC_CTX *frame = talloc_stackframe();
856         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
857
858         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
859         if (!pdb_set_logon_divs(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
860                 talloc_free(frame);
861                 return -1;
862         }
863         talloc_free(frame);
864         return 0;
865 }
866
867 static PyObject *py_samu_get_hours_len(PyObject *obj, void *closure)
868 {
869         TALLOC_CTX *frame = talloc_stackframe();
870         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
871         PyObject *py_hours_len;
872
873         py_hours_len = PyLong_FromLong(pdb_get_hours_len(sam_acct));
874         talloc_free(frame);
875         return py_hours_len;
876 }
877
878 static int py_samu_set_hours_len(PyObject *obj, PyObject *value, void *closure)
879 {
880         TALLOC_CTX *frame = talloc_stackframe();
881         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
882
883         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
884         if (!pdb_set_hours_len(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
885                 talloc_free(frame);
886                 return -1;
887         }
888         talloc_free(frame);
889         return 0;
890 }
891
892 static PyObject *py_samu_get_hours(PyObject *obj, void *closure)
893 {
894         TALLOC_CTX *frame = talloc_stackframe();
895         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
896         PyObject *py_hours;
897         const char *hours;
898         int hours_len, i;
899
900         hours = (const char *)pdb_get_hours(sam_acct);
901         if(! hours) {
902                 Py_RETURN_NONE;
903         }
904
905         hours_len = pdb_get_hours_len(sam_acct);
906         if ((py_hours = PyList_New(hours_len)) == NULL) {
907                 PyErr_NoMemory();
908                 talloc_free(frame);
909                 return NULL;
910         }
911
912         for (i=0; i<hours_len; i++) {
913                 PyList_SetItem(py_hours, i, PyLong_FromLong(hours[i]));
914         }
915         talloc_free(frame);
916         return py_hours;
917 }
918
919 static int py_samu_set_hours(PyObject *obj, PyObject *value, void *closure)
920 {
921         TALLOC_CTX *frame = talloc_stackframe();
922         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
923         int i;
924         uint8_t *hours;
925         int hours_len;
926         bool status;
927
928         PY_CHECK_TYPE(&PyList_Type, value, return -1;);
929
930         hours_len = PyList_GET_SIZE(value);
931
932         hours = talloc_array(pytalloc_get_mem_ctx(obj), uint8_t, hours_len);
933         if (!hours) {
934                 PyErr_NoMemory();
935                 talloc_free(frame);
936                 return -1;
937         }
938
939         for (i=0; i < hours_len; i++) {
940                 PY_CHECK_TYPE(&PyLong_Type, PyList_GET_ITEM(value,i), return -1;);
941                 hours[i] = PyLong_AsLong(PyList_GET_ITEM(value, i));
942         }
943
944         status = pdb_set_hours(sam_acct, hours, hours_len, PDB_CHANGED);
945         talloc_free(hours);
946
947         if(! status) {
948                 talloc_free(frame);
949                 return -1;
950         }
951         talloc_free(frame);
952         return 0;
953 }
954
955 static PyObject *py_samu_get_bad_password_count(PyObject *obj, void *closure)
956 {
957         TALLOC_CTX *frame = talloc_stackframe();
958         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
959         PyObject *py_bad_password_count;
960
961         py_bad_password_count = PyLong_FromLong(pdb_get_bad_password_count(sam_acct));
962         talloc_free(frame);
963         return py_bad_password_count;
964 }
965
966 static int py_samu_set_bad_password_count(PyObject *obj, PyObject *value, void *closure)
967 {
968         TALLOC_CTX *frame = talloc_stackframe();
969         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
970
971         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
972         if (!pdb_set_bad_password_count(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
973                 talloc_free(frame);
974                 return -1;
975         }
976         talloc_free(frame);
977         return 0;
978 }
979
980 static PyObject *py_samu_get_logon_count(PyObject *obj, void *closure)
981 {
982         TALLOC_CTX *frame = talloc_stackframe();
983         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
984         PyObject *py_logon_count;
985
986         py_logon_count = PyLong_FromLong(pdb_get_logon_count(sam_acct));
987         talloc_free(frame);
988         return py_logon_count;
989 }
990
991 static int py_samu_set_logon_count(PyObject *obj, PyObject *value, void *closure)
992 {
993         TALLOC_CTX *frame = talloc_stackframe();
994         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
995
996         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
997         if (!pdb_set_logon_count(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
998                 talloc_free(frame);
999                 return -1;
1000         }
1001         talloc_free(frame);
1002         return 0;
1003 }
1004
1005 static PyObject *py_samu_get_country_code(PyObject *obj, void *closure)
1006 {
1007         TALLOC_CTX *frame = talloc_stackframe();
1008         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1009         PyObject *py_country_code;
1010
1011         py_country_code = PyLong_FromLong(pdb_get_country_code(sam_acct));
1012         talloc_free(frame);
1013         return py_country_code;
1014 }
1015
1016 static int py_samu_set_country_code(PyObject *obj, PyObject *value, void *closure)
1017 {
1018         TALLOC_CTX *frame = talloc_stackframe();
1019         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1020
1021         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
1022         if (!pdb_set_country_code(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
1023                 talloc_free(frame);
1024                 return -1;
1025         }
1026         talloc_free(frame);
1027         return 0;
1028 }
1029
1030 static PyObject *py_samu_get_code_page(PyObject *obj, void *closure)
1031 {
1032         TALLOC_CTX *frame = talloc_stackframe();
1033         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1034         PyObject *py_code_page;
1035
1036         py_code_page = PyLong_FromLong(pdb_get_code_page(sam_acct));
1037         talloc_free(frame);
1038         return py_code_page;
1039 }
1040
1041 static int py_samu_set_code_page(PyObject *obj, PyObject *value, void *closure)
1042 {
1043         TALLOC_CTX *frame = talloc_stackframe();
1044         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
1045
1046         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
1047         if (!pdb_set_code_page(sam_acct, PyLong_AsLong(value), PDB_CHANGED)) {
1048                 talloc_free(frame);
1049                 return -1;
1050         }
1051         talloc_free(frame);
1052         return 0;
1053 }
1054
1055 static PyGetSetDef py_samu_getsetters[] = {
1056         {
1057                 .name = discard_const_p(char, "logon_time"),
1058                 .get  = py_samu_get_logon_time,
1059                 .set  = py_samu_set_logon_time,
1060         },
1061         {
1062                 .name = discard_const_p(char, "logoff_time"),
1063                 .get  = py_samu_get_logoff_time,
1064                 .set  = py_samu_set_logoff_time,
1065         },
1066         {
1067                 .name = discard_const_p(char, "kickoff_time"),
1068                 .get  = py_samu_get_kickoff_time,
1069                 .set  = py_samu_set_kickoff_time,
1070         },
1071         {
1072                 .name = discard_const_p(char, "bad_password_time"),
1073                 .get  = py_samu_get_bad_password_time,
1074                 .set  = py_samu_set_bad_password_time,
1075         },
1076         {
1077                 .name = discard_const_p(char, "pass_last_set_time"),
1078                 .get  = py_samu_get_pass_last_set_time,
1079                 .set  = py_samu_set_pass_last_set_time,
1080         },
1081         {
1082                 .name = discard_const_p(char, "pass_can_change_time"),
1083                 .get  = py_samu_get_pass_can_change_time,
1084                 .set  = py_samu_set_pass_can_change_time,
1085         },
1086         {
1087                 .name = discard_const_p(char, "pass_must_change_time"),
1088                 .get  = py_samu_get_pass_must_change_time,
1089                 .set  = py_samu_set_pass_must_change_time,
1090         },
1091         {
1092                 .name = discard_const_p(char, "username"),
1093                 .get  = py_samu_get_username,
1094                 .set  = py_samu_set_username,
1095         },
1096         {
1097                 .name = discard_const_p(char, "domain"),
1098                 .get  = py_samu_get_domain,
1099                 .set  = py_samu_set_domain,
1100         },
1101         {
1102                 .name = discard_const_p(char, "nt_username"),
1103                 .get  = py_samu_get_nt_username,
1104                 .set  = py_samu_set_nt_username,
1105         },
1106         {
1107                 .name = discard_const_p(char, "full_name"),
1108                 .get  = py_samu_get_full_name,
1109                 .set  = py_samu_set_full_name,
1110         },
1111         {
1112                 .name = discard_const_p(char, "home_dir"),
1113                 .get  = py_samu_get_home_dir,
1114                 .set  = py_samu_set_home_dir,
1115         },
1116         {
1117                 .name = discard_const_p(char, "dir_drive"),
1118                 .get  = py_samu_get_dir_drive,
1119                 .set  = py_samu_set_dir_drive,
1120         },
1121         {
1122                 .name = discard_const_p(char, "logon_script"),
1123                 .get  = py_samu_get_logon_script,
1124                 .set  = py_samu_set_logon_script,
1125         },
1126         {
1127                 .name = discard_const_p(char, "profile_path"),
1128                 .get  = py_samu_get_profile_path,
1129                 .set  = py_samu_set_profile_path,
1130         },
1131         {
1132                 .name = discard_const_p(char, "acct_desc"),
1133                 .get  = py_samu_get_acct_desc,
1134                 .set  = py_samu_set_acct_desc,
1135         },
1136         {
1137                 .name = discard_const_p(char, "workstations"),
1138                 .get  = py_samu_get_workstations,
1139                 .set  = py_samu_set_workstations,
1140         },
1141         {
1142                 .name = discard_const_p(char, "comment"),
1143                 .get  = py_samu_get_comment,
1144                 .set  = py_samu_set_comment,
1145         },
1146         {
1147                 .name = discard_const_p(char, "munged_dial"),
1148                 .get  = py_samu_get_munged_dial,
1149                 .set  = py_samu_set_munged_dial,
1150         },
1151         {
1152                 .name = discard_const_p(char, "user_sid"),
1153                 .get  = py_samu_get_user_sid,
1154                 .set  = py_samu_set_user_sid,
1155         },
1156         {
1157                 .name = discard_const_p(char, "group_sid"),
1158                 .get  = py_samu_get_group_sid,
1159                 .set  = py_samu_set_group_sid,
1160         },
1161         {
1162                 .name = discard_const_p(char, "lanman_passwd"),
1163                 .get  = py_samu_get_lanman_passwd,
1164                 .set  = py_samu_set_lanman_passwd,
1165         },
1166         {
1167                 .name = discard_const_p(char, "nt_passwd"),
1168                 .get  = py_samu_get_nt_passwd,
1169                 .set  = py_samu_set_nt_passwd,
1170         },
1171         {
1172                 .name = discard_const_p(char, "pw_history"),
1173                 .get  = py_samu_get_pw_history,
1174                 .set  = py_samu_set_pw_history,
1175         },
1176         {
1177                 .name = discard_const_p(char, "plaintext_passwd"),
1178                 .get  = py_samu_get_plaintext_passwd,
1179                 .set  = py_samu_set_plaintext_passwd,
1180         },
1181         {
1182                 .name = discard_const_p(char, "acct_ctrl"),
1183                 .get  = py_samu_get_acct_ctrl,
1184                 .set  = py_samu_set_acct_ctrl,
1185         },
1186         {
1187                 .name = discard_const_p(char, "logon_divs"),
1188                 .get  = py_samu_get_logon_divs,
1189                 .set  = py_samu_set_logon_divs,
1190         },
1191         {
1192                 .name = discard_const_p(char, "hours_len"),
1193                 .get  = py_samu_get_hours_len,
1194                 .set  = py_samu_set_hours_len,
1195         },
1196         {
1197                 .name = discard_const_p(char, "hours"),
1198                 .get  = py_samu_get_hours,
1199                 .set  = py_samu_set_hours,
1200         },
1201         {
1202                 .name = discard_const_p(char, "bad_password_count"),
1203                 .get  = py_samu_get_bad_password_count,
1204                 .set  = py_samu_set_bad_password_count,
1205         },
1206         {
1207                 .name = discard_const_p(char, "logon_count"),
1208                 .get  = py_samu_get_logon_count,
1209                 .set  = py_samu_set_logon_count,
1210         },
1211         {
1212                 .name = discard_const_p(char, "country_code"),
1213                 .get  = py_samu_get_country_code,
1214                 .set  = py_samu_set_country_code,
1215         },
1216         {
1217                 .name = discard_const_p(char, "code_page"),
1218                 .get  = py_samu_get_code_page,
1219                 .set  = py_samu_set_code_page,
1220         },
1221         {
1222                 .name = NULL,
1223         }
1224 };
1225
1226
1227 /************************** PIDL Autogeneratd ******************************/
1228
1229 static PyObject *py_samu_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1230 {
1231         TALLOC_CTX *frame = talloc_stackframe();
1232         struct samu *sam_acct;
1233
1234         sam_acct = samu_new(NULL);
1235         if (!sam_acct) {
1236                 PyErr_NoMemory();
1237                 talloc_free(frame);
1238                 return NULL;
1239         }
1240
1241         talloc_free(frame);
1242         return pytalloc_steal(type, sam_acct);
1243 }
1244
1245 static PyTypeObject PySamu = {
1246         .tp_name = "passdb.Samu",
1247         .tp_getset = py_samu_getsetters,
1248         .tp_methods = NULL,
1249         .tp_new = py_samu_new,
1250         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1251         .tp_doc = "Samu() -> samu object\n",
1252 };
1253
1254
1255 static PyObject *py_groupmap_get_gid(PyObject *obj, void *closure)
1256 {
1257         TALLOC_CTX *frame = talloc_stackframe();
1258         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1259         PyObject *py_gid;
1260
1261         py_gid = Py_BuildValue("i", group_map->gid);
1262         talloc_free(frame);
1263         return py_gid;
1264 }
1265
1266 static int py_groupmap_set_gid(PyObject *obj, PyObject *value, void *closure)
1267 {
1268         TALLOC_CTX *frame = talloc_stackframe();
1269         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1270
1271         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
1272         group_map->gid = PyLong_AsLong(value);
1273         talloc_free(frame);
1274         return 0;
1275 }
1276
1277 static PyObject *py_groupmap_get_sid(PyObject *obj, void *closure)
1278 {
1279         TALLOC_CTX *frame = talloc_stackframe();
1280         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1281         PyObject *py_sid;
1282         struct dom_sid *group_sid;
1283         TALLOC_CTX *mem_ctx;
1284
1285         mem_ctx = talloc_new(NULL);
1286         if (mem_ctx == NULL) {
1287                 PyErr_NoMemory();
1288                 talloc_free(frame);
1289                 return NULL;
1290         }
1291
1292         group_sid = dom_sid_dup(mem_ctx, &group_map->sid);
1293         if (group_sid == NULL) {
1294                 PyErr_NoMemory();
1295                 talloc_free(mem_ctx);
1296                 talloc_free(frame);
1297                 return NULL;
1298         }
1299
1300         py_sid = pytalloc_steal(dom_sid_Type, group_sid);
1301
1302         talloc_free(mem_ctx);
1303
1304         talloc_free(frame);
1305         return py_sid;
1306 }
1307
1308 static int py_groupmap_set_sid(PyObject *obj, PyObject *value, void *closure)
1309 {
1310         TALLOC_CTX *frame = talloc_stackframe();
1311         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1312
1313         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
1314         group_map->sid = *pytalloc_get_type(value, struct dom_sid);
1315         talloc_free(frame);
1316         return 0;
1317 }
1318
1319 static PyObject *py_groupmap_get_sid_name_use(PyObject *obj, void *closure)
1320 {
1321         TALLOC_CTX *frame = talloc_stackframe();
1322         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1323         PyObject *py_sid_name_use;
1324
1325         py_sid_name_use = PyLong_FromLong(group_map->sid_name_use);
1326         talloc_free(frame);
1327         return py_sid_name_use;
1328 }
1329
1330 static int py_groupmap_set_sid_name_use(PyObject *obj, PyObject *value, void *closure)
1331 {
1332         TALLOC_CTX *frame = talloc_stackframe();
1333         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1334
1335         PY_CHECK_TYPE(&PyLong_Type, value, return -1;);
1336         group_map->sid_name_use = PyLong_AsLong(value);
1337         talloc_free(frame);
1338         return 0;
1339 }
1340
1341 static PyObject *py_groupmap_get_nt_name(PyObject *obj, void *closure)
1342 {
1343         TALLOC_CTX *frame = talloc_stackframe();
1344         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1345         PyObject *py_nt_name;
1346         if (group_map->nt_name == NULL) {
1347                 py_nt_name = Py_None;
1348                 Py_INCREF(py_nt_name);
1349         } else {
1350                 py_nt_name = PyUnicode_FromString(group_map->nt_name);
1351         }
1352         talloc_free(frame);
1353         return py_nt_name;
1354 }
1355
1356 static int py_groupmap_set_nt_name(PyObject *obj, PyObject *value, void *closure)
1357 {
1358         TALLOC_CTX *frame = talloc_stackframe();
1359         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1360
1361         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
1362         if (group_map->nt_name != NULL) {
1363                 TALLOC_FREE(group_map->nt_name);
1364         }
1365         if (value == Py_None) {
1366                 group_map->nt_name = talloc_strdup(group_map, "");
1367         } else {
1368                 group_map->nt_name = talloc_strdup(group_map,
1369                                                    PyUnicode_AsUTF8(value));
1370         }
1371         TALLOC_FREE(frame);
1372         if (group_map->nt_name == NULL) {
1373                 return -1;
1374         }
1375         return 0;
1376 }
1377
1378 static PyObject *py_groupmap_get_comment(PyObject *obj, void *closure)
1379 {
1380         TALLOC_CTX *frame = talloc_stackframe();
1381         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1382         PyObject *py_comment;
1383         if (group_map->comment == NULL) {
1384                 py_comment = Py_None;
1385                 Py_INCREF(py_comment);
1386         } else {
1387                 py_comment = PyUnicode_FromString(group_map->comment);
1388         }
1389         talloc_free(frame);
1390         return py_comment;
1391 }
1392
1393 static int py_groupmap_set_comment(PyObject *obj, PyObject *value, void *closure)
1394 {
1395         TALLOC_CTX *frame = talloc_stackframe();
1396         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1397
1398         PY_CHECK_TYPE(&PyUnicode_Type, value, return -1;);
1399         if (group_map->comment != NULL) {
1400                 TALLOC_FREE(group_map->comment);
1401         }
1402         if (value == Py_None) {
1403                 group_map->comment = talloc_strdup(group_map, "");
1404         } else {
1405                 group_map->comment = talloc_strdup(group_map,
1406                                                    PyUnicode_AsUTF8(value));
1407         }
1408         TALLOC_FREE(frame);
1409         if (group_map->comment == NULL) {
1410                 return -1;
1411         }
1412         return 0;
1413 }
1414
1415 static PyGetSetDef py_groupmap_getsetters[] = {
1416         {
1417                 .name = discard_const_p(char, "gid"),
1418                 .get  = py_groupmap_get_gid,
1419                 .set  = py_groupmap_set_gid,
1420         },
1421         {
1422                 .name = discard_const_p(char, "sid"),
1423                 .get  = py_groupmap_get_sid,
1424                 .set  = py_groupmap_set_sid,
1425         },
1426         {
1427                 .name = discard_const_p(char, "sid_name_use"),
1428                 .get  = py_groupmap_get_sid_name_use,
1429                 .set  = py_groupmap_set_sid_name_use,
1430         },
1431         {
1432                 .name = discard_const_p(char, "nt_name"),
1433                 .get  = py_groupmap_get_nt_name,
1434                 .set  = py_groupmap_set_nt_name,
1435         },
1436         {
1437                 .name = discard_const_p(char, "comment"),
1438                 .get  = py_groupmap_get_comment,
1439                 .set  = py_groupmap_set_comment,
1440         },
1441         {
1442                 .name = NULL,
1443         },
1444 };
1445
1446 static PyObject *py_groupmap_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1447 {
1448         TALLOC_CTX *frame = talloc_stackframe();
1449         GROUP_MAP *group_map;
1450         TALLOC_CTX *mem_ctx;
1451         PyObject *py_group_map;
1452
1453         mem_ctx = talloc_new(NULL);
1454         if (mem_ctx == NULL) {
1455                 PyErr_NoMemory();
1456                 talloc_free(frame);
1457                 return NULL;
1458         }
1459
1460         group_map = talloc_zero(mem_ctx, GROUP_MAP);
1461         if (group_map == NULL) {
1462                 PyErr_NoMemory();
1463                 talloc_free(mem_ctx);
1464                 talloc_free(frame);
1465                 return NULL;
1466         }
1467
1468         py_group_map = pytalloc_steal(type, group_map);
1469         if (py_group_map == NULL) {
1470                 PyErr_NoMemory();
1471                 talloc_free(mem_ctx);
1472                 talloc_free(frame);
1473                 return NULL;
1474         }
1475
1476         talloc_free(mem_ctx);
1477
1478         talloc_free(frame);
1479         return py_group_map;
1480 }
1481
1482
1483 static PyTypeObject PyGroupmap = {
1484         .tp_name = "passdb.Groupmap",
1485         .tp_getset = py_groupmap_getsetters,
1486         .tp_methods = NULL,
1487         .tp_new = py_groupmap_new,
1488         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1489         .tp_doc = "Groupmap() -> group map object\n",
1490 };
1491
1492
1493 static PyObject *py_pdb_domain_info(PyObject *self, PyObject *args)
1494 {
1495         TALLOC_CTX *frame = talloc_stackframe();
1496         struct pdb_methods *methods;
1497         struct pdb_domain_info *domain_info;
1498         PyObject *py_domain_info;
1499         struct dom_sid *sid;
1500         struct GUID *guid;
1501         PyObject *py_dom_sid = NULL;
1502         PyObject *py_guid = NULL;
1503
1504         methods = pytalloc_get_ptr(self);
1505
1506         domain_info = methods->get_domain_info(methods, frame);
1507         if (! domain_info) {
1508                 Py_RETURN_NONE;
1509         }
1510
1511         sid = dom_sid_dup(frame, &domain_info->sid);
1512         if (sid == NULL) {
1513                 PyErr_NoMemory();
1514                 talloc_free(frame);
1515                 return NULL;
1516         }
1517
1518         guid = talloc(frame, struct GUID);
1519         if (guid == NULL) {
1520                 PyErr_NoMemory();
1521                 talloc_free(frame);
1522                 return NULL;
1523         }
1524         *guid = domain_info->guid;
1525
1526         py_dom_sid = pytalloc_steal(dom_sid_Type, sid);
1527         py_guid = pytalloc_steal(guid_Type, guid);
1528
1529         py_domain_info = Py_BuildValue(
1530                 "{s:s, s:s, s:s, s:O, s:O}",
1531                 "name", domain_info->name,
1532                 "dns_domain", domain_info->dns_domain,
1533                 "dns_forest", domain_info->dns_forest,
1534                 "dom_sid", py_dom_sid,
1535                 "guid", py_guid);
1536
1537
1538         Py_CLEAR(py_dom_sid);
1539         Py_CLEAR(py_guid);
1540         talloc_free(frame);
1541         return py_domain_info;
1542 }
1543
1544
1545 static PyObject *py_pdb_getsampwnam(PyObject *self, PyObject *args)
1546 {
1547         TALLOC_CTX *frame = talloc_stackframe();
1548         NTSTATUS status;
1549         const char *username;
1550         struct pdb_methods *methods;
1551         struct samu *sam_acct;
1552         PyObject *py_sam_acct;
1553
1554         if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) {
1555                 talloc_free(frame);
1556                 return NULL;
1557         }
1558
1559         methods = pytalloc_get_ptr(self);
1560
1561         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1562         if (py_sam_acct == NULL) {
1563                 PyErr_NoMemory();
1564                 talloc_free(frame);
1565                 return NULL;
1566         }
1567         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1568
1569         status = methods->getsampwnam(methods, sam_acct, username);
1570         if (!NT_STATUS_IS_OK(status)) {
1571                 PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)",
1572                                 username,
1573                                 NT_STATUS_V(status),
1574                                 get_friendly_nt_error_msg(status));
1575                 Py_DECREF(py_sam_acct);
1576                 talloc_free(frame);
1577                 return NULL;
1578         }
1579
1580         talloc_free(frame);
1581         return py_sam_acct;
1582 }
1583
1584 static PyObject *py_pdb_getsampwsid(PyObject *self, PyObject *args)
1585 {
1586         TALLOC_CTX *frame = talloc_stackframe();
1587         NTSTATUS status;
1588         struct pdb_methods *methods;
1589         struct samu *sam_acct;
1590         PyObject *py_sam_acct;
1591         PyObject *py_user_sid;
1592
1593         if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) {
1594                 talloc_free(frame);
1595                 return NULL;
1596         }
1597
1598         methods = pytalloc_get_ptr(self);
1599
1600         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1601         if (py_sam_acct == NULL) {
1602                 PyErr_NoMemory();
1603                 talloc_free(frame);
1604                 return NULL;
1605         }
1606         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1607
1608         status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid));
1609         if (!NT_STATUS_IS_OK(status)) {
1610                 PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)",
1611                                 NT_STATUS_V(status),
1612                                 get_friendly_nt_error_msg(status));
1613                 Py_DECREF(py_sam_acct);
1614                 talloc_free(frame);
1615                 return NULL;
1616         }
1617
1618         talloc_free(frame);
1619         return py_sam_acct;
1620 }
1621
1622 static PyObject *py_pdb_create_user(PyObject *self, PyObject *args)
1623 {
1624         TALLOC_CTX *frame = talloc_stackframe();
1625         NTSTATUS status;
1626         struct pdb_methods *methods;
1627         const char *username;
1628         unsigned int acct_flags;
1629         unsigned int rid;
1630
1631         if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) {
1632                 talloc_free(frame);
1633                 return NULL;
1634         }
1635
1636         methods = pytalloc_get_ptr(self);
1637
1638         status = methods->create_user(methods, frame, username, acct_flags, &rid);
1639         if (!NT_STATUS_IS_OK(status)) {
1640                 PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)",
1641                                 username,
1642                                 NT_STATUS_V(status),
1643                                 get_friendly_nt_error_msg(status));
1644                 talloc_free(frame);
1645                 return NULL;
1646         }
1647
1648         talloc_free(frame);
1649         return PyLong_FromLong(rid);
1650 }
1651
1652 static PyObject *py_pdb_delete_user(PyObject *self, PyObject *args)
1653 {
1654         TALLOC_CTX *frame = talloc_stackframe();
1655         NTSTATUS status;
1656         struct pdb_methods *methods;
1657         struct samu *sam_acct;
1658         PyObject *py_sam_acct;
1659
1660         if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) {
1661                 talloc_free(frame);
1662                 return NULL;
1663         }
1664
1665         methods = pytalloc_get_ptr(self);
1666
1667         sam_acct = pytalloc_get_ptr(py_sam_acct);
1668
1669         status = methods->delete_user(methods, frame, sam_acct);
1670         if (!NT_STATUS_IS_OK(status)) {
1671                 PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)",
1672                                 NT_STATUS_V(status),
1673                                 get_friendly_nt_error_msg(status));
1674                 talloc_free(frame);
1675                 return NULL;
1676         }
1677
1678         talloc_free(frame);
1679         Py_RETURN_NONE;
1680 }
1681
1682 static PyObject *py_pdb_add_sam_account(PyObject *self, PyObject *args)
1683 {
1684         TALLOC_CTX *frame = talloc_stackframe();
1685         NTSTATUS status;
1686         struct pdb_methods *methods;
1687         struct samu *sam_acct;
1688         PyObject *py_sam_acct;
1689
1690         if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) {
1691                 talloc_free(frame);
1692                 return NULL;
1693         }
1694
1695         methods = pytalloc_get_ptr(self);
1696
1697         sam_acct = pytalloc_get_ptr(py_sam_acct);
1698
1699         status = methods->add_sam_account(methods, sam_acct);
1700         if (!NT_STATUS_IS_OK(status)) {
1701                 PyErr_Format(py_pdb_error, "Unable to add sam account '%s', (%d,%s)",
1702                                 sam_acct->username,
1703                                 NT_STATUS_V(status),
1704                                 get_friendly_nt_error_msg(status));
1705                 talloc_free(frame);
1706                 return NULL;
1707         }
1708
1709         talloc_free(frame);
1710         Py_RETURN_NONE;
1711 }
1712
1713 static PyObject *py_pdb_update_sam_account(PyObject *self, PyObject *args)
1714 {
1715         TALLOC_CTX *frame = talloc_stackframe();
1716         NTSTATUS status;
1717         struct pdb_methods *methods;
1718         struct samu *sam_acct;
1719         PyObject *py_sam_acct;
1720
1721         if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) {
1722                 talloc_free(frame);
1723                 return NULL;
1724         }
1725
1726         methods = pytalloc_get_ptr(self);
1727
1728         sam_acct = pytalloc_get_ptr(py_sam_acct);
1729
1730         status = methods->update_sam_account(methods, sam_acct);
1731         if (!NT_STATUS_IS_OK(status)) {
1732                 PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)",
1733                                 NT_STATUS_V(status),
1734                                 get_friendly_nt_error_msg(status));
1735                 talloc_free(frame);
1736                 return NULL;
1737         }
1738
1739         talloc_free(frame);
1740         Py_RETURN_NONE;
1741 }
1742
1743 static PyObject *py_pdb_delete_sam_account(PyObject *self, PyObject *args)
1744 {
1745         TALLOC_CTX *frame = talloc_stackframe();
1746         NTSTATUS status;
1747         struct pdb_methods *methods;
1748         struct samu *sam_acct;
1749         PyObject *py_sam_acct;
1750
1751         if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) {
1752                 talloc_free(frame);
1753                 return NULL;
1754         }
1755
1756         methods = pytalloc_get_ptr(self);
1757
1758         sam_acct = pytalloc_get_ptr(py_sam_acct);
1759
1760         status = methods->delete_sam_account(methods, sam_acct);
1761         if (!NT_STATUS_IS_OK(status)) {
1762                 PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)",
1763                                 NT_STATUS_V(status),
1764                                 get_friendly_nt_error_msg(status));
1765                 talloc_free(frame);
1766                 return NULL;
1767         }
1768
1769         talloc_free(frame);
1770         Py_RETURN_NONE;
1771 }
1772
1773 static PyObject *py_pdb_rename_sam_account(PyObject *self, PyObject *args)
1774 {
1775         TALLOC_CTX *frame = talloc_stackframe();
1776         NTSTATUS status;
1777         struct pdb_methods *methods;
1778         struct samu *sam_acct;
1779         const char *new_username;
1780         PyObject *py_sam_acct;
1781
1782         if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct,
1783                                         &new_username)) {
1784                 talloc_free(frame);
1785                 return NULL;
1786         }
1787
1788         methods = pytalloc_get_ptr(self);
1789
1790         sam_acct = pytalloc_get_ptr(py_sam_acct);
1791
1792         status = methods->rename_sam_account(methods, sam_acct, new_username);
1793         if (!NT_STATUS_IS_OK(status)) {
1794                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1795                                 NT_STATUS_V(status),
1796                                 get_friendly_nt_error_msg(status));
1797                 talloc_free(frame);
1798                 return NULL;
1799         }
1800
1801         talloc_free(frame);
1802         Py_RETURN_NONE;
1803 }
1804
1805
1806 static PyObject *py_pdb_getgrsid(PyObject *self, PyObject *args)
1807 {
1808         TALLOC_CTX *frame = talloc_stackframe();
1809         NTSTATUS status;
1810         struct pdb_methods *methods;
1811         GROUP_MAP *group_map;
1812         struct dom_sid *domain_sid;
1813         PyObject *py_domain_sid, *py_group_map;
1814
1815         if (!PyArg_ParseTuple(args, "O!:getgrsid", dom_sid_Type, &py_domain_sid)) {
1816                 talloc_free(frame);
1817                 return NULL;
1818         }
1819
1820         methods = pytalloc_get_ptr(self);
1821
1822         domain_sid = pytalloc_get_ptr(py_domain_sid);
1823
1824         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1825         if (py_group_map == NULL) {
1826                 PyErr_NoMemory();
1827                 talloc_free(frame);
1828                 return NULL;
1829         }
1830
1831         group_map = pytalloc_get_ptr(py_group_map);
1832
1833         status = methods->getgrsid(methods, group_map, *domain_sid);
1834         if (!NT_STATUS_IS_OK(status)) {
1835                 PyErr_Format(py_pdb_error, "Unable to get group information by sid, (%d,%s)",
1836                                 NT_STATUS_V(status),
1837                                 get_friendly_nt_error_msg(status));
1838                 talloc_free(frame);
1839                 return NULL;
1840         }
1841
1842         talloc_free(frame);
1843         return py_group_map;
1844 }
1845
1846
1847 static PyObject *py_pdb_getgrgid(PyObject *self, PyObject *args)
1848 {
1849         TALLOC_CTX *frame = talloc_stackframe();
1850         NTSTATUS status;
1851         struct pdb_methods *methods;
1852         GROUP_MAP *group_map;
1853         PyObject *py_group_map;
1854         unsigned int gid_value;
1855
1856         if (!PyArg_ParseTuple(args, "I:getgrgid", &gid_value)) {
1857                 talloc_free(frame);
1858                 return NULL;
1859         }
1860
1861         methods = pytalloc_get_ptr(self);
1862
1863         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1864         if (py_group_map == NULL) {
1865                 PyErr_NoMemory();
1866                 talloc_free(frame);
1867                 return NULL;
1868         }
1869
1870         group_map = pytalloc_get_ptr(py_group_map);
1871
1872         status = methods->getgrgid(methods, group_map, gid_value);
1873         if (!NT_STATUS_IS_OK(status)) {
1874                 PyErr_Format(py_pdb_error, "Unable to get group information by gid, (%d,%s)",
1875                                 NT_STATUS_V(status),
1876                                 get_friendly_nt_error_msg(status));
1877                 talloc_free(frame);
1878                 return NULL;
1879         }
1880
1881         talloc_free(frame);
1882         return py_group_map;
1883 }
1884
1885
1886 static PyObject *py_pdb_getgrnam(PyObject *self, PyObject *args)
1887 {
1888         TALLOC_CTX *frame = talloc_stackframe();
1889         NTSTATUS status;
1890         struct pdb_methods *methods;
1891         GROUP_MAP *group_map;
1892         PyObject *py_group_map;
1893         const char *groupname;
1894
1895         if (!PyArg_ParseTuple(args, "s:getgrnam", &groupname)) {
1896                 talloc_free(frame);
1897                 return NULL;
1898         }
1899
1900         methods = pytalloc_get_ptr(self);
1901
1902         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1903         if (py_group_map == NULL) {
1904                 PyErr_NoMemory();
1905                 talloc_free(frame);
1906                 return NULL;
1907         }
1908
1909         group_map = pytalloc_get_ptr(py_group_map);
1910
1911         status = methods->getgrnam(methods, group_map, groupname);
1912         if (!NT_STATUS_IS_OK(status)) {
1913                 PyErr_Format(py_pdb_error, "Unable to get group information by name, (%d,%s)",
1914                                 NT_STATUS_V(status),
1915                                 get_friendly_nt_error_msg(status));
1916                 talloc_free(frame);
1917                 return NULL;
1918         }
1919
1920         talloc_free(frame);
1921         return py_group_map;
1922 }
1923
1924
1925 static PyObject *py_pdb_create_dom_group(PyObject *self, PyObject *args)
1926 {
1927         TALLOC_CTX *frame = talloc_stackframe();
1928         NTSTATUS status;
1929         struct pdb_methods *methods;
1930         const char *groupname;
1931         uint32_t group_rid;
1932
1933         if (!PyArg_ParseTuple(args, "s:create_dom_group", &groupname)) {
1934                 talloc_free(frame);
1935                 return NULL;
1936         }
1937
1938         methods = pytalloc_get_ptr(self);
1939
1940         status = methods->create_dom_group(methods, frame, groupname, &group_rid);
1941         if (!NT_STATUS_IS_OK(status)) {
1942                 PyErr_Format(py_pdb_error, "Unable to create domain group (%s), (%d,%s)",
1943                                 groupname,
1944                                 NT_STATUS_V(status),
1945                                 get_friendly_nt_error_msg(status));
1946                 talloc_free(frame);
1947                 return NULL;
1948         }
1949
1950         talloc_free(frame);
1951         return PyLong_FromLong(group_rid);
1952 }
1953
1954
1955 static PyObject *py_pdb_delete_dom_group(PyObject *self, PyObject *args)
1956 {
1957         TALLOC_CTX *frame = talloc_stackframe();
1958         NTSTATUS status;
1959         struct pdb_methods *methods;
1960         unsigned int group_rid;
1961
1962         if (!PyArg_ParseTuple(args, "I:delete_dom_group", &group_rid)) {
1963                 talloc_free(frame);
1964                 return NULL;
1965         }
1966
1967         methods = pytalloc_get_ptr(self);
1968
1969         status = methods->delete_dom_group(methods, frame, group_rid);
1970         if (!NT_STATUS_IS_OK(status)) {
1971                 PyErr_Format(py_pdb_error, "Unable to delete domain group (rid=%d), (%d,%s)",
1972                                 group_rid,
1973                                 NT_STATUS_V(status),
1974                                 get_friendly_nt_error_msg(status));
1975                 talloc_free(frame);
1976                 return NULL;
1977         }
1978
1979         talloc_free(frame);
1980         Py_RETURN_NONE;
1981 }
1982
1983
1984 static PyObject *py_pdb_add_group_mapping_entry(PyObject *self, PyObject *args)
1985 {
1986         TALLOC_CTX *frame = talloc_stackframe();
1987         NTSTATUS status;
1988         struct pdb_methods *methods;
1989         PyObject *py_group_map;
1990         GROUP_MAP *group_map;
1991
1992         if (!PyArg_ParseTuple(args, "O!:add_group_mapping_entry", &PyGroupmap, &py_group_map)) {
1993                 talloc_free(frame);
1994                 return NULL;
1995         }
1996
1997         methods = pytalloc_get_ptr(self);
1998
1999         group_map = pytalloc_get_ptr(py_group_map);
2000
2001         status = methods->add_group_mapping_entry(methods, group_map);
2002         if (!NT_STATUS_IS_OK(status)) {
2003                 PyErr_Format(py_pdb_error, "Unable to add group mapping entry, (%d,%s)",
2004                                 NT_STATUS_V(status),
2005                                 get_friendly_nt_error_msg(status));
2006                 talloc_free(frame);
2007                 return NULL;
2008         }
2009
2010         talloc_free(frame);
2011         Py_RETURN_NONE;
2012 }
2013
2014
2015 static PyObject *py_pdb_update_group_mapping_entry(PyObject *self, PyObject *args)
2016 {
2017         TALLOC_CTX *frame = talloc_stackframe();
2018         NTSTATUS status;
2019         struct pdb_methods *methods;
2020         PyObject *py_group_map;
2021         GROUP_MAP *group_map;
2022
2023         if (!PyArg_ParseTuple(args, "O!:update_group_mapping_entry", &PyGroupmap, &py_group_map)) {
2024                 talloc_free(frame);
2025                 return NULL;
2026         }
2027
2028         methods = pytalloc_get_ptr(self);
2029
2030         group_map = pytalloc_get_ptr(py_group_map);
2031
2032         status = methods->update_group_mapping_entry(methods, group_map);
2033         if (!NT_STATUS_IS_OK(status)) {
2034                 PyErr_Format(py_pdb_error, "Unable to update group mapping entry, (%d,%s)",
2035                                 NT_STATUS_V(status),
2036                                 get_friendly_nt_error_msg(status));
2037                 talloc_free(frame);
2038                 return NULL;
2039         }
2040
2041         talloc_free(frame);
2042         Py_RETURN_NONE;
2043 }
2044
2045
2046 static PyObject *py_pdb_delete_group_mapping_entry(PyObject *self, PyObject *args)
2047 {
2048         TALLOC_CTX *frame = talloc_stackframe();
2049         NTSTATUS status;
2050         struct pdb_methods *methods;
2051         PyObject *py_group_sid;
2052         struct dom_sid *group_sid;
2053
2054         if (!PyArg_ParseTuple(args, "O!:delete_group_mapping_entry", dom_sid_Type, &py_group_sid)) {
2055                 talloc_free(frame);
2056                 return NULL;
2057         }
2058
2059         methods = pytalloc_get_ptr(self);
2060
2061         group_sid = pytalloc_get_ptr(py_group_sid);
2062
2063         status = methods->delete_group_mapping_entry(methods, *group_sid);
2064         if (!NT_STATUS_IS_OK(status)) {
2065                 PyErr_Format(py_pdb_error, "Unable to delete group mapping entry, (%d,%s)",
2066                                 NT_STATUS_V(status),
2067                                 get_friendly_nt_error_msg(status));
2068                 talloc_free(frame);
2069                 return NULL;
2070         }
2071
2072         talloc_free(frame);
2073         Py_RETURN_NONE;
2074 }
2075
2076
2077 static PyObject *py_pdb_enum_group_mapping(PyObject *self, PyObject *args)
2078 {
2079         TALLOC_CTX *frame = talloc_stackframe();
2080         NTSTATUS status;
2081         struct pdb_methods *methods;
2082         enum lsa_SidType sid_name_use;
2083         int lsa_sidtype_value = SID_NAME_UNKNOWN;
2084         int unix_only = 0;
2085         PyObject *py_domain_sid = Py_None;
2086         struct dom_sid *domain_sid = NULL;
2087         GROUP_MAP **gmap = NULL;
2088         GROUP_MAP *group_map;
2089         size_t i, num_entries;
2090         PyObject *py_gmap_list, *py_group_map;
2091
2092         if (!PyArg_ParseTuple(args, "|O!ii:enum_group_mapping", dom_sid_Type, &py_domain_sid,
2093                                         &lsa_sidtype_value, &unix_only)) {
2094                 talloc_free(frame);
2095                 return NULL;
2096         }
2097
2098         methods = pytalloc_get_ptr(self);
2099
2100         sid_name_use = lsa_sidtype_value;
2101
2102         if (py_domain_sid != Py_None) {
2103                 domain_sid = pytalloc_get_ptr(py_domain_sid);
2104         }
2105
2106         status = methods->enum_group_mapping(methods, domain_sid, sid_name_use,
2107                                                 &gmap, &num_entries, unix_only);
2108         if (!NT_STATUS_IS_OK(status)) {
2109                 PyErr_Format(py_pdb_error, "Unable to enumerate group mappings, (%d,%s)",
2110                                 NT_STATUS_V(status),
2111                                 get_friendly_nt_error_msg(status));
2112                 talloc_free(frame);
2113                 return NULL;
2114         }
2115
2116         py_gmap_list = PyList_New(0);
2117         if (py_gmap_list == NULL) {
2118                 PyErr_NoMemory();
2119                 talloc_free(frame);
2120                 return NULL;
2121         }
2122
2123         for(i=0; i<num_entries; i++) {
2124                 py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
2125                 if (py_group_map) {
2126                         int res = 0;
2127                         group_map = pytalloc_get_ptr(py_group_map);
2128                         *group_map = *gmap[i];
2129                         talloc_steal(group_map, gmap[i]->nt_name);
2130                         talloc_steal(group_map, gmap[i]->comment);
2131
2132                         res = PyList_Append(py_gmap_list, py_group_map);
2133                         Py_CLEAR(py_group_map);
2134                         if (res == -1) {
2135                                 Py_CLEAR(py_gmap_list);
2136                                 talloc_free(frame);
2137                                 return NULL;
2138                         }
2139                 }
2140         }
2141
2142         talloc_free(gmap);
2143
2144         talloc_free(frame);
2145         return py_gmap_list;
2146 }
2147
2148
2149 static PyObject *py_pdb_enum_group_members(PyObject *self, PyObject *args)
2150 {
2151         TALLOC_CTX *frame = talloc_stackframe();
2152         NTSTATUS status;
2153         struct pdb_methods *methods;
2154         PyObject *py_group_sid;
2155         struct dom_sid *group_sid;
2156         uint32_t *member_rids;
2157         size_t i, num_members;
2158         PyObject *py_sid_list;
2159         struct dom_sid *domain_sid, *member_sid;
2160
2161         if (!PyArg_ParseTuple(args, "O!:enum_group_members", dom_sid_Type, &py_group_sid)) {
2162                 talloc_free(frame);
2163                 return NULL;
2164         }
2165
2166         methods = pytalloc_get_ptr(self);
2167
2168         group_sid = pytalloc_get_ptr(py_group_sid);
2169
2170         status = methods->enum_group_members(methods, frame, group_sid,
2171                                                 &member_rids, &num_members);
2172         if (!NT_STATUS_IS_OK(status)) {
2173                 PyErr_Format(py_pdb_error, "Unable to enumerate group members, (%d,%s)",
2174                                 NT_STATUS_V(status),
2175                                 get_friendly_nt_error_msg(status));
2176                 talloc_free(frame);
2177                 return NULL;
2178         }
2179
2180         py_sid_list = PyList_New(0);
2181         if (py_sid_list == NULL) {
2182                 PyErr_NoMemory();
2183                 talloc_free(frame);
2184                 return NULL;
2185         }
2186
2187         domain_sid = get_global_sam_sid();
2188
2189         for(i=0; i<num_members; i++) {
2190                 int res = 0;
2191                 PyObject *py_member_sid = NULL;
2192                 member_sid = dom_sid_add_rid(frame, domain_sid, member_rids[i]);
2193                 py_member_sid = pytalloc_steal(dom_sid_Type, member_sid);
2194                 res = PyList_Append(py_sid_list,
2195                                     py_member_sid);
2196                 Py_CLEAR(py_member_sid);
2197                 if (res == -1) {
2198                         talloc_free(frame);
2199                         Py_CLEAR(py_sid_list);
2200                         return NULL;
2201                 }
2202         }
2203
2204         talloc_free(frame);
2205         return py_sid_list;
2206 }
2207
2208
2209 static PyObject *py_pdb_enum_group_memberships(PyObject *self, PyObject *args)
2210 {
2211         TALLOC_CTX *frame = talloc_stackframe();
2212         NTSTATUS status;
2213         struct pdb_methods *methods;
2214         uint32_t i;
2215
2216         struct samu *sam_acct;
2217         PyObject *py_sam_acct;
2218         PyObject *py_sid_list;
2219         struct dom_sid *user_group_sids = NULL;
2220         gid_t *user_group_ids = NULL;
2221         uint32_t num_groups = 0;
2222
2223         if (!PyArg_ParseTuple(args, "O!:enum_group_memberships", &PySamu, &py_sam_acct)) {
2224                 talloc_free(frame);
2225                 return NULL;
2226         }
2227
2228         methods = pytalloc_get_ptr(self);
2229
2230         sam_acct = pytalloc_get_ptr(py_sam_acct);
2231
2232         status = methods->enum_group_memberships(methods, frame, sam_acct,
2233                                                  &user_group_sids, &user_group_ids, &num_groups);
2234         if (!NT_STATUS_IS_OK(status)) {
2235                 PyErr_Format(py_pdb_error, "Unable to enumerate group memberships, (%d,%s)",
2236                                 NT_STATUS_V(status),
2237                                 get_friendly_nt_error_msg(status));
2238                 talloc_free(frame);
2239                 return NULL;
2240         }
2241
2242         py_sid_list = PyList_New(0);
2243         if (py_sid_list == NULL) {
2244                 PyErr_NoMemory();
2245                 talloc_free(frame);
2246                 return NULL;
2247         }
2248
2249         for(i=0; i<num_groups; i++) {
2250                 PyObject *py_sid =
2251                         pytalloc_steal(dom_sid_Type,
2252                                        dom_sid_dup(NULL, &user_group_sids[i]));
2253                 PyList_Append(py_sid_list, py_sid);
2254                 Py_CLEAR(py_sid);
2255         }
2256
2257         talloc_free(frame);
2258         return py_sid_list;
2259 }
2260
2261
2262 static PyObject *py_pdb_add_groupmem(PyObject *self, PyObject *args)
2263 {
2264         TALLOC_CTX *frame = talloc_stackframe();
2265         NTSTATUS status;
2266         struct pdb_methods *methods;
2267         uint32_t group_rid, member_rid;
2268
2269         if (!PyArg_ParseTuple(args, "II:add_groupmem", &group_rid, &member_rid)) {
2270                 talloc_free(frame);
2271                 return NULL;
2272         }
2273
2274         methods = pytalloc_get_ptr(self);
2275
2276         status = methods->add_groupmem(methods, frame, group_rid, member_rid);
2277         if (!NT_STATUS_IS_OK(status)) {
2278                 PyErr_Format(py_pdb_error, "Unable to add group member, (%d,%s)",
2279                                 NT_STATUS_V(status),
2280                                 get_friendly_nt_error_msg(status));
2281                 talloc_free(frame);
2282                 return NULL;
2283         }
2284
2285         talloc_free(frame);
2286         Py_RETURN_NONE;
2287 }
2288
2289
2290 static PyObject *py_pdb_del_groupmem(PyObject *self, PyObject *args)
2291 {
2292         TALLOC_CTX *frame = talloc_stackframe();
2293         NTSTATUS status;
2294         struct pdb_methods *methods;
2295         uint32_t group_rid, member_rid;
2296
2297         if (!PyArg_ParseTuple(args, "II:del_groupmem", &group_rid, &member_rid)) {
2298                 talloc_free(frame);
2299                 return NULL;
2300         }
2301
2302         methods = pytalloc_get_ptr(self);
2303
2304         status = methods->del_groupmem(methods, frame, group_rid, member_rid);
2305         if (!NT_STATUS_IS_OK(status)) {
2306                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
2307                                 NT_STATUS_V(status),
2308                                 get_friendly_nt_error_msg(status));
2309                 talloc_free(frame);
2310                 return NULL;
2311         }
2312
2313         talloc_free(frame);
2314         Py_RETURN_NONE;
2315 }
2316
2317
2318 static PyObject *py_pdb_create_alias(PyObject *self, PyObject *args)
2319 {
2320         TALLOC_CTX *frame = talloc_stackframe();
2321         NTSTATUS status;
2322         struct pdb_methods *methods;
2323         const char *alias_name;
2324         uint32_t rid;
2325
2326         if (!PyArg_ParseTuple(args, "s:create_alias", &alias_name)) {
2327                 talloc_free(frame);
2328                 return NULL;
2329         }
2330
2331         methods = pytalloc_get_ptr(self);
2332
2333         status = methods->create_alias(methods, alias_name, &rid);
2334         if (!NT_STATUS_IS_OK(status)) {
2335                 PyErr_Format(py_pdb_error, "Unable to create alias (%s), (%d,%s)",
2336                                 alias_name,
2337                                 NT_STATUS_V(status),
2338                                 get_friendly_nt_error_msg(status));
2339                 talloc_free(frame);
2340                 return NULL;
2341         }
2342
2343         talloc_free(frame);
2344         return PyLong_FromLong(rid);
2345 }
2346
2347
2348 static PyObject *py_pdb_delete_alias(PyObject *self, PyObject *args)
2349 {
2350         TALLOC_CTX *frame = talloc_stackframe();
2351         NTSTATUS status;
2352         struct pdb_methods *methods;
2353         PyObject *py_alias_sid;
2354         struct dom_sid *alias_sid;
2355
2356         if (!PyArg_ParseTuple(args, "O!:delete_alias", dom_sid_Type, &py_alias_sid)) {
2357                 talloc_free(frame);
2358                 return NULL;
2359         }
2360
2361         methods = pytalloc_get_ptr(self);
2362
2363         alias_sid = pytalloc_get_ptr(py_alias_sid);
2364
2365         status = methods->delete_alias(methods, alias_sid);
2366         if (!NT_STATUS_IS_OK(status)) {
2367                 PyErr_Format(py_pdb_error, "Unable to delete alias, (%d,%s)",
2368                                 NT_STATUS_V(status),
2369                                 get_friendly_nt_error_msg(status));
2370                 talloc_free(frame);
2371                 return NULL;
2372         }
2373
2374         talloc_free(frame);
2375         Py_RETURN_NONE;
2376 }
2377
2378
2379 static PyObject *py_pdb_get_aliasinfo(PyObject *self, PyObject *args)
2380 {
2381         TALLOC_CTX *frame = talloc_stackframe();
2382         NTSTATUS status;
2383         struct pdb_methods *methods;
2384         PyObject *py_alias_sid;
2385         struct dom_sid *alias_sid;
2386         struct acct_info *alias_info;
2387         PyObject *py_alias_info;
2388
2389         if (!PyArg_ParseTuple(args, "O!:get_aliasinfo", dom_sid_Type, &py_alias_sid)) {
2390                 talloc_free(frame);
2391                 return NULL;
2392         }
2393
2394         methods = pytalloc_get_ptr(self);
2395
2396         alias_sid = pytalloc_get_ptr(py_alias_sid);
2397
2398         alias_info = talloc_zero(frame, struct acct_info);
2399         if (!alias_info) {
2400                 PyErr_NoMemory();
2401                 talloc_free(frame);
2402                 return NULL;
2403         }
2404
2405         status = methods->get_aliasinfo(methods, alias_sid, alias_info);
2406         if (!NT_STATUS_IS_OK(status)) {
2407                 PyErr_Format(py_pdb_error, "Unable to get alias information, (%d,%s)",
2408                                 NT_STATUS_V(status),
2409                                 get_friendly_nt_error_msg(status));
2410                 talloc_free(frame);
2411                 return NULL;
2412         }
2413
2414         py_alias_info = Py_BuildValue(
2415                 "{s:s, s:s, s:l}",
2416                 "acct_name", alias_info->acct_name,
2417                 "acct_desc", alias_info->acct_desc,
2418                 "rid", alias_info->rid);
2419
2420         talloc_free(frame);
2421         return py_alias_info;
2422 }
2423
2424
2425 static PyObject *py_pdb_set_aliasinfo(PyObject *self, PyObject *args)
2426 {
2427         TALLOC_CTX *frame = talloc_stackframe();
2428         NTSTATUS status;
2429         struct pdb_methods *methods;
2430         PyObject *py_alias_sid, *py_alias_info;
2431         struct dom_sid *alias_sid;
2432         struct acct_info alias_info;
2433
2434         if (!PyArg_ParseTuple(args, "O!O:set_alias_info", dom_sid_Type, &py_alias_sid,
2435                                 &py_alias_info)) {
2436                 talloc_free(frame);
2437                 return NULL;
2438         }
2439
2440         methods = pytalloc_get_ptr(self);
2441
2442         alias_sid = pytalloc_get_ptr(py_alias_sid);
2443
2444         alias_info.acct_name = talloc_strdup(frame, PyUnicode_AsUTF8(PyDict_GetItemString(py_alias_info, "acct_name")));
2445         if (alias_info.acct_name == NULL) {
2446                 PyErr_Format(py_pdb_error, "Unable to allocate memory");
2447                 talloc_free(frame);
2448                 return NULL;
2449         }
2450         alias_info.acct_desc = talloc_strdup(frame, PyUnicode_AsUTF8(PyDict_GetItemString(py_alias_info, "acct_desc")));
2451         if (alias_info.acct_desc == NULL) {
2452                 PyErr_Format(py_pdb_error, "Unable to allocate memory");
2453                 talloc_free(frame);
2454                 return NULL;
2455         }
2456
2457         status = methods->set_aliasinfo(methods, alias_sid, &alias_info);
2458         if (!NT_STATUS_IS_OK(status)) {
2459                 PyErr_Format(py_pdb_error, "Unable to set alias information, (%d,%s)",
2460                                 NT_STATUS_V(status),
2461                                 get_friendly_nt_error_msg(status));
2462                 talloc_free(frame);
2463                 return NULL;
2464         }
2465
2466         talloc_free(frame);
2467         Py_RETURN_NONE;
2468 }
2469
2470
2471 static PyObject *py_pdb_add_aliasmem(PyObject *self, PyObject *args)
2472 {
2473         TALLOC_CTX *frame = talloc_stackframe();
2474         NTSTATUS status;
2475         struct pdb_methods *methods;
2476         PyObject *py_alias_sid, *py_member_sid;
2477         struct dom_sid *alias_sid, *member_sid;
2478
2479         if (!PyArg_ParseTuple(args, "O!O!:add_aliasmem", dom_sid_Type, &py_alias_sid,
2480                                         dom_sid_Type, &py_member_sid)) {
2481                 talloc_free(frame);
2482                 return NULL;
2483         }
2484
2485         methods = pytalloc_get_ptr(self);
2486
2487         alias_sid = pytalloc_get_ptr(py_alias_sid);
2488         member_sid = pytalloc_get_ptr(py_member_sid);
2489
2490         status = methods->add_aliasmem(methods, alias_sid, member_sid);
2491         if (!NT_STATUS_IS_OK(status)) {
2492                 PyErr_Format(py_pdb_error, "Unable to add member to alias, (%d,%s)",
2493                                 NT_STATUS_V(status),
2494                                 get_friendly_nt_error_msg(status));
2495                 talloc_free(frame);
2496                 return NULL;
2497         }
2498
2499         talloc_free(frame);
2500         Py_RETURN_NONE;
2501 }
2502
2503
2504 static PyObject *py_pdb_del_aliasmem(PyObject *self, PyObject *args)
2505 {
2506         TALLOC_CTX *frame = talloc_stackframe();
2507         NTSTATUS status;
2508         struct pdb_methods *methods;
2509         PyObject *py_alias_sid, *py_member_sid;
2510         const struct dom_sid *alias_sid, *member_sid;
2511
2512         if (!PyArg_ParseTuple(args, "O!O!:del_aliasmem", dom_sid_Type, &py_alias_sid,
2513                                         dom_sid_Type, &py_member_sid)) {
2514                 talloc_free(frame);
2515                 return NULL;
2516         }
2517
2518         methods = pytalloc_get_ptr(self);
2519
2520         alias_sid = pytalloc_get_ptr(py_alias_sid);
2521         member_sid = pytalloc_get_ptr(py_member_sid);
2522
2523         status = methods->del_aliasmem(methods, alias_sid, member_sid);
2524         if (!NT_STATUS_IS_OK(status)) {
2525                 PyErr_Format(py_pdb_error, "Unable to delete member from alias, (%d,%s)",
2526                                 NT_STATUS_V(status),
2527                                 get_friendly_nt_error_msg(status));
2528                 talloc_free(frame);
2529                 return NULL;
2530         }
2531
2532         talloc_free(frame);
2533         Py_RETURN_NONE;
2534 }
2535
2536
2537 static PyObject *py_pdb_enum_aliasmem(PyObject *self, PyObject *args)
2538 {
2539         TALLOC_CTX *frame = talloc_stackframe();
2540         NTSTATUS status;
2541         struct pdb_methods *methods;
2542         PyObject *py_alias_sid;
2543         struct dom_sid *alias_sid, *member_sid, *tmp_sid;
2544         PyObject *py_member_list, *py_member_sid;
2545         size_t i, num_members;
2546
2547         if (!PyArg_ParseTuple(args, "O!:enum_aliasmem", dom_sid_Type, &py_alias_sid)) {
2548                 talloc_free(frame);
2549                 return NULL;
2550         }
2551
2552         methods = pytalloc_get_ptr(self);
2553
2554         alias_sid = pytalloc_get_ptr(py_alias_sid);
2555
2556         status = methods->enum_aliasmem(methods, alias_sid, frame, &member_sid, &num_members);
2557         if (!NT_STATUS_IS_OK(status)) {
2558                 PyErr_Format(py_pdb_error, "Unable to enumerate members for alias, (%d,%s)",
2559                                 NT_STATUS_V(status),
2560                                 get_friendly_nt_error_msg(status));
2561                 talloc_free(frame);
2562                 return NULL;
2563         }
2564
2565         py_member_list = PyList_New(0);
2566         if (py_member_list == NULL) {
2567                 PyErr_NoMemory();
2568                 talloc_free(frame);
2569                 return NULL;
2570         }
2571
2572         for(i=0; i<num_members; i++) {
2573                 int res = 0;
2574                 py_member_sid = pytalloc_new(struct dom_sid, dom_sid_Type);
2575                 if (py_member_sid == NULL) {
2576                         PyErr_NoMemory();
2577                         Py_CLEAR(py_member_list);
2578                         talloc_free(frame);
2579                         return NULL;
2580                 }
2581                 tmp_sid = pytalloc_get_ptr(py_member_sid);
2582                 *tmp_sid = member_sid[i];
2583                 res = PyList_Append(py_member_list, py_member_sid);
2584                 Py_CLEAR(py_member_sid);
2585                 if (res == -1) {
2586                         Py_CLEAR(py_member_list);
2587                         talloc_free(frame);
2588                         return NULL;
2589                 }
2590         }
2591
2592         talloc_free(frame);
2593         return py_member_list;
2594 }
2595
2596
2597 static PyObject *py_pdb_get_account_policy(PyObject *self, PyObject *unused)
2598 {
2599         TALLOC_CTX *frame = talloc_stackframe();
2600         NTSTATUS status;
2601         struct pdb_methods *methods;
2602         PyObject *py_acct_policy;
2603         uint32_t value;
2604         const char **names;
2605         int count, i;
2606         enum pdb_policy_type type;
2607
2608         methods = pytalloc_get_ptr(self);
2609
2610         py_acct_policy = PyDict_New();
2611         if (py_acct_policy == NULL) {
2612                 PyErr_NoMemory();
2613                 talloc_free(frame);
2614                 return NULL;
2615         }
2616
2617         account_policy_names_list(frame, &names, &count);
2618         for (i=0; i<count; i++) {
2619                 type = account_policy_name_to_typenum(names[i]);
2620                 status = methods->get_account_policy(methods, type, &value);
2621                 if (NT_STATUS_IS_OK(status)) {
2622                         int res = 0;
2623                         PyObject *py_value = Py_BuildValue("i", value);
2624                         if (py_value == NULL) {
2625                                 Py_CLEAR(py_acct_policy);
2626                                 break;
2627                         }
2628                         res = PyDict_SetItemString(py_acct_policy,
2629                                                    names[i],
2630                                                    py_value);
2631                         Py_CLEAR(py_value);
2632                         if (res == -1) {
2633                                 Py_CLEAR(py_acct_policy);
2634                                 break;
2635                         }
2636                 }
2637         }
2638
2639         talloc_free(frame);
2640         return py_acct_policy;
2641 }
2642
2643
2644 static PyObject *py_pdb_set_account_policy(PyObject *self, PyObject *args)
2645 {
2646         TALLOC_CTX *frame = talloc_stackframe();
2647         NTSTATUS status;
2648         struct pdb_methods *methods;
2649         PyObject *py_acct_policy, *py_value;
2650         const char **names;
2651         int count, i;
2652         enum pdb_policy_type type;
2653
2654         if (!PyArg_ParseTuple(args, "O!:set_account_policy", PyDict_Type, &py_acct_policy)) {
2655                 talloc_free(frame);
2656                 return NULL;
2657         }
2658
2659         methods = pytalloc_get_ptr(self);
2660
2661         account_policy_names_list(frame, &names, &count);
2662         for (i=0; i<count; i++) {
2663                 if ((py_value = PyDict_GetItemString(py_acct_policy, names[i])) != NULL) {
2664                         type = account_policy_name_to_typenum(names[i]);
2665                         status = methods->set_account_policy(methods, type, PyLong_AsLong(py_value));
2666                         if (!NT_STATUS_IS_OK(status)) {
2667                                 PyErr_Format(py_pdb_error, "Error setting account policy (%s), (%d,%s)",
2668                                                 names[i],
2669                                                 NT_STATUS_V(status),
2670                                                 get_friendly_nt_error_msg(status));
2671                         }
2672                 }
2673         }
2674
2675         talloc_free(frame);
2676         Py_RETURN_NONE;
2677 }
2678
2679 static PyObject *py_pdb_search_users(PyObject *self, PyObject *args)
2680 {
2681         TALLOC_CTX *frame = talloc_stackframe();
2682         struct pdb_methods *methods;
2683         unsigned int acct_flags;
2684         struct pdb_search *search;
2685         struct samr_displayentry *entry;
2686         PyObject *py_userlist, *py_dict;
2687
2688         if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) {
2689                 talloc_free(frame);
2690                 return NULL;
2691         }
2692
2693         methods = pytalloc_get_ptr(self);
2694
2695         search = talloc_zero(frame, struct pdb_search);
2696         if (search == NULL) {
2697                 PyErr_NoMemory();
2698                 talloc_free(frame);
2699                 return NULL;
2700         }
2701
2702         if (!methods->search_users(methods, search, acct_flags)) {
2703                 PyErr_Format(py_pdb_error, "Unable to search users");
2704                 talloc_free(frame);
2705                 return NULL;
2706         }
2707
2708         entry = talloc_zero(frame, struct samr_displayentry);
2709         if (entry == NULL) {
2710                 PyErr_NoMemory();
2711                 talloc_free(frame);
2712                 return NULL;
2713         }
2714
2715         py_userlist = PyList_New(0);
2716         if (py_userlist == NULL) {
2717                 PyErr_NoMemory();
2718                 talloc_free(frame);
2719                 return NULL;
2720         }
2721
2722         while (search->next_entry(search, entry)) {
2723                 int res = 1;
2724                 py_dict = Py_BuildValue(
2725                         "{s:l, s:l, s:l, s:s, s:s, s:s}",
2726                         "idx", entry->idx,
2727                         "rid", entry->rid,
2728                         "acct_flags", entry->acct_flags,
2729                         "account_name", entry->account_name,
2730                         "fullname", entry->fullname,
2731                         "description", entry->description);
2732                 if (py_dict == NULL) {
2733                         Py_CLEAR(py_userlist);
2734                         goto out;
2735                 }
2736
2737                 res = PyList_Append(py_userlist, py_dict);
2738                 Py_CLEAR(py_dict);
2739                 if (res == -1) {
2740                         Py_CLEAR(py_userlist);
2741                         goto out;
2742                 }
2743         }
2744         search->search_end(search);
2745
2746 out:
2747         talloc_free(frame);
2748         return py_userlist;
2749 }
2750
2751
2752 static PyObject *py_pdb_search_groups(PyObject *self, PyObject *unused)
2753 {
2754         TALLOC_CTX *frame = talloc_stackframe();
2755         struct pdb_methods *methods;
2756         struct pdb_search *search;
2757         struct samr_displayentry *entry;
2758         PyObject *py_grouplist, *py_dict;
2759
2760         methods = pytalloc_get_ptr(self);
2761
2762         search = talloc_zero(frame, struct pdb_search);
2763         if (search == NULL) {
2764                 PyErr_NoMemory();
2765                 talloc_free(frame);
2766                 return NULL;
2767         }
2768
2769         if (!methods->search_groups(methods, search)) {
2770                 PyErr_Format(py_pdb_error, "Unable to search groups");
2771                 talloc_free(frame);
2772                 return NULL;
2773         }
2774
2775         entry = talloc_zero(frame, struct samr_displayentry);
2776         if (entry == NULL) {
2777                 PyErr_NoMemory();
2778                 talloc_free(frame);
2779                 return NULL;
2780         }
2781
2782         py_grouplist = PyList_New(0);
2783         if (py_grouplist == NULL) {
2784                 PyErr_NoMemory();
2785                 talloc_free(frame);
2786                 return NULL;
2787         }
2788
2789         while (search->next_entry(search, entry)) {
2790                 int res = 0;
2791                 py_dict = Py_BuildValue(
2792                         "{s:l, s:l, s:l, s:s, s:s, s:s}",
2793                         "idx", entry->idx,
2794                         "rid", entry->rid,
2795                         "acct_flags", entry->acct_flags,
2796                         "account_name", entry->account_name,
2797                         "fullname", entry->fullname,
2798                         "description", entry->description);
2799
2800                 if (py_dict == NULL) {
2801                         Py_CLEAR(py_grouplist);
2802                         goto out;
2803                 }
2804
2805                 res = PyList_Append(py_grouplist, py_dict);
2806                 Py_CLEAR(py_dict);
2807                 if (res == -1) {
2808                         Py_CLEAR(py_grouplist);
2809                         goto out;
2810                 }
2811         }
2812         search->search_end(search);
2813 out:
2814         talloc_free(frame);
2815         return py_grouplist;
2816 }
2817
2818
2819 static PyObject *py_pdb_search_aliases(PyObject *self, PyObject *args)
2820 {
2821         TALLOC_CTX *frame = talloc_stackframe();
2822         struct pdb_methods *methods;
2823         struct pdb_search *search;
2824         struct samr_displayentry *entry;
2825         PyObject *py_aliaslist, *py_dict;
2826         PyObject *py_domain_sid = Py_None;
2827         struct dom_sid *domain_sid = NULL;
2828
2829         if (!PyArg_ParseTuple(args, "|O!:search_aliases", dom_sid_Type, &py_domain_sid)) {
2830                 talloc_free(frame);
2831                 return NULL;
2832         }
2833
2834         methods = pytalloc_get_ptr(self);
2835
2836         if (py_domain_sid != Py_None) {
2837                 domain_sid = pytalloc_get_ptr(py_domain_sid);
2838         }
2839
2840         search = talloc_zero(frame, struct pdb_search);
2841         if (search == NULL) {
2842                 PyErr_NoMemory();
2843                 talloc_free(frame);
2844                 return NULL;
2845         }
2846
2847         if (!methods->search_aliases(methods, search, domain_sid)) {
2848                 PyErr_Format(py_pdb_error, "Unable to search aliases");
2849                 talloc_free(frame);
2850                 return NULL;
2851         }
2852
2853         entry = talloc_zero(frame, struct samr_displayentry);
2854         if (entry == NULL) {
2855                 PyErr_NoMemory();
2856                 talloc_free(frame);
2857                 return NULL;
2858         }
2859
2860         py_aliaslist = PyList_New(0);
2861         if (py_aliaslist == NULL) {
2862                 PyErr_NoMemory();
2863                 talloc_free(frame);
2864                 return NULL;
2865         }
2866
2867         while (search->next_entry(search, entry)) {
2868                 int res = 0;
2869
2870                 py_dict = Py_BuildValue(
2871                         "{s:l, s:l, s:l, s:s, s:s, s:s}",
2872                         "idx", entry->idx,
2873                         "rid", entry->rid,
2874                         "acct_flags", entry->acct_flags,
2875                         "account_name", entry->account_name,
2876                         "fullname", entry->fullname,
2877                         "description", entry->description);
2878
2879                 if (py_dict == NULL) {
2880                         Py_CLEAR(py_aliaslist);
2881                         goto out;
2882                 }
2883                 res = PyList_Append(py_aliaslist, py_dict);
2884                 Py_CLEAR(py_dict);
2885                 if (res == -1) {
2886                         Py_CLEAR(py_aliaslist);
2887                         goto out;
2888                 }
2889         }
2890         search->search_end(search);
2891 out:
2892         talloc_free(frame);
2893         return py_aliaslist;
2894 }
2895
2896
2897 static PyObject *py_pdb_uid_to_sid(PyObject *self, PyObject *args)
2898 {
2899         TALLOC_CTX *frame = talloc_stackframe();
2900         struct pdb_methods *methods;
2901         struct unixid id;
2902         unsigned int uid;
2903         struct dom_sid user_sid, *copy_user_sid;
2904         PyObject *py_user_sid;
2905
2906         if (!PyArg_ParseTuple(args, "I:uid_to_sid", &uid)) {
2907                 talloc_free(frame);
2908                 return NULL;
2909         }
2910
2911         methods = pytalloc_get_ptr(self);
2912
2913         id.id = uid;
2914         id.type = ID_TYPE_UID;
2915
2916         if (!methods->id_to_sid(methods, &id, &user_sid)) {
2917                 PyErr_Format(py_pdb_error, "Unable to get sid for uid=%d", uid);
2918                 talloc_free(frame);
2919                 return NULL;
2920         }
2921
2922         copy_user_sid = dom_sid_dup(frame, &user_sid);
2923         if (copy_user_sid == NULL) {
2924                 PyErr_NoMemory();
2925                 talloc_free(frame);
2926                 return NULL;
2927         }
2928
2929         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
2930
2931         talloc_free(frame);
2932         return py_user_sid;
2933 }
2934
2935
2936 static PyObject *py_pdb_gid_to_sid(PyObject *self, PyObject *args)
2937 {
2938         TALLOC_CTX *frame = talloc_stackframe();
2939         struct pdb_methods *methods;
2940         struct unixid id;
2941         unsigned int gid;
2942         struct dom_sid group_sid, *copy_group_sid;
2943         PyObject *py_group_sid;
2944
2945         if (!PyArg_ParseTuple(args, "I:gid_to_sid", &gid)) {
2946                 talloc_free(frame);
2947                 return NULL;
2948         }
2949
2950         id.id = gid;
2951         id.type = ID_TYPE_GID;
2952
2953         methods = pytalloc_get_ptr(self);
2954
2955         if (!methods->id_to_sid(methods, &id, &group_sid)) {
2956                 PyErr_Format(py_pdb_error, "Unable to get sid for gid=%d", gid);
2957                 talloc_free(frame);
2958                 return NULL;
2959         }
2960
2961         copy_group_sid = dom_sid_dup(frame, &group_sid);
2962         if (copy_group_sid == NULL) {
2963                 PyErr_NoMemory();
2964                 talloc_free(frame);
2965                 return NULL;
2966         }
2967
2968         py_group_sid = pytalloc_steal(dom_sid_Type, copy_group_sid);
2969
2970         talloc_free(frame);
2971         return py_group_sid;
2972 }
2973
2974
2975 static PyObject *py_pdb_sid_to_id(PyObject *self, PyObject *args)
2976 {
2977         TALLOC_CTX *frame = talloc_stackframe();
2978         struct pdb_methods *methods;
2979         PyObject *py_sid;
2980         struct dom_sid *sid;
2981         struct unixid id;
2982
2983         if (!PyArg_ParseTuple(args, "O!:sid_to_id", dom_sid_Type, &py_sid)) {
2984                 talloc_free(frame);
2985                 return NULL;
2986         }
2987
2988         methods = pytalloc_get_ptr(self);
2989
2990         sid = pytalloc_get_ptr(py_sid);
2991
2992         if (!methods->sid_to_id(methods, sid, &id)) {
2993                 PyErr_Format(py_pdb_error, "Unable to get id for sid");
2994                 talloc_free(frame);
2995                 return NULL;
2996         }
2997
2998         talloc_free(frame);
2999         return Py_BuildValue("(II)", id.id, id.type);
3000 }
3001
3002
3003 static PyObject *py_pdb_new_rid(PyObject *self, PyObject *unused)
3004 {
3005         TALLOC_CTX *frame = talloc_stackframe();
3006         struct pdb_methods *methods;
3007         uint32_t rid;
3008
3009         methods = pytalloc_get_ptr(self);
3010
3011         if (!methods->new_rid(methods, &rid)) {
3012                 PyErr_Format(py_pdb_error, "Unable to get new rid");
3013                 talloc_free(frame);
3014                 return NULL;
3015         }
3016
3017         talloc_free(frame);
3018         return PyLong_FromLong(rid);
3019 }
3020
3021
3022 static PyObject *py_pdb_get_trusteddom_pw(PyObject *self, PyObject *args)
3023 {
3024         TALLOC_CTX *frame = talloc_stackframe();
3025         struct pdb_methods *methods;
3026         const char *domain;
3027         char *pwd;
3028         struct dom_sid sid, *copy_sid;
3029         PyObject *py_sid;
3030         time_t last_set_time;
3031         PyObject *py_value;
3032
3033         if (!PyArg_ParseTuple(args, "s:get_trusteddom_pw", &domain)) {
3034                 talloc_free(frame);
3035                 return NULL;
3036         }
3037
3038         methods = pytalloc_get_ptr(self);
3039
3040         if (!methods->get_trusteddom_pw(methods, domain, &pwd, &sid, &last_set_time)) {
3041                 PyErr_Format(py_pdb_error, "Unable to get trusted domain password");
3042                 talloc_free(frame);
3043                 return NULL;
3044         }
3045
3046         copy_sid = dom_sid_dup(frame, &sid);
3047         if (copy_sid == NULL) {
3048                 PyErr_NoMemory();
3049                 talloc_free(frame);
3050                 return NULL;
3051         }
3052
3053         py_sid = pytalloc_steal(dom_sid_Type, copy_sid);
3054         if (py_sid == NULL) {
3055                 PyErr_NoMemory();
3056                 talloc_free(frame);
3057                 return NULL;
3058         }
3059
3060         py_value = Py_BuildValue(
3061                 "{s:s, s:O, s:l}",
3062                 "pwd", pwd,
3063                 "sid", py_sid,
3064                 "last_set_tim", last_set_time);
3065
3066         Py_CLEAR(py_sid);
3067         talloc_free(frame);
3068         return py_value;
3069 }
3070
3071
3072 static PyObject *py_pdb_set_trusteddom_pw(PyObject *self, PyObject *args)
3073 {
3074         TALLOC_CTX *frame = talloc_stackframe();
3075         struct pdb_methods *methods;
3076         const char *domain;
3077         const char *pwd;
3078         const struct dom_sid *domain_sid;
3079         PyObject *py_domain_sid;
3080
3081         if (!PyArg_ParseTuple(args, "ssO!:set_trusteddom_pw", &domain, &pwd,
3082                                         dom_sid_Type, &py_domain_sid)) {
3083                 talloc_free(frame);
3084                 return NULL;
3085         }
3086
3087         methods = pytalloc_get_ptr(self);
3088
3089         domain_sid = pytalloc_get_ptr(py_domain_sid);
3090
3091         if (!methods->set_trusteddom_pw(methods, domain, pwd, domain_sid)) {
3092                 PyErr_Format(py_pdb_error, "Unable to set trusted domain password");
3093                 talloc_free(frame);
3094                 return NULL;
3095         }
3096
3097         talloc_free(frame);
3098         Py_RETURN_NONE;
3099 }
3100
3101
3102 static PyObject *py_pdb_del_trusteddom_pw(PyObject *self, PyObject *args)
3103 {
3104         TALLOC_CTX *frame = talloc_stackframe();
3105         struct pdb_methods *methods;
3106         const char *domain;
3107
3108         if (!PyArg_ParseTuple(args, "s:del_trusteddom_pw", &domain)) {
3109                 talloc_free(frame);
3110                 return NULL;
3111         }
3112
3113         methods = pytalloc_get_ptr(self);
3114
3115         if (!methods->del_trusteddom_pw(methods, domain)) {
3116                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain password");
3117                 talloc_free(frame);
3118                 return NULL;
3119         }
3120
3121         talloc_free(frame);
3122         Py_RETURN_NONE;
3123 }
3124
3125
3126 static PyObject *py_pdb_enum_trusteddoms(PyObject *self, PyObject *unused)
3127 {
3128         TALLOC_CTX *frame = talloc_stackframe();
3129         NTSTATUS status;
3130         struct pdb_methods *methods;
3131         uint32_t i, num_domains;
3132         struct trustdom_info **domains;
3133         PyObject *py_domain_list, *py_dict;
3134
3135         methods = pytalloc_get_ptr(self);
3136
3137         status = methods->enum_trusteddoms(methods, frame, &num_domains, &domains);
3138         if (!NT_STATUS_IS_OK(status)) {
3139                 PyErr_Format(py_pdb_error, "Unable to enumerate trusted domains, (%d,%s)",
3140                                 NT_STATUS_V(status),
3141                                 get_friendly_nt_error_msg(status));
3142                 talloc_free(frame);
3143                 return NULL;
3144         }
3145
3146         py_domain_list = PyList_New(0);
3147         if (py_domain_list == NULL) {
3148                 PyErr_NoMemory();
3149                 talloc_free(frame);
3150                 return NULL;
3151         }
3152
3153         for(i=0; i<num_domains; i++) {
3154                 int res = 0;
3155                 PyObject *py_sid =
3156                         pytalloc_steal(dom_sid_Type, &domains[i]->sid);
3157                 py_dict = Py_BuildValue(
3158                         "{s:s, s:O}",
3159                         "name", domains[i]->name,
3160                         "sid", py_sid);
3161                 Py_CLEAR(py_sid);
3162                 if (py_dict == NULL) {
3163                         DBG_ERR("Failed to insert entry to dict\n");
3164                                 Py_CLEAR(py_domain_list);
3165                                 break;
3166                 }
3167
3168                 res = PyList_Append(py_domain_list, py_dict);
3169                 Py_CLEAR(py_dict);
3170                 if (res == -1) {
3171                         Py_CLEAR(py_domain_list);
3172                         break;
3173                 }
3174         }
3175
3176         talloc_free(frame);
3177         return py_domain_list;
3178 }
3179
3180
3181 static PyObject *py_pdb_get_trusted_domain(PyObject *self, PyObject *args)
3182 {
3183         TALLOC_CTX *frame = talloc_stackframe();
3184         NTSTATUS status;
3185         struct pdb_methods *methods;
3186         const char *domain;
3187         struct pdb_trusted_domain *td;
3188         PyObject *py_domain_info;
3189         PyObject *py_sid = NULL;
3190
3191         if (!PyArg_ParseTuple(args, "s:get_trusted_domain", &domain)) {
3192                 talloc_free(frame);
3193                 return NULL;
3194         }
3195
3196         methods = pytalloc_get_ptr(self);
3197
3198         status = methods->get_trusted_domain(methods, frame, domain, &td);
3199         if (!NT_STATUS_IS_OK(status)) {
3200                 PyErr_Format(py_pdb_error, "Unable to get trusted domain information, (%d,%s)",
3201                                 NT_STATUS_V(status),
3202                                 get_friendly_nt_error_msg(status));
3203                 talloc_free(frame);
3204                 return NULL;
3205         }
3206
3207         py_sid = pytalloc_steal(dom_sid_Type, &td->security_identifier);
3208
3209         py_domain_info = Py_BuildValue(
3210                 "{s:s, s:s, s:O,"
3211                         " s:"PYARG_BYTES_LEN","
3212                         " s:"PYARG_BYTES_LEN","
3213                         " s:l, s:l, s:l,"
3214                         " s:"PYARG_BYTES_LEN"}",
3215                 "domain_name", td->domain_name,
3216                 "netbios_name", td->netbios_name,
3217                 "security_identifier", py_sid,
3218                 "trust_auth_incoming",
3219                         (const char *)td->trust_auth_incoming.data,
3220                         td->trust_auth_incoming.length,
3221                 "trust_auth_outgoing",
3222                         (const char *)td->trust_auth_outgoing.data,
3223                         td->trust_auth_outgoing.length,
3224                 "trust_direction", td->trust_direction,
3225                 "trust_type", td->trust_type,
3226                 "trust_attributes", td->trust_attributes,
3227                 "trust_forest_trust_info",
3228                         (const char *)td->trust_forest_trust_info.data,
3229                         td->trust_forest_trust_info.length);
3230         Py_CLEAR(py_sid);
3231
3232         talloc_free(frame);
3233         return py_domain_info;
3234 }
3235
3236
3237 static PyObject *py_pdb_get_trusted_domain_by_sid(PyObject *self, PyObject *args)
3238 {
3239         TALLOC_CTX *frame = talloc_stackframe();
3240         NTSTATUS status;
3241         struct pdb_methods *methods;
3242         PyObject *py_domain_sid;
3243         struct dom_sid *domain_sid;
3244         struct pdb_trusted_domain *td;
3245         PyObject *py_domain_info;
3246         PyObject *py_sid = NULL;
3247
3248         if (!PyArg_ParseTuple(args, "O!:get_trusted_domain_by_sid", dom_sid_Type, &py_domain_sid)) {
3249                 talloc_free(frame);
3250                 return NULL;
3251         }
3252
3253         methods = pytalloc_get_ptr(self);
3254
3255         domain_sid = pytalloc_get_ptr(py_domain_sid);
3256
3257         status = methods->get_trusted_domain_by_sid(methods, frame, domain_sid, &td);
3258         if (!NT_STATUS_IS_OK(status)) {
3259                 PyErr_Format(py_pdb_error, "Unable to get trusted domain information, (%d,%s)",
3260                                 NT_STATUS_V(status),
3261                                 get_friendly_nt_error_msg(status));
3262                 talloc_free(frame);
3263                 return NULL;
3264         }
3265
3266         py_sid = pytalloc_steal(dom_sid_Type, &td->security_identifier);
3267
3268         py_domain_info = Py_BuildValue(
3269                 "{s:s, s:s, s:O,"
3270                         " s:"PYARG_BYTES_LEN","
3271                         " s:"PYARG_BYTES_LEN","
3272                         " s:l, s:l, s:l,"
3273                         " s:"PYARG_BYTES_LEN"}",
3274                 "domain_name", td->domain_name,
3275                 "netbios_name", td->netbios_name,
3276                 "security_identifier", py_sid,
3277                 "trust_auth_incoming",
3278                         (const char *)td->trust_auth_incoming.data,
3279                         td->trust_auth_incoming.length,
3280                 "trust_auth_outgoing",
3281                         (const char *)td->trust_auth_outgoing.data,
3282                         td->trust_auth_outgoing.length,
3283                 "trust_direction", td->trust_direction,
3284                 "trust_type", td->trust_type,
3285                 "trust_attributes", td->trust_attributes,
3286                 "trust_forest_trust_info",
3287                         (const char *)td->trust_forest_trust_info.data,
3288                         td->trust_forest_trust_info.length);
3289         Py_CLEAR(py_sid);
3290
3291         talloc_free(frame);
3292         return py_domain_info;
3293 }
3294
3295
3296 static PyObject *py_pdb_set_trusted_domain(PyObject *self, PyObject *args)
3297 {
3298         TALLOC_CTX *frame = talloc_stackframe();
3299         NTSTATUS status;
3300         struct pdb_methods *methods;
3301         const char *domain;
3302         PyObject *py_td_info;
3303         struct pdb_trusted_domain td_info;
3304         PyObject *py_tmp;
3305         Py_ssize_t len;
3306
3307         if (!PyArg_ParseTuple(args, "sO!:set_trusted_domain", &domain, &PyDict_Type, &py_td_info)) {
3308                 talloc_free(frame);
3309                 return NULL;
3310         }
3311
3312         py_tmp = PyDict_GetItemString(py_td_info, "domain_name");
3313         td_info.domain_name = discard_const_p(char, PyUnicode_AsUTF8(py_tmp));
3314
3315         py_tmp = PyDict_GetItemString(py_td_info, "netbios_name");
3316         td_info.netbios_name = discard_const_p(char, PyUnicode_AsUTF8(py_tmp));
3317
3318         py_tmp = PyDict_GetItemString(py_td_info, "security_identifier");
3319         td_info.security_identifier = *pytalloc_get_type(py_tmp, struct dom_sid);
3320
3321         py_tmp = PyDict_GetItemString(py_td_info, "trust_auth_incoming");
3322         PyBytes_AsStringAndSize(py_tmp, (char **)&td_info.trust_auth_incoming.data, &len);
3323         td_info.trust_auth_incoming.length = len;
3324
3325         py_tmp = PyDict_GetItemString(py_td_info, "trust_auth_outgoing");
3326         PyBytes_AsStringAndSize(py_tmp, (char **)&td_info.trust_auth_outgoing.data, &len);
3327         td_info.trust_auth_outgoing.length = len;
3328
3329         py_tmp = PyDict_GetItemString(py_td_info, "trust_direction");
3330         td_info.trust_direction = PyLong_AsLong(py_tmp);
3331
3332         py_tmp = PyDict_GetItemString(py_td_info, "trust_type");
3333         td_info.trust_type = PyLong_AsLong(py_tmp);
3334
3335         py_tmp = PyDict_GetItemString(py_td_info, "trust_attributes");
3336         td_info.trust_attributes = PyLong_AsLong(py_tmp);
3337
3338         py_tmp = PyDict_GetItemString(py_td_info, "trust_forest_trust_info");
3339         PyBytes_AsStringAndSize(py_tmp, (char **)&td_info.trust_forest_trust_info.data, &len);
3340         td_info.trust_forest_trust_info.length = len;
3341
3342         methods = pytalloc_get_ptr(self);
3343
3344         status = methods->set_trusted_domain(methods, domain, &td_info);
3345         if (!NT_STATUS_IS_OK(status)) {
3346                 PyErr_Format(py_pdb_error, "Unable to set trusted domain information, (%d,%s)",
3347                                 NT_STATUS_V(status),
3348                                 get_friendly_nt_error_msg(status));
3349                 talloc_free(frame);
3350                 return NULL;
3351         }
3352
3353         talloc_free(frame);
3354         Py_RETURN_NONE;
3355 }
3356
3357
3358 static PyObject *py_pdb_del_trusted_domain(PyObject *self, PyObject *args)
3359 {
3360         TALLOC_CTX *frame = talloc_stackframe();
3361         NTSTATUS status;
3362         struct pdb_methods *methods;
3363         const char *domain;
3364
3365         if (!PyArg_ParseTuple(args, "s:del_trusted_domain", &domain)) {
3366                 talloc_free(frame);
3367                 return NULL;
3368         }
3369
3370         methods = pytalloc_get_ptr(self);
3371
3372         status = methods->del_trusted_domain(methods, domain);
3373         if (!NT_STATUS_IS_OK(status)) {
3374                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain, (%d,%s)",
3375                                 NT_STATUS_V(status),
3376                                 get_friendly_nt_error_msg(status));
3377                 talloc_free(frame);
3378                 return NULL;
3379         }
3380
3381         talloc_free(frame);
3382         Py_RETURN_NONE;
3383 }
3384
3385
3386 static PyObject *py_pdb_enum_trusted_domains(PyObject *self, PyObject *args)
3387 {
3388         TALLOC_CTX *frame = talloc_stackframe();
3389         NTSTATUS status;
3390         struct pdb_methods *methods;
3391         uint32_t i, num_domains;
3392         struct pdb_trusted_domain **td_info;
3393         PyObject *py_td_info, *py_domain_info;
3394
3395         methods = pytalloc_get_ptr(self);
3396
3397         status = methods->enum_trusted_domains(methods, frame, &num_domains, &td_info);
3398         if (!NT_STATUS_IS_OK(status)) {
3399                 PyErr_Format(py_pdb_error, "Unable to delete trusted domain, (%d,%s)",
3400                                 NT_STATUS_V(status),
3401                                 get_friendly_nt_error_msg(status));
3402                 talloc_free(frame);
3403                 return NULL;
3404         }
3405
3406         py_td_info = PyList_New(0);
3407         if (py_td_info == NULL) {
3408                 PyErr_NoMemory();
3409                 talloc_free(frame);
3410                 return NULL;
3411         }
3412
3413         for (i=0; i<num_domains; i++) {
3414                 int res = 0;
3415                 struct pdb_trusted_domain *td = td_info[i];
3416                 PyObject *py_sid =
3417                         pytalloc_steal(dom_sid_Type, &td->security_identifier);
3418
3419                 py_domain_info = Py_BuildValue(
3420                         "{s:s, s:s, s:O,"
3421                                 " s:"PYARG_BYTES_LEN","
3422                                 " s:"PYARG_BYTES_LEN","
3423                                 " s:l, s:l, s:l,"
3424                                 " s:"PYARG_BYTES_LEN"}",
3425                         "domain_name", td->domain_name,
3426                         "netbios_name", td->netbios_name,
3427                         "security_identifier", py_sid,
3428                         "trust_auth_incoming",
3429                                 (const char *)td->trust_auth_incoming.data,
3430                                 td->trust_auth_incoming.length,
3431                         "trust_auth_outgoing",
3432                                 (const char *)td->trust_auth_outgoing.data,
3433                                 td->trust_auth_outgoing.length,
3434                         "trust_direction", td->trust_direction,
3435                         "trust_type", td->trust_type,
3436                         "trust_attributes", td->trust_attributes,
3437                         "trust_forest_trust_info",
3438                                 (const char *)td->trust_forest_trust_info.data,
3439                                 td->trust_forest_trust_info.length);
3440                 Py_CLEAR(py_sid);
3441
3442                 if (py_domain_info == NULL) {
3443                         Py_CLEAR(py_td_info);
3444                         break;
3445                 }
3446                 res = PyList_Append(py_td_info, py_domain_info);
3447                 Py_CLEAR(py_domain_info);
3448                 if (res == -1) {
3449                         Py_CLEAR(py_td_info);
3450                         break;
3451                 }
3452         }
3453
3454         talloc_free(frame);
3455         return py_td_info;
3456 }
3457
3458
3459 static PyObject *py_pdb_get_secret(PyObject *self, PyObject *args)
3460 {
3461         TALLOC_CTX *frame = talloc_stackframe();
3462         NTSTATUS status;
3463         struct pdb_methods *methods;
3464         const char *secret_name;
3465         DATA_BLOB secret_current, secret_old;
3466         NTTIME secret_current_lastchange, secret_old_lastchange;
3467         PyObject *py_sd;
3468         struct security_descriptor *sd;
3469         PyObject *py_secret;
3470
3471         if (!PyArg_ParseTuple(args, "s:get_secret_name", &secret_name)) {
3472                 talloc_free(frame);
3473                 return NULL;
3474         }
3475
3476         methods = pytalloc_get_ptr(self);
3477
3478         py_sd = pytalloc_new(struct security_descriptor, security_Type);
3479         if (py_sd == NULL) {
3480                 PyErr_NoMemory();
3481                 talloc_free(frame);
3482                 return NULL;
3483         }
3484         sd = pytalloc_get_ptr(py_sd);
3485
3486         status = methods->get_secret(methods, frame, secret_name,
3487                                         &secret_current,
3488                                         &secret_current_lastchange,
3489                                         &secret_old,
3490                                         &secret_old_lastchange,
3491                                         &sd);
3492         if (!NT_STATUS_IS_OK(status)) {
3493                 PyErr_Format(py_pdb_error, "Unable to get information for secret (%s), (%d,%s)",
3494                                 secret_name,
3495                                 NT_STATUS_V(status),
3496                                 get_friendly_nt_error_msg(status));
3497                 talloc_free(frame);
3498                 return NULL;
3499         }
3500
3501         py_secret = Py_BuildValue(
3502                 "{s:"PYARG_BYTES_LEN","
3503                         " s:K"
3504                         " s:"PYARG_BYTES_LEN","
3505                         " s:K, s:O}",
3506                 "secret_current", (const char*)secret_current.data,
3507                                 secret_current.length,
3508                 "secret_current_lastchange", secret_current_lastchange,
3509                 "secret_old", (const char*)secret_old.data,
3510                                 secret_old.length,
3511                 "secret_old_lastchange", secret_old_lastchange,
3512                 "sd", py_sd);
3513
3514         Py_CLEAR(py_sd);
3515         if (py_secret == NULL) {
3516                 talloc_free(frame);
3517                 return NULL;
3518         }
3519
3520         talloc_free(frame);
3521         return py_secret;
3522 }
3523
3524
3525 static PyObject *py_pdb_set_secret(PyObject *self, PyObject *args)
3526 {
3527         TALLOC_CTX *frame = talloc_stackframe();
3528         NTSTATUS status;
3529         struct pdb_methods *methods;
3530         const char *secret_name;
3531         PyObject *py_secret;
3532         PyObject *py_secret_cur, *py_secret_old, *py_sd;
3533         DATA_BLOB secret_current, secret_old;
3534         struct security_descriptor *sd;
3535         Py_ssize_t len;
3536
3537         if (!PyArg_ParseTuple(args, "sO!:set_secret_name", &secret_name, PyDict_Type, &py_secret)) {
3538                 talloc_free(frame);
3539                 return NULL;
3540         }
3541
3542         py_secret_cur = PyDict_GetItemString(py_secret, "secret_current");
3543         py_secret_old = PyDict_GetItemString(py_secret, "secret_old");
3544         py_sd = PyDict_GetItemString(py_secret, "sd");
3545
3546         PY_CHECK_TYPE(&PyBytes_Type, py_secret_cur, return NULL;);
3547         PY_CHECK_TYPE(&PyBytes_Type, py_secret_old, return NULL;);
3548         PY_CHECK_TYPE(security_Type, py_sd, return NULL;);
3549
3550         methods = pytalloc_get_ptr(self);
3551
3552         PyBytes_AsStringAndSize(py_secret_cur, (char **)&secret_current.data, &len);
3553         secret_current.length = len;
3554         PyBytes_AsStringAndSize(py_secret_old, (char **)&secret_old.data, &len);
3555         secret_current.length = len;
3556         sd = pytalloc_get_ptr(py_sd);
3557
3558         status = methods->set_secret(methods, secret_name, &secret_current, &secret_old, sd);
3559         if (!NT_STATUS_IS_OK(status)) {
3560                 PyErr_Format(py_pdb_error, "Unable to set information for secret (%s), (%d,%s)",
3561                                 secret_name,
3562                                 NT_STATUS_V(status),
3563                                 get_friendly_nt_error_msg(status));
3564                 talloc_free(frame);
3565                 return NULL;
3566         }
3567
3568         talloc_free(frame);
3569         Py_RETURN_NONE;
3570 }
3571
3572
3573 static PyObject *py_pdb_delete_secret(PyObject *self, PyObject *args)
3574 {
3575         TALLOC_CTX *frame = talloc_stackframe();
3576         NTSTATUS status;
3577         struct pdb_methods *methods;
3578         const char *secret_name;
3579
3580         if (!PyArg_ParseTuple(args, "s:delete_secret", &secret_name)) {
3581                 talloc_free(frame);
3582                 return NULL;
3583         }
3584
3585         methods = pytalloc_get_ptr(self);
3586
3587         status = methods->delete_secret(methods, secret_name);
3588         if (!NT_STATUS_IS_OK(status)) {
3589                 PyErr_Format(py_pdb_error, "Unable to delete secret (%s), (%d,%s)",
3590                                 secret_name,
3591                                 NT_STATUS_V(status),
3592                                 get_friendly_nt_error_msg(status));
3593                 talloc_free(frame);
3594                 return NULL;
3595         }
3596
3597         talloc_free(frame);
3598         Py_RETURN_NONE;
3599 }
3600
3601 static PyMethodDef py_pdb_methods[] = {
3602         { "domain_info", py_pdb_domain_info, METH_NOARGS,
3603                 "domain_info() -> str\n\n \
3604                 Get domain information for the database." },
3605         { "getsampwnam", py_pdb_getsampwnam, METH_VARARGS,
3606                 "getsampwnam(username) -> samu object\n\n \
3607                 Get user information by name." },
3608         { "getsampwsid", py_pdb_getsampwsid, METH_VARARGS,
3609                 "getsampwsid(user_sid) -> samu object\n\n \
3610                 Get user information by sid (dcerpc.security.dom_sid object)." },
3611         { "create_user", py_pdb_create_user, METH_VARARGS,
3612                 "create_user(username, acct_flags) -> rid\n\n \
3613                 Create user. acct_flags are samr account control flags." },
3614         { "delete_user", py_pdb_delete_user, METH_VARARGS,
3615                 "delete_user(samu object) -> None\n\n \
3616                 Delete user." },
3617         { "add_sam_account", py_pdb_add_sam_account, METH_VARARGS,
3618                 "add_sam_account(samu object) -> None\n\n \
3619                 Add SAM account." },
3620         { "update_sam_account", py_pdb_update_sam_account, METH_VARARGS,
3621                 "update_sam_account(samu object) -> None\n\n \
3622                 Update SAM account." },
3623         { "delete_sam_account", py_pdb_delete_sam_account, METH_VARARGS,
3624                 "delete_sam_account(samu object) -> None\n\n \
3625                 Delete SAM account." },
3626         { "rename_sam_account", py_pdb_rename_sam_account, METH_VARARGS,
3627                 "rename_sam_account(samu object1, new_username) -> None\n\n \
3628                 Rename SAM account." },
3629         /* update_login_attempts */
3630         { "getgrsid", py_pdb_getgrsid, METH_VARARGS,
3631                 "getgrsid(group_sid) -> groupmap object\n\n \
3632                 Get group information by sid (dcerpc.security.dom_sid object)." },
3633         { "getgrgid", py_pdb_getgrgid, METH_VARARGS,
3634                 "getgrsid(gid) -> groupmap object\n\n \
3635                 Get group information by gid." },
3636         { "getgrnam", py_pdb_getgrnam, METH_VARARGS,
3637                 "getgrsid(groupname) -> groupmap object\n\n \
3638                 Get group information by name." },
3639         { "create_dom_group", py_pdb_create_dom_group, METH_VARARGS,
3640                 "create_dom_group(groupname) -> group_rid\n\n \
3641                 Create new domain group by name." },
3642         { "delete_dom_group", py_pdb_delete_dom_group, METH_VARARGS,
3643                 "delete_dom_group(group_rid) -> None\n\n \
3644                 Delete domain group identified by rid" },
3645         { "add_group_mapping_entry", py_pdb_add_group_mapping_entry, METH_VARARGS,
3646                 "add_group_mapping_entry(groupmap) -> None\n \
3647                 Add group mapping entry for groupmap object." },
3648         { "update_group_mapping_entry", py_pdb_update_group_mapping_entry, METH_VARARGS,
3649                 "update_group_mapping_entry(groupmap) -> None\n\n \
3650                 Update group mapping entry for groupmap object." },
3651         { "delete_group_mapping_entry", py_pdb_delete_group_mapping_entry, METH_VARARGS,
3652                 "delete_group_mapping_entry(groupmap) -> None\n\n \
3653                 Delete group mapping entry for groupmap object." },
3654         { "enum_group_mapping", py_pdb_enum_group_mapping, METH_VARARGS,
3655                 "enum_group_mapping([domain_sid, [type, [unix_only]]]) -> List\n\n \
3656                 Return list of group mappings as groupmap objects. Optional arguments are domain_sid object, type of group, unix only flag." },
3657         { "enum_group_members", py_pdb_enum_group_members, METH_VARARGS,
3658                 "enum_group_members(group_sid) -> List\n\n \
3659                 Return list of users (dom_sid object) in group." },
3660         { "enum_group_memberships", py_pdb_enum_group_memberships, METH_VARARGS,
3661                 "enum_group_memberships(samu object) -> List\n\n \
3662                 Return list of groups (dom_sid object) this user is part of." },
3663         /* set_unix_primary_group */
3664         { "add_groupmem", py_pdb_add_groupmem, METH_VARARGS,
3665                 "add_groupmem(group_rid, member_rid) -> None\n\n \
3666                 Add user to group." },
3667         { "del_groupmem", py_pdb_del_groupmem, METH_VARARGS,
3668                 "del_groupmem(group_rid, member_rid) -> None\n\n \
3669                 Remove user from from group." },
3670         { "create_alias", py_pdb_create_alias, METH_VARARGS,
3671                 "create_alias(alias_name) -> alias_rid\n\n \
3672                 Create alias entry." },
3673         { "delete_alias", py_pdb_delete_alias, METH_VARARGS,
3674                 "delete_alias(alias_sid) -> None\n\n \
3675                 Delete alias entry." },
3676         { "get_aliasinfo", py_pdb_get_aliasinfo, METH_VARARGS,
3677                 "get_aliasinfo(alias_sid) -> Mapping\n\n \
3678                 Get alias information as a dictionary with keys - acct_name, acct_desc, rid." },
3679         { "set_aliasinfo", py_pdb_set_aliasinfo, METH_VARARGS,
3680                 "set_alias_info(alias_sid, Mapping) -> None\n\n \
3681                 Set alias information from a dictionary with keys - acct_name, acct_desc." },
3682         { "add_aliasmem", py_pdb_add_aliasmem, METH_VARARGS,
3683                 "add_aliasmem(alias_sid, member_sid) -> None\n\n \
3684                 Add user to alias entry." },
3685         { "del_aliasmem", py_pdb_del_aliasmem, METH_VARARGS,
3686                 "del_aliasmem(alias_sid, member_sid) -> None\n\n \
3687                 Remove a user from alias entry." },
3688         { "enum_aliasmem", py_pdb_enum_aliasmem, METH_VARARGS,
3689                 "enum_aliasmem(alias_sid) -> List\n\n \
3690                 Return a list of members (dom_sid object) for alias entry." },
3691         /* enum_alias_memberships */
3692         /* lookup_rids */
3693         /* lookup_names */
3694         { "get_account_policy", py_pdb_get_account_policy, METH_NOARGS,
3695                 "get_account_policy() -> Mapping\n\n \
3696                 Get account policy information as a dictionary." },
3697         { "set_account_policy", py_pdb_set_account_policy, METH_VARARGS,
3698                 "get_account_policy(Mapping) -> None\n\n \
3699                 Set account policy settings from a dicionary." },
3700         /* get_seq_num */
3701         { "search_users", py_pdb_search_users, METH_VARARGS,
3702                 "search_users(acct_flags) -> List\n\n \
3703                 Search users. acct_flags are samr account control flags.\n \
3704                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3705         { "search_groups", py_pdb_search_groups, METH_NOARGS,
3706                 "search_groups() -> List\n\n \
3707                 Search unix only groups. \n \
3708                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3709         { "search_aliases", py_pdb_search_aliases, METH_VARARGS,
3710                 "search_aliases([domain_sid]) -> List\n\n \
3711                 Search aliases. domain_sid is dcerpc.security.dom_sid object.\n \
3712                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
3713         { "uid_to_sid", py_pdb_uid_to_sid, METH_VARARGS,
3714                 "uid_to_sid(uid) -> sid\n\n \
3715                 Return sid for given user id." },
3716         { "gid_to_sid", py_pdb_gid_to_sid, METH_VARARGS,
3717                 "gid_to_sid(gid) -> sid\n\n \
3718                 Return sid for given group id." },
3719         { "sid_to_id", py_pdb_sid_to_id, METH_VARARGS,
3720                 "sid_to_id(sid) -> Tuple\n\n \
3721                 Return id and type for given sid." },
3722         /* capabilities */
3723         { "new_rid", py_pdb_new_rid, METH_NOARGS,
3724                 "new_rid() -> rid\n\n \
3725                 Get a new rid." },
3726         { "get_trusteddom_pw", py_pdb_get_trusteddom_pw, METH_VARARGS,
3727                 "get_trusteddom_pw(domain) -> Mapping\n\n \
3728                 Get trusted domain password, sid and last set time in a dictionary." },
3729         { "set_trusteddom_pw", py_pdb_set_trusteddom_pw, METH_VARARGS,
3730                 "set_trusteddom_pw(domain, pwd, sid) -> None\n\n \
3731                 Set trusted domain password." },
3732         { "del_trusteddom_pw", py_pdb_del_trusteddom_pw, METH_VARARGS,
3733                 "del_trusteddom_pw(domain) -> None\n\n \
3734                 Delete trusted domain password." },
3735         { "enum_trusteddoms", py_pdb_enum_trusteddoms, METH_NOARGS,
3736                 "enum_trusteddoms() -> List\n\n \
3737                 Get list of trusted domains. Each item is a dictionary with name and sid keys" },
3738         { "get_trusted_domain", py_pdb_get_trusted_domain, METH_VARARGS,
3739                 "get_trusted_domain(domain) -> Mapping\n\n \
3740                 Get trusted domain information by name. Information is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3741         { "get_trusted_domain_by_sid", py_pdb_get_trusted_domain_by_sid, METH_VARARGS,
3742                 "get_trusted_domain_by_sid(domain_sid) -> Mapping\n\n \
3743                 Get trusted domain information by sid. Information is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info" },
3744         { "set_trusted_domain", py_pdb_set_trusted_domain, METH_VARARGS,
3745                 "set_trusted_domain(domain, Mapping) -> None\n\n \
3746                 Set trusted domain information for domain. Mapping is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3747         { "del_trusted_domain", py_pdb_del_trusted_domain, METH_VARARGS,
3748                 "del_trusted_domain(domain) -> None\n\n \
3749                 Delete trusted domain." },
3750         { "enum_trusted_domains", py_pdb_enum_trusted_domains, METH_VARARGS,
3751                 "enum_trusted_domains() -> List\n\n \
3752                 Get list of trusted domains. Each entry is a dictionary with keys - domain_name, netbios_name, security_identifier, trust_auth_incoming, trust_auth_outgoing, trust_direction, trust_type, trust_attributes, trust_forest_trust_info." },
3753         { "get_secret", py_pdb_get_secret, METH_VARARGS,
3754                 "get_secret(secret_name) -> Mapping\n\n \
3755                 Get secret information for secret_name. Information is a dictionary with keys - secret_current, secret_current_lastchange, secret_old, secret_old_lastchange, sd." },
3756         { "set_secret", py_pdb_set_secret, METH_VARARGS,
3757                 "set_secret(secret_name, Mapping) -> None\n\n \
3758                 Set secret information for secret_name using dictionary with keys - secret_current, sd." },
3759         { "delete_secret", py_pdb_delete_secret, METH_VARARGS,
3760                 "delete_secret(secret_name) -> None\n\n \
3761                 Delete secret information for secret_name." },
3762         {0},
3763 };
3764
3765
3766 static PyObject *py_pdb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3767 {
3768         TALLOC_CTX *frame = talloc_stackframe();
3769         const char *url = NULL;
3770         PyObject *pypdb;
3771         NTSTATUS status;
3772         struct pdb_methods *methods;
3773
3774         if (!PyArg_ParseTuple(args, "s", &url)) {
3775                 talloc_free(frame);
3776                 return NULL;
3777         }
3778
3779         /* Initialize list of methods */
3780         status = make_pdb_method_name(&methods, url);
3781         if (!NT_STATUS_IS_OK(status)) {
3782                 PyErr_Format(py_pdb_error, "Cannot load backend methods for '%s' backend (%d,%s)",
3783                                 url,
3784                                 NT_STATUS_V(status),
3785                                 get_friendly_nt_error_msg(status));
3786                 talloc_free(frame);
3787                 return NULL;
3788         }
3789
3790         if ((pypdb = pytalloc_steal(type, methods)) == NULL) {
3791                 PyErr_NoMemory();
3792                 talloc_free(frame);
3793                 return NULL;
3794         }
3795
3796         talloc_free(frame);
3797         return pypdb;
3798 }
3799
3800
3801 static PyTypeObject PyPDB = {
3802         .tp_name = "passdb.PDB",
3803         .tp_new = py_pdb_new,
3804         .tp_flags = Py_TPFLAGS_DEFAULT,
3805         .tp_methods = py_pdb_methods,
3806         .tp_doc = "PDB(url[, read_write_flags]) -> Password DB object\n",
3807 };
3808
3809
3810 /*
3811  * Return a list of passdb backends
3812  */
3813 static PyObject *py_passdb_backends(PyObject *self, PyObject *unused)
3814 {
3815         TALLOC_CTX *frame = talloc_stackframe();
3816         PyObject *py_blist;
3817         const struct pdb_init_function_entry *entry;
3818
3819         entry = pdb_get_backends();
3820         if(! entry) {
3821                 Py_RETURN_NONE;
3822         }
3823
3824         if((py_blist = PyList_New(0)) == NULL) {
3825                 PyErr_NoMemory();
3826                 talloc_free(frame);
3827                 return NULL;
3828         }
3829
3830         while(entry) {
3831                 int res = 0;
3832                 PyObject *entry_name = PyUnicode_FromString(entry->name);
3833                 if (entry_name) {
3834                         res = PyList_Append(py_blist, entry_name);
3835                 } else {
3836                         Py_CLEAR(entry_name);
3837                         Py_CLEAR(py_blist);
3838                         break;
3839                 }
3840                 Py_CLEAR(entry_name);
3841                 if (res == -1) {
3842                         Py_CLEAR(py_blist);
3843                         break;
3844                 }
3845                 entry = entry->next;
3846         }
3847
3848         talloc_free(frame);
3849         return py_blist;
3850 }
3851
3852
3853 static PyObject *py_set_smb_config(PyObject *self, PyObject *args)
3854 {
3855         TALLOC_CTX *frame = talloc_stackframe();
3856         const char *smb_config;
3857
3858         if (!PyArg_ParseTuple(args, "s", &smb_config)) {
3859                 talloc_free(frame);
3860                 return NULL;
3861         }
3862
3863         /* Load smbconf parameters */
3864         if (!lp_load_global(smb_config)) {
3865                 PyErr_Format(py_pdb_error, "Cannot open '%s'", smb_config);
3866                 talloc_free(frame);
3867                 return NULL;
3868         }
3869
3870         talloc_free(frame);
3871         Py_RETURN_NONE;
3872 }
3873
3874
3875 static PyObject *py_set_secrets_dir(PyObject *self, PyObject *args)
3876 {
3877         TALLOC_CTX *frame = talloc_stackframe();
3878         const char *private_dir;
3879
3880         if (!PyArg_ParseTuple(args, "s", &private_dir)) {
3881                 talloc_free(frame);
3882                 return NULL;
3883         }
3884
3885         /* Initialize secrets database */
3886         if (!secrets_init_path(private_dir)) {
3887                 PyErr_Format(py_pdb_error, "Cannot open secrets file database in '%s'",
3888                                 private_dir);
3889                 talloc_free(frame);
3890                 return NULL;
3891         }
3892
3893         talloc_free(frame);
3894         Py_RETURN_NONE;
3895 }
3896
3897 static PyObject *py_reload_static_pdb(PyObject *self, PyObject *args)
3898 {
3899         TALLOC_CTX *frame = talloc_stackframe();
3900
3901         /* Initialize secrets database */
3902         if (!initialize_password_db(true, NULL)) {
3903                 PyErr_Format(py_pdb_error, "Cannot re-open passdb backend %s", lp_passdb_backend());
3904                 talloc_free(frame);
3905                 return NULL;
3906         }
3907
3908         talloc_free(frame);
3909         Py_RETURN_NONE;
3910 }
3911
3912 static PyObject *py_get_domain_sid(PyObject *self, PyObject *unused)
3913 {
3914         TALLOC_CTX *frame = talloc_stackframe();
3915         struct dom_sid domain_sid, *domain_sid_copy;
3916         PyObject *py_dom_sid = Py_None;
3917         bool ret = false;
3918
3919         ret = secrets_fetch_domain_sid(lp_workgroup(), &domain_sid);
3920         if (!ret) {
3921                 talloc_free(frame);
3922                 return PyErr_NoMemory();
3923         }
3924
3925         domain_sid_copy = dom_sid_dup(frame, &domain_sid);
3926         if (domain_sid_copy == NULL) {
3927                 talloc_free(frame);
3928                 return PyErr_NoMemory();
3929         }
3930
3931         py_dom_sid = pytalloc_steal(dom_sid_Type, domain_sid_copy);
3932
3933         talloc_free(frame);
3934         return py_dom_sid;
3935 }
3936
3937 static PyObject *py_get_global_sam_sid(PyObject *self, PyObject *unused)
3938 {
3939         TALLOC_CTX *frame = talloc_stackframe();
3940         struct dom_sid *domain_sid, *domain_sid_copy;
3941         PyObject *py_dom_sid;
3942
3943         domain_sid = get_global_sam_sid();
3944
3945         domain_sid_copy = dom_sid_dup(frame, domain_sid);
3946         if (domain_sid_copy == NULL) {
3947                 PyErr_NoMemory();
3948                 talloc_free(frame);
3949                 return NULL;
3950         }
3951
3952         py_dom_sid = pytalloc_steal(dom_sid_Type, domain_sid_copy);
3953
3954         talloc_free(frame);
3955         return py_dom_sid;
3956 }
3957
3958
3959 static PyMethodDef py_passdb_methods[] = {
3960         { "get_backends", py_passdb_backends, METH_NOARGS,
3961                 "get_backends() -> list\n\n \
3962                 Get a list of password database backends supported." },
3963         { "set_smb_config", py_set_smb_config, METH_VARARGS,
3964                 "set_smb_config(path) -> None\n\n \
3965                 Set path to smb.conf file to load configuration parameters." },
3966         { "set_secrets_dir", py_set_secrets_dir, METH_VARARGS,
3967                 "set_secrets_dir(private_dir) -> None\n\n \
3968                 Set path to private directory to load secrets database from non-default location." },
3969         { "get_global_sam_sid", py_get_global_sam_sid, METH_NOARGS,
3970                 "get_global_sam_sid() -> dom_sid\n\n \
3971                 Return domain SID." },
3972         { "get_domain_sid", py_get_domain_sid, METH_NOARGS,
3973                 "get_domain_sid() -> dom_sid\n\n \
3974                 Return domain SID from secrets database." },
3975         { "reload_static_pdb", py_reload_static_pdb, METH_NOARGS,
3976                 "reload_static_pdb() -> None\n\n \
3977                 Re-initialise the static pdb used internally.  Needed if 'passdb backend' is changed." },
3978         {0},
3979 };
3980
3981 static struct PyModuleDef moduledef = {
3982     PyModuleDef_HEAD_INIT,
3983     .m_name = "passdb",
3984     .m_doc = "SAMBA Password Database",
3985     .m_size = -1,
3986     .m_methods = py_passdb_methods,
3987 };
3988
3989 MODULE_INIT_FUNC(passdb)
3990 {
3991         TALLOC_CTX *frame = talloc_stackframe();
3992         PyObject *m = NULL, *mod = NULL;
3993         char exception_name[] = "passdb.error";
3994
3995         if (pytalloc_BaseObject_PyType_Ready(&PyPDB) < 0) {
3996                 talloc_free(frame);
3997                 return NULL;
3998         }
3999
4000         if (pytalloc_BaseObject_PyType_Ready(&PySamu) < 0) {
4001                 talloc_free(frame);
4002                 return NULL;
4003         }
4004
4005         if (pytalloc_BaseObject_PyType_Ready(&PyGroupmap) < 0) {
4006                 talloc_free(frame);
4007                 return NULL;
4008         }
4009
4010         m = PyModule_Create(&moduledef);
4011         if (m == NULL) {
4012             talloc_free(frame);
4013             return NULL;
4014         }
4015
4016         /* Create new exception for passdb module */
4017         py_pdb_error = PyErr_NewException(exception_name, NULL, NULL);
4018         Py_INCREF(py_pdb_error);
4019         PyModule_AddObject(m, "error", py_pdb_error);
4020
4021         Py_INCREF(&PyPDB);
4022         PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB);
4023
4024         Py_INCREF(&PySamu);
4025         PyModule_AddObject(m, "Samu", (PyObject *)&PySamu);
4026
4027         Py_INCREF(&PyGroupmap);
4028         PyModule_AddObject(m, "Groupmap", (PyObject *)&PyGroupmap);
4029
4030         /* Import dom_sid type from dcerpc.security */
4031         mod = PyImport_ImportModule("samba.dcerpc.security");
4032         if (mod == NULL) {
4033                 talloc_free(frame);
4034                 return NULL;
4035         }
4036
4037         dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid");
4038         if (dom_sid_Type == NULL) {
4039                 Py_DECREF(mod);
4040                 talloc_free(frame);
4041                 return NULL;
4042         }
4043
4044         /* Import security_descriptor type from dcerpc.security */
4045         security_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "descriptor");
4046         Py_DECREF(mod);
4047         if (security_Type == NULL) {
4048                 Py_DECREF(dom_sid_Type);
4049                 talloc_free(frame);
4050                 return NULL;
4051         }
4052
4053         /* Import GUID type from dcerpc.misc */
4054         mod = PyImport_ImportModule("samba.dcerpc.misc");
4055         if (mod == NULL) {
4056                 Py_DECREF(security_Type);
4057                 Py_DECREF(dom_sid_Type);
4058                 talloc_free(frame);
4059                 return NULL;
4060         }
4061
4062         guid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "GUID");
4063         Py_DECREF(mod);
4064         if (guid_Type == NULL) {
4065                 Py_DECREF(security_Type);
4066                 Py_DECREF(dom_sid_Type);
4067                 talloc_free(frame);
4068                 return NULL;
4069         }
4070         talloc_free(frame);
4071         return m;
4072 }