Ejemplo n.º 1
0
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryAuthDN(const nsACString & aValueUsedToFindDn)
{
    if(!mInitialized) 
        return NS_ERROR_NOT_INITIALIZED;

    nsresult rv = NS_OK; 

    CharPtrArrayGuard attributes;
    *attributes.GetSizeAddr() = 2;
    *attributes.GetArrayAddr() = NS_STATIC_CAST(char **, nsMemory::Alloc((*attributes.GetSizeAddr()) * sizeof(char *)));
    attributes.GetArray()[0] = ToNewCString(nsDependentCString(DIR_GetFirstAttributeString(mDirServer, cn)));
    attributes.GetArray()[1] = nsnull;
    
    nsCAutoString filter(DIR_GetFirstAttributeString(mDirServer, auth));
    filter += '=';
    filter += aValueUsedToFindDn;

    nsCAutoString dn;
    rv = mURL->GetDn(dn);
    if(NS_FAILED(rv)) 
        return rv;

    rv = CreateNewLDAPOperation();
    NS_ENSURE_SUCCESS(rv, rv);

    return mOperation->SearchExt(dn, nsILDAPURL::SCOPE_SUBTREE, filter, 
                               attributes.GetSize(), attributes.GetArray(),
                               0, 0);
}
Ejemplo n.º 2
0
NS_IMETHODIMP nsAbLDAPChangeLogQuery::QueryChangedEntries(const nsACString & aChangedEntryDN)
{
    if(!mInitialized) 
        return NS_ERROR_NOT_INITIALIZED;
    if(aChangedEntryDN.IsEmpty()) 
        return NS_ERROR_UNEXPECTED;

    nsCAutoString urlFilter;
    nsresult rv = mURL->GetFilter(urlFilter);
    if(NS_FAILED(rv)) 
        return rv;

    PRInt32 scope;
    rv = mURL->GetScope(&scope);
    if(NS_FAILED(rv)) 
        return rv;

    CharPtrArrayGuard attributes;
    rv = mURL->GetAttributes(attributes.GetSizeAddr(), attributes.GetArrayAddr());
    if(NS_FAILED(rv)) 
        return rv;

    rv = CreateNewLDAPOperation();
    NS_ENSURE_SUCCESS(rv, rv);
    return mOperation->SearchExt(aChangedEntryDN, scope, urlFilter, 
                               attributes.GetSize(), attributes.GetArray(),
                               0, 0);
}
Ejemplo n.º 3
0
nsresult nsAbQueryLDAPMessageListener::DoSearch()
{
    nsresult rv;
    mCanceled = mFinished = PR_FALSE;

    mSearchOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIProxyObjectManager> proxyMgr =
        do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsILDAPMessageListener> proxyListener;
    rv = proxyMgr->GetProxyForObject( NS_UI_THREAD_EVENTQ, NS_GET_IID(nsILDAPMessageListener),
                                      this, PROXY_SYNC | PROXY_ALWAYS, getter_AddRefs(proxyListener));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mSearchOperation->Init (mConnection, proxyListener, nsnull);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCAutoString dn;
    rv = mUrl->GetDn (dn);
    NS_ENSURE_SUCCESS(rv, rv);

    PRInt32 scope;
    rv = mUrl->GetScope (&scope);
    NS_ENSURE_SUCCESS(rv, rv);

    nsCAutoString filter;
    rv = mUrl->GetFilter (filter);
    NS_ENSURE_SUCCESS(rv, rv);

    CharPtrArrayGuard attributes;
    rv = mUrl->GetAttributes (attributes.GetSizeAddr (), attributes.GetArrayAddr ());
    NS_ENSURE_SUCCESS(rv, rv);

    // I don't _think_ it's ever actually possible to get here without having
    // an nsAbLDAPDirectory object, but, just in case, I'll do a QI instead
    // of just static casts...
    nsCOMPtr<nsIAbLDAPDirectory> nsIAbDir =
        do_QueryInterface(mDirectoryQuery, &rv);
    NS_ENSURE_SUCCESS(rv, rv);
    nsAbLDAPDirectory *dir =
        NS_STATIC_CAST(nsAbLDAPDirectory *,
                       NS_STATIC_CAST(nsIAbLDAPDirectory *, nsIAbDir.get()));

    rv = mSearchOperation->SetServerControls(dir->mSearchServerControls.get());
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mSearchOperation->SetClientControls(dir->mSearchClientControls.get());
    NS_ENSURE_SUCCESS(rv, rv);

    rv = mSearchOperation->SearchExt (dn, scope, filter,
                                      attributes.GetSize (), attributes.GetArray (),
                                      mTimeOut, mResultLimit);
    return rv;
}
nsresult nsAbLDAPProcessChangeLogData::ParseRootDSEEntry(nsILDAPMessage *aMessage)
{
    NS_ENSURE_ARG_POINTER(aMessage);
    if (!mInitialized)
        return NS_ERROR_NOT_INITIALIZED;

    // Populate the RootDSEChangeLogEntry
    CharPtrArrayGuard attrs;
    nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
    // No attributes
    if(NS_FAILED(rv)) 
        return rv;

    for(PRInt32 i=attrs.GetSize()-1; i >= 0; i--) {
        PRUnicharPtrArrayGuard vals;
        rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
        if(NS_FAILED(rv))
            continue;
        if(vals.GetSize()) {
            if (!PL_strcasecmp(attrs[i], "changelog"))
                CopyUTF16toUTF8(vals[0], mRootDSEEntry.changeLogDN);
            if (!PL_strcasecmp(attrs[i], "firstChangeNumber"))
                mRootDSEEntry.firstChangeNumber = atol(NS_LossyConvertUTF16toASCII(vals[0]).get());
            if (!PL_strcasecmp(attrs[i], "lastChangeNumber"))
                mRootDSEEntry.lastChangeNumber = atol(NS_LossyConvertUTF16toASCII(vals[0]).get());
            if (!PL_strcasecmp(attrs[i], "dataVersion"))
                CopyUTF16toUTF8(vals[0], mRootDSEEntry.dataVersion);
        }
    }

    PRInt32 lastChangeNumber;
    mDirectory->GetLastChangeNumber(&lastChangeNumber);

    if ((mRootDSEEntry.lastChangeNumber > 0) &&
        (lastChangeNumber < mRootDSEEntry.lastChangeNumber) &&
        (lastChangeNumber > mRootDSEEntry.firstChangeNumber))
        mUseChangeLog = PR_TRUE;

    if (mRootDSEEntry.lastChangeNumber &&
        (lastChangeNumber == mRootDSEEntry.lastChangeNumber)) {
        Done(PR_TRUE); // We are up to date no need to replicate, db not open yet so call Done
        return NS_OK;
    }

    return rv;
}
NS_IMETHODIMP nsAbLDAPDirectory::ModifyCard(nsIAbCard *aUpdatedCard)
{
  NS_ENSURE_ARG_POINTER(aUpdatedCard);
  
  nsCOMPtr<nsIAbLDAPAttributeMap> attrMap;
  nsresult rv = GetAttributeMap(getter_AddRefs(attrMap));
  NS_ENSURE_SUCCESS(rv, rv);

  // Get the LDAP card
  nsCOMPtr<nsIAbLDAPCard> card = do_QueryInterface(aUpdatedCard, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = Initiate();
  NS_ENSURE_SUCCESS(rv, rv);
  
  // Retrieve preferences
  nsAutoCString prefString;
  rv = GetObjectClasses(prefString);
  NS_ENSURE_SUCCESS(rv, rv);
  
  CharPtrArrayGuard objClass;
  rv = SplitStringList(prefString, objClass.GetSizeAddr(),
    objClass.GetArrayAddr());
  NS_ENSURE_SUCCESS(rv, rv);

  // Process updates
  nsCOMPtr<nsIArray> modArray;
  rv = card->GetLDAPMessageInfo(attrMap, objClass.GetSize(), objClass.GetArray(),
    nsILDAPModification::MOD_REPLACE, getter_AddRefs(modArray));
  NS_ENSURE_SUCCESS(rv, rv);
  
  // Get current DN
  nsAutoCString oldDN;
  rv = card->GetDn(oldDN);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsILDAPService> ldapSvc = do_GetService(
    "@mozilla.org/network/ldap-service;1", &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // Retrieve base DN and RDN attributes
  nsAutoCString baseDN;
  nsAutoCString oldRDN;
  CharPtrArrayGuard rdnAttrs;
  rv = ldapSvc->ParseDn(oldDN.get(), oldRDN, baseDN,
                        rdnAttrs.GetSizeAddr(), rdnAttrs.GetArrayAddr());
  NS_ENSURE_SUCCESS(rv, rv);

  // Calculate new RDN and check whether it has changed
  nsAutoCString newRDN;
  rv = card->BuildRdn(attrMap, rdnAttrs.GetSize(), rdnAttrs.GetArray(),
    newRDN);
  NS_ENSURE_SUCCESS(rv, rv);
      
  if (newRDN.Equals(oldRDN))
  {
    // Launch query
    rv = DoModify(this, nsILDAPModification::MOD_REPLACE, oldDN, modArray,
                  EmptyCString(), EmptyCString());
  }
  else
  {
    // Build and store the new DN
    nsAutoCString newDN(newRDN);
    newDN.AppendLiteral(",");
    newDN.Append(baseDN);
    
    rv = card->SetDn(newDN);
    NS_ENSURE_SUCCESS(rv, rv);
    
    // Launch query
    rv = DoModify(this, nsILDAPModification::MOD_REPLACE, oldDN, modArray,
                  newRDN, baseDN);
  }
  return rv;
}
NS_IMETHODIMP nsAbLDAPDirectory::AddCard(nsIAbCard *aUpdatedCard,
                                         nsIAbCard **aAddedCard)
{
  NS_ENSURE_ARG_POINTER(aUpdatedCard);
  NS_ENSURE_ARG_POINTER(aAddedCard);
  
  nsCOMPtr<nsIAbLDAPAttributeMap> attrMap;
  nsresult rv = GetAttributeMap(getter_AddRefs(attrMap));
  NS_ENSURE_SUCCESS(rv, rv);

  // Create a new LDAP card
  nsCOMPtr<nsIAbLDAPCard> card =
    do_CreateInstance(NS_ABLDAPCARD_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = Initiate();
  NS_ENSURE_SUCCESS(rv, rv);

  // Copy over the card data
  nsCOMPtr<nsIAbCard> copyToCard = do_QueryInterface(card, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = copyToCard->Copy(aUpdatedCard);
  NS_ENSURE_SUCCESS(rv, rv);
  
  // Retrieve preferences
  nsAutoCString prefString;
  rv = GetRdnAttributes(prefString);
  NS_ENSURE_SUCCESS(rv, rv);

  CharPtrArrayGuard rdnAttrs;
  rv = SplitStringList(prefString, rdnAttrs.GetSizeAddr(),
    rdnAttrs.GetArrayAddr());
  NS_ENSURE_SUCCESS(rv, rv);
  
  rv = GetObjectClasses(prefString);
  NS_ENSURE_SUCCESS(rv, rv);
  
  CharPtrArrayGuard objClass;
  rv = SplitStringList(prefString, objClass.GetSizeAddr(),
    objClass.GetArrayAddr());
  NS_ENSURE_SUCCESS(rv, rv);

  // Process updates
  nsCOMPtr<nsIArray> modArray;
  rv = card->GetLDAPMessageInfo(attrMap, objClass.GetSize(), objClass.GetArray(),
    nsILDAPModification::MOD_ADD, getter_AddRefs(modArray));
  NS_ENSURE_SUCCESS(rv, rv);
  
  // For new cards, the base DN is the search base DN
  nsCOMPtr<nsILDAPURL> currentUrl;
  rv = GetLDAPURL(getter_AddRefs(currentUrl));
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString baseDN;
  rv = currentUrl->GetDn(baseDN);
  NS_ENSURE_SUCCESS(rv, rv);
 
  // Calculate DN
  nsAutoCString cardDN;
  rv = card->BuildRdn(attrMap, rdnAttrs.GetSize(), rdnAttrs.GetArray(),
    cardDN);
  NS_ENSURE_SUCCESS(rv, rv);
  cardDN.AppendLiteral(",");
  cardDN.Append(baseDN);

  rv = card->SetDn(cardDN);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoCString ourUuid;
  GetUuid(ourUuid);
  copyToCard->SetDirectoryId(ourUuid);

  // Launch query
  rv = DoModify(this, nsILDAPModification::MOD_ADD, cardDN, modArray,
                EmptyCString(), EmptyCString());
  NS_ENSURE_SUCCESS(rv, rv);

  NS_ADDREF(*aAddedCard = copyToCard);
  return NS_OK;
}
nsresult nsAbLDAPProcessChangeLogData::ParseChangeLogEntries(nsILDAPMessage *aMessage)
{
    NS_ENSURE_ARG_POINTER(aMessage);
    if(!mInitialized) 
        return NS_ERROR_NOT_INITIALIZED;

    // Populate the RootDSEChangeLogEntry
    CharPtrArrayGuard attrs;
    nsresult rv = aMessage->GetAttributes(attrs.GetSizeAddr(), attrs.GetArrayAddr());
    // No attributes
    if(NS_FAILED(rv)) 
        return rv;

    nsAutoString targetDN;
    UpdateOp operation = NO_OP;
    for(PRInt32 i = attrs.GetSize()-1; i >= 0; i--) {
        PRUnicharPtrArrayGuard vals;
        rv = aMessage->GetValues(attrs.GetArray()[i], vals.GetSizeAddr(), vals.GetArrayAddr());
        if(NS_FAILED(rv))
            continue;
        if(vals.GetSize()) {
            if (!PL_strcasecmp(attrs[i], "targetdn"))
                targetDN = vals[0];
            if (!PL_strcasecmp(attrs[i], "changetype")) {
                if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("add"), nsCaseInsensitiveStringComparator()))
                    operation = ENTRY_ADD;
                if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("modify"), nsCaseInsensitiveStringComparator()))
                    operation = ENTRY_MODIFY;
                if (!Compare(nsDependentString(vals[0]), NS_LITERAL_STRING("delete"), nsCaseInsensitiveStringComparator()))
                    operation = ENTRY_DELETE;
            }
        }
    }

    mChangeLogEntriesCount++;
    if(!(mChangeLogEntriesCount % 10)) { // Inform the listener every 10 entries
        mListener->OnProgressChange(nsnull,nsnull,mChangeLogEntriesCount, -1, mChangeLogEntriesCount, -1);
        // In case if the LDAP Connection thread is starved and causes problem
        // uncomment this one and try.
        // PR_Sleep(PR_INTERVAL_NO_WAIT); // give others a chance
    }

#ifdef DEBUG_rdayal
    printf ("ChangeLog Replication : Updated Entry : %s for OpType : %u\n", 
                                    NS_ConvertUTF16toUTF8(targetDN).get(), operation);
#endif

    switch(operation) {
    case ENTRY_ADD:
        // Add the DN to the add list if not already in the list
        if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
            mEntriesToAdd.AppendString(targetDN);
        break;
    case ENTRY_DELETE:
        // Do not check the return here since delete may fail if
        // entry deleted in changelog does not exist in DB
        // for e.g if the user specifies a filter, so go next entry
        DeleteCard(targetDN);
        break;
    case ENTRY_MODIFY:
        // For modify, delete the entry from DB and add updated entry
        // we do this since we cannot access the changes attribs of changelog
        rv = DeleteCard(targetDN);
        if (NS_SUCCEEDED(rv)) 
            if(!(mEntriesToAdd.IndexOf(targetDN) >= 0))
                mEntriesToAdd.AppendString(targetDN);
        break;
    default:
        // Should not come here, would come here only
        // if the entry is not a changeLog entry
        NS_WARNING("nsAbLDAPProcessChangeLogData::ParseChangeLogEntries"
           "Not an changelog entry");
    }

    // Go ahead processing the next entry, a modify or delete DB operation
    // can 'correctly' fail if the entry is not present in the DB,
    // e.g. in case a filter is specified.
    return NS_OK;
}