Ejemplo n.º 1
0
/**
   \details Release the MAPI handles context used by EMSMDB provider
   context

   \param data pointer on data to destroy

   \return 0 on success, otherwise -1
 */
static int emsmdbp_mapi_handles_destructor(void *data)
{
	enum MAPISTATUS			retval;
	struct mapi_handles_context	*handles_ctx = (struct mapi_handles_context *) data;

	retval = mapi_handles_release(handles_ctx);
	OC_DEBUG(6, "MAPI handles context released (%s)\n", mapi_get_errstr(retval));

	return (retval == MAPI_E_SUCCESS) ? 0 : -1;
}
Ejemplo n.º 2
0
/**
   \details Release the MAPI handles context used by EMSMDB provider
   context

   \param data pointer on data to destroy

   \return 0 on success, otherwise -1
 */
static int emsmdbp_mapi_handles_destructor(void *data)
{
	enum MAPISTATUS			retval;
	struct mapi_handles_context	*handles_ctx = (struct mapi_handles_context *) data;

	retval = mapi_handles_release(handles_ctx);
	DEBUG(6, ("[%s:%d]: MAPI handles context released (%s)\n", __FUNCTION__, __LINE__,
		  mapi_get_errstr(retval)));

	return (retval == MAPI_E_SUCCESS) ? 0 : -1;
}
Ejemplo n.º 3
0
/**
   \details EcDoRpc CreateFolder (0x1c) Rop. This operation creates a
   folder on the remote server.

   \param mem_ctx pointer to the memory context
   \param emsmdbp_ctx pointer to the emsmdb provider context
   \param mapi_req pointer to the CreateFolder EcDoRpc_MAPI_REQ
   structure
   \param mapi_repl pointer to the CreateFolder EcDoRpc_MAPI_REPL
   structure
   \param handles pointer to the MAPI handles array
   \param size pointer to the mapi_response size to update

   \return MAPI_E_SUCCESS on success, otherwise MAPI error

   \note We do not provide support for GhostInfo
 */
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCreateFolder(TALLOC_CTX *mem_ctx,
						 struct emsmdbp_context *emsmdbp_ctx,
						 struct EcDoRpc_MAPI_REQ *mapi_req,
						 struct EcDoRpc_MAPI_REPL *mapi_repl,
						 uint32_t *handles, uint16_t *size)
{
	enum MAPISTATUS			retval;
	enum mapistore_error		ret;
	struct mapi_handles		*parent = NULL;
	uint32_t			handle;
	uint64_t			parent_fid, fid, cn;
	struct SPropValue		cnValue;
	struct emsmdbp_object		*parent_object = NULL;
	struct emsmdbp_object		*object = NULL;
	struct CreateFolder_req		*request;
	struct CreateFolder_repl	*response;
	struct SRow			*aRow = NULL;
	void				*data;
	struct mapi_handles		*rec = NULL;

	OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder (0x1c)\n");

	/* Sanity checks */
	OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
	OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);

	/* Set up sensible values for the reply */
	mapi_repl->opnum = mapi_req->opnum;
	mapi_repl->error_code = MAPI_E_SUCCESS;
	mapi_repl->handle_idx = mapi_req->u.mapi_CreateFolder.handle_idx;

	if (!mapi_req->u.mapi_CreateFolder.ulFolderType ||
	    mapi_req->u.mapi_CreateFolder.ulFolderType > 0x2) {
		mapi_repl->error_code = MAPI_E_INVALID_PARAMETER;
		goto end;
	}

	/* Step 1. Retrieve parent handle in the hierarchy */
	handle = handles[mapi_req->handle_idx];
	retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
	OPENCHANGE_RETVAL_IF(retval, retval, NULL);

	/* With CreateFolder, the parent object really IS the parent object */
	mapi_handles_get_private_data(parent, &data);
	parent_object = (struct emsmdbp_object *)data;
	if (!parent_object) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder null object\n");
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	if (parent_object->type == EMSMDBP_OBJECT_MAILBOX) {
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	if (parent_object->type != EMSMDBP_OBJECT_FOLDER && parent_object->type != EMSMDBP_OBJECT_MAILBOX) {
		OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] CreateFolder wrong object type: 0x%x\n", parent_object->type);
		mapi_repl->error_code = MAPI_E_NO_SUPPORT;
		goto end;
	}

	request = &mapi_req->u.mapi_CreateFolder;
	response = &mapi_repl->u.mapi_CreateFolder;

	/* OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] CreateFolder parent: 0x%.16"PRIx64"\n", parent_fid)); */
	/* OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Creating %s\n", request->FolderName.lpszW)); */

	/* if (request->ulFolderType != FOLDER_GENERIC) { */
	/* 	OC_DEBUG(4, ("exchange_emsmdb: [OXCFOLD] Unexpected folder type 0x%x\n", request->ulType)); */
	/* 	mapi_repl->error_code = MAPI_E_NO_SUPPORT; */
	/* 	goto end; */
	/* } */

	response->IsExistingFolder = false;

	ret = emsmdbp_object_get_fid_by_name(emsmdbp_ctx, parent_object, request->FolderName.lpszW, &fid);
	if (ret == MAPISTORE_SUCCESS) {
		if (oxosfld_is_special_folder(emsmdbp_ctx, fid) || request->ulFlags == OPEN_IF_EXISTS) {
			response->IsExistingFolder = true;
		} else {
			if (emsmdbp_is_mapistore(parent_object)) {
				OC_DEBUG(5, "Folder %s exists in MAPIStore", request->FolderName.lpszW);
			} else {
				OC_DEBUG(5, "Folder %s exists in OpenChangeDB", request->FolderName.lpszW);
			}
			mapi_repl->error_code = MAPI_E_COLLISION;
			goto end;
		}
	}

	mapi_handles_add(emsmdbp_ctx->handles_ctx, 0, &rec);
	if (response->IsExistingFolder) {
		retval = emsmdbp_object_open_folder_by_fid(rec, emsmdbp_ctx, parent_object, fid, &object);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Failure opening existing folder: %s\n", mapi_get_errstr(retval));
			mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
			mapi_repl->error_code = retval;
			goto end;
		}
	} else {
		/* Step 3. Turn CreateFolder parameters into MAPI property array */
		parent_fid = parent_object->object.folder->folderID;
		if (openchangedb_is_public_folder_id(emsmdbp_ctx->oc_ctx, parent_fid)) {
			retval = openchangedb_get_new_public_folderID(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, &fid);
		} else {
			retval = mapistore_error_to_mapi(mapistore_indexing_get_new_folderID(emsmdbp_ctx->mstore_ctx, &fid));
		}
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Could not obtain a new folder id\n");
			mapi_repl->error_code = MAPI_E_NO_SUPPORT;
			goto end;
		}

		retval = openchangedb_get_new_changeNumber(emsmdbp_ctx->oc_ctx, emsmdbp_ctx->username, &cn);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(4, "exchange_emsmdb: [OXCFOLD] Could not obtain a new folder cn\n");
			mapi_repl->error_code = MAPI_E_NO_SUPPORT;
			goto end;
		}

		aRow = libmapiserver_ROP_request_to_properties(mem_ctx, (void *)&mapi_req->u.mapi_CreateFolder, op_MAPI_CreateFolder);
		aRow->lpProps = add_SPropValue(mem_ctx, aRow->lpProps, &(aRow->cValues), PR_PARENT_FID, (void *)(&parent_fid));
		cnValue.ulPropTag = PidTagChangeNumber;
		cnValue.value.d = cn;
		SRow_addprop(aRow, cnValue);

		retval = emsmdbp_object_create_folder(emsmdbp_ctx, parent_object, rec, fid,
						      aRow, true, &object);
		if (retval != MAPI_E_SUCCESS) {
			OC_DEBUG(5, "folder creation failed\n");
			mapi_handles_delete(emsmdbp_ctx->handles_ctx, rec->handle);
			mapi_repl->error_code = retval;
			goto end;
		}
	}

	handles[mapi_repl->handle_idx] = rec->handle;
	mapi_handles_set_private_data(rec, object);

	response->folder_id = fid;

	if (response->IsExistingFolder == true) {
		response->GhostUnion.GhostInfo.HasRules = false;
		response->GhostUnion.GhostInfo.IsGhosted = false;
	}

