Created
October 4, 2012 08:05
-
-
Save haad/3832101 to your computer and use it in GitHub Desktop.
ldap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static int update_ldap(const char *basedn, const char *table_name, const char *attribute, | |
1177 const char *lookup, va_list ap) | |
1178{ | |
1179 int error = 0; | |
1180 LDAPMessage *ldap_entry = NULL; | |
1181 LDAPMod **ldap_mods; | |
1182 const char *newparam = NULL; | |
1183 const char *newval = NULL; | |
1184 char *dn; | |
1185 int num_entries = 0; | |
1186 int i = 0; | |
1187 int mods_size = 0; | |
1188 int mod_exists = 0; | |
1189 struct ldap_table_config *table_config = NULL; | |
1190 char *clean_basedn = NULL; | |
1191 struct ast_str *filter = NULL; | |
1192 int tries = 0; | |
1193 int result = 0; | |
1194 LDAPMessage *ldap_result_msg = NULL; | |
1195 | |
1196 if (!table_name) { | |
1197 ast_log(LOG_ERROR, "No table_name specified.\n"); | |
1198 return -1; | |
1199 } | |
1200 | |
1201 if (!(filter = ast_str_create(80))) { | |
1202 return -1; | |
1203 } | |
1204 | |
1205 if (!attribute || !lookup) { | |
1206 ast_log(LOG_WARNING, "LINE(%d): search parameters are empty.\n", __LINE__); | |
1207 return -1; | |
1208 } | |
1209 ast_mutex_lock(&ldap_lock); | |
1210 | |
1211 /* We now have our complete statement; Lets connect to the server and execute it. */ | |
1212 if (!ldap_reconnect()) { | |
1213 ast_mutex_unlock(&ldap_lock); | |
1214 return -1; | |
1215 } | |
1216 | |
1217 table_config = table_config_for_table_name(table_name); | |
1218 if (!table_config) { | |
1219 ast_log(LOG_ERROR, "No table named '%s'.\n", table_name); | |
1220 ast_mutex_unlock(&ldap_lock); | |
1221 return -1; | |
1222 } | |
1223 | |
1224 clean_basedn = cleaned_basedn(NULL, basedn); | |
1225 | |
1226 /* Create the filter with the table additional filter and the parameter/value pairs we were given */ | |
1227 ast_str_append(&filter, 0, "(&"); | |
1228 if (table_config && table_config->additional_filter) { | |
1229 ast_str_append(&filter, 0, "%s", table_config->additional_filter); | |
1230 } | |
1231 if (table_config != base_table_config && base_table_config && base_table_config->additional_filter) { | |
1232 ast_str_append(&filter, 0, "%s", base_table_config->additional_filter); | |
1233 } | |
1234 append_var_and_value_to_filter(&filter, table_config, attribute, lookup); | |
1235 ast_str_append(&filter, 0, ")"); | |
1236 | |
1237 /* Create the modification array with the parameter/value pairs we were given, | |
1238 * if there are several parameters with the same name, we collect them into | |
1239 * one parameter/value pair and delimit them with a semicolon */ | |
1240 newparam = va_arg(ap, const char *); | |
1241 newparam = convert_attribute_name_to_ldap(table_config, newparam); | |
1242 newval = va_arg(ap, const char *); | |
1243 if (!newparam || !newval) { | |
1244 ast_log(LOG_WARNING, "LINE(%d): need at least one parameter to modify.\n", __LINE__); | |
1245 return -1; | |
1246 } | |
1247 | |
1248 mods_size = 2; /* one for the first param/value pair and one for the the terminating NULL */ | |
1249 ldap_mods = ast_calloc(sizeof(LDAPMod *), mods_size); | |
1250 ldap_mods[0] = ast_calloc(1, sizeof(LDAPMod)); | |
1251 | |
1252 ldap_mods[0]->mod_op = LDAP_MOD_REPLACE; | |
1253 ldap_mods[0]->mod_type = ast_strdup(newparam); | |
1254 | |
1255 ldap_mods[0]->mod_values = ast_calloc(sizeof(char *), 2); | |
1256 ldap_mods[0]->mod_values[0] = ast_strdup(newval); | |
1257 | |
1258 while ((newparam = va_arg(ap, const char *))) { | |
1259 newparam = convert_attribute_name_to_ldap(table_config, newparam); | |
1260 newval = va_arg(ap, const char *); | |
1261 mod_exists = 0; | |
1262 | |
1263 for (i = 0; i < mods_size - 1; i++) { | |
1264 if (ldap_mods[i]&& !strcmp(ldap_mods[i]->mod_type, newparam)) { | |
1265 /* We have the parameter allready, adding the value as a semicolon delimited value */ | |
1266 ldap_mods[i]->mod_values[0] = ast_realloc(ldap_mods[i]->mod_values[0], sizeof(char) * (strlen(ldap_mods[i]->mod_values[0]) + strlen(newval) + 2)); | |
1267 strcat(ldap_mods[i]->mod_values[0], ";"); | |
1268 strcat(ldap_mods[i]->mod_values[0], newval); | |
1269 mod_exists = 1; | |
1270 break; | |
1271 } | |
1272 } | |
1273 | |
1274 /* create new mod */ | |
1275 if (!mod_exists) { | |
1276 mods_size++; | |
1277 ldap_mods = ast_realloc(ldap_mods, sizeof(LDAPMod *) * mods_size); | |
1278 ldap_mods[mods_size - 1] = NULL; | |
1279 | |
1280 ldap_mods[mods_size - 2] = ast_calloc(1, sizeof(LDAPMod)); | |
1281 | |
1282 ldap_mods[mods_size - 2]->mod_type = ast_calloc(sizeof(char), strlen(newparam) + 1); | |
1283 strcpy(ldap_mods[mods_size - 2]->mod_type, newparam); | |
1284 | |
1285 if (strlen(newval) == 0) { | |
1286 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_DELETE; | |
1287 } else { | |
1288 ldap_mods[mods_size - 2]->mod_op = LDAP_MOD_REPLACE; | |
1289 | |
1290 ldap_mods[mods_size - 2]->mod_values = ast_calloc(sizeof(char *), 2); | |
1291 ldap_mods[mods_size - 2]->mod_values[0] = ast_calloc(sizeof(char), strlen(newval) + 1); | |
1292 strcpy(ldap_mods[mods_size - 2]->mod_values[0], newval); | |
1293 } | |
1294 } | |
1295 } | |
1296 /* freeing ldap_mods further down */ | |
1297 | |
1298 do { | |
1299 /* freeing ldap_result further down */ | |
1300 result = ldap_search_ext_s(ldapConn, clean_basedn, | |
1301 LDAP_SCOPE_SUBTREE, ast_str_buffer(filter), NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, | |
1302 &ldap_result_msg); | |
1303 if (result != LDAP_SUCCESS && is_ldap_connect_error(result)) { | |
1304 ast_log(LOG_WARNING, "Failed to query directory. Try %d/3\n", tries + 1); | |
1305 tries++; | |
1306 if (tries < 3) { | |
1307 usleep(500000L * tries); | |
1308 if (ldapConn) { | |
1309 ldap_unbind_ext_s(ldapConn, NULL, NULL); | |
1310 ldapConn = NULL; | |
1311 } | |
1312 if (!ldap_reconnect()) | |
1313 break; | |
1314 } | |
1315 } | |
1316 } while (result != LDAP_SUCCESS && tries < 3 && is_ldap_connect_error(result)); | |
1317 | |
1318 if (result != LDAP_SUCCESS) { | |
1319 ast_log(LOG_WARNING, "Failed to query directory. Error: %s.\n", ldap_err2string(result)); | |
1320 ast_log(LOG_WARNING, "Query: %s\n", ast_str_buffer(filter)); | |
1321 | |
1322 ast_mutex_unlock(&ldap_lock); | |
1323 free(filter); | |
1324 free(clean_basedn); | |
1325 ldap_msgfree(ldap_result_msg); | |
1326 ldap_mods_free(ldap_mods, 0); | |
1327 return -1; | |
1328 } | |
1329 /* Ready to update */ | |
1330 if ((num_entries = ldap_count_entries(ldapConn, ldap_result_msg)) > 0) { | |
1331 ast_debug(3, "LINE(%d) Modifying %s=%s hits: %d\n", __LINE__, attribute, lookup, num_entries); | |
1332 for (i = 0; option_debug > 2 && i < mods_size - 1; i++) { | |
1333 if (ldap_mods[i]->mod_op != LDAP_MOD_DELETE) { | |
1334 ast_debug(3, "LINE(%d) %s=%s \n", __LINE__, ldap_mods[i]->mod_type, ldap_mods[i]->mod_values[0]); | |
1335 } else { | |
1336 ast_debug(3, "LINE(%d) deleting %s \n", __LINE__, ldap_mods[i]->mod_type); | |
1337 } | |
1338 } | |
1339 ldap_entry = ldap_first_entry(ldapConn, ldap_result_msg); | |
1340 | |
1341 for (i = 0; ldap_entry; i++) { | |
1342 dn = ldap_get_dn(ldapConn, ldap_entry); | |
1343 if ((error = ldap_modify_ext_s(ldapConn, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { | |
1344 ast_log(LOG_ERROR, "Couldn't modify '%s'='%s', dn:%s because %s\n", | |
1345 attribute, lookup, dn, ldap_err2string(error)); | |
1346 } | |
1347 ldap_memfree(dn); | |
1348 ldap_entry = ldap_next_entry(ldapConn, ldap_entry); | |
1349 } | |
1350 } | |
1351 | |
1352 ast_mutex_unlock(&ldap_lock); | |
1353 ast_free(filter); | |
1354 ast_free(clean_basedn); | |
1355 ldap_msgfree(ldap_result_msg); | |
1356 ldap_mods_free(ldap_mods, 0); | |
1357 return num_entries; | |
1358} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment