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