From 342002b3362a7b7da691795a1caea43e93076eec Mon Sep 17 00:00:00 2001 From: Iustin Pop Date: Tue, 26 Feb 2008 20:59:55 +0100 Subject: [PATCH] Imported upstream version 0.3.0 --- BENCHMARK | 20 -- ChangeLog | 108 ------- MANIFEST | 3 +- NEWS | 8 + PKG-INFO | 2 +- acl.c | 778 ++++++++++++++++++++++++++++++++------------------- posix1e.html | 212 +++++++------- posix1e.txt | 225 +++++++-------- setup.py | 10 +- 9 files changed, 704 insertions(+), 662 deletions(-) delete mode 100644 BENCHMARK delete mode 100644 ChangeLog create mode 100644 NEWS diff --git a/BENCHMARK b/BENCHMARK deleted file mode 100644 index 3c9cea1..0000000 --- a/BENCHMARK +++ /dev/null @@ -1,20 +0,0 @@ -On my Duron 1000, Linux 2.4, creating 1.000.000 ACLs and discarding them: - -empty ACL: 4.48user 0.03system 0:04.50elapsed 100%CPU -from text: 13.87user 0.09system 0:13.97elapsed 99%CPU -XFS, file: 14.17user 14.95system 0:29.13elapsed 99%CPU - -creating a list from the entries of an ACL: -no entries: 3.86user 0.01system 0:03.86elapsed 100%CPU -6 entries: 16.39user 0.00system 0:16.38elapsed 100%CPU - -As you can see, creating from file is the longest (as expected). More than -half time when creating from file was in kernel mode. - - -In freebsd 4.6, UNDER VMWARE!!!!, same machine: -empty ACL: 3.409u 0.432s 0:03.85 99.4% 516+15695k 0+0io 0pf+0w -from text: 10.672u 1.016s 0:11.71 99.7% 508+24230k 0+0io 0pf+0w - -Interesting results, it seems from text is faster here - but here -the library doens't support editing, so maybe that's why. diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index 35f2eb4..0000000 --- a/ChangeLog +++ /dev/null @@ -1,108 +0,0 @@ -2006-12-03 11:15 Iustin Pop - - * setup.py: Add support for building on GNU/kFreeBSD - -2004-04-27 20:27 Iustin Pop - - * MANIFEST.in: Added ChangeLog to distribution - -2002-12-29 20:41 Iustin Pop - - * BENCHMARK, MANIFEST.in, setup.py: Release 0.2.1 - -2002-12-29 06:48 Iustin Pop - - * acl.c: Fixed compilation on LEVEL1 platform (broke since after - 0.1) - -2002-12-29 06:36 Iustin Pop - - * BENCHMARK, acl.c: Added missing functionality (acl_calc_mask) and - some convenience functions. - -2002-12-27 21:55 Iustin Pop - - * MANIFEST.in, setup.py: Small changes - -2002-12-27 19:47 Iustin Pop - - * IMPLEMENTATION, acl.c: Prepare for release 0.2 - -2002-12-27 19:43 Iustin Pop - - * Makefile: Small makefile - -2002-12-27 19:42 Iustin Pop - - * MANIFEST.in: Distutils file - -2002-12-27 19:42 Iustin Pop - - * os_linux.c: Linux-specific file - -2002-12-27 11:35 Iustin Pop - - * PORTING: Informations for porting to other platforms. - -2002-12-26 09:21 Iustin Pop - - * acl.c: Added the Permset type/object and some other naming - changes - -2002-12-26 06:48 Iustin Pop - - * acl.c: Renamed type & object names from ACLType to ACL_Type and - so on. Also ACLEntry is now jus Entry. - -2002-12-26 06:43 Iustin Pop - - * acl.c: Renamed some fields from ob_x to x, as per other modules - in python - -2002-12-26 06:41 Iustin Pop - - * IMPLEMENTATION, acl.c: Added acl_entry_t type (named - ACLEntryType, respectively ACLEntryObject) - -2002-12-26 03:24 Iustin Pop - - * acl.c: Documentation typo - -2002-12-24 15:35 Iustin Pop - - * setup.cfg: Added setup.cfg, mainly for bdist_rpm - -2002-12-24 15:29 Iustin Pop - - * setup.py: Don't call python2, only python - -2002-12-24 15:19 Iustin Pop - - * acl.c, setup.py: Prepare for first public release - -2002-12-24 03:35 Iustin Pop - - * PLATFORMS, acl.c, setup.py: Moved to real instance creation via - type() - -2002-12-23 21:05 Iustin Pop - - * IMPLEMENTATION, PLATFORMS, README, acl.c, setup.py: Addedd - __setstate__ and some docs - -2002-12-23 16:55 Iustin Pop - - * README, setup.py: Initial revision - -2002-12-23 16:55 Iustin Pop - - * acl.c: Many functions added, started working on level 2 support - -2002-12-21 21:55 Iustin Pop - - * acl.c: Initial revision - -2002-12-21 21:55 - - * branches, tags, .: New repository initialized by cvs2svn. - diff --git a/MANIFEST b/MANIFEST index 6d339f4..57f40a1 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,7 +1,6 @@ -BENCHMARK -ChangeLog IMPLEMENTATION MANIFEST +NEWS PLATFORMS README acl.c diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..41c538c --- /dev/null +++ b/NEWS @@ -0,0 +1,8 @@ +version 0.3 +----------- + + Under Linux, implement more functions from libacl: + - add ACL(mode=...), implementing acl_from_mode + - add ACL().to_any_text, implementing acl_to_any_text + - add ACL comparison, using acl_cmp + - add ACL().check, which is a more descriptive function than validate diff --git a/PKG-INFO b/PKG-INFO index 1752799..96bd276 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.0 Name: pylibacl -Version: 0.2.2 +Version: 0.3.0 Summary: POSIX.1e ACLs for python Home-page: http://pylibacl.sourceforge.net Author: Iustin Pop diff --git a/acl.c b/acl.c index e4248a6..a477b73 100644 --- a/acl.c +++ b/acl.c @@ -17,7 +17,8 @@ static PyObject* ACL_set_state(PyObject *obj, PyObject* args); staticforward PyTypeObject Entry_Type; staticforward PyTypeObject Permset_Type; -static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds); +static PyObject* Permset_new(PyTypeObject* type, PyObject* args, + PyObject *keywds); #endif static acl_perm_t holder_ACL_EXECUTE = ACL_EXECUTE; @@ -49,7 +50,8 @@ typedef struct { #endif /* Creation of a new ACL instance */ -static PyObject* ACL_new(PyTypeObject* type, PyObject* args, PyObject *keywds) { +static PyObject* ACL_new(PyTypeObject* type, PyObject* args, + PyObject *keywds) { PyObject* newacl; newacl = type->tp_alloc(type, 0); @@ -67,7 +69,15 @@ static PyObject* ACL_new(PyTypeObject* type, PyObject* args, PyObject *keywds) { /* Initialization of a new ACL instance */ static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) { ACL_Object* self = (ACL_Object*) obj; +#ifdef HAVE_LINUX + static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", + "mode", NULL }; + char *format = "|sisO!sH"; + mode_t mode = 0; +#else static char *kwlist[] = { "file", "fd", "text", "acl", "filedef", NULL }; + char *format = "|sisO!s"; +#endif char *file = NULL; char *filedef = NULL; char *text = NULL; @@ -76,11 +86,17 @@ static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) { if(!PyTuple_Check(args) || PyTuple_Size(args) != 0 || (keywds != NULL && PyDict_Check(keywds) && PyDict_Size(keywds) > 1)) { - PyErr_SetString(PyExc_ValueError, "a max of one keyword argument must be passed"); + PyErr_SetString(PyExc_ValueError, "a max of one keyword argument" + " must be passed"); return -1; } - if(!PyArg_ParseTupleAndKeywords(args, keywds, "|sisO!s", kwlist, - &file, &fd, &text, &ACL_Type, &thesrc, &filedef)) + if(!PyArg_ParseTupleAndKeywords(args, keywds, format, kwlist, + &file, &fd, &text, &ACL_Type, + &thesrc, &filedef +#ifdef HAVE_LINUX + , &mode +#endif + )) return -1; /* Free the old acl_t without checking for error, we don't @@ -98,6 +114,10 @@ static int ACL_init(PyObject* obj, PyObject* args, PyObject *keywds) { self->acl = acl_dup(thesrc->acl); else if(filedef != NULL) self->acl = acl_get_file(filedef, ACL_TYPE_DEFAULT); +#ifdef HAVE_LINUX + else if(PyMapping_HasKeyString(keywds, kwlist[5])) + self->acl = acl_from_mode(mode); +#endif else self->acl = acl_init(0); @@ -142,16 +162,147 @@ static PyObject* ACL_str(PyObject *obj) { return ret; } +#ifdef HAVE_LINUX +static char __to_any_text_doc__[] = + "Convert the ACL to a custom text format.\n" + "\n" + "This method encapsulates the acl_to_any_text function. It allows a \n" + "customized text format to be generated for the ACL. See\n" + "acl_to_any_text(3) for more details.\n" + "\n" + "Parameters:\n" + " - prefix: if given, this string will be prepended to all lines\n" + " - separator: a single character (defaults to '\\n'); this will be\n" + " user to separate the entries in the ACL\n" + " - options: a bitwise combination of:\n" + " TEXT_ABBREVIATE: use 'u' instead of 'user', 'g' instead of \n" + " 'group', etc.\n" + " TEXT_NUMERIC_IDS: User and group IDs are included as decimal\n" + " numbers instead of names\n" + " TEXT_SOME_EFFECTIVE: Include comments denoting the effective\n" + " permissions when some are masked\n" + " TEXT_ALL_EFFECTIVE: Include comments after all ACL entries\n" + " affected by an ACL_MASK entry\n" + " TEXT_SMART_INDENT: Used in combination with the _EFFECTIVE\n" + " options, this will ensure that comments \n" + " are alligned to the fourth tab position\n" + " (assuming one tab equal eight spaces\n" + ; + +/* Converts the acl to a custom text format */ +static PyObject* ACL_to_any_text(PyObject *obj, PyObject *args, + PyObject *kwds) { + char *text; + ACL_Object *self = (ACL_Object*) obj; + PyObject *ret; + char *arg_prefix = NULL; + char arg_separator = '\n'; + int arg_options = 0; + static char *kwlist[] = {"prefix", "separator", "options", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sci", kwlist, &arg_prefix, + &arg_separator, &arg_options)) + return NULL; + + text = acl_to_any_text(self->acl, arg_prefix, arg_separator, arg_options); + if(text == NULL) { + return PyErr_SetFromErrno(PyExc_IOError); + } + ret = PyString_FromString(text); + if(acl_free(text) != 0) { + Py_DECREF(ret); + return PyErr_SetFromErrno(PyExc_IOError); + } + return ret; +} + +static char __check_doc__[] = + "Check the ACL validity.\n" + "\n" + "This is a non-portable, Linux specific extension that allow more\n" + "information to be retrieved in case an ACL is not valid than the\n" + "validate() method.\n" + "\n" + "This method will return either False (the ACL is valid), or a tuple\n" + "with two elements. The first element is one of the following\n" + "constants:\n" + " - ACL_MULTI_ERROR: The ACL contains multiple entries that have a\n" + " tag type that may occur at most once\n" + " - ACL_DUPLICATE_ERROR: The ACL contains multiple ACL_USER or \n" + " ACL_GROUP entries with the same ID\n" + " - ACL_MISS_ERROR: A required entry is missing\n" + " - ACL_ENTRY_ERROR: The ACL contains an invalid entry tag type\n" + "\n" + "The second element of the tuple is the index of the entry that is\n" + "invalid (in the same order as by iterating over the ACL entry)\n" + ; + +/* The acl_check method */ +static PyObject* ACL_check(PyObject* obj, PyObject* args) { + ACL_Object *self = (ACL_Object*) obj; + int result; + int eindex; + + if((result = acl_check(self->acl, &eindex)) == -1) + return PyErr_SetFromErrno(PyExc_IOError); + if(result == 0) { + Py_INCREF(Py_False); + return Py_False; + } + return PyTuple_Pack(2, PyInt_FromLong(result), PyInt_FromLong(eindex)); +} + +/* Implementation of the rich compare for ACLs */ +static PyObject* ACL_richcompare(PyObject* o1, PyObject* o2, int op) { + ACL_Object *acl1, *acl2; + int n; + PyObject *ret; + + if(!PyObject_IsInstance(o2, (PyObject*)&ACL_Type)) { + if(op == Py_EQ) + Py_RETURN_FALSE; + if(op == Py_NE) + Py_RETURN_TRUE; + PyErr_SetString(PyExc_TypeError, "can only compare to an ACL"); + return NULL; + } + + acl1 = (ACL_Object*)o1; + acl2 = (ACL_Object*)o2; + if((n=acl_cmp(acl1->acl, acl2->acl))==-1) + return PyErr_SetFromErrno(PyExc_IOError); + switch(op) { + case Py_EQ: + ret = n == 0 ? Py_True : Py_False; + break; + case Py_NE: + ret = n == 1 ? Py_True : Py_False; + break; + default: + ret = Py_NotImplemented; + } + Py_INCREF(ret); + return ret; +} +#endif + +/* Implementation of the compare for ACLs */ +static int ACL_nocmp(PyObject* o1, PyObject* o2) { + + PyErr_SetString(PyExc_TypeError, "cannot compare ACLs using cmp()"); + return -1; +} + /* Custom methods */ -static char __applyto_doc__[] = \ -"Apply the ACL to a file or filehandle.\n" \ -"\n" \ -"Parameters:\n" \ -" - either a filename or a file-like object or an integer; this\n" \ -" represents the filesystem object on which to act\n" \ -" - optional flag representing the type of ACL to set, either\n" \ -" ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULT\n" \ -; +static char __applyto_doc__[] = + "Apply the ACL to a file or filehandle.\n" + "\n" + "Parameters:\n" + " - either a filename or a file-like object or an integer; this\n" + " represents the filesystem object on which to act\n" + " - optional flag representing the type of ACL to set, either\n" + " ACL_TYPE_ACCESS (default) or ACL_TYPE_DEFAULT\n" + ; /* Applyes the ACL to a file */ static PyObject* ACL_applyto(PyObject* obj, PyObject* args) { @@ -170,7 +321,8 @@ static PyObject* ACL_applyto(PyObject* obj, PyObject* args) { } else if((fd = PyObject_AsFileDescriptor(myarg)) != -1) { nret = acl_set_fd(fd, self->acl); } else { - PyErr_SetString(PyExc_TypeError, "argument 1 must be string, int, or file-like object"); + PyErr_SetString(PyExc_TypeError, "argument 1 must be string, int," + " or file-like object"); return 0; } if(nret == -1) { @@ -182,28 +334,30 @@ static PyObject* ACL_applyto(PyObject* obj, PyObject* args) { return Py_None; } -static char __valid_doc__[] = \ -"Test the ACL for validity.\n" \ -"\n" \ -"This method tests the ACL to see if it is a valid ACL\n" \ -"in terms of the filesystem. More precisely, it checks:\n" \ -"A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,\n" \ -"ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and\n" \ -"ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that\n" \ -"contains entries of ACL_USER or ACL_GROUP tag types must contain exactly\n" \ -"one entry of the ACL_MASK tag type. If an ACL contains no entries of\n" \ -"ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.\n" \ -"\n" \ -"All user ID qualifiers must be unique among all entries of ACL_USER tag\n" \ -"type, and all group IDs must be unique among all entries of ACL_GROUP tag\n" \ -"type.\n" \ -"\n" \ -"The method will return 1 for a valid ACL and 0 for an invalid one.\n" \ -"This has been chosen because the specification for acl_valid in POSIX.1e\n" \ -"documents only one possible value for errno in case of an invalid ACL, \n" \ -"so we can't differentiate between classes of errors. Other suggestions \n" \ -"are welcome.\n" \ -; +static char __valid_doc__[] = + "Test the ACL for validity.\n" + "\n" + "This method tests the ACL to see if it is a valid ACL\n" + "in terms of the filesystem. More precisely, it checks that:\n" + "\n" + "The ACL contains exactly one entry with each of the\n" + "ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries\n" + "with ACL_USER and ACL_GROUP tag types may appear zero or more\n" + "times in an ACL. An ACL that contains entries of ACL_USER or\n" + "ACL_GROUP tag types must contain exactly one entry of the \n" + "ACL_MASK tag type. If an ACL contains no entries of\n" + "ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.\n" + "\n" + "All user ID qualifiers must be unique among all entries of\n" + "the ACL_USER tag type, and all group IDs must be unique among all\n" + "entries of ACL_GROUP tag type.\n" + "\n" + "The method will return 1 for a valid ACL and 0 for an invalid one.\n" + "This has been chosen because the specification for acl_valid in\n" + "the POSIX.1e standard documents only one possible value for errno\n" + "in case of an invalid ACL, so we can't differentiate between\n" + "classes of errors. Other suggestions are welcome.\n" + ; /* Checks the ACL for validity */ static PyObject* ACL_valid(PyObject* obj, PyObject* args) { @@ -233,12 +387,12 @@ static PyObject* ACL_get_state(PyObject *obj, PyObject* args) { if((ret = PyString_FromStringAndSize(NULL, size)) == NULL) return NULL; buf = PyString_AsString(ret); - + if((nsize = acl_copy_ext(buf, self->acl, size)) == -1) { Py_DECREF(ret); return PyErr_SetFromErrno(PyExc_IOError); } - + return ret; } @@ -255,7 +409,7 @@ static PyObject* ACL_set_state(PyObject *obj, PyObject* args) { /* Try to import the external representation */ if((ptr = acl_copy_int(buf)) == NULL) return PyErr_SetFromErrno(PyExc_IOError); - + /* Free the old acl. Should we ignore errors here? */ if(self->acl != NULL) { if(acl_free(self->acl) == -1) @@ -285,7 +439,7 @@ static PyObject* ACL_iternext(PyObject *obj) { acl_entry_t the_entry_t; Entry_Object *the_entry_obj; int nerr; - + nerr = acl_get_entry(self->acl, self->entry_id, &the_entry_t); self->entry_id = ACL_NEXT_ENTRY; if(nerr == -1) @@ -299,7 +453,7 @@ static PyObject* ACL_iternext(PyObject *obj) { the_entry_obj = (Entry_Object*) PyType_GenericNew(&Entry_Type, NULL, NULL); if(the_entry_obj == NULL) return NULL; - + the_entry_obj->entry = the_entry_t; the_entry_obj->parent_acl = obj; @@ -308,15 +462,15 @@ static PyObject* ACL_iternext(PyObject *obj) { return (PyObject*)the_entry_obj; } -static char __ACL_delete_entry_doc__[] = \ -"Deletes an entry from the ACL.\n" \ -"\n" \ -"Note: Only with level 2\n" \ -"Parameters:\n" \ -" - the Entry object which should be deleted; note that after\n" \ -" this function is called, that object is unusable any longer\n" \ -" and should be deleted\n" \ -; +static char __ACL_delete_entry_doc__[] = + "Deletes an entry from the ACL.\n" + "\n" + "Note: Only with level 2\n" + "Parameters:\n" + " - the Entry object which should be deleted; note that after\n" + " this function is called, that object is unusable any longer\n" + " and should be deleted\n" + ; /* Deletes an entry from the ACL */ static PyObject* ACL_delete_entry(PyObject *obj, PyObject *args) { @@ -334,25 +488,25 @@ static PyObject* ACL_delete_entry(PyObject *obj, PyObject *args) { return Py_None; } -static char __ACL_calc_mask_doc__[] = \ -"Compute the file group class mask.\n" \ -"\n" \ -"The calc_mask() method calculates and sets the permissions \n" \ -"associated with the ACL_MASK Entry of the ACL.\n" \ -"The value of the new permissions is the union of the permissions \n" \ -"granted by all entries of tag type ACL_GROUP, ACL_GROUP_OBJ, or \n" \ -"ACL_USER. If the ACL already contains an ACL_MASK entry, its \n" \ -"permissions are overwritten; if it does not contain an ACL_MASK \n" \ -"Entry, one is added.\n" \ -"\n" \ -"The order of existing entries in the ACL is undefined after this \n" \ -"function.\n" \ -; +static char __ACL_calc_mask_doc__[] = + "Compute the file group class mask.\n" + "\n" + "The calc_mask() method calculates and sets the permissions \n" + "associated with the ACL_MASK Entry of the ACL.\n" + "The value of the new permissions is the union of the permissions \n" + "granted by all entries of tag type ACL_GROUP, ACL_GROUP_OBJ, or \n" + "ACL_USER. If the ACL already contains an ACL_MASK entry, its \n" + "permissions are overwritten; if it does not contain an ACL_MASK \n" + "Entry, one is added.\n" + "\n" + "The order of existing entries in the ACL is undefined after this \n" + "function.\n" + ; /* Updates the mask entry in the ACL */ static PyObject* ACL_calc_mask(PyObject *obj, PyObject *args) { ACL_Object *self = (ACL_Object*)obj; - + if(acl_calc_mask(&self->acl) == -1) return PyErr_SetFromErrno(PyExc_IOError); @@ -361,15 +515,15 @@ static PyObject* ACL_calc_mask(PyObject *obj, PyObject *args) { return Py_None; } -static char __ACL_append_doc__[] = \ -"Append a new Entry to the ACL and return it.\n" \ -"\n" \ -"This is a convenience function to create a new Entry \n" \ -"and append it to the ACL.\n" \ -"If a parameter of type Entry instance is given, the \n" \ -"entry will be a copy of that one (as if copied with \n" \ -"Entry.copy()), otherwise, the new entry will be empty.\n" \ -; +static char __ACL_append_doc__[] = + "Append a new Entry to the ACL and return it.\n" + "\n" + "This is a convenience function to create a new Entry \n" + "and append it to the ACL.\n" + "If a parameter of type Entry instance is given, the \n" + "entry will be a copy of that one (as if copied with \n" + "Entry.copy()), otherwise, the new entry will be empty.\n" + ; /* Convenience method to create a new Entry */ static PyObject* ACL_append(PyObject *obj, PyObject *args) { @@ -402,14 +556,15 @@ static PyObject* ACL_append(PyObject *obj, PyObject *args) { newentry->parent_acl = obj; Py_INCREF(obj); - + return (PyObject*)newentry; } /***** Entry type *****/ /* Creation of a new Entry instance */ -static PyObject* Entry_new(PyTypeObject* type, PyObject* args, PyObject *keywds) { +static PyObject* Entry_new(PyTypeObject* type, PyObject* args, + PyObject *keywds) { PyObject* newentry; newentry = PyType_GenericNew(type, args, keywds); @@ -481,7 +636,7 @@ static PyObject* Entry_str(PyObject *obj) { } else { qualifier = 0; } - + format = PyString_FromString("ACL entry for %s"); if(format == NULL) return NULL; @@ -495,9 +650,11 @@ static PyObject* Entry_str(PyObject *obj) { } else if(tag == ACL_OTHER) { PyTuple_SetItem(list, 0, PyString_FromString("the others")); } else if(tag == ACL_USER) { - PyTuple_SetItem(list, 0, PyString_FromFormat("user with uid %d", qualifier)); + PyTuple_SetItem(list, 0, PyString_FromFormat("user with uid %d", + qualifier)); } else if(tag == ACL_GROUP) { - PyTuple_SetItem(list, 0, PyString_FromFormat("group with gid %d", qualifier)); + PyTuple_SetItem(list, 0, PyString_FromFormat("group with gid %d", + qualifier)); } else if(tag == ACL_MASK) { PyTuple_SetItem(list, 0, PyString_FromString("the mask")); } else { @@ -592,22 +749,22 @@ static PyObject* Entry_get_qualifier(PyObject *obj, void* arg) { } value = *(uid_t*)p; acl_free(p); - + return PyInt_FromLong(value); } /* Returns the parent ACL of the entry */ static PyObject* Entry_get_parent(PyObject *obj, void* arg) { Entry_Object *self = (Entry_Object*) obj; - + Py_INCREF(self->parent_acl); return self->parent_acl; } -/* Returns the a new Permset representing the permset of the entry +/* Returns the a new Permset representing the permset of the entry * FIXME: Should return a new reference to the same object, which * should be created at init time! -*/ + */ static PyObject* Entry_get_permset(PyObject *obj, void* arg) { Entry_Object *self = (Entry_Object*)obj; PyObject *p; @@ -644,20 +801,20 @@ static int Entry_set_permset(PyObject* obj, PyObject* value, void* arg) { return 0; } -static char __Entry_copy_doc__[] = \ -"Copy an ACL entry.\n" \ -"\n" \ -"This method sets all the parameters to those of another\n" \ -"entry, even one of another's ACL\n" \ -"Parameters:\n" \ -" - src, instance of type Entry\n" \ -; +static char __Entry_copy_doc__[] = + "Copy an ACL entry.\n" + "\n" + "This method sets all the parameters to those of another\n" + "entry, even one of another's ACL\n" + "Parameters:\n" + " - src, instance of type Entry\n" + ; /* Sets all the entry parameters to another's entry */ static PyObject* Entry_copy(PyObject *obj, PyObject *args) { Entry_Object *self = (Entry_Object*)obj; Entry_Object *other; - + if(!PyArg_ParseTuple(args, "O!", &Entry_Type, &other)) return NULL; @@ -671,7 +828,8 @@ static PyObject* Entry_copy(PyObject *obj, PyObject *args) { /**** Permset type *****/ /* Creation of a new Permset instance */ -static PyObject* Permset_new(PyTypeObject* type, PyObject* args, PyObject *keywds) { +static PyObject* Permset_new(PyTypeObject* type, PyObject* args, + PyObject *keywds) { PyObject* newpermset; newpermset = PyType_GenericNew(type, args, keywds); @@ -731,9 +889,9 @@ static PyObject* Permset_str(PyObject *obj) { return PyString_FromStringAndSize(pstr, 3); } -static char __Permset_clear_doc__[] = \ -"Clear all permissions from the permission set.\n" \ -; +static char __Permset_clear_doc__[] = + "Clear all permissions from the permission set.\n" + ; /* Clears all permissions from the permset */ static PyObject* Permset_clear(PyObject* obj, PyObject* args) { @@ -765,9 +923,10 @@ static int Permset_set_right(PyObject* obj, PyObject* value, void* arg) { int nerr; if(!PyInt_Check(value)) { - PyErr_SetString(PyExc_ValueError, "a maximum of one argument must be passed"); + PyErr_SetString(PyExc_ValueError, "a maximum of one argument must" + " be passed"); return -1; - } + } on = PyInt_AsLong(value); if(on) nerr = acl_add_perm(self->permset, *(acl_perm_t*)arg); @@ -780,19 +939,19 @@ static int Permset_set_right(PyObject* obj, PyObject* value, void* arg) { return 0; } -static char __Permset_add_doc__[] = \ -"Add a permission to the permission set.\n" \ -"\n" \ -"The add() function adds the permission contained in \n" \ -"the argument perm to the permission set. An attempt \n" \ -"to add a permission that is already contained in the \n" \ -"permission set is not considered an error.\n" \ -"Parameters:\n" \ -" - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \ -"Return value:\n" \ -" None\n" \ -"Can raise: IOError\n" \ -; +static char __Permset_add_doc__[] = + "Add a permission to the permission set.\n" + "\n" + "The add() function adds the permission contained in \n" + "the argument perm to the permission set. An attempt \n" + "to add a permission that is already contained in the \n" + "permission set is not considered an error.\n" + "Parameters:\n" + " - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" + "Return value:\n" + " None\n" + "Can raise: IOError\n" + ; static PyObject* Permset_add(PyObject* obj, PyObject* args) { Permset_Object *self = (Permset_Object*) obj; @@ -809,19 +968,19 @@ static PyObject* Permset_add(PyObject* obj, PyObject* args) { return Py_None; } -static char __Permset_delete_doc__[] = \ -"Delete a permission from the permission set.\n" \ -"\n" \ -"The delete() function deletes the permission contained in \n" \ -"the argument perm from the permission set. An attempt \n" \ -"to delete a permission that is not contained in the \n" \ -"permission set is not considered an error.\n" \ -"Parameters:\n" \ -" - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \ -"Return value:\n" \ -" None\n" \ -"Can raise: IOError\n" \ -; +static char __Permset_delete_doc__[] = + "Delete a permission from the permission set.\n" + "\n" + "The delete() function deletes the permission contained in \n" + "the argument perm from the permission set. An attempt \n" + "to delete a permission that is not contained in the \n" + "permission set is not considered an error.\n" + "Parameters:\n" + " - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" + "Return value:\n" + " None\n" + "Can raise: IOError\n" + ; static PyObject* Permset_delete(PyObject* obj, PyObject* args) { Permset_Object *self = (Permset_Object*) obj; @@ -838,17 +997,17 @@ static PyObject* Permset_delete(PyObject* obj, PyObject* args) { return Py_None; } -static char __Permset_test_doc__[] = \ -"Test if a permission exists in the permission set.\n" \ -"\n" \ -"The test() function tests if the permission contained in \n" \ -"the argument perm exits the permission set.\n" \ -"Parameters:\n" \ -" - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" \ -"Return value:\n" \ -" Bool\n" \ -"Can raise: IOError\n" \ -; +static char __Permset_test_doc__[] = + "Test if a permission exists in the permission set.\n" + "\n" + "The test() function tests if the permission contained in \n" + "the argument perm exits the permission set.\n" + "Parameters:\n" + " - perm a permission (ACL_WRITE, ACL_READ, ACL_EXECUTE, ...\n" + "Return value:\n" + " Bool\n" + "Can raise: IOError\n" + ; static PyObject* Permset_test(PyObject* obj, PyObject* args) { Permset_Object *self = (Permset_Object*) obj; @@ -873,33 +1032,43 @@ static PyObject* Permset_test(PyObject* obj, PyObject* args) { #endif -static char __ACL_Type_doc__[] = \ -"Type which represents a POSIX ACL\n" \ -"\n" \ -"Parameters:\n" \ -" Only one keword parameter should be provided:\n" -" - file=\"...\", meaning create ACL representing\n" -" the access ACL of that file\n" \ -" - filedef=\"...\", meaning create ACL representing\n" -" the default ACL of that directory\n" \ -" - fd=, meaning create ACL representing\n" \ -" the access ACL of that file descriptor\n" \ -" - text=\"...\", meaning create ACL from a \n" \ -" textual description\n" \ -" - acl=, meaning create a copy\n" \ -" of an existing ACL instance\n" \ -"If no parameters are passed, create an empty ACL; this\n" \ -"makes sense only when your OS supports ACL modification\n" \ -" (i.e. it implements full POSIX.1e support)\n" \ -; +static char __ACL_Type_doc__[] = + "Type which represents a POSIX ACL\n" + "\n" + "Parameters:\n" + " Only one keword parameter should be provided:\n" + " - file=\"...\", meaning create ACL representing\n" + " the access ACL of that file\n" + " - filedef=\"...\", meaning create ACL representing\n" + " the default ACL of that directory\n" + " - fd=, meaning create ACL representing\n" + " the access ACL of that file descriptor\n" + " - text=\"...\", meaning create ACL from a \n" + " textual description\n" + " - acl=, meaning create a copy\n" + " of an existing ACL instance\n" + " - mode=, meaning create an ACL from a numeric mode\n" + " (e.g. mode=0644) (this is valid only when the C library\n" + " provides the acl_from_mode call)\n" + "If no parameters are passed, create an empty ACL; this\n" + "makes sense only when your OS supports ACL modification\n" + " (i.e. it implements full POSIX.1e support)\n" + ; /* ACL type methods */ static PyMethodDef ACL_methods[] = { {"applyto", ACL_applyto, METH_VARARGS, __applyto_doc__}, {"valid", ACL_valid, METH_NOARGS, __valid_doc__}, +#ifdef HAVE_LINUX + {"to_any_text", (PyCFunction)ACL_to_any_text, METH_VARARGS | METH_KEYWORDS, + __to_any_text_doc__}, + {"check", ACL_check, METH_NOARGS, __check_doc__}, +#endif #ifdef HAVE_LEVEL2 - {"__getstate__", ACL_get_state, METH_NOARGS, "Dumps the ACL to an external format."}, - {"__setstate__", ACL_set_state, METH_VARARGS, "Loads the ACL from an external format."}, + {"__getstate__", ACL_get_state, METH_NOARGS, + "Dumps the ACL to an external format."}, + {"__setstate__", ACL_set_state, METH_VARARGS, + "Loads the ACL from an external format."}, {"delete_entry", ACL_delete_entry, METH_VARARGS, __ACL_delete_entry_doc__}, {"calc_mask", ACL_calc_mask, METH_NOARGS, __ACL_calc_mask_doc__}, {"append", ACL_append, METH_VARARGS, __ACL_append_doc__}, @@ -919,7 +1088,7 @@ static PyTypeObject ACL_Type = { 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + ACL_nocmp, /* tp_compare */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ @@ -934,7 +1103,11 @@ static PyTypeObject ACL_Type = { __ACL_Type_doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ +#ifdef HAVE_LINUX + ACL_richcompare, /* tp_richcompare */ +#else 0, /* tp_richcompare */ +#endif 0, /* tp_weaklistoffset */ #ifdef HAVE_LEVEL2 ACL_iter, @@ -964,58 +1137,60 @@ static PyMethodDef Entry_methods[] = { {NULL, NULL, 0, NULL} }; -static char __Entry_tagtype_doc__[] = \ -"The tag type of the current entry\n" \ -"\n" \ -"This is one of:\n" \ -" - ACL_UNDEFINED_TAG\n" \ -" - ACL_USER_OBJ\n" \ -" - ACL_USER\n" \ -" - ACL_GROUP_OBJ\n" \ -" - ACL_GROUP\n" \ -" - ACL_MASK\n" \ -" - ACL_OTHER\n" \ -; - -static char __Entry_qualifier_doc__[] = \ -"The qualifier of the current entry\n" \ -"\n" \ -"If the tag type is ACL_USER, this should be a user id.\n" \ -"If the tag type if ACL_GROUP, this should be a group id.\n" \ -"Else, it doesn't matter.\n" \ -; - -static char __Entry_parent_doc__[] = \ -"The parent ACL of this entry\n" \ -; - -static char __Entry_permset_doc__[] = \ -"The permission set of this ACL entry\n" \ -; +static char __Entry_tagtype_doc__[] = + "The tag type of the current entry\n" + "\n" + "This is one of:\n" + " - ACL_UNDEFINED_TAG\n" + " - ACL_USER_OBJ\n" + " - ACL_USER\n" + " - ACL_GROUP_OBJ\n" + " - ACL_GROUP\n" + " - ACL_MASK\n" + " - ACL_OTHER\n" + ; + +static char __Entry_qualifier_doc__[] = + "The qualifier of the current entry\n" + "\n" + "If the tag type is ACL_USER, this should be a user id.\n" + "If the tag type if ACL_GROUP, this should be a group id.\n" + "Else, it doesn't matter.\n" + ; + +static char __Entry_parent_doc__[] = + "The parent ACL of this entry\n" + ; + +static char __Entry_permset_doc__[] = + "The permission set of this ACL entry\n" + ; /* Entry getset */ static PyGetSetDef Entry_getsets[] = { - {"tag_type", Entry_get_tag_type, Entry_set_tag_type, __Entry_tagtype_doc__}, - {"qualifier", Entry_get_qualifier, Entry_set_qualifier, __Entry_qualifier_doc__}, + {"tag_type", Entry_get_tag_type, Entry_set_tag_type, + __Entry_tagtype_doc__}, + {"qualifier", Entry_get_qualifier, Entry_set_qualifier, + __Entry_qualifier_doc__}, {"parent", Entry_get_parent, NULL, __Entry_parent_doc__}, {"permset", Entry_get_permset, Entry_set_permset, __Entry_permset_doc__}, {NULL} }; -static char __Entry_Type_doc__[] = \ -"Type which represents an entry in an ACL.\n" \ -"\n" \ -"The type exists only if the OS has full support for POSIX.1e\n" \ -"Can be created either by:\n" \ -" e = posix1e.Entry(myACL) # this creates a new entry in the ACL\n" \ -"or by:\n" \ -" for entry in myACL:\n" \ -" print entry\n" \ -"\n" \ -"Note that the Entry keeps a reference to its ACL, so even if \n" \ -"you delete the ACL, it won't be cleaned up and will continue to \n" \ -"exist until its Entry(ies) will be deleted.\n" \ -; +static char __Entry_Type_doc__[] = + "Type which represents an entry in an ACL.\n" + "\n" + "The type exists only if the OS has full support for POSIX.1e\n" + "Can be created either by:\n" + " e = posix1e.Entry(myACL) # this creates a new entry in the ACL\n" + "or by:\n" + " for entry in myACL:\n" + " print entry\n" + "\n" + "Note that the Entry keeps a reference to its ACL, so even if \n" + "you delete the ACL, it won't be cleaned up and will continue to \n" + "exist until its Entry(ies) will be deleted.\n" + ; /* The definition of the Entry Type */ static PyTypeObject Entry_Type = { PyObject_HEAD_INIT(NULL) @@ -1068,57 +1243,57 @@ static PyMethodDef Permset_methods[] = { {NULL, NULL, 0, NULL} }; -static char __Permset_execute_doc__[] = \ -"Execute permsission\n" \ -"\n" \ -"This is a convenience method of access; the \n" \ -"same effect can be achieved using the functions\n" \ -"add(), test(), delete(), and those can take any \n" \ -"permission defined by your platform.\n" \ -; - -static char __Permset_read_doc__[] = \ -"Read permsission\n" \ -"\n" \ -"This is a convenience method of access; the \n" \ -"same effect can be achieved using the functions\n" \ -"add(), test(), delete(), and those can take any \n" \ -"permission defined by your platform.\n" \ -; - -static char __Permset_write_doc__[] = \ -"Write permsission\n" \ -"\n" \ -"This is a convenience method of access; the \n" \ -"same effect can be achieved using the functions\n" \ -"add(), test(), delete(), and those can take any \n" \ -"permission defined by your platform.\n" \ -; +static char __Permset_execute_doc__[] = + "Execute permsission\n" + "\n" + "This is a convenience method of access; the \n" + "same effect can be achieved using the functions\n" + "add(), test(), delete(), and those can take any \n" + "permission defined by your platform.\n" + ; + +static char __Permset_read_doc__[] = + "Read permsission\n" + "\n" + "This is a convenience method of access; the \n" + "same effect can be achieved using the functions\n" + "add(), test(), delete(), and those can take any \n" + "permission defined by your platform.\n" + ; + +static char __Permset_write_doc__[] = + "Write permsission\n" + "\n" + "This is a convenience method of access; the \n" + "same effect can be achieved using the functions\n" + "add(), test(), delete(), and those can take any \n" + "permission defined by your platform.\n" + ; /* Permset getset */ static PyGetSetDef Permset_getsets[] = { - {"execute", Permset_get_right, Permset_set_right, \ + {"execute", Permset_get_right, Permset_set_right, __Permset_execute_doc__, &holder_ACL_EXECUTE}, - {"read", Permset_get_right, Permset_set_right, \ + {"read", Permset_get_right, Permset_set_right, __Permset_read_doc__, &holder_ACL_READ}, - {"write", Permset_get_right, Permset_set_right, \ + {"write", Permset_get_right, Permset_set_right, __Permset_write_doc__, &holder_ACL_WRITE}, {NULL} }; -static char __Permset_Type_doc__[] = \ -"Type which represents the permission set in an ACL entry\n" \ -"\n" \ -"The type exists only if the OS has full support for POSIX.1e\n" \ -"Can be created either by:\n" \ -" perms = myEntry.permset\n" \ -"or by:\n" \ -" perms = posix1e.Permset(myEntry)\n" \ -"\n" \ -"Note that the Permset keeps a reference to its Entry, so even if \n" \ -"you delete the entry, it won't be cleaned up and will continue to \n" \ -"exist until its Permset will be deleted.\n" \ -; +static char __Permset_Type_doc__[] = + "Type which represents the permission set in an ACL entry\n" + "\n" + "The type exists only if the OS has full support for POSIX.1e\n" + "Can be created either by:\n" + " perms = myEntry.permset\n" + "or by:\n" + " perms = posix1e.Permset(myEntry)\n" + "\n" + "Note that the Permset keeps a reference to its Entry, so even if \n" + "you delete the entry, it won't be cleaned up and will continue to \n" + "exist until its Permset will be deleted.\n" + ; /* The definition of the Permset Type */ static PyTypeObject Permset_Type = { @@ -1167,16 +1342,16 @@ static PyTypeObject Permset_Type = { /* Module methods */ -static char __deletedef_doc__[] = \ -"Delete the default ACL from a directory.\n" \ -"\n" \ -"This function deletes the default ACL associated with \n" \ -"a directory (the ACL which will be ANDed with the mode\n" \ -"parameter to the open, creat functions).\n" \ -"Parameters:\n" \ -" - a string representing the directory whose default ACL\n" \ -" should be deleted\n" \ -; +static char __deletedef_doc__[] = + "Delete the default ACL from a directory.\n" + "\n" + "This function deletes the default ACL associated with \n" + "a directory (the ACL which will be ANDed with the mode\n" + "parameter to the open, creat functions).\n" + "Parameters:\n" + " - a string representing the directory whose default ACL\n" + " should be deleted\n" + ; /* Deletes the default ACL from a directory */ static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) { @@ -1197,48 +1372,49 @@ static PyObject* aclmodule_delete_default(PyObject* obj, PyObject* args) { /* The module methods */ static PyMethodDef aclmodule_methods[] = { - {"delete_default", aclmodule_delete_default, METH_VARARGS, __deletedef_doc__}, + {"delete_default", aclmodule_delete_default, METH_VARARGS, + __deletedef_doc__}, {NULL, NULL, 0, NULL} }; -static char __posix1e_doc__[] = \ -"POSIX.1e ACLs manipulation\n" \ -"\n" \ -"This module provides support for manipulating POSIX.1e ACLS\n" \ -"\n" \ -"Depending on the operating system support for POSIX.1e, \n" \ -"the ACL type will have more or less capabilities:\n" \ -" - level 1, only basic support, you can create\n" \ -" ACLs from files and text descriptions;\n" \ -" once created, the type is immutable\n" \ -" - level 2, complete support, you can alter\n"\ -" the ACL once it is created\n" \ -"\n" \ -"Also, in level 2, more types are available, corresponding\n" \ -"to acl_entry_t (Entry type), acl_permset_t (Permset type).\n" \ -"\n" \ -"Example:\n" \ -">>> import posix1e\n" \ -">>> acl1 = posix1e.ACL(file=\"file.txt\") \n" \ -">>> print acl1\n" \ -"user::rw-\n" \ -"group::rw-\n" \ -"other::r--\n" \ -"\n" \ -">>> b = posix1e.ACL(text=\"u::rx,g::-,o::-\")\n" \ -">>> print b\n" \ -"user::r-x\n" \ -"group::---\n" \ -"other::---\n" \ -"\n" \ -">>> b.applyto(\"file.txt\")\n" \ -">>> print posix1e.ACL(file=\"file.txt\")\n" \ -"user::r-x\n" \ -"group::---\n" \ -"other::---\n" \ -"\n" \ -">>>\n" \ -; +static char __posix1e_doc__[] = + "POSIX.1e ACLs manipulation\n" + "\n" + "This module provides support for manipulating POSIX.1e ACLS\n" + "\n" + "Depending on the operating system support for POSIX.1e, \n" + "the ACL type will have more or less capabilities:\n" + " - level 1, only basic support, you can create\n" + " ACLs from files and text descriptions;\n" + " once created, the type is immutable\n" + " - level 2, complete support, you can alter\n" + " the ACL once it is created\n" + "\n" + "Also, in level 2, more types are available, corresponding\n" + "to acl_entry_t (Entry type), acl_permset_t (Permset type).\n" + "\n" + "Example:\n" + ">>> import posix1e\n" + ">>> acl1 = posix1e.ACL(file=\"file.txt\") \n" + ">>> print acl1\n" + "user::rw-\n" + "group::rw-\n" + "other::r--\n" + "\n" + ">>> b = posix1e.ACL(text=\"u::rx,g::-,o::-\")\n" + ">>> print b\n" + "user::r-x\n" + "group::---\n" + "other::---\n" + "\n" + ">>> b.applyto(\"file.txt\")\n" + ">>> print posix1e.ACL(file=\"file.txt\")\n" + "user::r-x\n" + "group::---\n" + "other::---\n" + "\n" + ">>>\n" + ; void initposix1e(void) { PyObject *m, *d; @@ -1299,4 +1475,20 @@ void initposix1e(void) { PyModule_AddIntConstant(m, "ACL_OTHER", ACL_OTHER); #endif + +#ifdef HAVE_LINUX + /* Linux libacl specific acl_to_any_text constants */ + PyModule_AddIntConstant(m, "TEXT_ABBREVIATE", TEXT_ABBREVIATE); + PyModule_AddIntConstant(m, "TEXT_NUMERIC_IDS", TEXT_NUMERIC_IDS); + PyModule_AddIntConstant(m, "TEXT_SOME_EFFECTIVE", TEXT_SOME_EFFECTIVE); + PyModule_AddIntConstant(m, "TEXT_ALL_EFFECTIVE", TEXT_ALL_EFFECTIVE); + PyModule_AddIntConstant(m, "TEXT_SMART_INDENT", TEXT_SMART_INDENT); + + /* Linux libacl specific acl_check constants */ + PyModule_AddIntConstant(m, "ACL_MULTI_ERROR", ACL_MULTI_ERROR); + PyModule_AddIntConstant(m, "ACL_DUPLICATE_ERROR", ACL_DUPLICATE_ERROR); + PyModule_AddIntConstant(m, "ACL_MISS_ERROR", ACL_MISS_ERROR); + PyModule_AddIntConstant(m, "ACL_ENTRY_ERROR", ACL_ENTRY_ERROR); +#endif + } diff --git a/posix1e.html b/posix1e.html index 9b488ff..3698a0f 100644 --- a/posix1e.html +++ b/posix1e.html @@ -1,16 +1,14 @@ Python: module posix1e - +
 
 
posix1e
index
/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so
+>index
/home/iusty/work/pylibacl/build/lib.linux-x86_64-2.4/posix1e.so

POSIX.1e ACLs manipulation
 
This module provides support for manipulating POSIX.1e ACLS
@@ -47,13 +45,13 @@ group::---
other::---
 
>>>

- +

- +
 
Classes
            
       
__builtin__.object
@@ -64,13 +62,13 @@ other::---
- +

- + - +
 
class ACL(__builtin__.object)
     
    Type which represents a POSIX ACL
 
Parameters:
@@ -85,17 +83,34 @@ Parameters:
    textual description
  - acl=<ACL instance>, meaning create a copy
    of an existing ACL instance
+  - mode=<int>, meaning create an ACL from a numeric mode
+    (e.g. mode=0644) (this is valid only when the C library
+    provides the acl_from_mode call)
If no parameters are passed, create an empty ACL; this
makes sense only when your OS supports ACL modification
 (i.e. it implements full POSIX.1e support)
 
  
  Methods defined here:
+
__cmp__(...)
x.__cmp__(y) <==> cmp(x,y)
+ +
__eq__(...)
x.__eq__(y) <==> x==y
+ +
__ge__(...)
x.__ge__(y) <==> x>=y
+
__getstate__(...)
Dumps the ACL to an external format.
+
__gt__(...)
x.__gt__(y) <==> x>y
+
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
__iter__(...)
x.__iter__() <==> iter(x)
+
__le__(...)
x.__le__(y) <==> x<=y
+ +
__lt__(...)
x.__lt__(y) <==> x<y
+ +
__ne__(...)
x.__ne__(y) <==> x!=y
+
__setstate__(...)
Loads the ACL from an external format.
__str__(...)
x.__str__() <==> str(x)
@@ -129,6 +144,25 @@ permissions are overwritten; if it does not c The order of existing entries in the ACL is undefined after this 
function. +
check(...)
Check the ACL validity.

+This is a non-portable, Linux specific extension that allow more
+information to be retrieved in case an ACL is not valid than the
+validate() method.

+This method will return either False (the ACL is valid), or a tuple
+with two elements. The first element is one of the following
+constants:
+  - ACL_MULTI_ERROR: The ACL contains multiple entries that have a
+                     tag type that may occur at most once
+  - ACL_DUPLICATE_ERROR: The ACL contains multiple ACL_USER or 
+                         ACL_GROUP entries  with the same ID
+  - ACL_MISS_ERROR: A required entry is missing
+  - ACL_ENTRY_ERROR: The ACL contains an invalid entry tag type

+The second element of the tuple is the index of the entry that is
+invalid (in the same order as by iterating over the ACL entry)
+
delete_entry(...)
Deletes an entry from the ACL.
 
Note: Only with level 2
@@ -139,61 +173,64 @@ Parameters:
next(...)
x.next() -> the next value, or raise StopIteration
+
to_any_text(...)
Convert the ACL to a custom text format.

+This method encapsulates the acl_to_any_text function. It allows a 
+customized text format to be generated for the ACL. See
+acl_to_any_text(3) for more details.

+Parameters:
+  - prefix: if given, this string will be prepended to all lines
+  - separator: a single character (defaults to '\n'); this will be
+               user to separate the entries in the ACL
+  - options: a bitwise combination of:
+      TEXT_ABBREVIATE: use 'u' instead of 'user', 'g' instead of 
+                       'group', etc.
+      TEXT_NUMERIC_IDS: User and group IDs are included as decimal
+                        numbers instead of names
+      TEXT_SOME_EFFECTIVE: Include comments denoting the effective
+                           permissions when some are masked
+      TEXT_ALL_EFFECTIVE: Include comments after all ACL entries
+                          affected by an ACL_MASK entry
+      TEXT_SMART_INDENT: Used in combination with the _EFFECTIVE
+                         options, this will ensure that comments 
+                         are alligned to the fourth tab position
+                         (assuming one tab equal eight spaces
+
valid(...)
Test the ACL for validity.
 
This method tests the ACL to see if it is a valid ACL
-in terms of the filesystem. More precisely, it checks:
-A valid ACL contains exactly one entry with each of the ACL_USER_OBJ,
-ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and
-ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that
-contains entries of ACL_USER or ACL_GROUP tag types must contain exactly
-one entry of the ACL_MASK tag type. If an ACL contains no entries of
+in terms of the filesystem. More precisely, it checks that:

+The ACL contains exactly one entry with each of the
+ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries
+with ACL_USER and ACL_GROUP tag types may appear zero or more
+times in an ACL. An ACL that contains entries of ACL_USER or
+ACL_GROUP tag types must contain exactly one entry of the 
+ACL_MASK tag type. If an ACL contains no entries of
ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional.
 
-All user ID qualifiers must be unique among all entries of ACL_USER tag
-type, and all group IDs must be unique among all entries of ACL_GROUP tag
-type.
+All user ID qualifiers must be unique among all entries of
+the ACL_USER tag type, and all group IDs must be unique among all
+entries of ACL_GROUP tag type.
 
The method will return 1 for a valid ACL and 0 for an invalid one.
-This has been chosen because the specification for acl_valid in POSIX.1e
-documents only one possible value for errno in case of an invalid ACL
-so we can't differentiate between classes of errors. Other suggestions 
-are welcome.
+This has been chosen because the specification for acl_valid in
+the POSIX.1e standard documents only one possible value for errno
+in case of an invalid ACL, so we can't differentiate between
+classes of errors. Other suggestions are welcome.

-Data and non-method functions defined here:
-
__doc__ = 'Type which represents a POSIX ACL\n\nParameters:\n ...tion\n (i.e. it implements full POSIX.1e support)\n'
str(object) -> string

-Return a nice string representation of the object.
-If the argument is a string, the return value is the same object.
- +Data and other attributes defined here:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
-
-Methods inherited from __builtin__.object:
-
__delattr__(...)
x.__delattr__('name') <==> del x.name
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__hash__(...)
x.__hash__() <==> hash(x)
- -
__reduce__(...)
helper for pickle
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
- -
-Data and non-method functions inherited from __builtin__.object:
-
__class__ = <type 'type'>
the object's class
- -
+

- + - +
 
class Entry(__builtin__.object)
     
    Type which represents an entry in an ACL.
 
The type exists only if the OS has full support for POSIX.1e
@@ -206,7 +243,7 @@ or by:
Note that the Entry keeps a reference to its ACL, so even if 
you delete the ACL, it won't be cleaned up and will continue to 
exist until its Entry(ies) will be deleted.
 
  
  Methods defined here:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
@@ -220,12 +257,7 @@ Parameters:
 - src, instance of type Entry
-Data and non-method functions defined here:
-
__doc__ = 'Type which represents an entry in an ACL.\n\nThe t... to \nexist until its Entry(ies) will be deleted.\n'
str(object) -> string

-Return a nice string representation of the object.
-If the argument is a string, the return value is the same object.
- +Data and other attributes defined here:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
parent = <attribute 'parent' of 'posix1e.Entry' objects>
The parent ACL of this entry
@@ -249,31 +281,13 @@ This is one of:
 - ACL_MASK
 - ACL_OTHER -
-Methods inherited from __builtin__.object:
-
__delattr__(...)
x.__delattr__('name') <==> del x.name
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__hash__(...)
x.__hash__() <==> hash(x)
- -
__reduce__(...)
helper for pickle
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
- -
-Data and non-method functions inherited from __builtin__.object:
-
__class__ = <type 'type'>
the object's class
- -
+

- + - +
 
class Permset(__builtin__.object)
     
    Type which represents the permission set in an ACL entry
 
The type exists only if the OS has full support for POSIX.1e
@@ -285,7 +299,7 @@ or by:
Note that the Permset keeps a reference to its Entry, so even if 
you delete the entry, it won't be cleaned up and will continue to 
exist until its Permset will be deleted.
 
  
  Methods defined here:
__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
@@ -328,12 +342,7 @@ Return value:
Can raise: IOError
-Data and non-method functions defined here:
-
__doc__ = 'Type which represents the permission set in an A...nue to \nexist until its Permset will be deleted.\n'
str(object) -> string

-Return a nice string representation of the object.
-If the argument is a string, the return value is the same object.
- +Data and other attributes defined here:
__new__ = <built-in method __new__ of type object>
T.__new__(S, ...) -> a new object with type S, a subtype of T
execute = <attribute 'execute' of 'posix1e.Permset' objects>
Execute permsission
@@ -357,31 +366,13 @@ same effect can be achieved using the functio add(), test(), delete(), and those can take any 
permission defined by your platform.
-
-Methods inherited from __builtin__.object:
-
__delattr__(...)
x.__delattr__('name') <==> del x.name
- -
__getattribute__(...)
x.__getattribute__('name') <==> x.name
- -
__hash__(...)
x.__hash__() <==> hash(x)
- -
__reduce__(...)
helper for pickle
- -
__repr__(...)
x.__repr__() <==> repr(x)
- -
__setattr__(...)
x.__setattr__('name', value) <==> x.name = value
- -
-Data and non-method functions inherited from __builtin__.object:
-
__class__ = <type 'type'>
the object's class
- -
+

- +
 
Functions
            
       
delete_default(...)
Delete the default ACL from a directory.
 
This function deletes the default ACL associated with 
@@ -390,17 +381,21 @@ parameter to the open, creat functions).
Parameters:
  - a string representing the directory whose default ACL
    should be deleted
-
+

- - +
 
Data
            ACL_EXECUTE = 1
+
       ACL_DUPLICATE_ERROR = 8192
+ACL_ENTRY_ERROR = 16384
+ACL_EXECUTE = 1
ACL_GROUP = 8
ACL_GROUP_OBJ = 4
ACL_MASK = 16
+ACL_MISS_ERROR = 12288
+ACL_MULTI_ERROR = 4096
ACL_OTHER = 32
ACL_READ = 4
ACL_TYPE_ACCESS = 32768
@@ -409,6 +404,9 @@ Parameters:
ACL_USER = 2
ACL_USER_OBJ = 1
ACL_WRITE = 2
-__file__ = '/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so'
-__name__ = 'posix1e'
+TEXT_ABBREVIATE = 16
+TEXT_ALL_EFFECTIVE = 2
+TEXT_NUMERIC_IDS = 8
+TEXT_SMART_INDENT = 4
+TEXT_SOME_EFFECTIVE = 1 \ No newline at end of file diff --git a/posix1e.txt b/posix1e.txt index 7657830..ef00239 100644 --- a/posix1e.txt +++ b/posix1e.txt @@ -1,10 +1,10 @@ -Python Library Documentation: module posix1e +Help on module posix1e: NAME posix1e - POSIX.1e ACLs manipulation FILE - /home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e.so + /home/iusty/work/pylibacl/build/lib.linux-x86_64-2.4/posix1e.so DESCRIPTION This module provides support for manipulating POSIX.1e ACLS @@ -63,21 +63,45 @@ CLASSES | textual description | - acl=, meaning create a copy | of an existing ACL instance + | - mode=, meaning create an ACL from a numeric mode + | (e.g. mode=0644) (this is valid only when the C library + | provides the acl_from_mode call) | If no parameters are passed, create an empty ACL; this | makes sense only when your OS supports ACL modification | (i.e. it implements full POSIX.1e support) | | Methods defined here: | + | __cmp__(...) + | x.__cmp__(y) <==> cmp(x,y) + | + | __eq__(...) + | x.__eq__(y) <==> x==y + | + | __ge__(...) + | x.__ge__(y) <==> x>=y + | | __getstate__(...) | Dumps the ACL to an external format. | + | __gt__(...) + | x.__gt__(y) <==> x>y + | | __init__(...) | x.__init__(...) initializes x; see x.__class__.__doc__ for signature | | __iter__(...) | x.__iter__() <==> iter(x) | + | __le__(...) + | x.__le__(y) <==> x<=y + | + | __lt__(...) + | x.__lt__(y) <==> x x!=y + | | __setstate__(...) | Loads the ACL from an external format. | @@ -116,6 +140,26 @@ CLASSES | The order of existing entries in the ACL is undefined after this | function. | + | check(...) + | Check the ACL validity. + | + | This is a non-portable, Linux specific extension that allow more + | information to be retrieved in case an ACL is not valid than the + | validate() method. + | + | This method will return either False (the ACL is valid), or a tuple + | with two elements. The first element is one of the following + | constants: + | - ACL_MULTI_ERROR: The ACL contains multiple entries that have a + | tag type that may occur at most once + | - ACL_DUPLICATE_ERROR: The ACL contains multiple ACL_USER or + | ACL_GROUP entries with the same ID + | - ACL_MISS_ERROR: A required entry is missing + | - ACL_ENTRY_ERROR: The ACL contains an invalid entry tag type + | + | The second element of the tuple is the index of the entry that is + | invalid (in the same order as by iterating over the ACL entry) + | | delete_entry(...) | Deletes an entry from the ACL. | @@ -128,66 +172,60 @@ CLASSES | next(...) | x.next() -> the next value, or raise StopIteration | + | to_any_text(...) + | Convert the ACL to a custom text format. + | + | This method encapsulates the acl_to_any_text function. It allows a + | customized text format to be generated for the ACL. See + | acl_to_any_text(3) for more details. + | + | Parameters: + | - prefix: if given, this string will be prepended to all lines + | - separator: a single character (defaults to '\n'); this will be + | user to separate the entries in the ACL + | - options: a bitwise combination of: + | TEXT_ABBREVIATE: use 'u' instead of 'user', 'g' instead of + | 'group', etc. + | TEXT_NUMERIC_IDS: User and group IDs are included as decimal + | numbers instead of names + | TEXT_SOME_EFFECTIVE: Include comments denoting the effective + | permissions when some are masked + | TEXT_ALL_EFFECTIVE: Include comments after all ACL entries + | affected by an ACL_MASK entry + | TEXT_SMART_INDENT: Used in combination with the _EFFECTIVE + | options, this will ensure that comments + | are alligned to the fourth tab position + | (assuming one tab equal eight spaces + | | valid(...) | Test the ACL for validity. | | This method tests the ACL to see if it is a valid ACL - | in terms of the filesystem. More precisely, it checks: - | A valid ACL contains exactly one entry with each of the ACL_USER_OBJ, - | ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries with ACL_USER and - | ACL_GROUP tag types may appear zero or more times in an ACL. An ACL that - | contains entries of ACL_USER or ACL_GROUP tag types must contain exactly - | one entry of the ACL_MASK tag type. If an ACL contains no entries of + | in terms of the filesystem. More precisely, it checks that: + | + | The ACL contains exactly one entry with each of the + | ACL_USER_OBJ, ACL_GROUP_OBJ, and ACL_OTHER tag types. Entries + | with ACL_USER and ACL_GROUP tag types may appear zero or more + | times in an ACL. An ACL that contains entries of ACL_USER or + | ACL_GROUP tag types must contain exactly one entry of the + | ACL_MASK tag type. If an ACL contains no entries of | ACL_USER or ACL_GROUP tag types, the ACL_MASK entry is optional. | - | All user ID qualifiers must be unique among all entries of ACL_USER tag - | type, and all group IDs must be unique among all entries of ACL_GROUP tag - | type. + | All user ID qualifiers must be unique among all entries of + | the ACL_USER tag type, and all group IDs must be unique among all + | entries of ACL_GROUP tag type. | | The method will return 1 for a valid ACL and 0 for an invalid one. - | This has been chosen because the specification for acl_valid in POSIX.1e - | documents only one possible value for errno in case of an invalid ACL, - | so we can't differentiate between classes of errors. Other suggestions - | are welcome. + | This has been chosen because the specification for acl_valid in + | the POSIX.1e standard documents only one possible value for errno + | in case of an invalid ACL, so we can't differentiate between + | classes of errors. Other suggestions are welcome. | | ---------------------------------------------------------------------- - | Data and non-method functions defined here: - | - | __doc__ = 'Type which represents a POSIX ACL\n\nParameters:\n ...tion\... - | str(object) -> string - | - | Return a nice string representation of the object. - | If the argument is a string, the return value is the same object. + | Data and other attributes defined here: | | __new__ = | T.__new__(S, ...) -> a new object with type S, a subtype of T - | - | ---------------------------------------------------------------------- - | Methods inherited from __builtin__.object: - | - | __delattr__(...) - | x.__delattr__('name') <==> del x.name - | - | __getattribute__(...) - | x.__getattribute__('name') <==> x.name - | - | __hash__(...) - | x.__hash__() <==> hash(x) - | - | __reduce__(...) - | helper for pickle - | - | __repr__(...) - | x.__repr__() <==> repr(x) - | - | __setattr__(...) - | x.__setattr__('name', value) <==> x.name = value - | - | ---------------------------------------------------------------------- - | Data and non-method functions inherited from __builtin__.object: - | - | __class__ = - | the object's class class Entry(__builtin__.object) | Type which represents an entry in an ACL. @@ -220,13 +258,7 @@ CLASSES | - src, instance of type Entry | | ---------------------------------------------------------------------- - | Data and non-method functions defined here: - | - | __doc__ = 'Type which represents an entry in an ACL.\n\nThe t... to \n... - | str(object) -> string - | - | Return a nice string representation of the object. - | If the argument is a string, the return value is the same object. + | Data and other attributes defined here: | | __new__ = | T.__new__(S, ...) -> a new object with type S, a subtype of T @@ -234,11 +266,9 @@ CLASSES | parent = | The parent ACL of this entry | - | | permset = | The permission set of this ACL entry | - | | qualifier = | The qualifier of the current entry | @@ -246,7 +276,6 @@ CLASSES | If the tag type if ACL_GROUP, this should be a group id. | Else, it doesn't matter. | - | | tag_type = | The tag type of the current entry | @@ -258,34 +287,6 @@ CLASSES | - ACL_GROUP | - ACL_MASK | - ACL_OTHER - | - | - | ---------------------------------------------------------------------- - | Methods inherited from __builtin__.object: - | - | __delattr__(...) - | x.__delattr__('name') <==> del x.name - | - | __getattribute__(...) - | x.__getattribute__('name') <==> x.name - | - | __hash__(...) - | x.__hash__() <==> hash(x) - | - | __reduce__(...) - | helper for pickle - | - | __repr__(...) - | x.__repr__() <==> repr(x) - | - | __setattr__(...) - | x.__setattr__('name', value) <==> x.name = value - | - | ---------------------------------------------------------------------- - | Data and non-method functions inherited from __builtin__.object: - | - | __class__ = - | the object's class class Permset(__builtin__.object) | Type which represents the permission set in an ACL entry @@ -349,13 +350,7 @@ CLASSES | Can raise: IOError | | ---------------------------------------------------------------------- - | Data and non-method functions defined here: - | - | __doc__ = 'Type which represents the permission set in an A...nue to \... - | str(object) -> string - | - | Return a nice string representation of the object. - | If the argument is a string, the return value is the same object. + | Data and other attributes defined here: | | __new__ = | T.__new__(S, ...) -> a new object with type S, a subtype of T @@ -368,7 +363,6 @@ CLASSES | add(), test(), delete(), and those can take any | permission defined by your platform. | - | | read = | Read permsission | @@ -377,7 +371,6 @@ CLASSES | add(), test(), delete(), and those can take any | permission defined by your platform. | - | | write = | Write permsission | @@ -385,34 +378,6 @@ CLASSES | same effect can be achieved using the functions | add(), test(), delete(), and those can take any | permission defined by your platform. - | - | - | ---------------------------------------------------------------------- - | Methods inherited from __builtin__.object: - | - | __delattr__(...) - | x.__delattr__('name') <==> del x.name - | - | __getattribute__(...) - | x.__getattribute__('name') <==> x.name - | - | __hash__(...) - | x.__hash__() <==> hash(x) - | - | __reduce__(...) - | helper for pickle - | - | __repr__(...) - | x.__repr__() <==> repr(x) - | - | __setattr__(...) - | x.__setattr__('name', value) <==> x.name = value - | - | ---------------------------------------------------------------------- - | Data and non-method functions inherited from __builtin__.object: - | - | __class__ = - | the object's class FUNCTIONS delete_default(...) @@ -426,10 +391,14 @@ FUNCTIONS should be deleted DATA + ACL_DUPLICATE_ERROR = 8192 + ACL_ENTRY_ERROR = 16384 ACL_EXECUTE = 1 ACL_GROUP = 8 ACL_GROUP_OBJ = 4 ACL_MASK = 16 + ACL_MISS_ERROR = 12288 + ACL_MULTI_ERROR = 4096 ACL_OTHER = 32 ACL_READ = 4 ACL_TYPE_ACCESS = 32768 @@ -438,6 +407,10 @@ DATA ACL_USER = 2 ACL_USER_OBJ = 1 ACL_WRITE = 2 - __file__ = '/home/iusty/work/pylibacl/build/lib.linux-i686-2.2/posix1e... - __name__ = 'posix1e' + TEXT_ABBREVIATE = 16 + TEXT_ALL_EFFECTIVE = 2 + TEXT_NUMERIC_IDS = 8 + TEXT_SMART_INDENT = 4 + TEXT_SOME_EFFECTIVE = 1 + diff --git a/setup.py b/setup.py index 95231f8..b2e0583 100755 --- a/setup.py +++ b/setup.py @@ -17,6 +17,8 @@ elif u_sysname == "GNU/kFreeBSD": libs.append("acl") elif u_sysname == "FreeBSD": macros.append(("HAVE_FREEBSD", None)) +elif u_sysname == "Darwin": + libs.append("pthread") else: raise ValueError("I don't know your system '%s'." " Please contact the author" % u_sysname) @@ -24,7 +26,9 @@ else: long_desc = """This is a C extension module for Python which implements POSIX ACLs manipulation. It is a wrapper on top of the systems's acl C library - see acl(5).""" -version = "0.2.2" + +version = "0.3.0" + setup(name="pylibacl", version=version, description="POSIX.1e ACLs for python", @@ -37,8 +41,4 @@ setup(name="pylibacl", libraries=libs, define_macros=macros, )], - data_files=[("/usr/share/doc/pylibacl-%s" % version, - ["README","IMPLEMENTATION", "PLATFORMS", - "BENCHMARK", - "posix1e.html", "posix1e.txt"])], ) -- 2.39.2