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