end:
	*size += libmapiserver_RopCreateFolder_size(mapi_repl);

	if (aRow) {
		talloc_free(aRow);
	}

	return MAPI_E_SUCCESS;
}
Ejemplo n.º 4
0
void import_mailbox(TALLOC_CTX *mem_ctx,
               struct mapi_session *session,
               struct mbox_data *mdata)
{
    enum MAPISTATUS retval;
    struct dirent   *direntp;
    DIR     *dirp;
    mapi_object_t   obj_store;
    char        *base_path;

    mdata->start_time = time(NULL);

    base_path = talloc_asprintf(mem_ctx, "%s/%s", DEFAULT_EXPORT_PATH, mdata->username);
    if (!base_path) {
        goto fail;
    }


    /* Open systemfolder database */
    mdata->tdb_sysfolder = tdb_open_database(mdata, base_path, TDB_SYSFOLDER);
    if (!mdata->tdb_sysfolder) {
        DEBUG(0, ("[!] Error opening system folder db\n"));
        goto fail;
    }

    /* Open PidTagFolderID to FolderName database */
    mdata->tdb_foldermap = tdb_open_database(mdata, base_path, TDB_FOLDERMAP);
    if (!mdata->tdb_foldermap) {
        DEBUG(0, ("[!] Error opening id mapping db\n"));
        goto fail;
    }

