static Slapi_Mods *windows_private_get_cookie_mod(Dirsync_Private *dp, int modtype) { Slapi_Mods *smods = NULL; smods = slapi_mods_new(); slapi_mods_add( smods, modtype, "nsds7DirsyncCookie", dp->dirsync_cookie_len , dp->dirsync_cookie); return smods; }
int ipapwd_set_extradata(const char *dn, const char *principal, time_t unixtime) { Slapi_Mods *smods; Slapi_Value *va[2] = { NULL }; struct berval bv; char *xdata; int xd_len; int p_len; int ret; p_len = strlen(principal); xd_len = 2 + 4 + p_len + 1; xdata = malloc(xd_len); if (!xdata) { return LDAP_OPERATIONS_ERROR; } smods = slapi_mods_new(); /* data type id */ xdata[0] = 0x00; xdata[1] = 0x02; /* unix timestamp in Little Endian */ xdata[2] = unixtime & 0xff; xdata[3] = (unixtime & 0xff00) >> 8; xdata[4] = (unixtime & 0xff0000) >> 16; xdata[5] = (unixtime & 0xff000000) >> 24; /* append the principal name */ strncpy(&xdata[6], principal, p_len); xdata[xd_len -1] = 0; bv.bv_val = xdata; bv.bv_len = xd_len; va[0] = slapi_value_new_berval(&bv); slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "krbExtraData", va); ret = ipapwd_apply_mods(dn, smods); slapi_value_free(&va[0]); slapi_mods_free(&smods); return ret; }
/* Modify the Password attributes of the entry */ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg, struct ipapwd_data *data, int is_krb) { int ret = 0; Slapi_Mods *smods = NULL; Slapi_Value **svals = NULL; Slapi_Value **ntvals = NULL; Slapi_Value **pwvals = NULL; char *nt = NULL; int is_smb = 0; int is_ipant = 0; int is_host = 0; Slapi_Value *sambaSamAccount; Slapi_Value *ipaNTUserAttrs; Slapi_Value *ipaHost; char *errMesg = NULL; char *modtime = NULL; LOG_TRACE("=>\n"); sambaSamAccount = slapi_value_new_string("sambaSamAccount"); if (slapi_entry_attr_has_syntax_value(data->target, "objectClass", sambaSamAccount)) { is_smb = 1; } slapi_value_free(&sambaSamAccount); ipaNTUserAttrs = slapi_value_new_string("ipaNTUserAttrs"); if (slapi_entry_attr_has_syntax_value(data->target, "objectClass", ipaNTUserAttrs)) { is_ipant = 1; } slapi_value_free(&ipaNTUserAttrs); ipaHost = slapi_value_new_string("ipaHost"); if (slapi_entry_attr_has_syntax_value(data->target, "objectClass", ipaHost)) { is_host = 1; } slapi_value_free(&ipaHost); ret = ipapwd_gen_hashes(krbcfg, data, data->password, is_krb, is_smb, is_ipant, &svals, &nt, &ntvals, &errMesg); if (ret) { goto free_and_return; } smods = slapi_mods_new(); if (svals) { slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "krbPrincipalKey", svals); /* krbLastPwdChange is used to tell whether a host entry has a * keytab so don't set it on hosts. */ if (!is_host) { /* change Last Password Change field with the current date */ ret = ipapwd_setdate(data->target, smods, "krbLastPwdChange", data->timeNow, false); if (ret != LDAP_SUCCESS) goto free_and_return; /* set Password Expiration date */ ret = ipapwd_setdate(data->target, smods, "krbPasswordExpiration", data->expireTime, (data->expireTime == 0)); if (ret != LDAP_SUCCESS) goto free_and_return; } } if (nt && is_smb) { slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "sambaNTPassword", nt); } if (ntvals && is_ipant) { slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "ipaNTHash", ntvals); } if (is_smb) { /* with samba integration we need to also set sambaPwdLastSet or * samba will decide the user has to change the password again */ if (data->changetype == IPA_CHANGETYPE_ADMIN) { /* if it is an admin change instead we need to let know to * samba as well that the use rmust change its password */ modtime = slapi_ch_smprintf("0"); } else { modtime = slapi_ch_smprintf("%ld", (long)data->timeNow); } if (!modtime) { LOG_FATAL("failed to smprintf string!\n"); ret = LDAP_OPERATIONS_ERROR; goto free_and_return; } slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "sambaPwdLastset", modtime); } if (is_krb) { if (data->changetype == IPA_CHANGETYPE_ADMIN) { slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "krbLoginFailedCount", "0"); } } /* let DS encode the password itself, this allows also other plugins to * intercept it to perform operations like synchronization with Active * Directory domains through the replication plugin */ slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "userPassword", data->password); /* set password history */ if (data->policy.history_length > 0) { pwvals = ipapwd_setPasswordHistory(smods, data); if (pwvals) { slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE, "passwordHistory", pwvals); } } /* FIXME: * instead of replace we should use a delete/add so that we are * completely sure nobody else modified the entry meanwhile and * fail if that's the case */ /* commit changes */ ret = ipapwd_apply_mods(data->dn, smods); LOG_TRACE("<= result: %d\n", ret); free_and_return: if (nt) slapi_ch_free((void **)&nt); if (modtime) slapi_ch_free((void **)&modtime); slapi_mods_free(&smods); ipapwd_free_slapi_value_array(&svals); ipapwd_free_slapi_value_array(&ntvals); ipapwd_free_slapi_value_array(&pwvals); return ret; }
/* * update multiple attribute values per _do_modify */ static int _update_all_per_mod(Slapi_DN *entrySDN, /* DN of the searched entry */ Slapi_Attr *attr, /* referred attribute */ char *attrName, Slapi_DN *origDN, /* original DN that was modified */ char *newRDN, /* new RDN from modrdn */ const char *newsuperior, /* new superior from modrdn */ Slapi_PBlock *mod_pb) { Slapi_Mods *smods = NULL; char *newDN = NULL; char **dnParts = NULL; char *sval = NULL; char *newvalue = NULL; char *p = NULL; size_t dnlen = 0; int rc = 0; int nval = 0; slapi_attr_get_numvalues(attr, &nval); if (NULL == newRDN && NULL == newsuperior) { /* in delete mode */ LDAPMod *mods[2]; char *values_del[2]; LDAPMod attribute1; /* delete old dn so set that up */ values_del[0] = (char *)slapi_sdn_get_dn(origDN); values_del[1] = NULL; attribute1.mod_type = attrName; attribute1.mod_op = LDAP_MOD_DELETE; attribute1.mod_values = values_del; mods[0] = &attribute1; /* terminate list of mods. */ mods[1] = NULL; rc = _do_modify(mod_pb, entrySDN, mods); if (rc) { slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "_update_all_per_mod: entry %s: deleting \"%s: %s\" failed (%d)" "\n", slapi_sdn_get_dn(entrySDN), attrName, slapi_sdn_get_dn(origDN), rc); } } else { /* in modrdn mode */ const char *superior = NULL; int nval = 0; Slapi_Value *v = NULL; if (NULL == origDN) { slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "_update_all_per_mod: NULL dn was passed\n"); goto bail; } /* need to put together rdn into a dn */ dnParts = slapi_ldap_explode_dn( slapi_sdn_get_dn(origDN), 0 ); if (NULL == dnParts) { slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "_update_all_per_mod: failed to explode dn %s\n", slapi_sdn_get_dn(origDN)); goto bail; } if (NULL == newRDN) { newRDN = dnParts[0]; } if (newsuperior) { superior = newsuperior; } else { /* do not free superior */ superior = slapi_dn_find_parent(slapi_sdn_get_dn(origDN)); } /* newRDN and superior are already normalized. */ newDN = slapi_ch_smprintf("%s,%s", newRDN, superior); slapi_dn_ignore_case(newDN); /* * Compare the modified dn with the value of * the target attribute of referint to find out * the modified dn is the ancestor (case 2) or * the value itself (case 1). * * E.g., * (case 1) * modrdn: uid=A,ou=B,o=C --> uid=A',ou=B',o=C * (origDN) (newDN) * member: uid=A,ou=B,ou=C --> uid=A',ou=B',ou=C * (sval) (newDN) * * (case 2) * modrdn: ou=B,o=C --> ou=B',o=C * (origDN) (newDN) * member: uid=A,ou=B,ou=C --> uid=A,ou=B',ou=C * (sval) (sval' + newDN) */ slapi_attr_get_numvalues(attr, &nval); smods = slapi_mods_new(); slapi_mods_init(smods, 2 * nval + 1); for (nval = slapi_attr_first_value(attr, &v); nval != -1; nval = slapi_attr_next_value(attr, nval, &v)) { p = NULL; dnlen = 0; /* DN syntax, which should be a string */ sval = slapi_ch_strdup(slapi_value_get_string(v)); rc = slapi_dn_normalize_case_ext(sval, 0, &p, &dnlen); if (rc == 0) { /* sval is passed in; not terminated */ *(p + dnlen) = '\0'; sval = p; } else if (rc > 0) { slapi_ch_free_string(&sval); sval = p; } /* else: (rc < 0) Ignore the DN normalization error for now. */ p = PL_strstr(sval, slapi_sdn_get_ndn(origDN)); if (p == sval) { /* (case 1) */ slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval); slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN); } else if (p) { /* (case 2) */ slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval); *p = '\0'; newvalue = slapi_ch_smprintf("%s%s", sval, newDN); slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue); slapi_ch_free_string(&newvalue); } /* else: value does not include the modified DN. Ignore it. */ slapi_ch_free_string(&sval); } rc = _do_modify(mod_pb, entrySDN, slapi_mods_get_ldapmods_byref(smods)); if (rc) { slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "_update_all_per_mod: entry %s failed (%d)\n", slapi_sdn_get_dn(entrySDN), rc); } /* cleanup memory allocated for dnParts and newDN */ if (dnParts){ slapi_ldap_value_free(dnParts); dnParts = NULL; } slapi_ch_free_string(&newDN); slapi_mods_free(&smods); } bail: return rc; }
/* * Check if we are modifying the config, or changing the shared config entry */ int memberof_shared_config_validate(Slapi_PBlock *pb) { Slapi_Entry *e = 0; Slapi_Entry *resulting_e = 0; Slapi_Entry *config_entry = NULL; Slapi_DN *sdn = NULL; Slapi_DN *config_sdn = NULL; Slapi_Mods *smods = 0; Slapi_Mod *smod = NULL, *nextmod = NULL; LDAPMod **mods = NULL; char returntext[SLAPI_DSE_RETURNTEXT_SIZE]; char *configarea_dn = NULL; int ret = SLAPI_PLUGIN_SUCCESS; slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn); if (slapi_sdn_compare(sdn, memberof_get_plugin_area()) == 0 || slapi_sdn_compare(sdn, memberof_get_config_area()) == 0) { slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e); if(e){ /* * Create a copy of the entry and apply the * mods to create the resulting entry. */ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); smods = slapi_mods_new(); slapi_mods_init_byref(smods, mods); resulting_e = slapi_entry_dup(e); if (mods && (slapi_entry_apply_mods(resulting_e, mods) != LDAP_SUCCESS)) { /* we don't care about this, the update is invalid and will be caught later */ goto bail; } if (slapi_sdn_compare(sdn, memberof_get_plugin_area())){ /* * This entry is a plugin config area entry, validate it. */ if( SLAPI_DSE_CALLBACK_ERROR == memberof_validate_config (pb, NULL, resulting_e, &ret, returntext,0)) { ret = LDAP_UNWILLING_TO_PERFORM; } } else { /* * This is the memberOf plugin entry, check if we are adding/replacing the * plugin config area. */ nextmod = slapi_mod_new(); for (smod = slapi_mods_get_first_smod(smods, nextmod); smod != NULL; smod = slapi_mods_get_next_smod(smods, nextmod) ) { if ( PL_strcasecmp(SLAPI_PLUGIN_SHARED_CONFIG_AREA, slapi_mod_get_type(smod)) == 0 ) { /* * Okay, we are modifying the plugin config area, we only care about * adds and replaces. */ if(SLAPI_IS_MOD_REPLACE(slapi_mod_get_operation(smod)) || SLAPI_IS_MOD_ADD(slapi_mod_get_operation(smod))) { struct berval *bv = NULL; int rc = 0; bv = slapi_mod_get_first_value(smod); configarea_dn = slapi_ch_strdup(bv->bv_val); if(configarea_dn){ /* Check the DN syntax */ rc = slapi_dn_syntax_check(pb, configarea_dn, 1); if (rc) { /* syntax check failed */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "%s does not contain a valid DN (%s)", SLAPI_PLUGIN_SHARED_CONFIG_AREA, configarea_dn); ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } /* Check if the plugin config area entry exists */ if((config_sdn = slapi_sdn_new_dn_byval(configarea_dn))){ rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, memberof_get_plugin_id()); if(config_entry){ int err = 0; /* * Validate the settings from the new config area. */ if ( memberof_validate_config(pb, NULL, config_entry, &err, returntext,0) == SLAPI_DSE_CALLBACK_ERROR ) { ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } } else { /* The config area does not exist */ PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE, "Unable to locate shared config entry (%s) error %d", slapi_sdn_get_dn(memberof_get_config_area()), rc); ret = LDAP_UNWILLING_TO_PERFORM; goto bail; } } } slapi_ch_free_string(&configarea_dn); slapi_sdn_free(&config_sdn); } } } } } else { PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Unable to locate shared config entry (%s)", slapi_sdn_get_dn(memberof_get_config_area())); ret = LDAP_UNWILLING_TO_PERFORM; } } bail: if (ret){ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ret); slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, returntext); slapi_log_err(SLAPI_LOG_ERR, MEMBEROF_PLUGIN_SUBSYSTEM, "memberof_shared_config_validate - %s/n", returntext); } slapi_sdn_free(&config_sdn); if(nextmod) slapi_mod_free(&nextmod); slapi_mods_free(&smods); slapi_entry_free(resulting_e); slapi_entry_free(config_entry); slapi_ch_free_string(&configarea_dn); return ret; }
int parent_update_on_childchange(modify_context *mc,int op, size_t *new_sub_count ) { int ret = 0; int mod_op = 0; Slapi_Attr *read_attr = NULL; size_t current_sub_count = 0; int already_present = 0; int repl_op = 0; Slapi_Mods *smods = NULL; char value_buffer[20]; /* enough digits for 2^64 children */ if (new_sub_count) *new_sub_count = 0; repl_op = PARENTUPDATE_TOMBSTONE_MASK & op; op &= PARENTUPDATE_MASK; /* Check nobody is trying to use op == 3, it's not implemented yet */ PR_ASSERT( (op == PARENTUPDATE_ADD) || (op == PARENTUPDATE_DEL)); /* We want to invent a mods set to be passed to modify_apply_mods() */ /* For now, we're only interested in subordinatecount. We first examine the present value for the attribute. If it isn't present and we're adding, we assign value 1 to the attribute and add it. If it is present, we increment or decrement depending upon whether we're adding or deleting. If the value after decrementing is zero, we remove it. */ smods = slapi_mods_new(); /* Get the present value of the subcount attr, or 0 if not present */ ret = slapi_entry_attr_find(mc->old_entry->ep_entry,numsubordinates,&read_attr); if (0 == ret) { /* decode the value */ Slapi_Value *sval; slapi_attr_first_value( read_attr, &sval ); if (sval!=NULL) { const struct berval *bval = slapi_value_get_berval(sval); if(NULL != bval) { already_present = 1; current_sub_count = atol(bval->bv_val); } } } if (PARENTUPDATE_DELETE_TOMBSTONE != repl_op) { /* are we adding ? */ if ( (PARENTUPDATE_ADD == op) && !already_present) { /* If so, and the parent entry does not already have a subcount * attribute, we need to add it */ mod_op = LDAP_MOD_ADD; } else if (PARENTUPDATE_DEL == op) { if (!already_present) { /* This means that something is wrong---deleting a child but no subcount present on parent */ LDAPDebug0Args( LDAP_DEBUG_ANY, "numsubordinates assertion failure\n" ); slapi_mods_free(&smods); return -1; } else { if (current_sub_count == 1) { mod_op = LDAP_MOD_DELETE; } else { mod_op = LDAP_MOD_REPLACE; } } } else { /* (PARENTUPDATE_ADD == op) && already_present */ mod_op = LDAP_MOD_REPLACE; } /* Now compute the new value */ if (PARENTUPDATE_ADD == op) { current_sub_count++; } else { current_sub_count--; } if (mod_op == LDAP_MOD_DELETE) { slapi_mods_add(smods, mod_op | LDAP_MOD_BVALUES, numsubordinates, 0, NULL); } else { sprintf(value_buffer,"%lu", current_sub_count); slapi_mods_add(smods, mod_op | LDAP_MOD_BVALUES, numsubordinates, strlen(value_buffer), value_buffer); } if (new_sub_count) { *new_sub_count = current_sub_count; } } /* tombstoneNumSubordinates is needed only when this is repl op * and a child is being deleted */ if (repl_op && (PARENTUPDATE_DEL == op)) { current_sub_count = LDAP_MAXINT; ret = slapi_entry_attr_find(mc->old_entry->ep_entry, tombstone_numsubordinates, &read_attr); if (0 == ret) { /* decode the value */ Slapi_Value *sval; slapi_attr_first_value( read_attr, &sval ); if (sval!=NULL) { const struct berval *bval = slapi_value_get_berval(sval); if(NULL != bval) { current_sub_count = atol(bval->bv_val); } } } if (PARENTUPDATE_DELETE_TOMBSTONE == repl_op) { /* deleting a tombstone entry: * reaping or manually deleting it */ if ((current_sub_count != LDAP_MAXINT) && (current_sub_count > 0)) { current_sub_count--; mod_op = LDAP_MOD_REPLACE; sprintf(value_buffer,"%lu", current_sub_count); slapi_mods_add(smods, mod_op | LDAP_MOD_BVALUES, tombstone_numsubordinates, strlen(value_buffer), value_buffer); } } if (PARENTUPDATE_CREATE_TOMBSTONE == repl_op) { /* creating a tombstone entry */ if (current_sub_count != LDAP_MAXINT) { current_sub_count++; } else { /* tombstonenumsubordinates does not exist */ current_sub_count = 1; } mod_op = LDAP_MOD_REPLACE; sprintf(value_buffer,"%lu", current_sub_count); slapi_mods_add(smods, mod_op | LDAP_MOD_BVALUES, tombstone_numsubordinates, strlen(value_buffer), value_buffer); } } ret = modify_apply_mods(mc, smods); /* smods passed in */ return ret; }