]> git.k1024.org Git - pylibacl.git/blob - acl.c
Added acl_entry_t type (named ACLEntryType, respectively ACLEntryObject)
[pylibacl.git] / acl.c
1 #include <sys/types.h>
2 #include <sys/acl.h>
3
4 #include <Python.h>
5
6 staticforward PyTypeObject ACLType;
7 static PyObject* ACL_applyto(PyObject* obj, PyObject* args);
8 static PyObject* ACL_valid(PyObject* obj, PyObject* args);
9 #ifdef HAVE_LEVEL2
10 static PyObject* ACL_get_state(PyObject *obj, PyObject* args);
11 static PyObject* ACL_set_state(PyObject *obj, PyObject* args);
12
13 staticforward PyTypeObject ACLEntryType;
14 #endif
15
16 typedef struct {
17     PyObject_HEAD
18     acl_t ob_acl;
19     int entry_id;
20 } ACLObject;
21
22 #ifdef HAVE_LEVEL2
23
24 typedef struct {
25     PyObject_HEAD
26     PyObject *parent; /* The parent object, so it won't run out on us */
27     acl_entry_t ob_entry;
28 } ACLEntryObject;
29
30 typedef struct {
31     PyObject_HEAD
32     acl_t ob_acl;
33 } PermsetObject;
34
35 #endif
36
37 /* Creation of a new ACL instance */
38 static PyObject* ACL_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
39     PyObject* newacl;
40
41     newacl = type->tp_alloc(type, 0);
42
43     if(newacl != NULL) {
44         ((ACLObject*)newacl)->ob_acl = NULL;
45         ((ACLObject*)newacl)->entry_id = ACL_FIRST_ENTRY;
46     }
47
48     return newacl;
49 }
50
51 /* Initialization of a new ACL instance */
52 static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) {
53     ACLObject* self = (ACLObject*) obj;
54     static char *kwlist[] = { "file", "fd", "text", "acl", NULL };
55     char *file = NULL;
56     char *text = NULL;
57     int fd = -1;
58     ACLObject* thesrc = NULL;
59     int tmp;
60
61     if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sisO!", kwlist,
62                                      &file, &fd, &text, &ACLType, &thesrc))
63         return -1;
64     tmp = 0;
65     if(file != NULL)
66         tmp++;
67     if(text != NULL)
68         tmp++;
69     if(fd != -1)
70         tmp++;
71     if(thesrc != NULL)
72         tmp++;
73     if(tmp > 1) {
74         PyErr_SetString(PyExc_ValueError, "a maximum of one argument must be passed");
75         return -1;
76     }
77
78     /* Free the old acl_t without checking for error, we don't
79      * care right now */
80     if(self->ob_acl != NULL)
81         acl_free(self->ob_acl);
82
83     if(file != NULL)
84         self->ob_acl = acl_get_file(file, ACL_TYPE_ACCESS);
85     else if(text != NULL)
86         self->ob_acl = acl_from_text(text);
87     else if(fd != -1)
88         self->ob_acl = acl_get_fd(fd);
89     else if(thesrc != NULL)
90         self->ob_acl = acl_dup(thesrc->ob_acl);
91     else
92         self->ob_acl = acl_init(0);
93
94     if(self->ob_acl == NULL) {
95         PyErr_SetFromErrno(PyExc_IOError);
96         return -1;
97     }
98
99     return 0;
100 }
101
102 /* Standard type functions */
103 static void ACL_dealloc(PyObject* obj) {
104     ACLObject *self = (ACLObject*) obj;
105     PyObject *err_type, *err_value, *err_traceback;
106     int have_error = PyErr_Occurred() ? 1 : 0;
107
108     if (have_error)
109         PyErr_Fetch(&err_type, &err_value, &err_traceback);
110     if(acl_free(self->ob_acl) != 0)
111         PyErr_WriteUnraisable(obj);
112     if (have_error)
113         PyErr_Restore(err_type, err_value, err_traceback);
114     PyObject_DEL(self);
115 }
116
117 /* Converts the acl to a text format */
118 static PyObject* ACL_repr(PyObject *obj) {
119     char *text;
120     ACLObject *self = (ACLObject*) obj;
121     PyObject *ret;
122
123     text = acl_to_text(self->ob_acl, NULL);
124     if(text == NULL) {
125         return PyErr_SetFromErrno(PyExc_IOError);
126     }
127     ret = PyString_FromString(text);
128     if(acl_free(text) != 0) {
129         Py_DECREF(ret);
130         return PyErr_SetFromErrno(PyExc_IOError);
131     }
132     return ret;
133 }
134
135 /* Custom methods */
136 static char __applyto_doc__[] = \
137 "Apply the ACL to a file or filehandle.\n" \
138 "\n" \
139 "Parameters:\n" \
140 "  - either a filename or a file-like object or an integer; this\n" \
141 "    represents the filesystem object on which to act\n" \
142 ;
143
144 /* Applyes the ACL to a file */
145 static PyObject* ACL_applyto(PyObject* obj, PyObject* args) {
146     ACLObject *self = (ACLObject*) obj;
147     PyObject *myarg;
148     int type_default = 0;
149     acl_type_t type = ACL_TYPE_ACCESS;
150     int nret;
151     int fd;
152
153     if (!PyArg_ParseTuple(args, "O|i", &myarg, &type_default))
154         return NULL;
155     if(type_default)
156         type = ACL_TYPE_DEFAULT;
157
158     if(PyString_Check(myarg)) {
159         char *filename = PyString_AS_STRING(myarg);
160         nret = acl_set_file(filename, type, self->ob_acl);
161     } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) {
162         nret = acl_set_fd(fd, self->ob_acl);
163     } else {
164         PyErr_SetString(PyExc_TypeError, "argument 1 must be string, int, or file-like object");
165         return 0;
166     }
167     if(nret == -1) {
168         return PyErr_SetFromErrno(PyExc_IOError);
169     }
170
171     /* Return the result */
172     Py_INCREF(Py_None);
173     return Py_None;
174 }
175
176 static char __valid_doc__[] = \
177 "Test the ACL for validity.\n" \
178 "\n" \
179 "This method tests the ACL to see if it is a valid ACL\n" \
180 "in terms of the filesystem. More precisely, it checks:\n" \
181 "A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,\n" \
182 "ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and\n" \
183 "ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that\n" \
184 "contains entries of ACL_USER or ACL_GROUP tag types must contain exactly\n" \
185 "one entry of the ACL_MASK tag type. If an ACL contains no entries of\n" \
186 "ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.\n" \
187 "\n" \
188 "All user ID qualifiers must be unique among all entries of ACL_USER tag\n" \
189 "type, and all group IDs must be unique among all entries of ACL_GROUP tag\n" \
190 "type." \
191 ;
192
193 /* Checks the ACL for validity */
194 static PyObject* ACL_valid(PyObject* obj, PyObject* args) {
195     ACLObject *self = (ACLObject*) obj;
196
197     if(acl_valid(self->ob_acl) == -1) {
198         return PyErr_SetFromErrno(PyExc_IOError);
199     }
200
201     /* Return the result */
202     Py_INCREF(Py_None);
203     return Py_None;
204 }
205
206 #ifdef HAVE_LEVEL2
207
208 static PyObject* ACL_get_state(PyObject *obj, PyObject* args) {
209     ACLObject *self = (ACLObject*) obj;
210     PyObject *ret;
211     ssize_t size, nsize;
212     char *buf;
213
214     size = acl_size(self->ob_acl);
215     if(size == -1)
216         return PyErr_SetFromErrno(PyExc_IOError);
217
218     if((ret = PyString_FromStringAndSize(NULL, size)) == NULL)
219         return NULL;
220     buf = PyString_AsString(ret);
221     
222     if((nsize = acl_copy_ext(buf, self->ob_acl, size)) == -1) {
223         Py_DECREF(ret);
224         return PyErr_SetFromErrno(PyExc_IOError);
225     }
226     
227     return ret;
228 }
229
230 static PyObject* ACL_set_state(PyObject *obj, PyObject* args) {
231     ACLObject *self = (ACLObject*) obj;
232     const void *buf;
233     int bufsize;
234     acl_t ptr;
235
236     /* Parse the argument */
237     if (!PyArg_ParseTuple(args, "s#", &buf, &bufsize))
238         return NULL;
239
240     /* Try to import the external representation */
241     if((ptr = acl_copy_int(buf)) == NULL)
242         return PyErr_SetFromErrno(PyExc_IOError);
243         
244     /* Free the old acl. Should we ignore errors here? */
245     if(self->ob_acl != NULL) {
246         if(acl_free(self->ob_acl) == -1)
247             return PyErr_SetFromErrno(PyExc_IOError);
248     }
249
250     self->ob_acl = ptr;
251
252     /* Return the result */
253     Py_INCREF(Py_None);
254     return Py_None;
255 }
256
257 static PyObject* ACL_iter(PyObject *obj) {
258     ACLObject *self = (ACLObject*)obj;
259     self->entry_id = ACL_FIRST_ENTRY;
260     Py_INCREF(obj);
261     return obj;
262 }
263
264 static PyObject* ACL_iternext(PyObject *obj) {
265     ACLObject *self = (ACLObject*)obj;
266     acl_entry_t the_entry_t;
267     ACLEntryObject *the_entry_obj;
268     int nerr;
269     
270     if((nerr = acl_get_entry(self->ob_acl, self->entry_id, &the_entry_t)) == -1)
271         return PyErr_SetFromErrno(PyExc_IOError);
272     self->entry_id = ACL_NEXT_ENTRY;
273     if(nerr == 0) {
274         PyErr_SetObject(PyExc_StopIteration, Py_None);
275         return NULL;
276     }
277
278     the_entry_obj = (ACLEntryObject*) PyType_GenericNew(&ACLEntryType, NULL, NULL);
279     if(the_entry_obj == NULL)
280         return NULL;
281     
282     the_entry_obj->ob_entry = the_entry_t;
283
284     the_entry_obj->parent = obj;
285     Py_INCREF(obj); /* For the reference we have in entry->parent */
286
287     return (PyObject*)the_entry_obj;
288 }
289
290 /* Creation of a new ACLEntry instance */
291 static PyObject* ACLEntry_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
292     PyObject* newentry;
293
294     newentry = PyType_GenericNew(type, args, keywds);
295
296     if(newentry != NULL) {
297         ((ACLEntryObject*)newentry)->ob_entry = NULL;
298         ((ACLEntryObject*)newentry)->parent = NULL;
299     }
300
301     return newentry;
302 }
303
304 /* Initialization of a new ACLEntry instance */
305 static int ACLEntry_init(PyObject* obj, PyObject* args, PyObject *keywds) {
306     ACLEntryObject* self = (ACLEntryObject*) obj;
307     ACLObject* parent = NULL;
308
309     if (!PyArg_ParseTuple(args, "O!", &ACLType, &parent))
310         return -1;
311
312     /* Free the old acl_entry_t without checking for error, we don't
313      * care right now */
314     if(self->ob_entry != NULL)
315         acl_free(self->ob_entry);
316
317     if(acl_create_entry(&parent->ob_acl, &self->ob_entry) == -1) {
318         PyErr_SetFromErrno(PyExc_IOError);
319         return -1;
320     }
321
322     self->parent = (PyObject*)parent;
323     Py_INCREF(parent);
324
325     return 0;
326 }
327
328 /* Free the ACLEntry instance */
329 static void ACLEntry_dealloc(PyObject* obj) {
330     ACLEntryObject *self = (ACLEntryObject*) obj;
331     PyObject *err_type, *err_value, *err_traceback;
332     int have_error = PyErr_Occurred() ? 1 : 0;
333
334     if (have_error)
335         PyErr_Fetch(&err_type, &err_value, &err_traceback);
336     if(self->parent != NULL) {
337         Py_DECREF(self->parent);
338         self->parent = NULL;
339     }
340     if (have_error)
341         PyErr_Restore(err_type, err_value, err_traceback);
342     PyObject_DEL(self);
343 }
344
345 static int ACLEntry_set_tag_type(PyObject* obj, PyObject* value, void* arg) {
346     ACLEntryObject *self = (ACLEntryObject*) obj;
347
348     if(value == NULL) {
349         PyErr_SetString(PyExc_TypeError,
350                         "tag type deletion is not supported");
351         return -1;
352     }
353
354     if(!PyInt_Check(value)) {
355         PyErr_SetString(PyExc_TypeError,
356                         "tag type must be integer");
357         return -1;
358     }
359     if(acl_set_tag_type(self->ob_entry, (acl_tag_t)PyInt_AsLong(value)) == -1) {
360         PyErr_SetFromErrno(PyExc_IOError);
361         return -1;
362     }
363
364     return 0;
365 }
366
367 static PyObject* ACLEntry_get_tag_type(PyObject *obj, void* arg) {
368     ACLEntryObject *self = (ACLEntryObject*) obj;
369     acl_tag_t value;
370
371     if (self->ob_entry == NULL) {
372         PyErr_SetString(PyExc_AttributeError, "entry attribute");
373         return NULL;
374     }
375     if(acl_get_tag_type(self->ob_entry, &value) == -1) {
376         PyErr_SetFromErrno(PyExc_IOError);
377         return NULL;
378     }
379
380     return PyInt_FromLong(value);
381 }
382
383 static int ACLEntry_set_qualifier(PyObject* obj, PyObject* value, void* arg) {
384     ACLEntryObject *self = (ACLEntryObject*) obj;
385     int uidgid;
386
387     if(value == NULL) {
388         PyErr_SetString(PyExc_TypeError,
389                         "qualifier deletion is not supported");
390         return -1;
391     }
392
393     if(!PyInt_Check(value)) {
394         PyErr_SetString(PyExc_TypeError,
395                         "tag type must be integer");
396         return -1;
397     }
398     uidgid = PyInt_AsLong(value);
399     if(acl_set_qualifier(self->ob_entry, (void*)&uidgid) == -1) {
400         PyErr_SetFromErrno(PyExc_IOError);
401         return -1;
402     }
403
404     return 0;
405 }
406
407 static PyObject* ACLEntry_get_qualifier(PyObject *obj, void* arg) {
408     ACLEntryObject *self = (ACLEntryObject*) obj;
409     void *p;
410     int value;
411
412     if (self->ob_entry == NULL) {
413         PyErr_SetString(PyExc_AttributeError, "entry attribute");
414         return NULL;
415     }
416     if((p = acl_get_qualifier(self->ob_entry)) == NULL) {
417         PyErr_SetFromErrno(PyExc_IOError);
418         return NULL;
419     }
420     value = *(uid_t*)p;
421     
422     return PyInt_FromLong(value);
423 }
424
425 static PyObject* ACLEntry_get_parent(PyObject *obj, void* arg) {
426     ACLEntryObject *self = (ACLEntryObject*) obj;
427     
428     Py_INCREF(self->parent);
429     return self->parent;
430 }
431
432 #endif
433
434 static char __acltype_doc__[] = \
435 "Type which represents a POSIX ACL\n" \
436 "\n" \
437 "Parameters:\n" \
438 "  Only one keword parameter should be provided:\n"
439 "  - file=\"...\", meaning create ACL representing\n"
440 "    the ACL of that file\n" \
441 "  - fd=<int>, meaning create ACL representing\n" \
442 "    the ACL of that file descriptor\n" \
443 "  - text=\"...\", meaning create ACL from a \n" \
444 "    textual description\n" \
445 "  - acl=<ACL instance>, meaning create a copy\n" \
446 "    of an existing ACL instance\n" \
447 ;
448
449 /* ACL type methods */
450 static PyMethodDef ACL_methods[] = {
451     {"applyto", ACL_applyto, METH_VARARGS, __applyto_doc__},
452     {"valid", ACL_valid, METH_NOARGS, __valid_doc__},
453 #ifdef HAVE_LEVEL2
454     {"__getstate__", ACL_get_state, METH_NOARGS, "Dumps the ACL to an external format."},
455     {"__setstate__", ACL_set_state, METH_VARARGS, "Loads the ACL from an external format."},
456 #endif
457     {NULL, NULL, 0, NULL}
458 };
459
460
461 /* The definition of the ACL Type */
462 static PyTypeObject ACLType = {
463     PyObject_HEAD_INIT(NULL)
464     0,
465     "posix1e.ACL",
466     sizeof(ACLObject),
467     0,
468     ACL_dealloc,        /* tp_dealloc */
469     0,                  /* tp_print */
470     0,                  /* tp_getattr */
471     0,                  /* tp_setattr */
472     0,                  /* tp_compare */
473     ACL_repr,           /* tp_repr */
474     0,                  /* tp_as_number */
475     0,                  /* tp_as_sequence */
476     0,                  /* tp_as_mapping */
477     0,                  /* tp_hash */
478     0,                  /* tp_call */
479     0,                  /* tp_str */
480     0,                  /* tp_getattro */
481     0,                  /* tp_setattro */
482     0,                  /* tp_as_buffer */
483     Py_TPFLAGS_DEFAULT, /* tp_flags */
484     __acltype_doc__,    /* tp_doc */
485     0,                  /* tp_traverse */
486     0,                  /* tp_clear */
487     0,                  /* tp_richcompare */
488     0,                  /* tp_weaklistoffset */
489 #ifdef HAVE_LEVEL2
490     ACL_iter,
491     ACL_iternext,
492 #else
493     0,                  /* tp_iter */
494     0,                  /* tp_iternext */
495 #endif
496     ACL_methods,        /* tp_methods */
497     0,                  /* tp_members */
498     0,                  /* tp_getset */
499     0,                  /* tp_base */
500     0,                  /* tp_dict */
501     0,                  /* tp_descr_get */
502     0,                  /* tp_descr_set */
503     0,                  /* tp_dictoffset */
504     ACL_init,           /* tp_init */
505     0,                  /* tp_alloc */
506     ACL_new,            /* tp_new */
507 };
508
509 #ifdef HAVE_LEVEL2
510
511 /* ACLEntry type methods */
512 static PyMethodDef ACLEntry_methods[] = {
513     {NULL, NULL, 0, NULL}
514 };
515
516 static char __ACLEntry_tagtype_doc__[] = \
517 "The tag type of the current entry\n" \
518 "\n" \
519 "This is one of:\n" \
520 " - ACL_UNDEFINED_TAG\n" \
521 " - ACL_USER_OBJ\n" \
522 " - ACL_USER\n" \
523 " - ACL_GROUP_OBJ\n" \
524 " - ACL_GROUP\n" \
525 " - ACL_MASK\n" \
526 " - ACL_OTHER\n" \
527 ;
528
529 static char __ACLEntry_qualifier_doc__[] = \
530 "The qualifier of the current entry\n" \
531 "\n" \
532 "If the tag type is ACL_USER, this should be a user id.\n" \
533 "If the tag type if ACL_GROUP, this should be a group id.\n" \
534 "Else, it doesn't matter.\n" \
535 ;
536
537 static char __ACLEntry_parent_doc__[] = \
538 "The parent ACL of this entry\n" \
539 ;
540
541 /* ACLEntry getset */
542 static PyGetSetDef ACLEntry_getsets[] = {
543     {"tag_type", ACLEntry_get_tag_type, ACLEntry_set_tag_type, __ACLEntry_tagtype_doc__},
544     {"qualifier", ACLEntry_get_qualifier, ACLEntry_set_qualifier, __ACLEntry_qualifier_doc__},
545     {"parent", ACLEntry_get_parent, NULL, __ACLEntry_parent_doc__},
546     {NULL}
547 };
548
549 /* The definition of the ACL Entry Type */
550 static PyTypeObject ACLEntryType = {
551     PyObject_HEAD_INIT(NULL)
552     0,
553     "posix1e.ACLEntry",
554     sizeof(ACLEntryObject),
555     0,
556     ACLEntry_dealloc,   /* tp_dealloc */
557     0,                  /* tp_print */
558     0,                  /* tp_getattr */
559     0,                  /* tp_setattr */
560     0,                  /* tp_compare */
561     0, //ACLEntry_repr,      /* tp_repr */
562     0,                  /* tp_as_number */
563     0,                  /* tp_as_sequence */
564     0,                  /* tp_as_mapping */
565     0,                  /* tp_hash */
566     0,                  /* tp_call */
567     0,                  /* tp_str */
568     0,                  /* tp_getattro */
569     0,                  /* tp_setattro */
570     0,                  /* tp_as_buffer */
571     Py_TPFLAGS_DEFAULT, /* tp_flags */
572     __acltype_doc__,    /* tp_doc */
573     0,                  /* tp_traverse */
574     0,                  /* tp_clear */
575     0,                  /* tp_richcompare */
576     0,                  /* tp_weaklistoffset */
577     0,                  /* tp_iter */
578     0,                  /* tp_iternext */
579     ACLEntry_methods,   /* tp_methods */
580     0,                  /* tp_members */
581     ACLEntry_getsets,   /* tp_getset */
582     0,                  /* tp_base */
583     0,                  /* tp_dict */
584     0,                  /* tp_descr_get */
585     0,                  /* tp_descr_set */
586     0,                  /* tp_dictoffset */
587     ACLEntry_init,      /* tp_init */
588     0,                  /* tp_alloc */
589     ACLEntry_new,       /* tp_new */
590 };
591
592 #endif
593
594 /* Module methods */
595
596 static char __deletedef_doc__[] = \
597 "Delete the default ACL from a directory.\n" \
598 "\n" \
599 "This function deletes the default ACL associated with \n" \
600 "a directory (the ACL which will be ANDed with the mode\n" \
601 "parameter to the open, creat functions).\n" \
602 "Parameters:\n" \
603 "  - a string representing the directory whose default ACL\n" \
604 "    should be deleted\n" \
605 ;
606
607 /* Deletes the default ACL from a directory */
608 static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) {
609     char *filename;
610
611     /* Parse the arguments */
612     if (!PyArg_ParseTuple(args, "s", &filename))
613         return NULL;
614
615     if(acl_delete_def_file(filename) == -1) {
616         return PyErr_SetFromErrno(PyExc_IOError);
617     }
618
619     /* Return the result */
620     Py_INCREF(Py_None);
621     return Py_None;
622 }
623
624 /* The module methods */
625 static PyMethodDef aclmodule_methods[] = {
626     {"delete_default", aclmodule_delete_default, METH_VARARGS, __deletedef_doc__},
627     {NULL, NULL, 0, NULL}
628 };
629
630 static char __posix1e_doc__[] = \
631 "POSIX.1e ACLs manipulation\n" \
632 "\n" \
633 "This module provides support for manipulating POSIX.1e ACLS\n" \
634 "\n" \
635 "Depending on the operating system support for POSIX.1e, \n" \
636 "the ACL type will have more or less capabilities:\n" \
637 "  - level 1, only basic support, you can create\n" \
638 "    ACLs from files and text descriptions;\n" \
639 "    once created, the type is immutable\n" \
640 "  - level 2, complete support, you can alter\n"\
641 "    the ACL once it is created\n" \
642 "\n" \
643 "Also, in level 2, more types will be available, corresponding\n" \
644 "to acl_entry_t, acl_permset_t, etc.\n" \
645 "\n" \
646 "Example:\n" \
647 ">>> import posix1e\n" \
648 ">>> acl1 = posix1e.ACL(file=\"file.txt\") \n" \
649 ">>> print acl1\n" \
650 "user::rw-\n" \
651 "group::rw-\n" \
652 "other::r--\n" \
653 "\n" \
654 ">>> b = posix1e.ACL(text=\"u::rx,g::-,o::-\")\n" \
655 ">>> print b\n" \
656 "user::r-x\n" \
657 "group::---\n" \
658 "other::---\n" \
659 "\n" \
660 ">>> b.applyto(\"file.txt\")\n" \
661 ">>> print posix1e.ACL(file=\"file.txt\")\n" \
662 "user::r-x\n" \
663 "group::---\n" \
664 "other::---\n" \
665 "\n" \
666 ">>>\n" \
667 ;
668
669 DL_EXPORT(void) initposix1e(void) {
670     PyObject *m, *d;
671
672     ACLType.ob_type = &PyType_Type;
673
674     if(PyType_Ready(&ACLType) < 0)
675         return;
676
677 #ifdef HAVE_LEVEL2
678     ACLEntryType.ob_type = &PyType_Type;
679
680     if(PyType_Ready(&ACLEntryType) < 0)
681         return;
682 #endif
683
684     m = Py_InitModule3("posix1e", aclmodule_methods, __posix1e_doc__);
685
686     d = PyModule_GetDict(m);
687     if (d == NULL)
688         return;
689
690     Py_INCREF(&ACLType);
691     if (PyDict_SetItemString(d, "ACL",
692                              (PyObject *) &ACLType) < 0)
693         return;
694 #ifdef HAVE_LEVEL2
695     Py_INCREF(&ACLEntryType);
696     if (PyDict_SetItemString(d, "ACLEntry",
697                              (PyObject *) &ACLEntryType) < 0)
698         return;
699
700     /* 23.2.2 acl_perm_t values */
701     PyModule_AddIntConstant(m, "ACL_READ", ACL_READ);
702     PyModule_AddIntConstant(m, "ACL_WRITE", ACL_WRITE);
703     PyModule_AddIntConstant(m, "ACL_EXECUTE", ACL_EXECUTE);
704
705     /* 23.2.5 acl_tag_t values */
706     PyModule_AddIntConstant(m, "ACL_UNDEFINED_TAG", ACL_UNDEFINED_TAG);
707     PyModule_AddIntConstant(m, "ACL_USER_OBJ", ACL_USER_OBJ);
708     PyModule_AddIntConstant(m, "ACL_USER", ACL_USER);
709     PyModule_AddIntConstant(m, "ACL_GROUP_OBJ", ACL_GROUP_OBJ);
710     PyModule_AddIntConstant(m, "ACL_GROUP", ACL_GROUP);
711     PyModule_AddIntConstant(m, "ACL_MASK", ACL_MASK);
712     PyModule_AddIntConstant(m, "ACL_OTHER", ACL_OTHER);
713
714     /* 23.3.6 acl_type_t values */    
715     PyModule_AddIntConstant(m, "ACL_TYPE_ACCESS", ACL_TYPE_ACCESS);
716     PyModule_AddIntConstant(m, "ACL_TYPE_DEFAULT", ACL_TYPE_DEFAULT);
717
718 #endif
719 }