Implemented routines to convert from a Python dictionary to a SEC_DESC
[kai/samba.git] / source3 / python / py_ntsec.c
1 /* 
2    Python wrappers for DCERPC/SMB client routines.
3
4    Copyright (C) Tim Potter, 2002
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22 #include "Python.h"
23
24 #include "python/py_common.h"
25
26 /* Convert a SID to a Python dict */
27
28 BOOL py_from_SID(PyObject **obj, DOM_SID *sid)
29 {
30         fstring sidstr;
31
32         if (!sid) {
33                 Py_INCREF(Py_None);
34                 *obj = Py_None;
35                 return True;
36         }
37
38         if (!sid_to_string(sidstr, sid))
39                 return False;
40
41         *obj = PyString_FromString(sidstr);
42
43         return True;
44 }
45
46 BOOL py_to_SID(DOM_SID *sid, PyObject *obj)
47 {
48         BOOL result;
49
50         if (!PyString_Check(obj))
51                 return False;
52
53         return string_to_sid(sid, PyString_AsString(obj));
54 }
55
56 BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace)
57 {
58         PyObject *obj;
59
60         if (!ace) {
61                 Py_INCREF(Py_None);
62                 *dict = Py_None;
63                 return True;
64         }
65
66         *dict = PyDict_New();
67
68         PyDict_SetItemString(*dict, "type", PyInt_FromLong(ace->type));
69         PyDict_SetItemString(*dict, "flags", PyInt_FromLong(ace->flags));
70         PyDict_SetItemString(*dict, "mask", PyInt_FromLong(ace->info.mask));
71
72         if (py_from_SID(&obj, &ace->trustee))
73                 PyDict_SetItemString(*dict, "trustee", obj);
74
75         return True;
76 }
77
78 BOOL py_to_ACE(SEC_ACE *ace, PyObject *dict)
79 {
80         PyObject *obj;
81         uint8 ace_type, ace_flags;
82         DOM_SID trustee;
83         SEC_ACCESS sec_access;
84
85         if (!PyDict_Check(dict))
86                 return False;
87
88         if (!(obj = PyDict_GetItemString(dict, "type")) ||
89             !PyInt_Check(obj))
90                 return False;
91
92         ace_type = PyInt_AsLong(obj);
93
94         if (!(obj = PyDict_GetItemString(dict, "flags")) ||
95             !PyInt_Check(obj))
96                 return False;
97
98         ace_flags = PyInt_AsLong(obj);
99
100         if (!(obj = PyDict_GetItemString(dict, "trustee")) ||
101             !PyString_Check(obj))
102                 return False;
103
104         if (!py_to_SID(&trustee, obj))
105                 return False;
106
107         if (!(obj = PyDict_GetItemString(dict, "mask")) ||
108             !PyInt_Check(obj))
109                 return False;
110
111         sec_access.mask = PyInt_AsLong(obj);
112
113         init_sec_ace(ace, &trustee, ace_type, sec_access, ace_flags);
114
115         /* Fill in size field */
116
117         ace->size = SEC_ACE_HEADER_SIZE + sid_size(&trustee);
118
119         return True;
120 }
121
122 BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl)
123 {
124         PyObject *ace_list;
125         int i;
126
127         if (!acl) {
128                 Py_INCREF(Py_None);
129                 *dict = Py_None;
130                 return True;
131         }
132
133         *dict = PyDict_New();
134
135         PyDict_SetItemString(*dict, "revision", PyInt_FromLong(acl->revision));
136
137         ace_list = PyList_New(acl->num_aces);
138
139         for (i = 0; i < acl->num_aces; i++) {
140                 PyObject *obj;
141
142                 if (py_from_ACE(&obj, &acl->ace[i]))
143                         PyList_SetItem(ace_list, i, obj);
144         }
145
146         PyDict_SetItemString(*dict, "ace_list", ace_list);
147
148         return True;
149 }
150
151 BOOL py_to_ACL(SEC_ACL *acl, PyObject *dict, TALLOC_CTX *mem_ctx)
152 {
153         PyObject *obj;
154         uint32 i;
155
156         if (!(obj = PyDict_GetItemString(dict, "revision")) ||
157             !PyInt_Check(obj))
158                 return False;
159
160         acl->revision = PyInt_AsLong(obj);
161
162         if (!(obj = PyDict_GetItemString(dict, "ace_list")) ||
163             !PyList_Check(obj)) 
164                 return False;
165         
166         acl->num_aces = PyList_Size(obj);
167
168         acl->ace = talloc(mem_ctx, acl->num_aces * sizeof(SEC_ACE));
169         acl->size = SEC_ACL_HEADER_SIZE;
170
171         for (i = 0; i < acl->num_aces; i++) {
172                 PyObject *py_ace = PyList_GetItem(obj, i);
173
174                 if (!py_to_ACE(&acl->ace[i], py_ace))
175                         return False;
176
177                 acl->size += acl->ace[i].size;
178         }
179
180         return True;
181 }
182
183 BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd)
184 {
185         PyObject *obj;
186
187         *dict = PyDict_New();
188
189         PyDict_SetItemString(*dict, "revision", PyInt_FromLong(sd->revision));
190
191         if (py_from_SID(&obj, sd->owner_sid))
192                 PyDict_SetItemString(*dict, "owner_sid", obj);
193
194         if (py_from_SID(&obj, sd->grp_sid))
195                 PyDict_SetItemString(*dict, "group_sid", obj);
196
197         if (py_from_ACL(&obj, sd->dacl))
198                 PyDict_SetItemString(*dict, "dacl", obj);
199
200         if (py_from_ACL(&obj, sd->sacl))
201                 PyDict_SetItemString(*dict, "sacl", obj);
202
203         return True;
204 }
205
206 BOOL py_to_SECDESC(SEC_DESC **sd, PyObject *dict, TALLOC_CTX *mem_ctx)
207 {
208         PyObject *obj;
209         uint16 revision;
210         DOM_SID owner_sid, group_sid;
211         SEC_ACL sacl, dacl;
212         BOOL got_dacl = False, got_sacl = False;
213         BOOL got_owner_sid = False, got_group_sid = False;
214
215         ZERO_STRUCT(dacl); ZERO_STRUCT(sacl);
216         ZERO_STRUCT(owner_sid); ZERO_STRUCT(group_sid);
217
218         if (!(obj = PyDict_GetItemString(dict, "revision")))
219                 return False;
220
221         revision = PyInt_AsLong(obj);
222
223         if ((obj = PyDict_GetItemString(dict, "owner_sid"))) {
224
225                 if (obj != Py_None) {
226
227                         if (!py_to_SID(&owner_sid, obj))
228                                 return False;
229
230                         got_owner_sid = True;
231                 }
232         }
233
234         if ((obj = PyDict_GetItemString(dict, "group_sid"))) {
235
236                 if (obj != Py_None) {
237
238                         if (!py_to_SID(&group_sid, obj))
239                                 return False;
240                         
241                         got_group_sid = True;
242                 }
243         }
244
245         if ((obj = PyDict_GetItemString(dict, "dacl"))) {
246
247                 if (obj != Py_None) {
248
249                         if (!py_to_ACL(&dacl, obj, mem_ctx))
250                                 return False;
251                         
252                         got_dacl = True;
253                 }
254         }
255
256         if ((obj = PyDict_GetItemString(dict, "sacl"))) {
257
258                 if (obj != Py_None) {
259
260                         if (!py_to_ACL(&sacl, obj, mem_ctx))
261                                 return False;
262
263                         got_sacl = True;
264                 }
265         }
266
267         *sd = make_sec_desc(mem_ctx, revision, 
268                             got_owner_sid ? &owner_sid : NULL, 
269                             got_group_sid ? &group_sid : NULL,
270                             got_sacl ? &sacl : NULL, 
271                             got_dacl ? &dacl : NULL);
272         
273         return True;
274 }