    /* Open the folder */
    dirp = opendir(base_path);
    if (!dirp) {
        DEBUG(0, ("[!] Error opening directory %s: %s (%d)\n",
            base_path, strerror(errno), errno));
        goto fail;
    }

    /* Open the root folder */
    mapi_object_init(&obj_store);
    retval = OpenUserMailbox(session, mdata->username, &obj_store);
        if (retval != MAPI_E_SUCCESS) {
        const char *error = mapi_get_errstr(GetLastError());
        DEBUG(0, ("[!] OpenUserMailbox: %s\n", error));
        goto fail;
    }

    /* Import the directory */
    while ((direntp = readdir(dirp)) != NULL) {
        if (strncasecmp(direntp->d_name, "0x", 2) == 0) {
            /* This is the root folder */
            char *path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name);
            retval = import_directory(mem_ctx, mdata, &obj_store, NULL, path);
            if (retval != MAPI_E_SUCCESS) {
                DEBUG(0, ("import_directory failed with %s\n",
                    mapi_get_errstr(GetLastError())));
                break;
            }
            talloc_free(path);
            break;
        }
    }

fail:
    mapi_object_release(&obj_store);
    if (dirp)
        closedir(dirp);
    if (mdata->tdb_foldermap) {
        tdb_close(mdata->tdb_foldermap);
        mdata->tdb_foldermap = NULL;
    }
    if (mdata->tdb_sysfolder) {
        tdb_close(mdata->tdb_sysfolder);
        mdata->tdb_sysfolder = NULL;
    }
    if (base_path)
        talloc_free(base_path);
    mdata->end_time = time(NULL);
    return;
}
Ejemplo n.º 5
0
static enum MAPISTATUS import_directory(TALLOC_CTX *mem_ctx,
                    const struct mbox_data *mdata,
                    mapi_object_t *obj_store,
                    mapi_object_t *obj_parent,
                    const char *base_path)
{
    enum MAPISTATUS retval;
    DIR     *dirp;
    struct dirent   *direntp;
    mapi_object_t   obj_folder;
    mapi_object_t   obj_inbox;
    mapi_object_t   obj_child;
    mapi_id_t   id_folder;
    char        *folder_id;
    char        *olFolderSrc;
    struct SPropTagArray        *SPropTagArray;
    struct SPropValue   *lpProps;
    uint32_t        cValues = 0;
    struct SRow          aRow;

    DEBUG(5,("[*] Importing directory %s\n", base_path));

    /* Open the filesystem folder */
    dirp = opendir(base_path);
    if (!dirp) {
        DEBUG(0, ("[!] Error opening directory %s: %s (%d)\n",
            base_path, strerror(errno), errno));
        return MAPI_E_NOT_FOUND; // TODO map to proper code
    }

    mapi_object_init(&obj_folder);
    mapi_object_init(&obj_child);
    mapi_object_init(&obj_inbox);

    /* I want to get the folder ID from the remote Exchange server and
    check in the systemfolder database if it matches with something.
    we can get the remote folder ID from the directory name */
    folder_id = import_get_folder_id(base_path);
    if (!folder_id) {
        DEBUG(0, ("[!] Error getting folder ID from directory name\n"));
        return MAPI_E_NOT_FOUND; // TODO map to proper code
    }

    if (!obj_parent) {
        DEBUG(5, ("parent is null\n"));

        retval = GetDefaultFolder(obj_store, &id_folder, olFolderInbox);
        if (retval != MAPI_E_SUCCESS) {
            DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError())));
            return retval;
        }
        DEBUG(4, ("[*] Opening folder %u\n", olFolderInbox));
        retval = OpenFolder(obj_store, id_folder, &obj_inbox);
        if (retval != MAPI_E_SUCCESS) {
            DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError())));
            return retval;
        }
        obj_parent = &obj_inbox;
    }

    /* XXX Begin of hack */
