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