/* Set new unique item at `i` index in LDAPValueList to `newitem`. Case-insensitive, the `newitem` is also appended to the added list, or remove from the deleted list. Same goes for the replaced item. */ int LDAPValueList_SetItem(LDAPValueList *self, Py_ssize_t i, PyObject *newitem) { int rc = -1; PyObject *olditem; if (UniqueList_SetItem((UniqueList *)self, i, newitem) != 0) return -1; olditem = PyList_GetItem((PyObject *)self, i); if (olditem == NULL) return -1; rc = UniqueList_Remove_wFlg(self->added, olditem); if (rc == -1) return -1; if (rc == 0) { if (UniqueList_Append(self->deleted, olditem) == -1) { PyErr_BadInternalCall(); return -1; } } rc = UniqueList_Remove_wFlg(self->deleted, newitem); if (rc == -1) return -1; if (rc == 0) { if (UniqueList_Append(self->added, newitem) == -1) { PyErr_BadInternalCall(); return -1; } } return 0; }
static PyObject * UL_append(UniqueList *self, PyObject *newitem) { if (UniqueList_Append(self, newitem) == 0) { return Py_None; } return NULL; }
/* Append new unique item to the LDAPValueList. Case-insensitive, the `newitem` is also appended to the added list, or remove from the deleted list. */ int LDAPValueList_Append(LDAPValueList *self, PyObject *newitem) { int rc = -1; rc = UniqueList_Append((UniqueList *)self, newitem); if (rc == -1) return -1; rc = UniqueList_Remove_wFlg(self->deleted, newitem); if (rc == -1) return -1; if (rc == 0) { if (UniqueList_Append(self->added, newitem) == -1) { PyErr_BadInternalCall(); return -1; } } return 0; }
/* Set item to LDAPEntry with a case-insensitive key. */ int LDAPEntry_SetItem(LDAPEntry *self, PyObject *key, PyObject *value) { int found = 0; int rc = 0; int status = 1; char *newkey = lowercase(PyObject2char(key)); LDAPValueList *list; /* Search for a match. */ key = searchLowerCaseKeyMatch(self, key, &found); if (found == 1) { status = 2; } if (value != NULL) { /* If theres an item with a `dn` key, and with a string value set to the dn attribute. */ if (strcmp(newkey, "dn") == 0) { if (PyUnicode_Check(value)) { char *dnstr = PyObject2char(value); LDAPEntry_SetStringDN(self, dnstr); free(dnstr); } else { PyErr_SetString(PyExc_TypeError, "Distinguished name must be string type."); Py_DECREF(key); return -1; } } else { /* Set the new value to the item. */ if (LDAPValueList_Check(value) == 0) { /* Convert value to LDAPValueList object. */ list = LDAPValueList_New(); if (PyList_Check(value) || PyTuple_Check(value)) { LDAPValueList_Extend(list, value); } else { LDAPValueList_Append(list, value); } rc = PyDict_SetItem((PyObject *)self, key, (PyObject *)list); list->status = status; Py_DECREF(list); } else { rc = PyDict_SetItem((PyObject *)self, key, value); ((LDAPValueList *)value)->status = status; } /* Avoid inconsistency. (same key in the added and the deleted list) */ if (PySequence_Contains((PyObject *)self->deleted, key)) { if (UniqueList_Remove(self->deleted, key) != 0) return -1; } if (rc != 0) return rc; /* New key should be added to the attribute list. */ if (found == 0) { if (UniqueList_Append(self->attributes, key) != 0) { Py_DECREF(key); return -1; } } } } else { /* This means, it has to remove the item. */ if (PyDict_DelItem((PyObject *)self, key) != 0) return -1; if (UniqueList_Append(self->deleted, key) != 0) return -1; /* Remove from the attributes list. */ if (PySequence_DelItem((PyObject *)self->attributes, PySequence_Index((PyObject *)self->attributes, key)) != 0) { Py_DECREF(key); return -1; } } Py_DECREF(key); return 0; }
/* Create a LDAPEntry from a LDAPMessage. */ LDAPEntry * LDAPEntry_FromLDAPMessage(LDAPMessage *entrymsg, LDAPClient *client) { int i; char *dn; char *attr; struct berval **values; BerElement *ber; PyObject *val, *attrobj; LDAPValueList *lvl = NULL; LDAPEntry *self; /* Create a new LDAPEntry, raise PyErr_NoMemory if it's failed. */ self = LDAPEntry_New(); if (self == NULL) { return (LDAPEntry *)PyErr_NoMemory(); } LDAPEntry_SetClient(self, client); /* Set the DN for LDAPEntry. */ dn = ldap_get_dn(client->ld, entrymsg); if (dn != NULL) { if (LDAPEntry_SetStringDN(self, dn) != 0) { Py_DECREF(self); ldap_memfree(dn); return NULL; } ldap_memfree(dn); } /* Iterate over the LDAP attributes. */ for (attr = ldap_first_attribute(client->ld, entrymsg, &ber); attr != NULL; attr = ldap_next_attribute(client->ld, entrymsg, ber)) { /* Create a string of attribute's name and add to the attributes list. */ attrobj = PyUnicode_FromString(attr); if (attrobj == NULL || UniqueList_Append(self->attributes, attrobj) != 0) { Py_DECREF(self); Py_XDECREF(attrobj); ldap_memfree(attr); if (ber != NULL) { ber_free(ber, 0); } return (LDAPEntry *)PyErr_NoMemory(); } values = ldap_get_values_len(client->ld, entrymsg, attr); if (values != NULL) { lvl = LDAPValueList_New(); if (lvl == NULL){ Py_DECREF(self); Py_DECREF(attrobj); ldap_memfree(attr); if (ber != NULL) { ber_free(ber, 0); } return (LDAPEntry *)PyErr_NoMemory(); } for (i = 0; values[i] != NULL; i++) { /* Convert berval to PyObject*, if it's failed skip it. */ val = berval2PyObject(values[i]); if (val == NULL) continue; /* If the attribute has more value, then append to the list. */ if (PyList_Append((PyObject *)lvl, val) != 0) { Py_DECREF(lvl); Py_DECREF(self); Py_DECREF(attrobj); ldap_memfree(attr); if (ber != NULL) { ber_free(ber, 0); } return (LDAPEntry *)PyErr_NoMemory(); } } PyDict_SetItem((PyObject *)self, attrobj, (PyObject *)lvl); } ldap_value_free_len(values); } /* Cleaning the mess. */ ldap_memfree(attr); if (ber != NULL) { ber_free(ber, 0); } return self; }