#if 0
    olFolderSrc = import_is_system_folder(mdata, folder_id);
    if (!olFolderSrc) {
        DEBUG(5, ("[*] Not system folder, skip\n"));
        talloc_free(olFolderSrc);
        return MAPI_E_SUCCESS;
    }
    uint32_t olFolder = atoi(olFolderSrc);
    talloc_free(olFolderSrc);
    retval = MAPI_E_SUCCESS;
    if (olFolder == olFolderContacts) {
        retval = GetDefaultFolder(obj_store, &id_folder, olFolderContacts);
    } else if (olFolder == olFolderCalendar) {
        retval = GetDefaultFolder(obj_store, &id_folder, olFolderCalendar);
    } else if (olFolder == olFolderTopInformationStore) {
        retval = GetDefaultFolder(obj_store, &id_folder, olFolderInbox);
    }

    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError())));
        return retval;
    }

    DEBUG(4, ("Opening folder %u\n", olFolder));
    retval = OpenFolder(obj_store, id_folder, &obj_folder);
    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError())));
        return retval;
    }
#endif
    /* XXX end of hack */
#if 1
    olFolderSrc = import_is_system_folder(mdata, folder_id);
    if (olFolderSrc) {
        char *folder_name = import_get_folder_name(mdata, folder_id);
        if (folder_name) {
            DEBUG(5, ("[*] Origin Folder '%s' mapped to name '%s'\n", folder_id, folder_name));
            talloc_free(folder_name);
            folder_name = NULL;
        }
        /* This is a system folder, then I am calling GetDefaultFolder
        to retrieve the id then I open the folder */
        uint32_t olFolder = atoi(olFolderSrc);
        talloc_free(olFolderSrc);

        retval = GetDefaultFolder(obj_store, &id_folder, olFolder);
        if (retval != MAPI_E_SUCCESS) {
            DEBUG(0, ("[!] GetDefaultFolder: %s\n", mapi_get_errstr(GetLastError())));
            return retval;
        }
        DEBUG(4, ("[*] Opening folder %u\n", olFolder));
        retval = OpenFolder(obj_store, id_folder, &obj_folder);
        if (retval != MAPI_E_SUCCESS) {
            DEBUG(0, ("[!] OpenFolder: %s\n", mapi_get_errstr(GetLastError())));
            return retval;
        }


        SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PidTagDisplayName);
        retval = GetProps(&obj_folder, MAPI_UNICODE, SPropTagArray, &lpProps, &cValues);
        MAPIFreeBuffer(SPropTagArray);
        if (retval == MAPI_E_SUCCESS) {
            aRow.cValues = cValues;
            aRow.lpProps = lpProps;
            folder_name = (char *) find_SPropValue_data(&aRow, PidTagDisplayName);
            if (folder_name) {
                DEBUG(5, ("[*] Destination Folder: '%s'\n", folder_name));
            }
        }
    } else {
        /*  this is not a system folder, I know what is the root base where
         need to create it i and open it */
        char *folder_name = import_get_folder_name(mdata, folder_id);
        if (!folder_name) {
            DEBUG(0, ("[!] Invalid Folder Name\n"));
            return MAPI_E_INVALID_PARAMETER;
        }
        DEBUG(4, ("[*] Creating folder %s\n", folder_name));
        retval = CreateFolder(obj_parent, FOLDER_GENERIC, folder_name,
                      NULL, OPEN_IF_EXISTS|MAPI_UNICODE, &obj_folder);
        if (retval != MAPI_E_SUCCESS) {
            DEBUG(0, ("[!] CreateFolder: %s\n", mapi_get_errstr(GetLastError())));
            talloc_free(folder_name);
            return retval;
        }
        talloc_free(folder_name);
        return MAPI_E_SUCCESS;
    }
