10 staticforward PyTypeObject ACL_Type;
11 static PyObject* ACL_applyto(PyObject* obj, PyObject* args);
12 static PyObject* ACL_valid(PyObject* obj, PyObject* args);
15 static PyObject* ACL_get_state(PyObject *obj, PyObject* args);
16 static PyObject* ACL_set_state(PyObject *obj, PyObject* args);
18 staticforward PyTypeObject Entry_Type;
19 staticforward PyTypeObject Permset_Type;
20 static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds);
33 PyObject *parent_acl; /* The parent acl, so it won't run out on us */
39 PyObject *parent_entry; /* The parent entry, so it won't run out on us */
40 acl_permset_t permset;
45 /* Creation of a new ACL instance */
46 static PyObject* ACL_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
49 newacl = type->tp_alloc(type, 0);
52 ((ACL_Object*)newacl)->acl = NULL;
53 ((ACL_Object*)newacl)->entry_id = ACL_FIRST_ENTRY;
59 /* Initialization of a new ACL instance */
60 static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) {
61 ACL_Object* self = (ACL_Object*) obj;
62 static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", NULL };
67 ACL_Object* thesrc = NULL;
69 if(!PyTuple_Check(args) || PyTuple_Size(args) != 0 ||
70 (keywds != NULL && PyDict_Check(keywds) && PyDict_Size(keywds) > 1)) {
71 PyErr_SetString(PyExc_ValueError, "a max of one keyword argument must be passed");
74 if(!PyArg_ParseTupleAndKeywords(args, keywds, "|sisO!s", kwlist,
75 &file, &fd, &text, &ACL_Type, &thesrc, &filedef))
78 /* Free the old acl_t without checking for error, we don't
84 self->acl = acl_get_file(file, ACL_TYPE_ACCESS);
86 self->acl = acl_from_text(text);
88 self->acl = acl_get_fd(fd);
89 else if(thesrc != NULL)
90 self->acl = acl_dup(thesrc->acl);
91 else if(filedef != NULL)
92 self->acl = acl_get_file(filedef, ACL_TYPE_DEFAULT);
94 self->acl = acl_init(0);
96 if(self->acl == NULL) {
97 PyErr_SetFromErrno(PyExc_IOError);
104 /* Standard type functions */
105 static void ACL_dealloc(PyObject* obj) {
106 ACL_Object *self = (ACL_Object*) obj;
107 PyObject *err_type, *err_value, *err_traceback;
108 int have_error = PyErr_Occurred() ? 1 : 0;
111 PyErr_Fetch(&err_type, &err_value, &err_traceback);
112 if(self->acl != NULL && acl_free(self->acl) != 0)
113 PyErr_WriteUnraisable(obj);
115 PyErr_Restore(err_type, err_value, err_traceback);
119 /* Converts the acl to a text format */
120 static PyObject* ACL_str(PyObject *obj) {
122 ACL_Object *self = (ACL_Object*) obj;
125 text = acl_to_text(self->acl, NULL);
127 return PyErr_SetFromErrno(PyExc_IOError);
129 ret = PyString_FromString(text);
130 if(acl_free(text) != 0) {
132 return PyErr_SetFromErrno(PyExc_IOError);
138 static char __applyto_doc__[] = \
139 "Apply the ACL to a file or filehandle.\n" \
142 " - either a filename or a file-like object or an integer; this\n" \
143 " represents the filesystem object on which to act\n" \
144 " - optional flag representing the type of ACL to set, either\n" \
145 " ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULT\n" \
148 /* Applyes the ACL to a file */
149 static PyObject* ACL_applyto(PyObject* obj, PyObject* args) {
150 ACL_Object *self = (ACL_Object*) obj;
152 acl_type_t type = ACL_TYPE_ACCESS;
156 if (!PyArg_ParseTuple(args, "O|i", &myarg, &type))
159 if(PyString_Check(myarg)) {
160 char *filename = PyString_AS_STRING(myarg);
161 nret = acl_set_file(filename, type, self->acl);
162 } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) {
163 nret = acl_set_fd(fd, self->acl);
165 PyErr_SetString(PyExc_TypeError, "argument 1 must be string, int, or file-like object");
169 return PyErr_SetFromErrno(PyExc_IOError);
172 /* Return the result */
177 static char __valid_doc__[] = \
178 "Test the ACL for validity.\n" \
180 "This method tests the ACL to see if it is a valid ACL\n" \
181 "in terms of the filesystem. More precisely, it checks:\n" \
182 "A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,\n" \
183 "ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and\n" \
184 "ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that\n" \
185 "contains entries of ACL_USER or ACL_GROUP tag types must contain exactly\n" \
186 "one entry of the ACL_MASK tag type. If an ACL contains no entries of\n" \
187 "ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.\n" \
189 "All user ID qualifiers must be unique among all entries of ACL_USER tag\n" \
190 "type, and all group IDs must be unique among all entries of ACL_GROUP tag\n" \
193 "The method will return 1 for a valid ACL and 0 for an invalid one.\n" \
194 "This has been chosen because the specification for acl_valid in POSIX.1e\n" \
195 "documents only one possible value for errno in case of an invalid ACL, \n" \
196 "so we can't differentiate between classes of errors. Other suggestions \n" \
200 /* Checks the ACL for validity */
201 static PyObject* ACL_valid(PyObject* obj, PyObject* args) {
202 ACL_Object *self = (ACL_Object*) obj;
204 if(acl_valid(self->acl) == -1) {
215 static PyObject* ACL_get_state(PyObject *obj, PyObject* args) {
216 ACL_Object *self = (ACL_Object*) obj;
221 size = acl_size(self->acl);
223 return PyErr_SetFromErrno(PyExc_IOError);
225 if((ret = PyString_FromStringAndSize(NULL, size)) == NULL)
227 buf = PyString_AsString(ret);
229 if((nsize = acl_copy_ext(buf, self->acl, size)) == -1) {
231 return PyErr_SetFromErrno(PyExc_IOError);
237 static PyObject* ACL_set_state(PyObject *obj, PyObject* args) {
238 ACL_Object *self = (ACL_Object*) obj;
243 /* Parse the argument */
244 if (!PyArg_ParseTuple(args, "s#", &buf, &bufsize))
247 /* Try to import the external representation */
248 if((ptr = acl_copy_int(buf)) == NULL)
249 return PyErr_SetFromErrno(PyExc_IOError);
251 /* Free the old acl. Should we ignore errors here? */
252 if(self->acl != NULL) {
253 if(acl_free(self->acl) == -1)
254 return PyErr_SetFromErrno(PyExc_IOError);
259 /* Return the result */
264 /* tp_iter for the ACL type; since it can be iterated only
265 * destructively, the type is its iterator
267 static PyObject* ACL_iter(PyObject *obj) {
268 ACL_Object *self = (ACL_Object*)obj;
269 self->entry_id = ACL_FIRST_ENTRY;
274 /* the tp_iternext function for the ACL type */
275 static PyObject* ACL_iternext(PyObject *obj) {
276 ACL_Object *self = (ACL_Object*)obj;
277 acl_entry_t the_entry_t;
278 Entry_Object *the_entry_obj;
281 nerr = acl_get_entry(self->acl, self->entry_id, &the_entry_t);
282 self->entry_id = ACL_NEXT_ENTRY;
284 return PyErr_SetFromErrno(PyExc_IOError);
286 /* Docs says this is not needed */
287 /*PyErr_SetObject(PyExc_StopIteration, Py_None);*/
291 the_entry_obj = (Entry_Object*) PyType_GenericNew(&Entry_Type, NULL, NULL);
292 if(the_entry_obj == NULL)
295 the_entry_obj->entry = the_entry_t;
297 the_entry_obj->parent_acl = obj;
298 Py_INCREF(obj); /* For the reference we have in entry->parent */
300 return (PyObject*)the_entry_obj;
303 static char __ACL_delentry_doc__[] = \
304 "Deletes an entry from the ACL.\n" \
306 "Note: Only with level 2\n" \
308 " - the Entry object which should be deleted; note that after\n" \
309 " this function is called, that object is unusable any longer\n" \
310 " and should be deleted\n" \
313 /* Deletes an entry from the ACL */
314 static PyObject* ACL_delentry(PyObject *obj, PyObject *args) {
315 ACL_Object *self = (ACL_Object*)obj;
318 if (!PyArg_ParseTuple(args, "O!", &Entry_Type, &e))
321 if(acl_delete_entry(self->acl, e->entry) == -1)
322 return PyErr_SetFromErrno(PyExc_IOError);
324 /* Return the result */
329 /* Creation of a new Entry instance */
330 static PyObject* Entry_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
333 newentry = PyType_GenericNew(type, args, keywds);
335 if(newentry != NULL) {
336 ((Entry_Object*)newentry)->entry = NULL;
337 ((Entry_Object*)newentry)->parent_acl = NULL;
343 /* Initialization of a new Entry instance */
344 static int Entry_init(PyObject* obj, PyObject* args, PyObject *keywds) {
345 Entry_Object* self = (Entry_Object*) obj;
346 ACL_Object* parent = NULL;
348 if (!PyArg_ParseTuple(args, "O!", &ACL_Type, &parent))
351 if(acl_create_entry(&parent->acl, &self->entry) == -1) {
352 PyErr_SetFromErrno(PyExc_IOError);
356 self->parent_acl = (PyObject*)parent;
362 /* Free the Entry instance */
363 static void Entry_dealloc(PyObject* obj) {
364 Entry_Object *self = (Entry_Object*) obj;
365 PyObject *err_type, *err_value, *err_traceback;
366 int have_error = PyErr_Occurred() ? 1 : 0;
369 PyErr_Fetch(&err_type, &err_value, &err_traceback);
370 if(self->parent_acl != NULL) {
371 Py_DECREF(self->parent_acl);
372 self->parent_acl = NULL;
375 PyErr_Restore(err_type, err_value, err_traceback);
379 /* Converts the entry to a text format */
380 static PyObject* Entry_str(PyObject *obj) {
385 PyObject *format, *list;
386 Entry_Object *self = (Entry_Object*) obj;
388 if(acl_get_tag_type(self->entry, &tag) == -1) {
389 PyErr_SetFromErrno(PyExc_IOError);
392 if(tag == ACL_USER || tag == ACL_GROUP) {
393 if((p = acl_get_qualifier(self->entry)) == NULL) {
394 PyErr_SetFromErrno(PyExc_IOError);
397 qualifier = *(uid_t*)p;
403 format = PyString_FromString("ACL entry for %s");
406 list = PyTuple_New(1);
407 if(tag == ACL_UNDEFINED_TAG) {
408 PyTuple_SetItem(list, 0, PyString_FromString("undefined type"));
409 } else if(tag == ACL_USER_OBJ) {
410 PyTuple_SetItem(list, 0, PyString_FromString("the owner"));
411 } else if(tag == ACL_GROUP_OBJ) {
412 PyTuple_SetItem(list, 0, PyString_FromString("the group"));
413 } else if(tag == ACL_OTHER) {
414 PyTuple_SetItem(list, 0, PyString_FromString("the others"));
415 } else if(tag == ACL_USER) {
416 PyTuple_SetItem(list, 0, PyString_FromFormat("user with uid %d", qualifier));
417 } else if(tag == ACL_GROUP) {
418 PyTuple_SetItem(list, 0, PyString_FromFormat("group with gid %d", qualifier));
419 } else if(tag == ACL_MASK) {
420 PyTuple_SetItem(list, 0, PyString_FromString("the mask"));
422 PyTuple_SetItem(list, 0, PyString_FromString("UNKNOWN_TAG_TYPE!"));
424 ret = PyString_Format(format, list);
430 /* Sets the tag type of the entry */
431 static int Entry_set_tag_type(PyObject* obj, PyObject* value, void* arg) {
432 Entry_Object *self = (Entry_Object*) obj;
435 PyErr_SetString(PyExc_TypeError,
436 "tag type deletion is not supported");
440 if(!PyInt_Check(value)) {
441 PyErr_SetString(PyExc_TypeError,
442 "tag type must be integer");
445 if(acl_set_tag_type(self->entry, (acl_tag_t)PyInt_AsLong(value)) == -1) {
446 PyErr_SetFromErrno(PyExc_IOError);
453 /* Returns the tag type of the entry */
454 static PyObject* Entry_get_tag_type(PyObject *obj, void* arg) {
455 Entry_Object *self = (Entry_Object*) obj;
458 if (self->entry == NULL) {
459 PyErr_SetString(PyExc_AttributeError, "entry attribute");
462 if(acl_get_tag_type(self->entry, &value) == -1) {
463 PyErr_SetFromErrno(PyExc_IOError);
467 return PyInt_FromLong(value);
470 /* Sets the qualifier (either uid_t or gid_t) for the entry,
471 * usable only if the tag type if ACL_USER or ACL_GROUP
473 static int Entry_set_qualifier(PyObject* obj, PyObject* value, void* arg) {
474 Entry_Object *self = (Entry_Object*) obj;
478 PyErr_SetString(PyExc_TypeError,
479 "qualifier deletion is not supported");
483 if(!PyInt_Check(value)) {
484 PyErr_SetString(PyExc_TypeError,
485 "tag type must be integer");
488 uidgid = PyInt_AsLong(value);
489 if(acl_set_qualifier(self->entry, (void*)&uidgid) == -1) {
490 PyErr_SetFromErrno(PyExc_IOError);
497 /* Returns the qualifier of the entry */
498 static PyObject* Entry_get_qualifier(PyObject *obj, void* arg) {
499 Entry_Object *self = (Entry_Object*) obj;
503 if (self->entry == NULL) {
504 PyErr_SetString(PyExc_AttributeError, "entry attribute");
507 if((p = acl_get_qualifier(self->entry)) == NULL) {
508 PyErr_SetFromErrno(PyExc_IOError);
514 return PyInt_FromLong(value);
517 /* Returns the parent ACL of the entry */
518 static PyObject* Entry_get_parent(PyObject *obj, void* arg) {
519 Entry_Object *self = (Entry_Object*) obj;
521 Py_INCREF(self->parent_acl);
522 return self->parent_acl;
525 /* Returns the a new Permset representing the permset of the entry
526 * FIXME: Should return a new reference to the same object, which
527 * should be created at init time!
529 static PyObject* Entry_get_permset(PyObject *obj, void* arg) {
530 Entry_Object *self = (Entry_Object*)obj;
534 p = Permset_new(&Permset_Type, NULL, NULL);
537 ps = (Permset_Object*)p;
538 if(acl_get_permset(self->entry, &ps->permset) == -1) {
539 PyErr_SetFromErrno(PyExc_IOError);
542 ps->parent_entry = obj;
548 /* Sets the permset of the entry to the passed Permset */
549 static int Entry_set_permset(PyObject* obj, PyObject* value, void* arg) {
550 Entry_Object *self = (Entry_Object*)obj;
553 if(!PyObject_IsInstance(value, (PyObject*)&Permset_Type)) {
554 PyErr_SetString(PyExc_TypeError, "argument 1 must be posix1e.Permset");
557 p = (Permset_Object*)value;
558 if(acl_set_permset(self->entry, p->permset) == -1) {
559 PyErr_SetFromErrno(PyExc_IOError);
565 static char __Entry_copy_doc__[] = \
566 "Copy an ACL entry.\n" \
568 "This method sets all the parameters to those of another\n" \
569 "entry, even one of another's ACL\n" \
571 " - src, instance of type Entry\n" \
574 /* Sets all the entry parameters to another's entry */
575 static PyObject* Entry_copy(PyObject *obj, PyObject *args) {
576 Entry_Object *self = (Entry_Object*)obj;
579 if(!PyArg_ParseTuple(args, "O!", &Entry_Type, &other))
582 if(acl_copy_entry(self->entry, other->entry) == -1)
583 return PyErr_SetFromErrno(PyExc_IOError);
589 /**** Permset type *****/
591 /* Creation of a new Permset instance */
592 static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds) {
593 PyObject* newpermset;
595 newpermset = PyType_GenericNew(type, args, keywds);
597 if(newpermset != NULL) {
598 ((Permset_Object*)newpermset)->permset = NULL;
599 ((Permset_Object*)newpermset)->parent_entry = NULL;
605 /* Initialization of a new Permset instance */
606 static int Permset_init(PyObject* obj, PyObject* args, PyObject *keywds) {
607 Permset_Object* self = (Permset_Object*) obj;
608 Entry_Object* parent = NULL;
610 if (!PyArg_ParseTuple(args, "O!", &Entry_Type, &parent))
613 if(acl_get_permset(parent->entry, &self->permset) == -1) {
614 PyErr_SetFromErrno(PyExc_IOError);
618 self->parent_entry = (PyObject*)parent;
624 /* Free the Permset instance */
625 static void Permset_dealloc(PyObject* obj) {
626 Permset_Object *self = (Permset_Object*) obj;
627 PyObject *err_type, *err_value, *err_traceback;
628 int have_error = PyErr_Occurred() ? 1 : 0;
631 PyErr_Fetch(&err_type, &err_value, &err_traceback);
632 if(self->parent_entry != NULL) {
633 Py_DECREF(self->parent_entry);
634 self->parent_entry = NULL;
637 PyErr_Restore(err_type, err_value, err_traceback);
641 /* Permset string representation */
642 static PyObject* Permset_str(PyObject *obj) {
643 Permset_Object *self = (Permset_Object*) obj;
646 pstr[0] = get_perm(self->permset, ACL_READ) ? 'r' : '-';
647 pstr[1] = get_perm(self->permset, ACL_WRITE) ? 'w' : '-';
648 pstr[2] = get_perm(self->permset, ACL_EXECUTE) ? 'x' : '-';
649 return PyString_FromStringAndSize(pstr, 3);
652 static char __Permset_clear_doc__[] = \
653 "Clear all permissions from the permission set.\n" \
656 /* Clears all permissions from the permset */
657 static PyObject* Permset_clear(PyObject* obj, PyObject* args) {
658 Permset_Object *self = (Permset_Object*) obj;
660 if(acl_clear_perms(self->permset) == -1)
661 return PyErr_SetFromErrno(PyExc_IOError);
663 /* Return the result */
668 static PyObject* Permset_get_right(PyObject *obj, void* arg) {
669 Permset_Object *self = (Permset_Object*) obj;
671 if(get_perm(self->permset, (int)arg)) {
680 static int Permset_set_right(PyObject* obj, PyObject* value, void* arg) {
681 Permset_Object *self = (Permset_Object*) obj;
685 if(!PyInt_Check(value)) {
686 PyErr_SetString(PyExc_ValueError, "a maximum of one argument must be passed");
689 on = PyInt_AsLong(value);
691 nerr = acl_add_perm(self->permset, (int)arg);
693 nerr = acl_delete_perm(self->permset, (int)arg);
695 PyErr_SetFromErrno(PyExc_IOError);
703 static char __ACL_Type_doc__[] = \
704 "Type which represents a POSIX ACL\n" \
707 " Only one keword parameter should be provided:\n"
708 " - file=\"...\", meaning create ACL representing\n"
709 " the access ACL of that file\n" \
710 " - filedef=\"...\", meaning create ACL representing\n"
711 " the default ACL of that directory\n" \
712 " - fd=<int>, meaning create ACL representing\n" \
713 " the access ACL of that file descriptor\n" \
714 " - text=\"...\", meaning create ACL from a \n" \
715 " textual description\n" \
716 " - acl=<ACL instance>, meaning create a copy\n" \
717 " of an existing ACL instance\n" \
718 "If no parameters are passed, create an empty ACL; this\n" \
719 "makes sense only when your OS supports ACL modification\n" \
720 " (i.e. it implements full POSIX.1e support)\n" \
723 /* ACL type methods */
724 static PyMethodDef ACL_methods[] = {
725 {"applyto", ACL_applyto, METH_VARARGS, __applyto_doc__},
726 {"valid", ACL_valid, METH_NOARGS, __valid_doc__},
728 {"__getstate__", ACL_get_state, METH_NOARGS, "Dumps the ACL to an external format."},
729 {"__setstate__", ACL_set_state, METH_VARARGS, "Loads the ACL from an external format."},
730 {"delentry", ACL_delentry, METH_VARARGS, __ACL_delentry_doc__},
732 {NULL, NULL, 0, NULL}
736 /* The definition of the ACL Type */
737 static PyTypeObject ACL_Type = {
738 PyObject_HEAD_INIT(NULL)
743 ACL_dealloc, /* tp_dealloc */
749 0, /* tp_as_number */
750 0, /* tp_as_sequence */
751 0, /* tp_as_mapping */
754 ACL_str, /* tp_str */
757 0, /* tp_as_buffer */
758 Py_TPFLAGS_DEFAULT, /* tp_flags */
759 __ACL_Type_doc__, /* tp_doc */
762 0, /* tp_richcompare */
763 0, /* tp_weaklistoffset */
771 ACL_methods, /* tp_methods */
776 0, /* tp_descr_get */
777 0, /* tp_descr_set */
778 0, /* tp_dictoffset */
779 ACL_init, /* tp_init */
781 ACL_new, /* tp_new */
786 /* Entry type methods */
787 static PyMethodDef Entry_methods[] = {
788 {"copy", Entry_copy, METH_VARARGS, __Entry_copy_doc__},
789 {NULL, NULL, 0, NULL}
792 static char __Entry_tagtype_doc__[] = \
793 "The tag type of the current entry\n" \
795 "This is one of:\n" \
796 " - ACL_UNDEFINED_TAG\n" \
797 " - ACL_USER_OBJ\n" \
799 " - ACL_GROUP_OBJ\n" \
805 static char __Entry_qualifier_doc__[] = \
806 "The qualifier of the current entry\n" \
808 "If the tag type is ACL_USER, this should be a user id.\n" \
809 "If the tag type if ACL_GROUP, this should be a group id.\n" \
810 "Else, it doesn't matter.\n" \
813 static char __Entry_parent_doc__[] = \
814 "The parent ACL of this entry\n" \
817 static char __Entry_permset_doc__[] = \
818 "The permission set of this ACL entry\n" \
822 static PyGetSetDef Entry_getsets[] = {
823 {"tag_type", Entry_get_tag_type, Entry_set_tag_type, __Entry_tagtype_doc__},
824 {"qualifier", Entry_get_qualifier, Entry_set_qualifier, __Entry_qualifier_doc__},
825 {"parent", Entry_get_parent, NULL, __Entry_parent_doc__},
826 {"permset", Entry_get_permset, Entry_set_permset, __Entry_permset_doc__},
830 static char __Entry_Type_doc__[] = \
831 "Type which represents an entry in an ACL.\n" \
833 "The type exists only if the OS has full support for POSIX.1e\n" \
834 "Can be created either by:\n" \
835 " e = posix1e.Entry(myACL) # this creates a new entry in the ACL\n" \
837 " for entry in myACL:\n" \
840 /* The definition of the Entry Type */
841 static PyTypeObject Entry_Type = {
842 PyObject_HEAD_INIT(NULL)
845 sizeof(Entry_Object),
847 Entry_dealloc, /* tp_dealloc */
853 0, /* tp_as_number */
854 0, /* tp_as_sequence */
855 0, /* tp_as_mapping */
858 Entry_str, /* tp_str */
861 0, /* tp_as_buffer */
862 Py_TPFLAGS_DEFAULT, /* tp_flags */
863 __Entry_Type_doc__, /* tp_doc */
866 0, /* tp_richcompare */
867 0, /* tp_weaklistoffset */
870 Entry_methods, /* tp_methods */
872 Entry_getsets, /* tp_getset */
875 0, /* tp_descr_get */
876 0, /* tp_descr_set */
877 0, /* tp_dictoffset */
878 Entry_init, /* tp_init */
880 Entry_new, /* tp_new */
883 /* Permset type methods */
884 static PyMethodDef Permset_methods[] = {
885 {"clear", Permset_clear, METH_NOARGS, __Permset_clear_doc__, },
886 {NULL, NULL, 0, NULL}
889 static char __Permset_execute_doc__[] = \
890 "Execute permsission\n" \
893 static char __Permset_read_doc__[] = \
894 "Read permsission\n" \
897 static char __Permset_write_doc__[] = \
898 "Write permsission\n" \
902 static PyGetSetDef Permset_getsets[] = {
903 {"execute", Permset_get_right, Permset_set_right, __Permset_execute_doc__, (void*)ACL_EXECUTE},
904 {"read", Permset_get_right, Permset_set_right, __Permset_read_doc__, (void*)ACL_READ},
905 {"write", Permset_get_right, Permset_set_right, __Permset_write_doc__, (void*)ACL_WRITE},
909 static char __Permset_Type_doc__[] = \
910 "Type which represents the permission set in an ACL entry\n" \
912 "The type exists only if the OS has full support for POSIX.1e\n" \
913 "Can be created either by:\n" \
914 " perms = myEntry.permset\n" \
916 " perms = posix1e.Permset(myEntry)\n" \
919 /* The definition of the Permset Type */
920 static PyTypeObject Permset_Type = {
921 PyObject_HEAD_INIT(NULL)
924 sizeof(Permset_Object),
926 Permset_dealloc, /* tp_dealloc */
932 0, /* tp_as_number */
933 0, /* tp_as_sequence */
934 0, /* tp_as_mapping */
937 Permset_str, /* tp_str */
940 0, /* tp_as_buffer */
941 Py_TPFLAGS_DEFAULT, /* tp_flags */
942 __Permset_Type_doc__,/* tp_doc */
945 0, /* tp_richcompare */
946 0, /* tp_weaklistoffset */
949 Permset_methods, /* tp_methods */
951 Permset_getsets, /* tp_getset */
954 0, /* tp_descr_get */
955 0, /* tp_descr_set */
956 0, /* tp_dictoffset */
957 Permset_init, /* tp_init */
959 Permset_new, /* tp_new */
966 static char __deletedef_doc__[] = \
967 "Delete the default ACL from a directory.\n" \
969 "This function deletes the default ACL associated with \n" \
970 "a directory (the ACL which will be ANDed with the mode\n" \
971 "parameter to the open, creat functions).\n" \
973 " - a string representing the directory whose default ACL\n" \
974 " should be deleted\n" \
977 /* Deletes the default ACL from a directory */
978 static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) {
981 /* Parse the arguments */
982 if (!PyArg_ParseTuple(args, "s", &filename))
985 if(acl_delete_def_file(filename) == -1) {
986 return PyErr_SetFromErrno(PyExc_IOError);
989 /* Return the result */
994 /* The module methods */
995 static PyMethodDef aclmodule_methods[] = {
996 {"delete_default", aclmodule_delete_default, METH_VARARGS, __deletedef_doc__},
997 {NULL, NULL, 0, NULL}
1000 static char __posix1e_doc__[] = \
1001 "POSIX.1e ACLs manipulation\n" \
1003 "This module provides support for manipulating POSIX.1e ACLS\n" \
1005 "Depending on the operating system support for POSIX.1e, \n" \
1006 "the ACL type will have more or less capabilities:\n" \
1007 " - level 1, only basic support, you can create\n" \
1008 " ACLs from files and text descriptions;\n" \
1009 " once created, the type is immutable\n" \
1010 " - level 2, complete support, you can alter\n"\
1011 " the ACL once it is created\n" \
1013 "Also, in level 2, more types are available, corresponding\n" \
1014 "to acl_entry_t (Entry type), acl_permset_t (Permset type).\n" \
1017 ">>> import posix1e\n" \
1018 ">>> acl1 = posix1e.ACL(file=\"file.txt\") \n" \
1019 ">>> print acl1\n" \
1024 ">>> b = posix1e.ACL(text=\"u::rx,g::-,o::-\")\n" \
1030 ">>> b.applyto(\"file.txt\")\n" \
1031 ">>> print posix1e.ACL(file=\"file.txt\")\n" \
1039 void initposix1e(void) {
1042 ACL_Type.ob_type = &PyType_Type;
1043 if(PyType_Ready(&ACL_Type) < 0)
1047 Entry_Type.ob_type = &PyType_Type;
1048 if(PyType_Ready(&Entry_Type) < 0)
1051 Permset_Type.ob_type = &PyType_Type;
1052 if(PyType_Ready(&Permset_Type) < 0)
1056 m = Py_InitModule3("posix1e", aclmodule_methods, __posix1e_doc__);
1058 d = PyModule_GetDict(m);
1062 Py_INCREF(&ACL_Type);
1063 if (PyDict_SetItemString(d, "ACL",
1064 (PyObject *) &ACL_Type) < 0)
1067 /* 23.3.6 acl_type_t values */
1068 PyModule_AddIntConstant(m, "ACL_TYPE_ACCESS", ACL_TYPE_ACCESS);
1069 PyModule_AddIntConstant(m, "ACL_TYPE_DEFAULT", ACL_TYPE_DEFAULT);
1073 Py_INCREF(&Entry_Type);
1074 if (PyDict_SetItemString(d, "Entry",
1075 (PyObject *) &Entry_Type) < 0)
1078 Py_INCREF(&Permset_Type);
1079 if (PyDict_SetItemString(d, "Permset",
1080 (PyObject *) &Permset_Type) < 0)
1083 /* 23.2.2 acl_perm_t values */
1084 PyModule_AddIntConstant(m, "ACL_READ", ACL_READ);
1085 PyModule_AddIntConstant(m, "ACL_WRITE", ACL_WRITE);
1086 PyModule_AddIntConstant(m, "ACL_EXECUTE", ACL_EXECUTE);
1088 /* 23.2.5 acl_tag_t values */
1089 PyModule_AddIntConstant(m, "ACL_UNDEFINED_TAG", ACL_UNDEFINED_TAG);
1090 PyModule_AddIntConstant(m, "ACL_USER_OBJ", ACL_USER_OBJ);
1091 PyModule_AddIntConstant(m, "ACL_USER", ACL_USER);
1092 PyModule_AddIntConstant(m, "ACL_GROUP_OBJ", ACL_GROUP_OBJ);
1093 PyModule_AddIntConstant(m, "ACL_GROUP", ACL_GROUP);
1094 PyModule_AddIntConstant(m, "ACL_MASK", ACL_MASK);
1095 PyModule_AddIntConstant(m, "ACL_OTHER", ACL_OTHER);