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