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