2b3ac5211051fd15bc68743f39bbbb25a4bd4ee7
[idra/samba.git] / source3 / passdb / py_passdb.c
1 /*
2    Python interface to passdb
3
4    Copyright (C) Amitay Isaacs 2011
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <Python.h>
21 #include <pytalloc.h>
22 #include "includes.h"
23 #include "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 *guid_Type = NULL;
47
48 staticforward PyTypeObject PySamu;
49 staticforward PyTypeObject PyGroupmap;
50 staticforward PyTypeObject PyPDB;
51
52 static PyObject *py_pdb_error;
53
54 void initpassdb(void);
55
56
57 /************************** PIDL Autogeneratd ******************************/
58
59 static PyObject *py_samu_get_logon_time(PyObject *obj, void *closure)
60 {
61         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
62         PyObject *py_logon_time;
63
64         py_logon_time = PyInt_FromLong(pdb_get_logon_time(sam_acct));
65         return py_logon_time;
66 }
67
68 static int py_samu_set_logon_time(PyObject *obj, PyObject *value, void *closure)
69 {
70         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
71
72         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
73         if (!pdb_set_logon_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
74                 return -1;
75         }
76         return 0;
77 }
78
79 static PyObject *py_samu_get_logoff_time(PyObject *obj, void *closure)
80 {
81         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
82         PyObject *py_logoff_time;
83
84         py_logoff_time = PyInt_FromLong(pdb_get_logoff_time(sam_acct));
85         return py_logoff_time;
86 }
87
88 static int py_samu_set_logoff_time(PyObject *obj, PyObject *value, void *closure)
89 {
90         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
91
92         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
93         if (!pdb_set_logoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
94                 return -1;
95         }
96         return 0;
97 }
98
99 static PyObject *py_samu_get_kickoff_time(PyObject *obj, void *closure)
100 {
101         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
102         PyObject *py_kickoff_time;
103
104         py_kickoff_time = PyInt_FromLong(pdb_get_kickoff_time(sam_acct));
105         return py_kickoff_time;
106 }
107
108 static int py_samu_set_kickoff_time(PyObject *obj, PyObject *value, void *closure)
109 {
110         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
111
112         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
113         if (!pdb_set_kickoff_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
114                 return -1;
115         }
116         return 0;
117 }
118
119 static PyObject *py_samu_get_bad_password_time(PyObject *obj, void *closure)
120 {
121         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
122         PyObject *py_bad_password_time;
123
124         py_bad_password_time = PyInt_FromLong(pdb_get_bad_password_time(sam_acct));
125         return py_bad_password_time;
126 }
127
128 static int py_samu_set_bad_password_time(PyObject *obj, PyObject *value, void *closure)
129 {
130         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
131
132         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
133         if (!pdb_set_bad_password_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
134                 return -1;
135         }
136         return 0;
137 }
138
139 static PyObject *py_samu_get_pass_last_set_time(PyObject *obj, void *closure)
140 {
141         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
142         PyObject *py_pass_last_set_time;
143
144         py_pass_last_set_time = PyInt_FromLong(pdb_get_pass_last_set_time(sam_acct));
145         return py_pass_last_set_time;
146 }
147
148 static int py_samu_set_pass_last_set_time(PyObject *obj, PyObject *value, void *closure)
149 {
150         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
151
152         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
153         if (!pdb_set_pass_last_set_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
154                 return -1;
155         }
156         return 0;
157 }
158
159 static PyObject *py_samu_get_pass_can_change_time(PyObject *obj, void *closure)
160 {
161         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
162         PyObject *py_pass_can_change_time;
163
164         py_pass_can_change_time = PyInt_FromLong(pdb_get_pass_can_change_time(sam_acct));
165         return py_pass_can_change_time;
166 }
167
168 static int py_samu_set_pass_can_change_time(PyObject *obj, PyObject *value, void *closure)
169 {
170         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
171
172         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
173         if (!pdb_set_pass_can_change_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
174                 return -1;
175         }
176         return 0;
177 }
178
179 static PyObject *py_samu_get_pass_must_change_time(PyObject *obj, void *closure)
180 {
181         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
182         PyObject *py_pass_must_change_time;
183
184         py_pass_must_change_time = PyInt_FromLong(pdb_get_pass_must_change_time(sam_acct));
185         return py_pass_must_change_time;
186 }
187
188 static int py_samu_set_pass_must_change_time(PyObject *obj, PyObject *value, void *closure)
189 {
190         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
191
192         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
193         if (!pdb_set_pass_must_change_time(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
194                 return -1;
195         }
196         return 0;
197 }
198
199 static PyObject *py_samu_get_username(PyObject *obj, void *closure)
200 {
201         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
202         PyObject *py_username;
203         const char *username;
204
205         username = pdb_get_username(sam_acct);
206         if (username == NULL) {
207                 Py_RETURN_NONE;
208         }
209
210         py_username = PyString_FromString(username);
211         return py_username;
212 }
213
214 static int py_samu_set_username(PyObject *obj, PyObject *value, void *closure)
215 {
216         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
217
218         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
219         if (!pdb_set_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
220                 return -1;
221         }
222         return 0;
223 }
224
225 static PyObject *py_samu_get_domain(PyObject *obj, void *closure)
226 {
227         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
228         PyObject *py_domain;
229         const char *domain;
230
231         domain = pdb_get_domain(sam_acct);
232         if (domain == NULL) {
233                 Py_RETURN_NONE;
234         }
235
236         py_domain = PyString_FromString(domain);
237         return py_domain;
238 }
239
240 static int py_samu_set_domain(PyObject *obj, PyObject *value, void *closure)
241 {
242         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
243
244         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
245         if (!pdb_set_domain(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
246                 return -1;
247         }
248         return 0;
249 }
250
251 static PyObject *py_samu_get_nt_username(PyObject *obj, void *closure)
252 {
253         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
254         PyObject *py_nt_username;
255         const char *nt_username;
256
257         nt_username = pdb_get_nt_username(sam_acct);
258         if (nt_username == NULL) {
259                 Py_RETURN_NONE;
260         }
261
262         py_nt_username = PyString_FromString(nt_username);
263         return py_nt_username;
264 }
265
266 static int py_samu_set_nt_username(PyObject *obj, PyObject *value, void *closure)
267 {
268         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
269
270         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
271         if (!pdb_set_nt_username(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
272                 return -1;
273         }
274         return 0;
275 }
276
277 static PyObject *py_samu_get_full_name(PyObject *obj, void *closure)
278 {
279         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
280         PyObject *py_full_name;
281         const char *full_name;
282
283         full_name = pdb_get_fullname(sam_acct);
284         if (full_name == NULL) {
285                 Py_RETURN_NONE;
286         }
287
288         py_full_name = PyString_FromString(full_name);
289         return py_full_name;
290 }
291
292 static int py_samu_set_full_name(PyObject *obj, PyObject *value, void *closure)
293 {
294         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
295
296         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
297         if (!pdb_set_fullname(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
298                 return -1;
299         }
300         return 0;
301 }
302
303 static PyObject *py_samu_get_home_dir(PyObject *obj, void *closure)
304 {
305         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
306         PyObject *py_home_dir;
307         const char *home_dir;
308
309         home_dir = pdb_get_homedir(sam_acct);
310         if (home_dir == NULL) {
311                 Py_RETURN_NONE;
312         }
313
314         py_home_dir = PyString_FromString(home_dir);
315         return py_home_dir;
316 }
317
318 static int py_samu_set_home_dir(PyObject *obj, PyObject *value, void *closure)
319 {
320         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
321
322         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
323         if (!pdb_set_homedir(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
324                 return -1;
325         }
326         return 0;
327 }
328
329 static PyObject *py_samu_get_dir_drive(PyObject *obj, void *closure)
330 {
331         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
332         PyObject *py_dir_drive;
333         const char *dir_drive;
334
335         dir_drive = pdb_get_dir_drive(sam_acct);
336         if (dir_drive == NULL) {
337                 Py_RETURN_NONE;
338         }
339
340         py_dir_drive = PyString_FromString(dir_drive);
341         return py_dir_drive;
342 }
343
344 static int py_samu_set_dir_drive(PyObject *obj, PyObject *value, void *closure)
345 {
346         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
347
348         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
349         if (!pdb_set_dir_drive(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
350                 return -1;
351         }
352         return 0;
353 }
354
355 static PyObject *py_samu_get_logon_script(PyObject *obj, void *closure)
356 {
357         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
358         PyObject *py_logon_script;
359         const char *logon_script;
360
361         logon_script = pdb_get_logon_script(sam_acct);
362         if (logon_script == NULL) {
363                 Py_RETURN_NONE;
364         }
365
366         py_logon_script = PyString_FromString(logon_script);
367         return py_logon_script;
368 }
369
370 static int py_samu_set_logon_script(PyObject *obj, PyObject *value, void *closure)
371 {
372         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
373
374         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
375         if (!pdb_set_logon_script(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
376                 return -1;
377         }
378         return 0;
379 }
380
381 static PyObject *py_samu_get_profile_path(PyObject *obj, void *closure)
382 {
383         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
384         PyObject *py_profile_path;
385         const char *profile_path;
386
387         profile_path = pdb_get_profile_path(sam_acct);
388         if (profile_path == NULL) {
389                 Py_RETURN_NONE;
390         }
391
392         py_profile_path = PyString_FromString(profile_path);
393         return py_profile_path;
394 }
395
396 static int py_samu_set_profile_path(PyObject *obj, PyObject *value, void *closure)
397 {
398         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
399
400         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
401         if (!pdb_set_profile_path(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
402                 return -1;
403         }
404         return 0;
405 }
406
407 static PyObject *py_samu_get_acct_desc(PyObject *obj, void *closure)
408 {
409         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
410         PyObject *py_acct_desc;
411         const char *acct_desc;
412
413         acct_desc = pdb_get_acct_desc(sam_acct);
414         if (acct_desc == NULL) {
415                 Py_RETURN_NONE;
416         }
417
418         py_acct_desc = PyString_FromString(acct_desc);
419         return py_acct_desc;
420 }
421
422 static int py_samu_set_acct_desc(PyObject *obj, PyObject *value, void *closure)
423 {
424         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
425
426         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
427         if (!pdb_set_acct_desc(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
428                 return -1;
429         }
430         return 0;
431 }
432
433 static PyObject *py_samu_get_workstations(PyObject *obj, void *closure)
434 {
435         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
436         PyObject *py_workstations;
437         const char *workstations;
438
439         workstations = pdb_get_workstations(sam_acct);
440         if (workstations == NULL) {
441                 Py_RETURN_NONE;
442         }
443
444         py_workstations = PyString_FromString(workstations);
445         return py_workstations;
446 }
447
448 static int py_samu_set_workstations(PyObject *obj, PyObject *value, void *closure)
449 {
450         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
451
452         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
453         if (!pdb_set_workstations(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
454                 return -1;
455         }
456         return 0;
457 }
458
459 static PyObject *py_samu_get_comment(PyObject *obj, void *closure)
460 {
461         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
462         PyObject *py_comment;
463         const char *comment;
464
465         comment = pdb_get_comment(sam_acct);
466         if (comment == NULL) {
467                 Py_RETURN_NONE;
468         }
469
470         py_comment = PyString_FromString(comment);
471         return py_comment;
472 }
473
474 static int py_samu_set_comment(PyObject *obj, PyObject *value, void *closure)
475 {
476         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
477
478         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
479         if (!pdb_set_comment(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
480                 return -1;
481         }
482         return 0;
483 }
484
485 static PyObject *py_samu_get_munged_dial(PyObject *obj, void *closure)
486 {
487         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
488         PyObject *py_munged_dial;
489         const char *munged_dial;
490
491         munged_dial = pdb_get_munged_dial(sam_acct);
492         if (munged_dial == NULL) {
493                 Py_RETURN_NONE;
494         }
495
496         py_munged_dial = PyString_FromString(munged_dial);
497         return py_munged_dial;
498 }
499
500 static int py_samu_set_munged_dial(PyObject *obj, PyObject *value, void *closure)
501 {
502         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
503
504         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
505         if (!pdb_set_munged_dial(sam_acct, PyString_AsString(value), PDB_CHANGED)) {
506                 return -1;
507         }
508         return 0;
509 }
510
511 static PyObject *py_samu_get_user_sid(PyObject *obj, void *closure)
512 {
513         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
514         PyObject *py_user_sid;
515         const struct dom_sid *user_sid;
516         struct dom_sid *copy_user_sid;
517         TALLOC_CTX *mem_ctx;
518
519         user_sid = pdb_get_user_sid(sam_acct);
520         if(user_sid == NULL) {
521                 Py_RETURN_NONE;
522         }
523
524         mem_ctx = talloc_new(NULL);
525         if (mem_ctx == NULL) {
526                 PyErr_NoMemory();
527                 return NULL;
528         }
529         copy_user_sid = dom_sid_dup(mem_ctx, user_sid);
530         if (copy_user_sid == NULL) {
531                 PyErr_NoMemory();
532                 talloc_free(mem_ctx);
533                 return NULL;
534         }
535
536         py_user_sid = pytalloc_steal(dom_sid_Type, copy_user_sid);
537
538         talloc_free(mem_ctx);
539
540         return py_user_sid;
541 }
542
543 static int py_samu_set_user_sid(PyObject *obj, PyObject *value, void *closure)
544 {
545         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
546
547         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
548         if (!pdb_set_user_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
549                 return -1;
550         }
551         return 0;
552 }
553
554 static PyObject *py_samu_get_group_sid(PyObject *obj, void *closure)
555 {
556         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
557         PyObject *py_group_sid;
558         const struct dom_sid *group_sid;
559         struct dom_sid *copy_group_sid;
560         TALLOC_CTX *mem_ctx;
561
562         group_sid = pdb_get_group_sid(sam_acct);
563         if (group_sid == NULL) {
564                 Py_RETURN_NONE;
565         }
566
567         mem_ctx = talloc_new(NULL);
568         if (mem_ctx == NULL) {
569                 PyErr_NoMemory();
570                 return NULL;
571         }
572         copy_group_sid = dom_sid_dup(mem_ctx, group_sid);
573         if (copy_group_sid == NULL) {
574                 PyErr_NoMemory();
575                 talloc_free(mem_ctx);
576                 return NULL;
577         }
578
579         py_group_sid = pytalloc_steal(dom_sid_Type, copy_group_sid);
580
581         talloc_free(mem_ctx);
582
583         return py_group_sid;
584 }
585
586 static int py_samu_set_group_sid(PyObject *obj, PyObject *value, void *closure)
587 {
588         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
589
590         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
591         if (!pdb_set_group_sid(sam_acct, (struct dom_sid *)pytalloc_get_ptr(value), PDB_CHANGED)) {
592                 return -1;
593         }
594         return 0;
595 }
596
597 static PyObject *py_samu_get_lanman_passwd(PyObject *obj, void *closure)
598 {
599         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
600         PyObject *py_lm_pw;
601         const char *lm_pw;
602
603         lm_pw = (const char *)pdb_get_lanman_passwd(sam_acct);
604         if (lm_pw == NULL) {
605                 Py_RETURN_NONE;
606         }
607
608         py_lm_pw = PyString_FromString(lm_pw);
609         return py_lm_pw;
610 }
611
612 static int py_samu_set_lanman_passwd(PyObject *obj, PyObject *value, void *closure)
613 {
614         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
615
616         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
617         if (!pdb_set_lanman_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
618                 return -1;
619         }
620         return 0;
621 }
622
623 static PyObject *py_samu_get_nt_passwd(PyObject *obj, void *closure)
624 {
625         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
626         PyObject *py_nt_pw;
627         const char *nt_pw;
628
629         nt_pw = (const char *)pdb_get_nt_passwd(sam_acct);
630         if (nt_pw == NULL) {
631                 Py_RETURN_NONE;
632         }
633
634         py_nt_pw = PyString_FromString(nt_pw);
635         return py_nt_pw;
636 }
637
638 static int py_samu_set_nt_passwd(PyObject *obj, PyObject *value, void *closure)
639 {
640         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
641
642         if (!pdb_set_nt_passwd(sam_acct, (uint8_t *)PyString_AsString(value), PDB_CHANGED)) {
643                 return -1;
644         }
645         return 0;
646 }
647
648 static PyObject *py_samu_get_pw_history(PyObject *obj, void *closure)
649 {
650         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
651         PyObject *py_nt_pw_his;
652         const char *nt_pw_his;
653         uint32_t hist_len;
654
655         nt_pw_his = (const char *)pdb_get_pw_history(sam_acct, &hist_len);
656         if (nt_pw_his == NULL) {
657                 Py_RETURN_NONE;
658         }
659
660         py_nt_pw_his = PyString_FromStringAndSize(nt_pw_his, hist_len);
661         return py_nt_pw_his;
662 }
663
664 static int py_samu_set_pw_history(PyObject *obj, PyObject *value, void *closure)
665 {
666         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
667         char *nt_pw_his;
668         Py_ssize_t len;
669         uint32_t hist_len;
670
671         PyString_AsStringAndSize(value, &nt_pw_his, &len);
672         hist_len = len;
673         if (!pdb_set_pw_history(sam_acct, (uint8_t *)nt_pw_his, hist_len, PDB_CHANGED)) {
674                 return -1;
675         }
676         return 0;
677 }
678
679 static PyObject *py_samu_get_plaintext_passwd(PyObject *obj, void *closure)
680 {
681         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
682         PyObject *py_plaintext_pw;
683         const char *plaintext_pw;
684
685         plaintext_pw = pdb_get_plaintext_passwd(sam_acct);
686         if (plaintext_pw == NULL) {
687                 Py_RETURN_NONE;
688         }
689
690         py_plaintext_pw = PyString_FromString(plaintext_pw);
691         return py_plaintext_pw;
692 }
693
694 static int py_samu_set_plaintext_passwd(PyObject *obj, PyObject *value, void *closure)
695 {
696         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
697
698         if (!pdb_set_plaintext_passwd(sam_acct, PyString_AsString(value))) {
699                 return -1;
700         }
701         return 0;
702 }
703
704 static PyObject *py_samu_get_acct_ctrl(PyObject *obj, void *closure)
705 {
706         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
707         PyObject *py_acct_ctrl;
708
709         py_acct_ctrl = PyInt_FromLong(pdb_get_acct_ctrl(sam_acct));
710         return py_acct_ctrl;
711 }
712
713 static int py_samu_set_acct_ctrl(PyObject *obj, PyObject *value, void *closure)
714 {
715         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
716
717         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
718         if (!pdb_set_acct_ctrl(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
719                 return -1;
720         }
721         return 0;
722 }
723
724 static PyObject *py_samu_get_logon_divs(PyObject *obj, void *closure)
725 {
726         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
727         PyObject *py_logon_divs;
728
729         py_logon_divs = PyInt_FromLong(pdb_get_logon_divs(sam_acct));
730         return py_logon_divs;
731 }
732
733 static int py_samu_set_logon_divs(PyObject *obj, PyObject *value, void *closure)
734 {
735         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
736
737         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
738         if (!pdb_set_logon_divs(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
739                 return -1;
740         }
741         return 0;
742 }
743
744 static PyObject *py_samu_get_hours_len(PyObject *obj, void *closure)
745 {
746         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
747         PyObject *py_hours_len;
748
749         py_hours_len = PyInt_FromLong(pdb_get_hours_len(sam_acct));
750         return py_hours_len;
751 }
752
753 static int py_samu_set_hours_len(PyObject *obj, PyObject *value, void *closure)
754 {
755         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
756
757         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
758         if (!pdb_set_hours_len(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
759                 return -1;
760         }
761         return 0;
762 }
763
764 static PyObject *py_samu_get_hours(PyObject *obj, void *closure)
765 {
766         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
767         PyObject *py_hours;
768         const char *hours;
769         int i;
770
771         hours = (const char *)pdb_get_hours(sam_acct);
772         if(! hours) {
773                 Py_RETURN_NONE;
774         }
775
776         if ((py_hours = PyList_New(MAX_HOURS_LEN)) == NULL) {
777                 PyErr_NoMemory();
778                 return NULL;
779         }
780
781         for (i=0; i<MAX_HOURS_LEN; i++) {
782                 PyList_SetItem(py_hours, i, PyInt_FromLong(hours[i]));
783         }
784         return py_hours;
785 }
786
787 static int py_samu_set_hours(PyObject *obj, PyObject *value, void *closure)
788 {
789         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
790         int i;
791         uint8_t *hours;
792         int hours_len;
793         bool status;
794
795         PY_CHECK_TYPE(&PyList_Type, value, return -1;);
796
797         hours_len = PyList_GET_SIZE(value);
798
799         hours = talloc_array(pytalloc_get_mem_ctx(obj), uint8_t, hours_len);
800         if (!hours) {
801                 PyErr_NoMemory();
802                 return -1;
803         }
804
805         for (i=0; i < hours_len; i++) {
806                 PY_CHECK_TYPE(&PyInt_Type, PyList_GET_ITEM(value,i), return -1;);
807                 hours[i] = PyInt_AsLong(PyList_GET_ITEM(value, i));
808         }
809
810         status = pdb_set_hours(sam_acct, hours, hours_len, PDB_CHANGED);
811         talloc_free(hours);
812
813         if(! status) {
814                 return -1;
815         }
816         return 0;
817 }
818
819 static PyObject *py_samu_get_bad_password_count(PyObject *obj, void *closure)
820 {
821         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
822         PyObject *py_bad_password_count;
823
824         py_bad_password_count = PyInt_FromLong(pdb_get_bad_password_count(sam_acct));
825         return py_bad_password_count;
826 }
827
828 static int py_samu_set_bad_password_count(PyObject *obj, PyObject *value, void *closure)
829 {
830         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
831
832         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
833         if (!pdb_set_bad_password_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
834                 return -1;
835         }
836         return 0;
837 }
838
839 static PyObject *py_samu_get_logon_count(PyObject *obj, void *closure)
840 {
841         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
842         PyObject *py_logon_count;
843
844         py_logon_count = PyInt_FromLong(pdb_get_logon_count(sam_acct));
845         return py_logon_count;
846 }
847
848 static int py_samu_set_logon_count(PyObject *obj, PyObject *value, void *closure)
849 {
850         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
851
852         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
853         if (!pdb_set_logon_count(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
854                 return -1;
855         }
856         return 0;
857 }
858
859 static PyObject *py_samu_get_country_code(PyObject *obj, void *closure)
860 {
861         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
862         PyObject *py_country_code;
863
864         py_country_code = PyInt_FromLong(pdb_get_country_code(sam_acct));
865         return py_country_code;
866 }
867
868 static int py_samu_set_country_code(PyObject *obj, PyObject *value, void *closure)
869 {
870         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
871
872         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
873         if (!pdb_set_country_code(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
874                 return -1;
875         }
876         return 0;
877 }
878
879 static PyObject *py_samu_get_code_page(PyObject *obj, void *closure)
880 {
881         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
882         PyObject *py_code_page;
883
884         py_code_page = PyInt_FromLong(pdb_get_code_page(sam_acct));
885         return py_code_page;
886 }
887
888 static int py_samu_set_code_page(PyObject *obj, PyObject *value, void *closure)
889 {
890         struct samu *sam_acct = (struct samu *)pytalloc_get_ptr(obj);
891
892         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
893         if (!pdb_set_code_page(sam_acct, PyInt_AsLong(value), PDB_CHANGED)) {
894                 return -1;
895         }
896         return 0;
897 }
898
899 static PyGetSetDef py_samu_getsetters[] = {
900         { discard_const_p(char, "logon_time"), py_samu_get_logon_time, py_samu_set_logon_time },
901         { discard_const_p(char, "logoff_time"), py_samu_get_logoff_time, py_samu_set_logoff_time },
902         { discard_const_p(char, "kickoff_time"), py_samu_get_kickoff_time, py_samu_set_kickoff_time },
903         { discard_const_p(char, "bad_password_time"), py_samu_get_bad_password_time, py_samu_set_bad_password_time },
904         { discard_const_p(char, "pass_last_set_time"), py_samu_get_pass_last_set_time, py_samu_set_pass_last_set_time },
905         { discard_const_p(char, "pass_can_change_time"), py_samu_get_pass_can_change_time, py_samu_set_pass_can_change_time },
906         { discard_const_p(char, "pass_must_change_time"), py_samu_get_pass_must_change_time, py_samu_set_pass_must_change_time },
907         { discard_const_p(char, "username"), py_samu_get_username, py_samu_set_username },
908         { discard_const_p(char, "domain"), py_samu_get_domain, py_samu_set_domain },
909         { discard_const_p(char, "nt_username"), py_samu_get_nt_username, py_samu_set_nt_username },
910         { discard_const_p(char, "full_name"), py_samu_get_full_name, py_samu_set_full_name },
911         { discard_const_p(char, "home_dir"), py_samu_get_home_dir, py_samu_set_home_dir },
912         { discard_const_p(char, "dir_drive"), py_samu_get_dir_drive, py_samu_set_dir_drive },
913         { discard_const_p(char, "logon_script"), py_samu_get_logon_script, py_samu_set_logon_script },
914         { discard_const_p(char, "profile_path"), py_samu_get_profile_path, py_samu_set_profile_path },
915         { discard_const_p(char, "acct_desc"), py_samu_get_acct_desc, py_samu_set_acct_desc },
916         { discard_const_p(char, "workstations"), py_samu_get_workstations, py_samu_set_workstations },
917         { discard_const_p(char, "comment"), py_samu_get_comment, py_samu_set_comment },
918         { discard_const_p(char, "munged_dial"), py_samu_get_munged_dial, py_samu_set_munged_dial },
919         { discard_const_p(char, "user_sid"), py_samu_get_user_sid, py_samu_set_user_sid },
920         { discard_const_p(char, "group_sid"), py_samu_get_group_sid, py_samu_set_group_sid },
921         { discard_const_p(char, "lanman_passwd"), py_samu_get_lanman_passwd, py_samu_set_lanman_passwd },
922         { discard_const_p(char, "nt_passwd"), py_samu_get_nt_passwd, py_samu_set_nt_passwd },
923         { discard_const_p(char, "pw_history"), py_samu_get_pw_history, py_samu_set_pw_history },
924         { discard_const_p(char, "plaintext_passwd"), py_samu_get_plaintext_passwd, py_samu_set_plaintext_passwd },
925         { discard_const_p(char, "acct_ctrl"), py_samu_get_acct_ctrl, py_samu_set_acct_ctrl },
926         { discard_const_p(char, "logon_divs"), py_samu_get_logon_divs, py_samu_set_logon_divs },
927         { discard_const_p(char, "hours_len"), py_samu_get_hours_len, py_samu_set_hours_len },
928         { discard_const_p(char, "hours"), py_samu_get_hours, py_samu_set_hours },
929         { discard_const_p(char, "bad_password_count"), py_samu_get_bad_password_count, py_samu_set_bad_password_count },
930         { discard_const_p(char, "logon_count"), py_samu_get_logon_count, py_samu_set_logon_count },
931         { discard_const_p(char, "country_code"), py_samu_get_country_code, py_samu_set_country_code },
932         { discard_const_p(char, "code_page"), py_samu_get_code_page, py_samu_set_code_page },
933         { NULL }
934 };
935
936
937 /************************** PIDL Autogeneratd ******************************/
938
939 static PyObject *py_samu_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
940 {
941         struct samu *sam_acct;
942
943         sam_acct = samu_new(NULL);
944         if (!sam_acct) {
945                 PyErr_NoMemory();
946                 return NULL;
947         }
948
949         return pytalloc_steal(type, sam_acct);
950 }
951
952 static PyTypeObject PySamu = {
953         .tp_name = "passdb.Samu",
954         .tp_basicsize = sizeof(pytalloc_Object),
955         .tp_getset = py_samu_getsetters,
956         .tp_methods = NULL,
957         .tp_new = py_samu_new,
958         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
959         .tp_doc = "Samu() -> samu object\n",
960 };
961
962
963 static PyObject *py_groupmap_get_gid(PyObject *obj, void *closure)
964 {
965         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
966         PyObject *py_gid;
967
968         py_gid = PyInt_FromLong(group_map->gid);
969         return py_gid;
970 }
971
972 static int py_groupmap_set_gid(PyObject *obj, PyObject *value, void *closure)
973 {
974         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
975
976         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
977         group_map->gid = PyInt_AsLong(value);
978         return 0;
979 }
980
981 static PyObject *py_groupmap_get_sid(PyObject *obj, void *closure)
982 {
983         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
984         PyObject *py_sid;
985         struct dom_sid *group_sid;
986         TALLOC_CTX *mem_ctx;
987
988         mem_ctx = talloc_new(NULL);
989         if (mem_ctx == NULL) {
990                 PyErr_NoMemory();
991                 return NULL;
992         }
993
994         group_sid = dom_sid_dup(mem_ctx, &group_map->sid);
995         if (group_sid == NULL) {
996                 PyErr_NoMemory();
997                 talloc_free(mem_ctx);
998                 return NULL;
999         }
1000
1001         py_sid = pytalloc_steal(dom_sid_Type, group_sid);
1002
1003         talloc_free(mem_ctx);
1004
1005         return py_sid;
1006 }
1007
1008 static int py_groupmap_set_sid(PyObject *obj, PyObject *value, void *closure)
1009 {
1010         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1011
1012         PY_CHECK_TYPE(dom_sid_Type, value, return -1;);
1013         group_map->sid = *pytalloc_get_type(value, struct dom_sid);
1014         return 0;
1015 }
1016
1017 static PyObject *py_groupmap_get_sid_name_use(PyObject *obj, void *closure)
1018 {
1019         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1020         PyObject *py_sid_name_use;
1021
1022         py_sid_name_use = PyInt_FromLong(group_map->sid_name_use);
1023         return py_sid_name_use;
1024 }
1025
1026 static int py_groupmap_set_sid_name_use(PyObject *obj, PyObject *value, void *closure)
1027 {
1028         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1029
1030         PY_CHECK_TYPE(&PyInt_Type, value, return -1;);
1031         group_map->sid_name_use = PyInt_AsLong(value);
1032         return 0;
1033 }
1034
1035 static PyObject *py_groupmap_get_nt_name(PyObject *obj, void *closure)
1036 {
1037         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1038         PyObject *py_nt_name;
1039         if (group_map->nt_name == NULL) {
1040                 py_nt_name = Py_None;
1041                 Py_INCREF(py_nt_name);
1042         } else {
1043                 py_nt_name = PyString_FromString(group_map->nt_name);
1044         }
1045         return py_nt_name;
1046 }
1047
1048 static int py_groupmap_set_nt_name(PyObject *obj, PyObject *value, void *closure)
1049 {
1050         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1051
1052         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
1053         if (value == Py_None) {
1054                 fstrcpy(group_map->nt_name, NULL);
1055         } else {
1056                 fstrcpy(group_map->nt_name, PyString_AsString(value));
1057         }
1058         return 0;
1059 }
1060
1061 static PyObject *py_groupmap_get_comment(PyObject *obj, void *closure)
1062 {
1063         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1064         PyObject *py_comment;
1065         if (group_map->comment == NULL) {
1066                 py_comment = Py_None;
1067                 Py_INCREF(py_comment);
1068         } else {
1069                 py_comment = PyString_FromString(group_map->comment);
1070         }
1071         return py_comment;
1072 }
1073
1074 static int py_groupmap_set_comment(PyObject *obj, PyObject *value, void *closure)
1075 {
1076         GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj);
1077
1078         PY_CHECK_TYPE(&PyString_Type, value, return -1;);
1079         if (value == Py_None) {
1080                 fstrcpy(group_map->comment, NULL);
1081         } else {
1082                 fstrcpy(group_map->comment, PyString_AsString(value));
1083         }
1084         return 0;
1085 }
1086
1087 static PyGetSetDef py_groupmap_getsetters[] = {
1088         { discard_const_p(char, "gid"), py_groupmap_get_gid, py_groupmap_set_gid },
1089         { discard_const_p(char, "sid"), py_groupmap_get_sid, py_groupmap_set_sid },
1090         { discard_const_p(char, "sid_name_use"), py_groupmap_get_sid_name_use, py_groupmap_set_sid_name_use },
1091         { discard_const_p(char, "nt_name"), py_groupmap_get_nt_name, py_groupmap_set_nt_name },
1092         { discard_const_p(char, "comment"), py_groupmap_get_comment, py_groupmap_set_comment },
1093         { NULL }
1094 };
1095
1096 static PyObject *py_groupmap_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
1097 {
1098         GROUP_MAP *group_map;
1099         TALLOC_CTX *mem_ctx;
1100         PyObject *py_group_map;
1101
1102         mem_ctx = talloc_new(NULL);
1103         if (mem_ctx == NULL) {
1104                 PyErr_NoMemory();
1105                 return NULL;
1106         }
1107
1108         group_map = talloc_zero(mem_ctx, GROUP_MAP);
1109         if (group_map == NULL) {
1110                 PyErr_NoMemory();
1111                 talloc_free(mem_ctx);
1112                 return NULL;
1113         }
1114
1115         py_group_map = pytalloc_steal(type, group_map);
1116         if (py_group_map == NULL) {
1117                 PyErr_NoMemory();
1118                 talloc_free(mem_ctx);
1119                 return NULL;
1120         }
1121
1122         talloc_free(mem_ctx);
1123
1124         return py_group_map;
1125 }
1126
1127
1128 static PyTypeObject PyGroupmap = {
1129         .tp_name = "passdb.Groupmap",
1130         .tp_basicsize = sizeof(pytalloc_Object),
1131         .tp_getset = py_groupmap_getsetters,
1132         .tp_methods = NULL,
1133         .tp_new = py_groupmap_new,
1134         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
1135         .tp_doc = "Groupmap() -> group map object\n",
1136 };
1137
1138
1139 static PyObject *py_pdb_domain_info(pytalloc_Object *self, PyObject *args)
1140 {
1141         struct pdb_methods *methods;
1142         struct pdb_domain_info *domain_info;
1143         PyObject *py_domain_info;
1144         TALLOC_CTX *tframe;
1145         struct dom_sid *sid;
1146         struct GUID *guid;
1147
1148         methods = pytalloc_get_ptr(self);
1149
1150         if ((tframe = talloc_stackframe()) == NULL) {
1151                 PyErr_NoMemory();
1152                 return NULL;
1153         }
1154
1155         domain_info = methods->get_domain_info(methods, tframe);
1156         if (! domain_info) {
1157                 Py_RETURN_NONE;
1158         }
1159
1160         sid = dom_sid_dup(tframe, &domain_info->sid);
1161         if (sid == NULL) {
1162                 PyErr_NoMemory();
1163                 talloc_free(tframe);
1164                 return NULL;
1165         }
1166
1167         guid = talloc(tframe, struct GUID);
1168         if (guid == NULL) {
1169                 PyErr_NoMemory();
1170                 talloc_free(tframe);
1171                 return NULL;
1172         }
1173         *guid = domain_info->guid;
1174
1175         if ((py_domain_info = PyDict_New()) == NULL) {
1176                 PyErr_NoMemory();
1177                 return NULL;
1178         }
1179
1180         PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name));
1181         PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->name));
1182         PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->name));
1183         PyDict_SetItemString(py_domain_info, "dom_sid", pytalloc_steal(dom_sid_Type, sid));
1184         PyDict_SetItemString(py_domain_info, "guid", pytalloc_steal(guid_Type, guid));
1185
1186         talloc_free(tframe);
1187
1188         return py_domain_info;
1189 }
1190
1191
1192 static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args)
1193 {
1194         NTSTATUS status;
1195         const char *username;
1196         struct pdb_methods *methods;
1197         struct samu *sam_acct;
1198         PyObject *py_sam_acct;
1199         TALLOC_CTX *tframe;
1200
1201         if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) {
1202                 return NULL;
1203         }
1204
1205         methods = pytalloc_get_ptr(self);
1206
1207         if ((tframe = talloc_stackframe()) == NULL) {
1208                 PyErr_NoMemory();
1209                 return NULL;
1210         }
1211
1212         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1213         if (py_sam_acct == NULL) {
1214                 PyErr_NoMemory();
1215                 talloc_free(tframe);
1216                 return NULL;
1217         }
1218         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1219
1220         status = methods->getsampwnam(methods, sam_acct, username);
1221         if (!NT_STATUS_IS_OK(status)) {
1222                 PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)",
1223                                 username,
1224                                 NT_STATUS_V(status),
1225                                 get_friendly_nt_error_msg(status));
1226                 Py_DECREF(py_sam_acct);
1227                 talloc_free(tframe);
1228                 return NULL;
1229         }
1230
1231         talloc_free(tframe);
1232         return py_sam_acct;
1233 }
1234
1235 static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args)
1236 {
1237         NTSTATUS status;
1238         struct pdb_methods *methods;
1239         struct samu *sam_acct;
1240         PyObject *py_sam_acct;
1241         TALLOC_CTX *tframe;
1242         PyObject *py_user_sid;
1243
1244         if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) {
1245                 return NULL;
1246         }
1247
1248         methods = pytalloc_get_ptr(self);
1249
1250         if ((tframe = talloc_stackframe()) == NULL) {
1251                 PyErr_NoMemory();
1252                 return NULL;
1253         }
1254
1255         py_sam_acct = py_samu_new(&PySamu, NULL, NULL);
1256         if (py_sam_acct == NULL) {
1257                 PyErr_NoMemory();
1258                 talloc_free(tframe);
1259                 return NULL;
1260         }
1261         sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct);
1262
1263         status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid));
1264         if (!NT_STATUS_IS_OK(status)) {
1265                 PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)",
1266                                 NT_STATUS_V(status),
1267                                 get_friendly_nt_error_msg(status));
1268                 Py_DECREF(py_sam_acct);
1269                 talloc_free(tframe);
1270                 return NULL;
1271         }
1272
1273         talloc_free(tframe);
1274         return py_sam_acct;
1275 }
1276
1277 static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args)
1278 {
1279         NTSTATUS status;
1280         struct pdb_methods *methods;
1281         const char *username;
1282         unsigned int acct_flags;
1283         unsigned int rid;
1284         TALLOC_CTX *tframe;
1285
1286         if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) {
1287                 return NULL;
1288         }
1289
1290         methods = pytalloc_get_ptr(self);
1291
1292         if ((tframe = talloc_stackframe()) == NULL) {
1293                 PyErr_NoMemory();
1294                 return NULL;
1295         }
1296
1297         status = methods->create_user(methods, tframe, username, acct_flags, &rid);
1298         if (!NT_STATUS_IS_OK(status)) {
1299                 PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)",
1300                                 username,
1301                                 NT_STATUS_V(status),
1302                                 get_friendly_nt_error_msg(status));
1303                 talloc_free(tframe);
1304                 return NULL;
1305         }
1306
1307         talloc_free(tframe);
1308         return PyInt_FromLong(rid);
1309 }
1310
1311 static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args)
1312 {
1313         NTSTATUS status;
1314         struct pdb_methods *methods;
1315         TALLOC_CTX *tframe;
1316         struct samu *sam_acct;
1317         PyObject *py_sam_acct;
1318
1319         if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) {
1320                 return NULL;
1321         }
1322
1323         methods = pytalloc_get_ptr(self);
1324
1325         if ((tframe = talloc_stackframe()) == NULL) {
1326                 PyErr_NoMemory();
1327                 return NULL;
1328         }
1329
1330         sam_acct = pytalloc_get_ptr(py_sam_acct);
1331
1332         status = methods->delete_user(methods, tframe, sam_acct);
1333         if (!NT_STATUS_IS_OK(status)) {
1334                 PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)",
1335                                 NT_STATUS_V(status),
1336                                 get_friendly_nt_error_msg(status));
1337                 talloc_free(tframe);
1338                 return NULL;
1339         }
1340
1341         talloc_free(tframe);
1342         Py_RETURN_NONE;
1343 }
1344
1345 static PyObject *py_pdb_add_sam_account(pytalloc_Object *self, PyObject *args)
1346 {
1347         NTSTATUS status;
1348         struct pdb_methods *methods;
1349         TALLOC_CTX *tframe;
1350         struct samu *sam_acct;
1351         PyObject *py_sam_acct;
1352
1353         if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) {
1354                 return NULL;
1355         }
1356
1357         methods = pytalloc_get_ptr(self);
1358
1359         if ((tframe = talloc_stackframe()) == NULL) {
1360                 PyErr_NoMemory();
1361                 return NULL;
1362         }
1363
1364         sam_acct = pytalloc_get_ptr(py_sam_acct);
1365
1366         status = methods->add_sam_account(methods, sam_acct);
1367         if (!NT_STATUS_IS_OK(status)) {
1368                 PyErr_Format(py_pdb_error, "Unable to add sam account, (%d,%s)",
1369                                 NT_STATUS_V(status),
1370                                 get_friendly_nt_error_msg(status));
1371                 talloc_free(tframe);
1372                 return NULL;
1373         }
1374
1375         talloc_free(tframe);
1376         Py_RETURN_NONE;
1377 }
1378
1379 static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args)
1380 {
1381         NTSTATUS status;
1382         struct pdb_methods *methods;
1383         TALLOC_CTX *tframe;
1384         struct samu *sam_acct;
1385         PyObject *py_sam_acct;
1386
1387         if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) {
1388                 return NULL;
1389         }
1390
1391         methods = pytalloc_get_ptr(self);
1392
1393         if ((tframe = talloc_stackframe()) == NULL) {
1394                 PyErr_NoMemory();
1395                 return NULL;
1396         }
1397
1398         sam_acct = pytalloc_get_ptr(py_sam_acct);
1399
1400         status = methods->update_sam_account(methods, sam_acct);
1401         if (!NT_STATUS_IS_OK(status)) {
1402                 PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)",
1403                                 NT_STATUS_V(status),
1404                                 get_friendly_nt_error_msg(status));
1405                 talloc_free(tframe);
1406                 return NULL;
1407         }
1408
1409         talloc_free(tframe);
1410         Py_RETURN_NONE;
1411 }
1412
1413 static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args)
1414 {
1415         NTSTATUS status;
1416         struct pdb_methods *methods;
1417         TALLOC_CTX *tframe;
1418         struct samu *sam_acct;
1419         PyObject *py_sam_acct;
1420
1421         if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) {
1422                 return NULL;
1423         }
1424
1425         methods = pytalloc_get_ptr(self);
1426
1427         if ((tframe = talloc_stackframe()) == NULL) {
1428                 PyErr_NoMemory();
1429                 return NULL;
1430         }
1431
1432         sam_acct = pytalloc_get_ptr(py_sam_acct);
1433
1434         status = methods->delete_sam_account(methods, sam_acct);
1435         if (!NT_STATUS_IS_OK(status)) {
1436                 PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)",
1437                                 NT_STATUS_V(status),
1438                                 get_friendly_nt_error_msg(status));
1439                 talloc_free(tframe);
1440                 return NULL;
1441         }
1442
1443         talloc_free(tframe);
1444         Py_RETURN_NONE;
1445 }
1446
1447 static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args)
1448 {
1449         NTSTATUS status;
1450         struct pdb_methods *methods;
1451         TALLOC_CTX *tframe;
1452         struct samu *sam_acct;
1453         const char *new_username;
1454         PyObject *py_sam_acct;
1455
1456         if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct,
1457                                         &new_username)) {
1458                 return NULL;
1459         }
1460
1461         methods = pytalloc_get_ptr(self);
1462
1463         if ((tframe = talloc_stackframe()) == NULL) {
1464                 PyErr_NoMemory();
1465                 return NULL;
1466         }
1467
1468         sam_acct = pytalloc_get_ptr(py_sam_acct);
1469
1470         status = methods->rename_sam_account(methods, sam_acct, new_username);
1471         if (!NT_STATUS_IS_OK(status)) {
1472                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1473                                 NT_STATUS_V(status),
1474                                 get_friendly_nt_error_msg(status));
1475                 talloc_free(tframe);
1476                 return NULL;
1477         }
1478
1479         talloc_free(tframe);
1480         Py_RETURN_NONE;
1481 }
1482
1483
1484 static PyObject *py_pdb_getgrsid(pytalloc_Object *self, PyObject *args)
1485 {
1486         NTSTATUS status;
1487         struct pdb_methods *methods;
1488         TALLOC_CTX *tframe;
1489         GROUP_MAP *group_map;
1490         struct dom_sid *domain_sid;
1491         PyObject *py_domain_sid, *py_group_map;
1492
1493         if (!PyArg_ParseTuple(args, "O!:getgrsid", dom_sid_Type, &py_domain_sid)) {
1494                 return NULL;
1495         }
1496
1497         methods = pytalloc_get_ptr(self);
1498
1499         if ((tframe = talloc_stackframe()) == NULL) {
1500                 PyErr_NoMemory();
1501                 return NULL;
1502         }
1503
1504         domain_sid = pytalloc_get_ptr(py_domain_sid);
1505
1506         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1507         if (py_group_map == NULL) {
1508                 PyErr_NoMemory();
1509                 talloc_free(tframe);
1510                 return NULL;
1511         }
1512
1513         group_map = pytalloc_get_ptr(py_group_map);
1514
1515         status = methods->getgrsid(methods, group_map, *domain_sid);
1516         if (!NT_STATUS_IS_OK(status)) {
1517                 PyErr_Format(py_pdb_error, "Unable to get group information by sid, (%d,%s)",
1518                                 NT_STATUS_V(status),
1519                                 get_friendly_nt_error_msg(status));
1520                 talloc_free(tframe);
1521                 return NULL;
1522         }
1523
1524         talloc_free(tframe);
1525         return py_group_map;
1526 }
1527
1528
1529 static PyObject *py_pdb_getgrgid(pytalloc_Object *self, PyObject *args)
1530 {
1531         NTSTATUS status;
1532         struct pdb_methods *methods;
1533         TALLOC_CTX *tframe;
1534         GROUP_MAP *group_map;
1535         PyObject *py_group_map;
1536         unsigned int gid_value;
1537
1538         if (!PyArg_ParseTuple(args, "I:getgrgid", &gid_value)) {
1539                 return NULL;
1540         }
1541
1542         methods = pytalloc_get_ptr(self);
1543
1544         if ((tframe = talloc_stackframe()) == NULL) {
1545                 PyErr_NoMemory();
1546                 return NULL;
1547         }
1548
1549         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1550         if (py_group_map == NULL) {
1551                 PyErr_NoMemory();
1552                 talloc_free(tframe);
1553                 return NULL;
1554         }
1555
1556         group_map = pytalloc_get_ptr(py_group_map);
1557
1558         status = methods->getgrgid(methods, group_map, gid_value);
1559         if (!NT_STATUS_IS_OK(status)) {
1560                 PyErr_Format(py_pdb_error, "Unable to get group information by gid, (%d,%s)",
1561                                 NT_STATUS_V(status),
1562                                 get_friendly_nt_error_msg(status));
1563                 talloc_free(tframe);
1564                 return NULL;
1565         }
1566
1567         talloc_free(tframe);
1568         return py_group_map;
1569 }
1570
1571
1572 static PyObject *py_pdb_getgrnam(pytalloc_Object *self, PyObject *args)
1573 {
1574         NTSTATUS status;
1575         struct pdb_methods *methods;
1576         TALLOC_CTX *tframe;
1577         GROUP_MAP *group_map;
1578         PyObject *py_group_map;
1579         const char *groupname;
1580
1581         if (!PyArg_ParseTuple(args, "s:getgrnam", &groupname)) {
1582                 return NULL;
1583         }
1584
1585         methods = pytalloc_get_ptr(self);
1586
1587         if ((tframe = talloc_stackframe()) == NULL) {
1588                 PyErr_NoMemory();
1589                 return NULL;
1590         }
1591
1592         py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1593         if (py_group_map == NULL) {
1594                 PyErr_NoMemory();
1595                 talloc_free(tframe);
1596                 return NULL;
1597         }
1598
1599         group_map = pytalloc_get_ptr(py_group_map);
1600
1601         status = methods->getgrnam(methods, group_map, groupname);
1602         if (!NT_STATUS_IS_OK(status)) {
1603                 PyErr_Format(py_pdb_error, "Unable to get group information by name, (%d,%s)",
1604                                 NT_STATUS_V(status),
1605                                 get_friendly_nt_error_msg(status));
1606                 talloc_free(tframe);
1607                 return NULL;
1608         }
1609
1610         talloc_free(tframe);
1611         return py_group_map;
1612 }
1613
1614
1615 static PyObject *py_pdb_create_dom_group(pytalloc_Object *self, PyObject *args)
1616 {
1617         NTSTATUS status;
1618         struct pdb_methods *methods;
1619         TALLOC_CTX *tframe;
1620         const char *groupname;
1621         uint32_t group_rid;
1622
1623         if (!PyArg_ParseTuple(args, "s:create_dom_group", &groupname)) {
1624                 return NULL;
1625         }
1626
1627         methods = pytalloc_get_ptr(self);
1628
1629         if ((tframe = talloc_stackframe()) == NULL) {
1630                 PyErr_NoMemory();
1631                 return NULL;
1632         }
1633
1634         status = methods->create_dom_group(methods, tframe, groupname, &group_rid);
1635         if (!NT_STATUS_IS_OK(status)) {
1636                 PyErr_Format(py_pdb_error, "Unable to create domain group (%s), (%d,%s)",
1637                                 groupname,
1638                                 NT_STATUS_V(status),
1639                                 get_friendly_nt_error_msg(status));
1640                 talloc_free(tframe);
1641                 return NULL;
1642         }
1643
1644         talloc_free(tframe);
1645         return PyInt_FromLong(group_rid);
1646 }
1647
1648
1649 static PyObject *py_pdb_delete_dom_group(pytalloc_Object *self, PyObject *args)
1650 {
1651         NTSTATUS status;
1652         struct pdb_methods *methods;
1653         TALLOC_CTX *tframe;
1654         unsigned int group_rid;
1655
1656         if (!PyArg_ParseTuple(args, "I:delete_dom_group", &group_rid)) {
1657                 return NULL;
1658         }
1659
1660         methods = pytalloc_get_ptr(self);
1661
1662         if ((tframe = talloc_stackframe()) == NULL) {
1663                 PyErr_NoMemory();
1664                 return NULL;
1665         }
1666
1667         status = methods->delete_dom_group(methods, tframe, group_rid);
1668         if (!NT_STATUS_IS_OK(status)) {
1669                 PyErr_Format(py_pdb_error, "Unable to delete domain group (rid=%d), (%d,%s)",
1670                                 group_rid,
1671                                 NT_STATUS_V(status),
1672                                 get_friendly_nt_error_msg(status));
1673                 talloc_free(tframe);
1674                 return NULL;
1675         }
1676
1677         talloc_free(tframe);
1678         Py_RETURN_NONE;
1679 }
1680
1681
1682 static PyObject *py_pdb_add_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1683 {
1684         NTSTATUS status;
1685         struct pdb_methods *methods;
1686         TALLOC_CTX *tframe;
1687         PyObject *py_group_map;
1688         GROUP_MAP *group_map;
1689
1690         if (!PyArg_ParseTuple(args, "O!:add_group_mapping_entry", &PyGroupmap, &py_group_map)) {
1691                 return NULL;
1692         }
1693
1694         methods = pytalloc_get_ptr(self);
1695
1696         if ((tframe = talloc_stackframe()) == NULL) {
1697                 PyErr_NoMemory();
1698                 return NULL;
1699         }
1700
1701         group_map = pytalloc_get_ptr(py_group_map);
1702
1703         status = methods->add_group_mapping_entry(methods, group_map);
1704         if (!NT_STATUS_IS_OK(status)) {
1705                 PyErr_Format(py_pdb_error, "Unable to add group mapping entry, (%d,%s)",
1706                                 NT_STATUS_V(status),
1707                                 get_friendly_nt_error_msg(status));
1708                 talloc_free(tframe);
1709                 return NULL;
1710         }
1711
1712         talloc_free(tframe);
1713         Py_RETURN_NONE;
1714 }
1715
1716
1717 static PyObject *py_pdb_update_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1718 {
1719         NTSTATUS status;
1720         struct pdb_methods *methods;
1721         TALLOC_CTX *tframe;
1722         PyObject *py_group_map;
1723         GROUP_MAP *group_map;
1724
1725         if (!PyArg_ParseTuple(args, "O!:update_group_mapping_entry", &PyGroupmap, &py_group_map)) {
1726                 return NULL;
1727         }
1728
1729         methods = pytalloc_get_ptr(self);
1730
1731         if ((tframe = talloc_stackframe()) == NULL) {
1732                 PyErr_NoMemory();
1733                 return NULL;
1734         }
1735
1736         group_map = pytalloc_get_ptr(py_group_map);
1737
1738         status = methods->update_group_mapping_entry(methods, group_map);
1739         if (!NT_STATUS_IS_OK(status)) {
1740                 PyErr_Format(py_pdb_error, "Unable to update group mapping entry, (%d,%s)",
1741                                 NT_STATUS_V(status),
1742                                 get_friendly_nt_error_msg(status));
1743                 talloc_free(tframe);
1744                 return NULL;
1745         }
1746
1747         talloc_free(tframe);
1748         Py_RETURN_NONE;
1749 }
1750
1751
1752 static PyObject *py_pdb_delete_group_mapping_entry(pytalloc_Object *self, PyObject *args)
1753 {
1754         NTSTATUS status;
1755         struct pdb_methods *methods;
1756         TALLOC_CTX *tframe;
1757         PyObject *py_group_sid;
1758         struct dom_sid *group_sid;
1759
1760         if (!PyArg_ParseTuple(args, "O!:delete_group_mapping_entry", dom_sid_Type, &py_group_sid)) {
1761                 return NULL;
1762         }
1763
1764         methods = pytalloc_get_ptr(self);
1765
1766         if ((tframe = talloc_stackframe()) == NULL) {
1767                 PyErr_NoMemory();
1768                 return NULL;
1769         }
1770
1771         group_sid = pytalloc_get_ptr(py_group_sid);
1772
1773         status = methods->delete_group_mapping_entry(methods, *group_sid);
1774         if (!NT_STATUS_IS_OK(status)) {
1775                 PyErr_Format(py_pdb_error, "Unable to delete group mapping entry, (%d,%s)",
1776                                 NT_STATUS_V(status),
1777                                 get_friendly_nt_error_msg(status));
1778                 talloc_free(tframe);
1779                 return NULL;
1780         }
1781
1782         talloc_free(tframe);
1783         Py_RETURN_NONE;
1784 }
1785
1786
1787 static PyObject *py_pdb_enum_group_mapping(pytalloc_Object *self, PyObject *args)
1788 {
1789         NTSTATUS status;
1790         struct pdb_methods *methods;
1791         TALLOC_CTX *tframe;
1792         enum lsa_SidType sid_name_use;
1793         int lsa_sidtype_value;
1794         int unix_only;
1795         PyObject *py_domain_sid;
1796         struct dom_sid *domain_sid;
1797         GROUP_MAP *gmap, *group_map;
1798         size_t num_entries;
1799         PyObject *py_gmap_list, *py_group_map;
1800         int i;
1801
1802         if (!PyArg_ParseTuple(args, "O!ii:enum_group_mapping", dom_sid_Type, &py_domain_sid,
1803                                         &lsa_sidtype_value, &unix_only)) {
1804                 return NULL;
1805         }
1806
1807         methods = pytalloc_get_ptr(self);
1808
1809         if ((tframe = talloc_stackframe()) == NULL) {
1810                 PyErr_NoMemory();
1811                 return NULL;
1812         }
1813
1814         sid_name_use = lsa_sidtype_value;
1815
1816         domain_sid = pytalloc_get_ptr(py_domain_sid);
1817
1818         status = methods->enum_group_mapping(methods, domain_sid, sid_name_use,
1819                                                 &gmap, &num_entries, unix_only);
1820         if (!NT_STATUS_IS_OK(status)) {
1821                 PyErr_Format(py_pdb_error, "Unable to enumerate group mappings, (%d,%s)",
1822                                 NT_STATUS_V(status),
1823                                 get_friendly_nt_error_msg(status));
1824                 talloc_free(tframe);
1825                 return NULL;
1826         }
1827
1828         py_gmap_list = PyList_New(0);
1829         if (py_gmap_list == NULL) {
1830                 PyErr_NoMemory();
1831                 talloc_free(tframe);
1832                 return NULL;
1833         }
1834
1835         for(i=0; i<num_entries; i++) {
1836                 py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL);
1837                 if (py_group_map) {
1838                         group_map = pytalloc_get_ptr(py_group_map);
1839                         *group_map = gmap[i];
1840
1841                         PyList_Append(py_gmap_list, py_group_map);
1842                 }
1843         }
1844
1845         free(gmap);
1846         talloc_free(tframe);
1847
1848         return py_gmap_list;
1849 }
1850
1851
1852 static PyObject *py_pdb_enum_group_members(pytalloc_Object *self, PyObject *args)
1853 {
1854         NTSTATUS status;
1855         struct pdb_methods *methods;
1856         TALLOC_CTX *tframe;
1857         PyObject *py_group_sid;
1858         struct dom_sid *group_sid;
1859         uint32_t *member_rids;
1860         size_t num_members;
1861         PyObject *py_rid_list;
1862         int i;
1863
1864         if (!PyArg_ParseTuple(args, "O!:enum_group_members", dom_sid_Type, &py_group_sid)) {
1865                 return NULL;
1866         }
1867
1868         methods = pytalloc_get_ptr(self);
1869
1870         if ((tframe = talloc_stackframe()) == NULL) {
1871                 PyErr_NoMemory();
1872                 return NULL;
1873         }
1874
1875         group_sid = pytalloc_get_ptr(py_group_sid);
1876
1877         status = methods->enum_group_members(methods, tframe, group_sid,
1878                                                 &member_rids, &num_members);
1879         if (!NT_STATUS_IS_OK(status)) {
1880                 PyErr_Format(py_pdb_error, "Unable to enumerate group members, (%d,%s)",
1881                                 NT_STATUS_V(status),
1882                                 get_friendly_nt_error_msg(status));
1883                 talloc_free(tframe);
1884                 return NULL;
1885         }
1886
1887         py_rid_list = PyList_New(0);
1888         if (py_rid_list == NULL) {
1889                 PyErr_NoMemory();
1890                 talloc_free(tframe);
1891                 return NULL;
1892         }
1893
1894         for(i=0; i<num_members; i++) {
1895                 PyList_Append(py_rid_list, PyInt_FromLong(member_rids[i]));
1896         }
1897
1898         talloc_free(tframe);
1899
1900         return py_rid_list;
1901 }
1902
1903
1904 static PyObject *py_pdb_add_groupmem(pytalloc_Object *self, PyObject *args)
1905 {
1906         NTSTATUS status;
1907         struct pdb_methods *methods;
1908         TALLOC_CTX *tframe;
1909         uint32_t group_rid, member_rid;
1910
1911         if (!PyArg_ParseTuple(args, "II:add_groupmem", &group_rid, &member_rid)) {
1912                 return NULL;
1913         }
1914
1915         methods = pytalloc_get_ptr(self);
1916
1917         if ((tframe = talloc_stackframe()) == NULL) {
1918                 PyErr_NoMemory();
1919                 return NULL;
1920         }
1921
1922         status = methods->add_groupmem(methods, tframe, group_rid, member_rid);
1923         if (!NT_STATUS_IS_OK(status)) {
1924                 PyErr_Format(py_pdb_error, "Unable to add group member, (%d,%s)",
1925                                 NT_STATUS_V(status),
1926                                 get_friendly_nt_error_msg(status));
1927                 talloc_free(tframe);
1928                 return NULL;
1929         }
1930
1931         talloc_free(tframe);
1932         Py_RETURN_NONE;
1933 }
1934
1935
1936 static PyObject *py_pdb_del_groupmem(pytalloc_Object *self, PyObject *args)
1937 {
1938         NTSTATUS status;
1939         struct pdb_methods *methods;
1940         TALLOC_CTX *tframe;
1941         uint32_t group_rid, member_rid;
1942
1943         if (!PyArg_ParseTuple(args, "II:del_groupmem", &group_rid, &member_rid)) {
1944                 return NULL;
1945         }
1946
1947         methods = pytalloc_get_ptr(self);
1948
1949         if ((tframe = talloc_stackframe()) == NULL) {
1950                 PyErr_NoMemory();
1951                 return NULL;
1952         }
1953
1954         status = methods->del_groupmem(methods, tframe, group_rid, member_rid);
1955         if (!NT_STATUS_IS_OK(status)) {
1956                 PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)",
1957                                 NT_STATUS_V(status),
1958                                 get_friendly_nt_error_msg(status));
1959                 talloc_free(tframe);
1960                 return NULL;
1961         }
1962
1963         talloc_free(tframe);
1964         Py_RETURN_NONE;
1965 }
1966
1967
1968 static PyObject *py_pdb_create_alias(pytalloc_Object *self, PyObject *args)
1969 {
1970         NTSTATUS status;
1971         struct pdb_methods *methods;
1972         TALLOC_CTX *tframe;
1973         const char *alias_name;
1974         uint32_t rid;
1975
1976         if (!PyArg_ParseTuple(args, "s:create_alias", &alias_name)) {
1977                 return NULL;
1978         }
1979
1980         methods = pytalloc_get_ptr(self);
1981
1982         if ((tframe = talloc_stackframe()) == NULL) {
1983                 PyErr_NoMemory();
1984                 return NULL;
1985         }
1986
1987         status = methods->create_alias(methods, alias_name, &rid);
1988         if (!NT_STATUS_IS_OK(status)) {
1989                 PyErr_Format(py_pdb_error, "Unable to create alias (%s), (%d,%s)",
1990                                 alias_name,
1991                                 NT_STATUS_V(status),
1992                                 get_friendly_nt_error_msg(status));
1993                 talloc_free(tframe);
1994                 return NULL;
1995         }
1996
1997         talloc_free(tframe);
1998
1999         return PyInt_FromLong(rid);
2000 }
2001
2002
2003 static PyObject *py_pdb_delete_alias(pytalloc_Object *self, PyObject *args)
2004 {
2005         NTSTATUS status;
2006         struct pdb_methods *methods;
2007         TALLOC_CTX *tframe;
2008         PyObject *py_alias_sid;
2009         struct dom_sid *alias_sid;
2010
2011         if (!PyArg_ParseTuple(args, "O!:delete_alias", dom_sid_Type, &py_alias_sid)) {
2012                 return NULL;
2013         }
2014
2015         methods = pytalloc_get_ptr(self);
2016
2017         if ((tframe = talloc_stackframe()) == NULL) {
2018                 PyErr_NoMemory();
2019                 return NULL;
2020         }
2021
2022         alias_sid = pytalloc_get_ptr(py_alias_sid);
2023
2024         status = methods->delete_alias(methods, alias_sid);
2025         if (!NT_STATUS_IS_OK(status)) {
2026                 PyErr_Format(py_pdb_error, "Unable to delete alias, (%d,%s)",
2027                                 NT_STATUS_V(status),
2028                                 get_friendly_nt_error_msg(status));
2029                 talloc_free(tframe);
2030                 return NULL;
2031         }
2032
2033         talloc_free(tframe);
2034         Py_RETURN_NONE;
2035 }
2036
2037
2038 static PyObject *py_pdb_get_aliasinfo(pytalloc_Object *self, PyObject *args)
2039 {
2040         NTSTATUS status;
2041         struct pdb_methods *methods;
2042         TALLOC_CTX *tframe;
2043         PyObject *py_alias_sid;
2044         struct dom_sid *alias_sid;
2045         struct acct_info alias_info;
2046         PyObject *py_alias_info;
2047
2048         if (!PyArg_ParseTuple(args, "O!:get_aliasinfo", dom_sid_Type, &py_alias_sid)) {
2049                 return NULL;
2050         }
2051
2052         methods = pytalloc_get_ptr(self);
2053
2054         if ((tframe = talloc_stackframe()) == NULL) {
2055                 PyErr_NoMemory();
2056                 return NULL;
2057         }
2058
2059         alias_sid = pytalloc_get_ptr(py_alias_sid);
2060
2061         status = methods->get_aliasinfo(methods, alias_sid, &alias_info);
2062         if (!NT_STATUS_IS_OK(status)) {
2063                 PyErr_Format(py_pdb_error, "Unable to get alias information, (%d,%s)",
2064                                 NT_STATUS_V(status),
2065                                 get_friendly_nt_error_msg(status));
2066                 talloc_free(tframe);
2067                 return NULL;
2068         }
2069
2070         py_alias_info = PyDict_New();
2071         if (py_alias_info == NULL) {
2072                 PyErr_NoMemory();
2073                 talloc_free(tframe);
2074                 return NULL;
2075         }
2076
2077         PyDict_SetItemString(py_alias_info, "acct_name", PyString_FromString(alias_info.acct_name));
2078         PyDict_SetItemString(py_alias_info, "acct_desc", PyString_FromString(alias_info.acct_desc));
2079         PyDict_SetItemString(py_alias_info, "rid", PyInt_FromLong(alias_info.rid));
2080
2081         talloc_free(tframe);
2082
2083         return py_alias_info;
2084 }
2085
2086
2087 static PyObject *py_pdb_set_aliasinfo(pytalloc_Object *self, PyObject *args)
2088 {
2089         NTSTATUS status;
2090         struct pdb_methods *methods;
2091         TALLOC_CTX *tframe;
2092         PyObject *py_alias_sid, *py_alias_info;
2093         struct dom_sid *alias_sid;
2094         struct acct_info alias_info;
2095
2096         if (!PyArg_ParseTuple(args, "O!O:set_alias_info", dom_sid_Type, &py_alias_sid,
2097                                 &py_alias_info)) {
2098                 return NULL;
2099         }
2100
2101         methods = pytalloc_get_ptr(self);
2102
2103         if ((tframe = talloc_stackframe()) == NULL) {
2104                 PyErr_NoMemory();
2105                 return NULL;
2106         }
2107
2108         alias_sid = pytalloc_get_ptr(py_alias_sid);
2109
2110         fstrcpy(alias_info.acct_name, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_name")));
2111         fstrcpy(alias_info.acct_desc, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_desc")));
2112
2113         status = methods->set_aliasinfo(methods, alias_sid, &alias_info);
2114         if (!NT_STATUS_IS_OK(status)) {
2115                 PyErr_Format(py_pdb_error, "Unable to set alias information, (%d,%s)",
2116                                 NT_STATUS_V(status),
2117                                 get_friendly_nt_error_msg(status));
2118                 talloc_free(tframe);
2119                 return NULL;
2120         }
2121
2122         talloc_free(tframe);
2123         Py_RETURN_NONE;
2124 }
2125
2126
2127 static PyObject *py_pdb_add_aliasmem(pytalloc_Object *self, PyObject *args)
2128 {
2129         NTSTATUS status;
2130         struct pdb_methods *methods;
2131         TALLOC_CTX *tframe;
2132         PyObject *py_alias_sid, *py_member_sid;
2133         struct dom_sid *alias_sid, *member_sid;
2134
2135         if (!PyArg_ParseTuple(args, "O!O!:add_aliasmem", dom_sid_Type, &py_alias_sid,
2136                                         dom_sid_Type, &py_member_sid)) {
2137                 return NULL;
2138         }
2139
2140         methods = pytalloc_get_ptr(self);
2141
2142         if ((tframe = talloc_stackframe()) == NULL) {
2143                 PyErr_NoMemory();
2144                 return NULL;
2145         }
2146
2147         alias_sid = pytalloc_get_ptr(py_alias_sid);
2148         member_sid = pytalloc_get_ptr(py_member_sid);
2149
2150         status = methods->add_aliasmem(methods, alias_sid, member_sid);
2151         if (!NT_STATUS_IS_OK(status)) {
2152                 PyErr_Format(py_pdb_error, "Unable to add member to alias, (%d,%s)",
2153                                 NT_STATUS_V(status),
2154                                 get_friendly_nt_error_msg(status));
2155                 talloc_free(tframe);
2156                 return NULL;
2157         }
2158
2159         talloc_free(tframe);
2160         Py_RETURN_NONE;
2161 }
2162
2163
2164 static PyObject *py_pdb_del_aliasmem(pytalloc_Object *self, PyObject *args)
2165 {
2166         NTSTATUS status;
2167         struct pdb_methods *methods;
2168         TALLOC_CTX *tframe;
2169         PyObject *py_alias_sid, *py_member_sid;
2170         const struct dom_sid *alias_sid, *member_sid;
2171
2172         if (!PyArg_ParseTuple(args, "O!O!:del_aliasmem", dom_sid_Type, &py_alias_sid,
2173                                         dom_sid_Type, &py_member_sid)) {
2174                 return NULL;
2175         }
2176
2177         methods = pytalloc_get_ptr(self);
2178
2179         if ((tframe = talloc_stackframe()) == NULL) {
2180                 PyErr_NoMemory();
2181                 return NULL;
2182         }
2183
2184         alias_sid = pytalloc_get_ptr(py_alias_sid);
2185         member_sid = pytalloc_get_ptr(py_member_sid);
2186
2187         status = methods->del_aliasmem(methods, alias_sid, member_sid);
2188         if (!NT_STATUS_IS_OK(status)) {
2189                 PyErr_Format(py_pdb_error, "Unable to delete member from alias, (%d,%s)",
2190                                 NT_STATUS_V(status),
2191                                 get_friendly_nt_error_msg(status));
2192                 talloc_free(tframe);
2193                 return NULL;
2194         }
2195
2196         talloc_free(tframe);
2197         Py_RETURN_NONE;
2198 }
2199
2200
2201 static PyObject *py_pdb_enum_aliasmem(pytalloc_Object *self, PyObject *args)
2202 {
2203         NTSTATUS status;
2204         struct pdb_methods *methods;
2205         TALLOC_CTX *tframe;
2206         PyObject *py_alias_sid;
2207         struct dom_sid *alias_sid, *member_sid;
2208         PyObject *py_member_list, *py_member_sid;
2209         size_t num_members;
2210         int i;
2211
2212         if (!PyArg_ParseTuple(args, "O!:enum_aliasmem", dom_sid_Type, &py_alias_sid)) {
2213                 return NULL;
2214         }
2215
2216         methods = pytalloc_get_ptr(self);
2217
2218         if ((tframe = talloc_stackframe()) == NULL) {
2219                 PyErr_NoMemory();
2220                 return NULL;
2221         }
2222
2223         alias_sid = pytalloc_get_ptr(py_alias_sid);
2224
2225         status = methods->enum_aliasmem(methods, alias_sid, tframe, &member_sid, &num_members);
2226         if (!NT_STATUS_IS_OK(status)) {
2227                 PyErr_Format(py_pdb_error, "Unable to enumerate members for alias, (%d,%s)",
2228                                 NT_STATUS_V(status),
2229                                 get_friendly_nt_error_msg(status));
2230                 talloc_free(tframe);
2231                 return NULL;
2232         }
2233
2234         py_member_list = PyList_New(0);
2235         if (py_member_list == NULL) {
2236                 PyErr_NoMemory();
2237                 talloc_free(tframe);
2238                 return NULL;
2239         }
2240
2241         for(i=0; i<num_members; i++) {
2242                 py_member_sid = pytalloc_steal(dom_sid_Type, &member_sid[i]);
2243                 if (py_member_sid) {
2244                         PyList_Append(py_member_list, py_member_sid);
2245                 }
2246         }
2247
2248         talloc_free(tframe);
2249
2250         return py_member_list;
2251 }
2252
2253
2254 static PyObject *py_pdb_get_account_policy(pytalloc_Object *self)
2255 {
2256         NTSTATUS status;
2257         struct pdb_methods *methods;
2258         TALLOC_CTX *tframe;
2259         PyObject *py_acct_policy;
2260         uint32_t value;
2261         const char **names;
2262         int count, i;
2263         enum pdb_policy_type type;
2264
2265         methods = pytalloc_get_ptr(self);
2266
2267         if ((tframe = talloc_stackframe()) == NULL) {
2268                 PyErr_NoMemory();
2269                 return NULL;
2270         }
2271
2272         py_acct_policy = PyDict_New();
2273         if (py_acct_policy == NULL) {
2274                 PyErr_NoMemory();
2275                 return NULL;
2276         }
2277
2278         account_policy_names_list(tframe, &names, &count);
2279         for (i=0; i<count; i++) {
2280                 type = account_policy_name_to_typenum(names[i]);
2281                 status = methods->get_account_policy(methods, type, &value);
2282                 if (NT_STATUS_IS_OK(status)) {
2283                         PyDict_SetItemString(py_acct_policy, names[i], PyInt_FromLong(value));
2284                 }
2285         }
2286
2287         talloc_free(tframe);
2288
2289         return py_acct_policy;
2290 }
2291
2292
2293 static PyObject *py_pdb_set_account_policy(pytalloc_Object *self, PyObject *args)
2294 {
2295         NTSTATUS status;
2296         struct pdb_methods *methods;
2297         TALLOC_CTX *tframe;
2298         PyObject *py_acct_policy, *py_value;
2299         const char **names;
2300         int count, i;
2301         enum pdb_policy_type type;
2302
2303         if (!PyArg_ParseTuple(args, "O!:set_account_policy", PyDict_Type, &py_acct_policy)) {
2304                 return NULL;
2305         }
2306
2307         methods = pytalloc_get_ptr(self);
2308
2309         if ((tframe = talloc_stackframe()) == NULL) {
2310                 PyErr_NoMemory();
2311                 return NULL;
2312         }
2313
2314         account_policy_names_list(tframe, &names, &count);
2315         for (i=0; i<count; i++) {
2316                 if ((py_value = PyDict_GetItemString(py_acct_policy, names[i])) != NULL) {
2317                         type = account_policy_name_to_typenum(names[i]);
2318                         status = methods->set_account_policy(methods, type, PyInt_AsLong(py_value));
2319                         if (!NT_STATUS_IS_OK(status)) {
2320                                 PyErr_Format(py_pdb_error, "Error setting account policy (%s), (%d,%s)",
2321                                                 names[i],
2322                                                 NT_STATUS_V(status),
2323                                                 get_friendly_nt_error_msg(status));
2324                         }
2325                 }
2326         }
2327
2328
2329         talloc_free(tframe);
2330
2331         Py_RETURN_NONE;
2332 }
2333
2334 static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args)
2335 {
2336         NTSTATUS status;
2337         struct pdb_methods *methods;
2338         TALLOC_CTX *tframe;
2339         unsigned int acct_flags;
2340         struct pdb_search *search;
2341         struct samr_displayentry *entry;
2342         PyObject *py_userlist, *py_dict;
2343
2344         if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) {
2345                 return NULL;
2346         }
2347
2348         methods = pytalloc_get_ptr(self);
2349
2350         if ((tframe = talloc_stackframe()) == NULL) {
2351                 PyErr_NoMemory();
2352                 return NULL;
2353         }
2354
2355         search = talloc_zero(tframe, struct pdb_search);
2356         if (search == NULL) {
2357                 PyErr_NoMemory();
2358                 talloc_free(tframe);
2359                 return NULL;
2360         }
2361
2362         if (!methods->search_users(methods, search, acct_flags)) {
2363                 PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)",
2364                                 NT_STATUS_V(status),
2365                                 get_friendly_nt_error_msg(status));
2366                 talloc_free(tframe);
2367                 return NULL;
2368         }
2369
2370         entry = talloc_zero(tframe, struct samr_displayentry);
2371         if (entry == NULL) {
2372                 PyErr_NoMemory();
2373                 talloc_free(tframe);
2374                 return NULL;
2375         }
2376
2377         py_userlist = PyList_New(0);
2378         if (py_userlist == NULL) {
2379                 PyErr_NoMemory();
2380                 talloc_free(tframe);
2381                 return NULL;
2382         }
2383
2384         while (search->next_entry(search, entry)) {
2385                 py_dict = PyDict_New();
2386                 if (py_dict == NULL) {
2387                         PyErr_NoMemory();
2388                 } else {
2389                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2390                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2391                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2392                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2393                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2394                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2395                         PyList_Append(py_userlist, py_dict);
2396                 }
2397         }
2398         search->search_end(search);
2399
2400         talloc_free(tframe);
2401
2402         return py_userlist;
2403 }
2404
2405
2406 static PyObject *py_pdb_search_groups(pytalloc_Object *self)
2407 {
2408         NTSTATUS status;
2409         struct pdb_methods *methods;
2410         TALLOC_CTX *tframe;
2411         struct pdb_search *search;
2412         struct samr_displayentry *entry;
2413         PyObject *py_grouplist, *py_dict;
2414
2415         methods = pytalloc_get_ptr(self);
2416
2417         if ((tframe = talloc_stackframe()) == NULL) {
2418                 PyErr_NoMemory();
2419                 return NULL;
2420         }
2421
2422         search = talloc_zero(tframe, struct pdb_search);
2423         if (search == NULL) {
2424                 PyErr_NoMemory();
2425                 talloc_free(tframe);
2426                 return NULL;
2427         }
2428
2429         if (!methods->search_groups(methods, search)) {
2430                 PyErr_Format(py_pdb_error, "Unable to search groups, (%d,%s)",
2431                                 NT_STATUS_V(status),
2432                                 get_friendly_nt_error_msg(status));
2433                 talloc_free(tframe);
2434                 return NULL;
2435         }
2436
2437         entry = talloc_zero(tframe, struct samr_displayentry);
2438         if (entry == NULL) {
2439                 PyErr_NoMemory();
2440                 talloc_free(tframe);
2441                 return NULL;
2442         }
2443
2444         py_grouplist = PyList_New(0);
2445         if (py_grouplist == NULL) {
2446                 PyErr_NoMemory();
2447                 talloc_free(tframe);
2448                 return NULL;
2449         }
2450
2451         while (search->next_entry(search, entry)) {
2452                 py_dict = PyDict_New();
2453                 if (py_dict == NULL) {
2454                         PyErr_NoMemory();
2455                 } else {
2456                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2457                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2458                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2459                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2460                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2461                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2462                         PyList_Append(py_grouplist, py_dict);
2463                 }
2464         }
2465         search->search_end(search);
2466
2467         talloc_free(tframe);
2468
2469         return py_grouplist;
2470 }
2471
2472
2473 static PyObject *py_pdb_search_aliases(pytalloc_Object *self, PyObject *args)
2474 {
2475         NTSTATUS status;
2476         struct pdb_methods *methods;
2477         TALLOC_CTX *tframe;
2478         struct pdb_search *search;
2479         struct samr_displayentry *entry;
2480         PyObject *py_aliaslist, *py_dict;
2481         PyObject *py_domain_sid;
2482         struct dom_sid *dom_sid;
2483
2484         if (!PyArg_ParseTuple(args, "O!:search_users", dom_sid_Type, &py_domain_sid)) {
2485                 return NULL;
2486         }
2487
2488         methods = pytalloc_get_ptr(self);
2489
2490         if ((tframe = talloc_stackframe()) == NULL) {
2491                 PyErr_NoMemory();
2492                 return NULL;
2493         }
2494
2495         dom_sid = pytalloc_get_ptr(py_domain_sid);
2496
2497         search = talloc_zero(tframe, struct pdb_search);
2498         if (search == NULL) {
2499                 PyErr_NoMemory();
2500                 talloc_free(tframe);
2501                 return NULL;
2502         }
2503
2504         if (!methods->search_aliases(methods, search, dom_sid)) {
2505                 PyErr_Format(py_pdb_error, "Unable to search aliases, (%d,%s)",
2506                                 NT_STATUS_V(status),
2507                                 get_friendly_nt_error_msg(status));
2508                 talloc_free(tframe);
2509                 return NULL;
2510         }
2511
2512         entry = talloc_zero(tframe, struct samr_displayentry);
2513         if (entry == NULL) {
2514                 PyErr_NoMemory();
2515                 talloc_free(tframe);
2516                 return NULL;
2517         }
2518
2519         py_aliaslist = PyList_New(0);
2520         if (py_aliaslist == NULL) {
2521                 PyErr_NoMemory();
2522                 talloc_free(tframe);
2523                 return NULL;
2524         }
2525
2526         while (search->next_entry(search, entry)) {
2527                 py_dict = PyDict_New();
2528                 if (py_dict == NULL) {
2529                         PyErr_NoMemory();
2530                 } else {
2531                         PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx));
2532                         PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid));
2533                         PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags));
2534                         PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name));
2535                         PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname));
2536                         PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description));
2537                         PyList_Append(py_aliaslist, py_dict);
2538                 }
2539         }
2540         search->search_end(search);
2541
2542         talloc_free(tframe);
2543
2544         return py_aliaslist;
2545 }
2546
2547 static PyMethodDef py_pdb_methods[] = {
2548         { "domain_info", (PyCFunction)py_pdb_domain_info, METH_NOARGS,
2549                 "domain_info() -> str\n\n \
2550                 Get domain information for the database." },
2551         { "getsampwnam", (PyCFunction)py_pdb_getsampwnam, METH_VARARGS,
2552                 "getsampwnam(username) -> samu object\n\n \
2553                 Get user information by name." },
2554         { "getsampwsid", (PyCFunction)py_pdb_getsampwsid, METH_VARARGS,
2555                 "getsampwsid(user_sid) -> samu object\n\n \
2556                 Get user information by sid (dcerpc.security.dom_sid object)." },
2557         { "create_user", (PyCFunction)py_pdb_create_user, METH_VARARGS,
2558                 "create_user(username, acct_flags) -> rid\n\n \
2559                 Create user. acct_flags are samr account control flags." },
2560         { "delete_user", (PyCFunction)py_pdb_delete_user, METH_VARARGS,
2561                 "delete_user(samu object) -> None\n\n \
2562                 Delete user." },
2563         { "add_sam_account", (PyCFunction)py_pdb_add_sam_account, METH_VARARGS,
2564                 "add_sam_account(samu object) -> None\n\n \
2565                 Add SAM account." },
2566         { "update_sam_account", (PyCFunction)py_pdb_update_sam_account, METH_VARARGS,
2567                 "update_sam_account(samu object) -> None\n\n \
2568                 Update SAM account." },
2569         { "delete_sam_account", (PyCFunction)py_pdb_delete_sam_account, METH_VARARGS,
2570                 "delete_sam_account(samu object) -> None\n\n \
2571                 Delete SAM account." },
2572         { "rename_sam_account", (PyCFunction)py_pdb_rename_sam_account, METH_VARARGS,
2573                 "rename_sam_account(samu object1, new_username) -> None\n\n \
2574                 Rename SAM account." },
2575         /* update_login_attempts */
2576         { "getgrsid", (PyCFunction)py_pdb_getgrsid, METH_VARARGS,
2577                 "getgrsid(group_sid) -> groupmap object\n\n \
2578                 Get group information by sid (dcerpc.security.dom_sid object)." },
2579         { "getgrgid", (PyCFunction)py_pdb_getgrgid, METH_VARARGS,
2580                 "getgrsid(gid) -> groupmap object\n\n \
2581                 Get group information by gid." },
2582         { "getgrnam", (PyCFunction)py_pdb_getgrnam, METH_VARARGS,
2583                 "getgrsid(groupname) -> groupmap object\n\n \
2584                 Get group information by name." },
2585         { "create_dom_group", (PyCFunction)py_pdb_create_dom_group, METH_VARARGS,
2586                 "create_dom_group(groupname) -> group_rid\n\n \
2587                 Create new domain group by name." },
2588         { "delete_dom_group", (PyCFunction)py_pdb_delete_dom_group, METH_VARARGS,
2589                 "delete_dom_group(group_rid) -> None\n\n \
2590                 Delete domain group identified by rid" },
2591         { "add_group_mapping_entry", (PyCFunction)py_pdb_add_group_mapping_entry, METH_VARARGS,
2592                 "add_group_mapping_entry(groupmap) -> None\n \
2593                 Add group mapping entry for groupmap object." },
2594         { "update_group_mapping_entry", (PyCFunction)py_pdb_update_group_mapping_entry, METH_VARARGS,
2595                 "update_group_mapping_entry(groupmap) -> None\n\n \
2596                 Update group mapping entry for groupmap object." },
2597         { "delete_group_mapping_entry", (PyCFunction)py_pdb_delete_group_mapping_entry, METH_VARARGS,
2598                 "delete_group_mapping_entry(groupmap) -> None\n\n \
2599                 Delete group mapping entry for groupmap object." },
2600         { "enum_group_mapping", (PyCFunction)py_pdb_enum_group_mapping, METH_VARARGS,
2601                 "enum_group_mapping(domain_sid) -> List\n\n \
2602                 Return list of group mappings as groupmap objects." },
2603         { "enum_group_members", (PyCFunction)py_pdb_enum_group_members, METH_VARARGS,
2604                 "enum_group_members(group_sid) -> List\n\n \
2605                 Return list of group members." },
2606         /* enum_group_memberships */
2607         /* set_unix_primary_group */
2608         { "add_groupmem", (PyCFunction)py_pdb_add_groupmem, METH_VARARGS,
2609                 "add_groupmem(group_rid, member_rid) -> None\n\n \
2610                 Add user to group." },
2611         { "del_groupmem", (PyCFunction)py_pdb_del_groupmem, METH_VARARGS,
2612                 "del_groupmem(group_rid, member_rid) -> None\n\n \
2613                 Remove user from from group." },
2614         { "create_alias", (PyCFunction)py_pdb_create_alias, METH_VARARGS,
2615                 "create_alias(alias_name) -> alias_rid\n\n \
2616                 Create alias entry." },
2617         { "delete_alias", (PyCFunction)py_pdb_delete_alias, METH_VARARGS,
2618                 "delete_alias(alias_sid) -> None\n\n \
2619                 Delete alias entry." },
2620         { "get_aliasinfo", (PyCFunction)py_pdb_get_aliasinfo, METH_VARARGS,
2621                 "get_aliasinfo(alias_sid) -> Mapping\n\n \
2622                 Get alias information as a dictionary with keys - acct_name, acct_desc, rid." },
2623         { "set_aliasinfo", (PyCFunction)py_pdb_set_aliasinfo, METH_VARARGS,
2624                 "set_alias_info(alias_sid, Mapping) -> None\n\n \
2625                 Set alias information from a dictionary with keys - acct_name, acct_desc." },
2626         { "add_aliasmem", (PyCFunction)py_pdb_add_aliasmem, METH_VARARGS,
2627                 "add_aliasmem(alias_sid, member_sid) -> None\n\n \
2628                 Add user to alias entry." },
2629         { "del_aliasmem", (PyCFunction)py_pdb_del_aliasmem, METH_VARARGS,
2630                 "del_aliasmem(alias_sid, member_sid) -> None\n\n \
2631                 Remove a user from alias entry." },
2632         { "enum_aliasmem", (PyCFunction)py_pdb_enum_aliasmem, METH_VARARGS,
2633                 "enum_aliasmem(alias_sid) -> List\n\n \
2634                 Return a list of users for alias entry." },
2635         /* enum_alias_memberships */
2636         /* lookup_rids */
2637         /* lookup_names */
2638         { "get_account_policy", (PyCFunction)py_pdb_get_account_policy, METH_NOARGS,
2639                 "get_account_policy() -> Mapping\n\n \
2640                 Get account policy information as a dictionary." },
2641         { "set_account_policy", (PyCFunction)py_pdb_set_account_policy, METH_VARARGS,
2642                 "get_account_policy(Mapping) -> None\n\n \
2643                 Set account policy settings from a dicionary." },
2644         /* get_seq_num */
2645         { "search_users", (PyCFunction)py_pdb_search_users, METH_VARARGS,
2646                 "search_users(acct_flags) -> List\n\n \
2647                 Search users. acct_flags are samr account control flags.\n \
2648                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
2649         { "search_groups", (PyCFunction)py_pdb_search_groups, METH_NOARGS,
2650                 "search_groups() -> List\n\n \
2651                 Search unix only groups. \n \
2652                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
2653         { "search_aliases", (PyCFunction)py_pdb_search_aliases, METH_VARARGS,
2654                 "search_aliases(domain_sid) -> List\n\n \
2655                 Search aliases. domain_sid is dcerpc.security.dom_sid object.\n \
2656                 Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." },
2657         /* uid_to_sid */
2658         /* gid_to_sid */
2659         /* sid_to_id */
2660         /* capabilities */
2661         /* new_rid */
2662         /* get_trusteddom_pw */
2663         /* set_trusteddom_pw */
2664         /* del_trusteddom_pw */
2665         /* enum_trusteddoms */
2666         /* get_trusted_domain */
2667         /* get_trusted_domain_by_sid */
2668         /* set_trusted_domain */
2669         /* del_trusted_domain */
2670         /* enum_trusted_domains */
2671         /* get_secret */
2672         /* set_secret */
2673         /* delete_secret */
2674         { NULL },
2675 };
2676
2677
2678 static PyObject *py_pdb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2679 {
2680         const char *url = NULL;
2681         PyObject *pypdb;
2682         NTSTATUS status;
2683         struct pdb_methods *methods;
2684
2685         if (!PyArg_ParseTuple(args, "s", &url)) {
2686                 return NULL;
2687         }
2688
2689         /* Initalize list of methods */
2690         status = make_pdb_method_name(&methods, url);
2691         if (!NT_STATUS_IS_OK(status)) {
2692                 PyErr_Format(py_pdb_error, "Cannot load backend methods for '%s' backend (%d,%s)",
2693                                 url,
2694                                 NT_STATUS_V(status),
2695                                 get_friendly_nt_error_msg(status));
2696                 return NULL;
2697         }
2698
2699         if ((pypdb = pytalloc_steal(type, methods)) == NULL) {
2700                 PyErr_NoMemory();
2701                 return NULL;
2702         }
2703
2704         return pypdb;
2705 }
2706
2707
2708 static PyTypeObject PyPDB = {
2709         .tp_name = "passdb.PDB",
2710         .tp_basicsize = sizeof(pytalloc_Object),
2711         .tp_new = py_pdb_new,
2712         .tp_flags = Py_TPFLAGS_DEFAULT,
2713         .tp_methods = py_pdb_methods,
2714         .tp_doc = "PDB(url[, read_write_flags]) -> Password DB object\n",
2715 };
2716
2717
2718 /*
2719  * Return a list of passdb backends
2720  */
2721 static PyObject *py_passdb_backends(PyObject *self)
2722 {
2723         PyObject *py_blist;
2724         const struct pdb_init_function_entry *entry;
2725         TALLOC_CTX *tframe;
2726
2727         if ((tframe = talloc_stackframe()) == NULL) {
2728                 PyErr_NoMemory();
2729                 return NULL;
2730         }
2731
2732         entry = pdb_get_backends();
2733         if(! entry) {
2734                 Py_RETURN_NONE;
2735         }
2736
2737         if((py_blist = PyList_New(0)) == NULL) {
2738                 PyErr_NoMemory();
2739                 return NULL;
2740         }
2741
2742         while(entry) {
2743                 PyList_Append(py_blist, PyString_FromString(entry->name));
2744                 entry = entry->next;
2745         }
2746
2747         talloc_free(tframe);
2748
2749         return py_blist;
2750 }
2751
2752
2753 static PyObject *py_set_smb_config(PyObject *self, PyObject *args)
2754 {
2755         const char *smb_config;
2756         TALLOC_CTX *tframe;
2757
2758         if (!PyArg_ParseTuple(args, "s", &smb_config)) {
2759                 return NULL;
2760         }
2761
2762         if ((tframe = talloc_stackframe()) == NULL) {
2763                 PyErr_NoMemory();
2764                 return NULL;
2765         }
2766
2767         /* Load smbconf parameters */
2768         if (!lp_load_global(smb_config)) {
2769                 PyErr_Format(py_pdb_error, "Cannot open '%s'", smb_config);
2770                 return NULL;
2771         }
2772
2773         talloc_free(tframe);
2774
2775         Py_RETURN_NONE;
2776 }
2777
2778
2779 static PyObject *py_set_secrets_dir(PyObject *self, PyObject *args)
2780 {
2781         const char *private_dir;
2782         TALLOC_CTX *tframe;
2783
2784         if (!PyArg_ParseTuple(args, "s", &private_dir)) {
2785                 return NULL;
2786         }
2787
2788         if ((tframe = talloc_stackframe()) == NULL) {
2789                 PyErr_NoMemory();
2790                 return NULL;
2791         }
2792
2793         /* Initialize secrets database */
2794         if (!secrets_init_path(private_dir)) {
2795                 PyErr_Format(py_pdb_error, "Cannot open secrets file database in '%s'",
2796                                 private_dir);
2797                 return NULL;
2798         }
2799
2800         talloc_free(tframe);
2801
2802         Py_RETURN_NONE;
2803 }
2804
2805 static PyObject *py_get_global_sam_sid(PyObject *self)
2806 {
2807         struct dom_sid *domain_sid, *domain_sid_copy;
2808         TALLOC_CTX *tframe;
2809         PyObject *py_dom_sid;
2810
2811         tframe = talloc_stackframe();
2812         if (tframe == NULL) {
2813                 PyErr_NoMemory();
2814                 return NULL;
2815         }
2816
2817         domain_sid = get_global_sam_sid();
2818
2819         domain_sid_copy = dom_sid_dup(tframe, domain_sid);
2820         if (domain_sid_copy == NULL) {
2821                 PyErr_NoMemory();
2822                 talloc_free(tframe);
2823                 return NULL;
2824         }
2825
2826         py_dom_sid = pytalloc_steal(dom_sid_Type, domain_sid_copy);
2827
2828         talloc_free(tframe);
2829
2830         return py_dom_sid;
2831 }
2832
2833
2834 static PyMethodDef py_passdb_methods[] = {
2835         { "get_backends", (PyCFunction)py_passdb_backends, METH_NOARGS,
2836                 "get_backends() -> list\n\n \
2837                 Get a list of password database backends supported." },
2838         { "set_smb_config", (PyCFunction)py_set_smb_config, METH_VARARGS,
2839                 "set_smb_config(path) -> None\n\n \
2840                 Set path to smb.conf file to load configuration parameters." },
2841         { "set_secrets_dir", (PyCFunction)py_set_secrets_dir, METH_VARARGS,
2842                 "set_secrets_dir(private_dir) -> None\n\n \
2843                 Set path to private directory to load secrets database from non-default location." },
2844         { "get_global_sam_sid", (PyCFunction)py_get_global_sam_sid, METH_NOARGS,
2845                 "get_global_sam_sid() -> dom_sid\n\n \
2846                 Return domain SID." },
2847         { NULL },
2848 };
2849
2850 void initpassdb(void)
2851 {
2852         PyObject *m, *mod;
2853         char exception_name[] = "passdb.error";
2854
2855         PyTypeObject *talloc_type = pytalloc_GetObjectType();
2856         if (talloc_type == NULL) {
2857                 return;
2858         }
2859
2860         PyPDB.tp_base = talloc_type;
2861         if (PyType_Ready(&PyPDB) < 0) {
2862                 return;
2863         }
2864
2865         PySamu.tp_base = talloc_type;
2866         if (PyType_Ready(&PySamu) < 0) {
2867                 return;
2868         }
2869
2870         PyGroupmap.tp_base = talloc_type;
2871         if (PyType_Ready(&PyGroupmap) < 0) {
2872                 return;
2873         }
2874
2875         m = Py_InitModule3("passdb", py_passdb_methods, "SAMBA Password Database");
2876         if (m == NULL) {
2877             return;
2878         }
2879
2880         /* Create new exception for passdb module */
2881         py_pdb_error = PyErr_NewException(exception_name, NULL, NULL);
2882         Py_INCREF(py_pdb_error);
2883         PyModule_AddObject(m, "error", py_pdb_error);
2884
2885         Py_INCREF(&PyPDB);
2886         PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB);
2887
2888         Py_INCREF(&PySamu);
2889         PyModule_AddObject(m, "Samu", (PyObject *)&PySamu);
2890
2891         Py_INCREF(&PyGroupmap);
2892         PyModule_AddObject(m, "Groupmap", (PyObject *)&PyGroupmap);
2893
2894         /* Import dom_sid type from dcerpc.security */
2895         mod = PyImport_ImportModule("samba.dcerpc.security");
2896         if (mod == NULL) {
2897                 return;
2898         }
2899
2900         dom_sid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "dom_sid");
2901         Py_DECREF(mod);
2902         if (dom_sid_Type == NULL) {
2903                 return;
2904         }
2905
2906         /* Import GUID type from dcerpc.misc */
2907         mod = PyImport_ImportModule("samba.dcerpc.misc");
2908         if (mod == NULL) {
2909                 return;
2910         }
2911
2912         guid_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "GUID");
2913         Py_DECREF(mod);
2914         if (guid_Type == NULL) {
2915                 return;
2916         }
2917 }