#endif

    /* Import the files and clildren folders */
    while ((direntp = readdir(dirp)) != NULL) {
        if (strcmp(direntp->d_name, ".") == 0) {
            continue;
        }
        if (strcmp(direntp->d_name, "..") == 0) {
            continue;
        }
        char *ext = strrchr(direntp->d_name, '.');
        if (!ext) {
            if (strncasecmp(direntp->d_name, "0x", 2) == 0) {
                char *child_path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name);
                retval = import_directory(mem_ctx, mdata, obj_store, &obj_folder, child_path);
                if (retval != MAPI_E_SUCCESS) {
                        DEBUG(0, ("import_directory failed with %s\n", mapi_get_errstr(GetLastError())));
                        talloc_free(child_path);
                        return retval;
                }
                talloc_free(child_path);
            }
            continue;
        }
        if (strncasecmp(ext, ".ocpf", 5) == 0) {
            char *child_path = talloc_asprintf(mem_ctx, "%s/%s", base_path, direntp->d_name);
            import_ocpf_file(mem_ctx, mdata, obj_store, &obj_folder, child_path);
            talloc_free(child_path);
        }
    }

    mapi_object_release(&obj_folder);
    mapi_object_release(&obj_inbox);

    /* Close directory */
    closedir(dirp);

    return retval;
}
Ejemplo n.º 6
0
static enum MAPISTATUS import_ocpf_file(TALLOC_CTX *mem_ctx,
                    const struct mbox_data *mdata,
                    mapi_object_t *obj_store,
                    mapi_object_t *obj_folder,
                    const char *base_path)
{
    int         ret;
    enum MAPISTATUS retval;
    mapi_object_t   obj_message;
    uint32_t    context_id;
    mapi_id_t   folder_id;
    uint32_t        cValues = 0;
    struct SPropValue *lpProps;

    DEBUG(4, ("[*] Importing OCPF file '%s'\n", base_path));

    /* Initialize OCPF context */
    ret = ocpf_init();
    if (ret == -1) {
        DEBUG(0, ("[!] ocpf_init\n"));
        return MAPI_E_CALL_FAILED;
    }

    folder_id =  mapi_object_get_id(obj_folder);
    if (folder_id == -1) {
        retval = MAPI_E_CALL_FAILED;
        DEBUG(0, ("[!] mapi_object_get_id: %s\n",
            mapi_get_errstr(retval)));
        return retval;
    }

    ret = ocpf_new_context(base_path, &context_id, OCPF_FLAGS_READ);
    if (ret == -1) {
        retval = MAPI_E_CALL_FAILED;
        DEBUG(0, ("[!] ocpf_new_context: %s\n", mapi_get_errstr(retval)));
        return retval;
    }

    ret = ocpf_parse(context_id);
    if (ret == -1) {
        retval = MAPI_E_CALL_FAILED;
        DEBUG(0, ("[!] ocpf_parse: %s\n", mapi_get_errstr(retval)));
        return retval;
    }

    /* Create the object */
    mapi_object_init(&obj_message);
    retval = CreateMessage(obj_folder, &obj_message);
    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] CreateMessage: %s\n", mapi_get_errstr(retval)));
        mapi_object_release(&obj_message);
        return retval;
    }

    /* Set message recipients */
    //retval = ocpf_set_Recipients(mem_ctx, context_id, &obj_message);
    //if (retval != MAPI_E_SUCCESS && GetLastError() != MAPI_E_NOT_FOUND) return false;
    //errno = MAPI_E_SUCCESS;

    /* Set message properties */
    retval = ocpf_set_SPropValue(mem_ctx, context_id, obj_folder, &obj_message);
    if (retval == MAPI_W_ERRORS_RETURNED) {
        DEBUG(0, ("[!] ocpf_set_SPropValue: %s\n", mapi_get_errstr(retval)));
    } else if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] ocpf_set_SPropValue: %s\n", mapi_get_errstr(retval)));
        mapi_object_release(&obj_message);
        return retval;
    }

    /* Set message properties */
    lpProps = ocpf_get_SPropValue(context_id, &cValues);
    retval = SetProps(&obj_message, 0, lpProps, cValues);
    MAPIFreeBuffer(lpProps);
    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] ocpf_get_SPropValue: %s\n", mapi_get_errstr(retval)));
        mapi_object_release(&obj_message);
        return retval;
    }

    retval = ocpf_server_set_folderID(context_id, folder_id);
    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] ocpf_server_set_folderIF: %s\n", mapi_get_errstr(retval)));
        mapi_object_release(&obj_message);
        return retval;
    }

    /* Save message */
    retval = SaveChangesMessage(obj_folder, &obj_message, KeepOpenReadOnly);
    if (retval != MAPI_E_SUCCESS) {
        DEBUG(0, ("[!] SaveChangesMessage: %s\n", mapi_get_errstr(retval)));
        return retval;
    }

    mapi_object_release(&obj_message);
    ocpf_del_context(context_id);
    ocpf_release();
    return MAPI_E_SUCCESS;
}